[GRASS-SVN] r34916 - in grass/trunk: include lib/display lib/driver lib/htmldriver lib/pngdriver lib/raster

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Dec 17 12:09:34 EST 2008


Author: glynn
Date: 2008-12-17 12:09:34 -0500 (Wed, 17 Dec 2008)
New Revision: 34916

Added:
   grass/trunk/lib/display/clip.c
   grass/trunk/lib/display/clip.h
   grass/trunk/lib/driver/path.h
Removed:
   grass/trunk/lib/driver/Polydots.c
   grass/trunk/lib/driver/Polygon.c
   grass/trunk/lib/driver/Polyline.c
Modified:
   grass/trunk/include/display.h
   grass/trunk/include/raster.h
   grass/trunk/lib/display/cnversions.c
   grass/trunk/lib/display/draw2.c
   grass/trunk/lib/display/window.c
   grass/trunk/lib/driver/Draw.c
   grass/trunk/lib/driver/Get_t_box.c
   grass/trunk/lib/driver/Text.c
   grass/trunk/lib/driver/Text_size.c
   grass/trunk/lib/driver/driver.h
   grass/trunk/lib/driver/driverlib.h
   grass/trunk/lib/driver/init.c
   grass/trunk/lib/driver/path.c
   grass/trunk/lib/driver/text2.c
   grass/trunk/lib/driver/text3.c
   grass/trunk/lib/htmldriver/Draw.c
   grass/trunk/lib/htmldriver/Polygon.c
   grass/trunk/lib/htmldriver/htmlmap.h
   grass/trunk/lib/pngdriver/Draw.c
   grass/trunk/lib/pngdriver/Draw_line.c
   grass/trunk/lib/pngdriver/Polygon.c
   grass/trunk/lib/pngdriver/pngdriver.h
   grass/trunk/lib/raster/raster.c
Log:
Display clean-up
Remove low-level line, polydots, polyline, polygon functions
Extend, clean-up path functions
Clean-up text functions
Add clipping, culling to display library



Modified: grass/trunk/include/display.h
===================================================================
--- grass/trunk/include/display.h	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/include/display.h	2008-12-17 17:09:34 UTC (rev 34916)
@@ -4,6 +4,13 @@
 #include <grass/gis.h>
 #include <grass/symbol.h>
 
+enum clip_mode
+{
+    M_NONE,
+    M_CULL,
+    M_CLIP,
+};
+
 /* cnversions.c */
 void D_update_conversions(void);
 void D_fit_d_to_u(void);
@@ -72,6 +79,8 @@
 
 void D_set_clip(double, double, double, double);
 void D_clip_to_map(void);
+void D_set_clip_mode(int);
+void D_set_reduction(double);
 
 void D_line_width(double);
 void D_get_text_box(const char *, double *, double *, double *, double *);
@@ -98,6 +107,7 @@
 void D_close(void);
 void D_stroke(void);
 void D_fill(void);
+void D_dots(void);
 
 /* icon.c */
 void D_plot_icon(double, double, int, double, double);

Modified: grass/trunk/include/raster.h
===================================================================
--- grass/trunk/include/raster.h	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/include/raster.h	2008-12-17 17:09:34 UTC (rev 34916)
@@ -14,10 +14,6 @@
 void R_erase(void);
 
 void R_pos_abs(double, double);
-void R_line_abs(double, double, double, double);
-void R_polydots_abs(const double *, const double *, int);
-void R_polyline_abs(const double *, const double *, int);
-void R_polygon_abs(const double *, const double *, int);
 void R_box_abs(double, double, double, double);
 
 void R_begin(void);

Added: grass/trunk/lib/display/clip.c
===================================================================
--- grass/trunk/lib/display/clip.c	                        (rev 0)
+++ grass/trunk/lib/display/clip.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -0,0 +1,163 @@
+
+#include <math.h>
+#include <string.h>
+
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/display.h>
+#include <grass/glocale.h>
+#include "path.h"
+#include "clip.h"
+
+/******************************************************************************/
+
+static double dist_plane(double x, double y, const struct plane *p)
+{
+    return x * p->x + y * p->y + p->k;
+}
+
+static double interpolate(double a, double b, double ka, double kb)
+{
+    return (a * kb - b * ka) / (kb - ka);
+}
+
+static void clip_path_plane(struct path *dst, const struct path *src,
+			    const struct plane *p)
+{
+    struct vertex *v0 = &src->vertices[src->count - 1];
+    double x0 = v0->x;
+    double y0 = v0->y;
+    double d0 = dist_plane(x0, y0, p);
+    int i;
+
+    path_reset(dst);
+
+    for (i = 0; i < src->count; i++) {
+	struct vertex *v1 = &src->vertices[i];
+	double x1 = v1->x;
+	double y1 = v1->y;
+	double d1 = dist_plane(x1, y1, p);
+	int in0 = d0 <= 0;
+	int in1 = d1 <= 0;
+
+	if (in0 && !in1) {
+	    /* leaving */
+	    double x = interpolate(x0, x1, d0, d1);
+	    double y = interpolate(y0, y1, d0, d1);
+	    path_cont(dst, x, y);
+	}
+
+	if (!in0 && in1) {
+	    /* entering */
+	    double x = interpolate(x0, x1, d0, d1);
+	    double y = interpolate(y0, y1, d0, d1);
+	    path_move(dst, x, y);
+	}
+
+	if (in1)
+	    /* inside */
+	    path_cont(dst, x1, y1);
+
+	x0 = x1;
+	y0 = y1;
+	d0 = d1;
+    }
+}
+
+/******************************************************************************/
+
+static void cull_path_plane(struct path *dst, const struct path *src,
+			    const struct plane *p)
+{
+    int last = -1;
+    int prev = src->count - 1;
+    struct vertex *v0 = &src->vertices[prev];
+    double x0 = v0->x;
+    double y0 = v0->y;
+    double d0 = dist_plane(x0, y0, p);
+    int i;
+
+    path_reset(dst);
+
+    for (i = 0; i < src->count; i++) {
+	struct vertex *v1 = &src->vertices[i];
+	double x1 = v1->x;
+	double y1 = v1->y;
+	double d1 = dist_plane(x1, y1, p);
+	int in0 = d0 <= 0;
+	int in1 = d1 <= 0;
+
+	if (!in0 && in1 && last != prev) {
+	    /* entering */
+	    path_move(dst, x0, y0);
+	    last = prev;
+	}
+
+	if (in1 || in0) {
+	    /* inside or leaving */
+	    path_cont(dst, x1, y1);
+	    last = i;
+	}
+
+	x0 = x1;
+	y0 = y1;
+	d0 = d1;
+	prev = i;
+    }
+}
+
+/******************************************************************************/
+
+void D__set_clip_planes(struct clip *clip, const struct rectangle *rect)
+{
+    clip->left.x = -1;
+    clip->left.y = 0;
+    clip->left.k = rect->left;
+
+    clip->rite.x = 1;
+    clip->rite.y = 0;
+    clip->rite.k = -rect->rite;
+
+    clip->bot.x = 0;
+    clip->bot.y = -1;
+    clip->bot.k = rect->bot;
+
+    clip->top.x = 0;
+    clip->top.y = 1;
+    clip->top.k = -rect->top;
+}
+
+void D__cull_path(struct path *dst, const struct path *src, const struct clip *clip)
+{
+    struct path tmp1, tmp2;
+
+    path_init(&tmp1);
+    path_init(&tmp2);
+
+    cull_path_plane(&tmp1, src, &clip->left);
+    cull_path_plane(&tmp2, &tmp1, &clip->rite);
+    cull_path_plane(&tmp1, &tmp2, &clip->bot);
+    cull_path_plane(dst, &tmp1, &clip->top);
+
+    path_free(&tmp1);
+    path_free(&tmp2);
+}
+
+void D__clip_path(struct path *dst, const struct path *src, const struct clip *clip)
+{
+    struct path tmp1, tmp2;
+
+    path_init(&tmp1);
+    path_init(&tmp2);
+
+    clip_path_plane(&tmp1, src, &clip->left);
+    clip_path_plane(&tmp2, &tmp1, &clip->rite);
+    clip_path_plane(&tmp1, &tmp2, &clip->bot);
+    clip_path_plane(dst, &tmp1, &clip->top);
+
+    path_free(&tmp1);
+    path_free(&tmp2);
+}
+
+/******************************************************************************/
+

Added: grass/trunk/lib/display/clip.h
===================================================================
--- grass/trunk/lib/display/clip.h	                        (rev 0)
+++ grass/trunk/lib/display/clip.h	2008-12-17 17:09:34 UTC (rev 34916)
@@ -0,0 +1,27 @@
+
+#ifndef DISPLAYLIB_CLIP_H
+#define DISPLAYLIB_CLIP_H
+
+#include "path.h"
+
+struct plane
+{
+    double x, y, k;
+};
+
+struct clip
+{
+    struct plane left, rite, bot, top;
+};
+
+struct rectangle
+{
+    double left, rite, bot, top;
+};
+
+void D__set_clip_planes(struct clip *, const struct rectangle *);
+void D__cull_path(struct path *, const struct path *, const struct clip *);
+void D__clip_path(struct path *, const struct path *, const struct clip *);
+
+#endif
+

Modified: grass/trunk/lib/display/cnversions.c
===================================================================
--- grass/trunk/lib/display/cnversions.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/display/cnversions.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -29,7 +29,7 @@
     double x, y;
 };
 
-struct rectangle
+struct rect
 {
     double west;
     double east;
@@ -39,9 +39,9 @@
 };
 
 /* Bounding rectangles */
-static struct rectangle D;	/* Display coordinates, pixels, (0,0) towards NW */
-static struct rectangle A;	/* Map array coordinates, integers, (0,0) towards NW */
-static struct rectangle U;	/* UTM coordinates, meters, (0,0) towards SW */
+static struct rect D;	/* Display coordinates, pixels, (0,0) towards NW */
+static struct rect A;	/* Map array coordinates, integers, (0,0) towards NW */
+static struct rect U;	/* UTM coordinates, meters, (0,0) towards SW */
 
 /* Conversion factors */
 static struct vector D_to_A_conv;	/* Display to Array */
@@ -68,7 +68,7 @@
  *  \return int
  */
 
-static void calc_size(struct rectangle *rect)
+static void calc_size(struct rect *rect)
 {
     rect->size.x = rect->east  - rect->west;
     rect->size.y = rect->south - rect->north;
@@ -81,7 +81,7 @@
     conv->y = dst->y / src->y;
 }
 
-static void fit_aspect(struct rectangle *rect, const struct rectangle *ref)
+static void fit_aspect(struct rect *rect, const struct rect *ref)
 {
     struct vector conv;
     double scale, size, delta;

Modified: grass/trunk/lib/display/draw2.c
===================================================================
--- grass/trunk/lib/display/draw2.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/display/draw2.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -6,21 +6,22 @@
 #include <grass/raster.h>
 #include <grass/display.h>
 #include <grass/glocale.h>
-#include "driverlib.h"
+#include "path.h"
+#include "clip.h"
 
-struct rectangle
-{
-    double left;
-    double rite;
-    double bot;
-    double top;
-};
-
 struct vector
 {
     double x, y;
 };
 
+/******************************************************************************/
+
+static struct path path;
+
+static int clip_mode = M_NONE;
+static double epsilon = 0.0;
+static struct path ll_path, clip_path, raw_path, eps_path;
+
 static struct vector cur;
 
 static struct rectangle clip;
@@ -30,102 +31,8 @@
 #define min(x,y) ((x) < (y) ? (x) : (y))
 #define max(x,y) ((x) > (y) ? (x) : (y))
 
-static double *xi, *yi;
-static int nalloc_i;
-
-static double *xf, *yf;
-static int nalloc_f;
-
 /******************************************************************************/
 
-static void alloc_dst(int n)
-{
-
-    if (nalloc_i >= n)
-	return;
-
-    nalloc_i = n;
-    xi = G_realloc(xi, nalloc_i * sizeof(double));
-    yi = G_realloc(yi, nalloc_i * sizeof(double));
-}
-
-static void alloc_src(int n)
-{
-
-    if (nalloc_f >= n)
-	return;
-
-    nalloc_f = n + 10;
-    xf = G_realloc(xf, nalloc_f * sizeof(double));
-    yf = G_realloc(yf, nalloc_f * sizeof(double));
-}
-
-static void dealloc_src(const double **x, const double **y, int release)
-{
-    if (release) {
-	G_free(*(double **)x);
-	G_free(*(double **)y);
-    }
-
-    *x = xf;
-    *y = yf;
-
-    nalloc_f = 0;
-
-    xf = NULL;
-    yf = NULL;
-}
-
-static int do_reduce(double *x, double *y, int n)
-{
-    static double eps = 0.5;
-    int i, j;
-
-    for (i = 0, j = 1; j < n; j++) {
-	if (fabs(x[j] - x[i]) < eps && fabs(y[j] - y[i]) < eps)
-	    continue;
-	i++;
-	if (i == j)
-	    continue;
-	x[i] = x[j];
-	y[i] = y[j];
-    }
-    return i + 1;
-}
-
-static int do_convert(const double *x, const double *y, int n)
-{
-    int i;
-
-    alloc_dst(n);
-
-    for (i = 0; i < n; i++) {
-	xi[i] = D_u_to_d_col(x[i]);
-	yi[i] = D_u_to_d_row(y[i]);
-    }
-
-    return do_reduce(xi, yi, n);
-}
-
-static void rel_to_abs(const double **px, const double **py, int n)
-{
-    const double *x = *px;
-    const double *y = *py;
-    int i;
-
-    alloc_src(n);
-
-    xf[0] = cur.x + x[0];
-    yf[0] = cur.y + y[0];
-
-    for (i = 1; i < n; i++) {
-	xf[i] = xf[i-1] + x[i];
-	yf[i] = yf[i-1] + y[i];
-    }
-
-    dealloc_src(px, py, 0);
-}
-
 static int shift_count(double dx)
 {
     return (int)floor(dx / 360);
@@ -144,7 +51,7 @@
     return x;
 }
 
-static int euclidify(double *x, const double *y, int n, int no_pole)
+static int euclidify(struct path *p, int no_pole)
 {
     double ux0 = clip.left;
     double ux1 = clip.rite;
@@ -152,113 +59,80 @@
     int lo, hi, count;
     int i;
 
-    x0 = x1 = x[0];
+    x0 = x1 = p->vertices[0].x;
 
-    for (i = 1; i < n; i++) {
-	if (fabs(y[i]) < 89.9)
-	    x[i] = x[i - 1] + coerce(x[i] - x[i - 1]);
+    for (i = 1; i < p->count; i++) {
+	if (fabs(p->vertices[i].y) < 89.9)
+	    p->vertices[i].x = p->vertices[i-1].x + coerce(p->vertices[i].x - p->vertices[i-1].x);
 
-	x0 = min(x0, x[i]);
-	x1 = max(x1, x[i]);
+	x0 = min(x0, p->vertices[i].x);
+	x1 = max(x1, p->vertices[i].x);
     }
 
-    if (no_pole && fabs(x[n - 1] - x[0]) > 180)
+    if (no_pole && fabs(p->vertices[p->count-1].x - p->vertices[0].x) > 180)
 	return 0;
 
     lo = -shift_count(ux1 - x0);
     hi = shift_count(x1 - ux0);
     count = hi - lo + 1;
 
-    for (i = 0; i < n; i++)
-	x[i] -= lo * 360;
+    for (i = 0; i < p->count; i++)
+	p->vertices[i].x -= lo * 360;
 
     return count;
 }
 
-static void ll_wrap_path(const double *x, const double *y, int n,
-			 void (*func) (const double *, const double *, int))
+static void ll_wrap_path(struct path *dst, const struct path *src, int no_pole)
 {
-    double *xx = G_malloc(n * sizeof(double));
-    int count, i;
+    int count, i, j;
 
-    memcpy(xx, x, n * sizeof(double));
-    count = euclidify(xx, y, n, 0);
+    path_copy(dst, src);
 
-    for (i = 0; i < count; i++) {
-	int j;
+    count = euclidify(dst, no_pole);
 
-	(*func) (xx, y, n);
-
-	for (j = 0; j < n; j++)
-	    xx[j] -= 360;
+    for (i = 0; i < count; i++) {
+	for (j = 0; j < src->count; j++) {
+	    struct vertex *v = &dst->vertices[j];
+	    path_append(dst, v->x - i * 360, v->y, v->mode);
+	}
     }
-
-    G_free(xx);
 }
 
-static void ll_wrap_line(double ax, double ay, double bx, double by,
-			 void (*func)(double, double, double, double))
+static void conv_path(struct path *dst, const struct path *src)
 {
-    double ux0 = clip.left;
-    double ux1 = clip.rite;
-    double x0, x1;
-    int lo, hi, i;
-    int ret;
+    int i;
 
-    bx = ax + coerce(bx - ax);
+    path_copy(dst, src);
 
-    x0 = min(ax, bx);
-    x1 = max(ax, bx);
-
-    lo = -shift_count(ux1 - x0);
-    hi = shift_count(x1 - ux0);
-
-    ret = 0;
-
-    for (i = lo; i <= hi; i++)
-	(*func)(ax - i * 360, ay, bx - i * 360, by);
+    for (i = 0; i < dst->count; i++) {
+	struct vertex *v = &dst->vertices[i];
+	v->x = D_u_to_d_col(v->x);
+	v->y = D_u_to_d_row(v->y);
+    }
 }
 
-/******************************************************************************/
-
-static void D_polydots_raw(const double *x, const double *y, int n)
+static void reduce_path(struct path *dst, const struct path *src, double eps)
 {
-    n = do_convert(x, y, n);
-    R_polydots_abs(xi, yi, n);
-}
+    struct vertex *v = &src->vertices[0];
+    int i;
 
-static void D_polyline_raw(const double *x, const double *y, int n)
-{
-    n = do_convert(x, y, n);
-    R_polyline_abs(xi, yi, n);
-}
+    path_reset(dst);
+    path_append(dst, v->x, v->y, v->mode);
 
-static void D_polygon_raw(const double *x, const double *y, int n)
-{
-    n = do_convert(x, y, n);
-    R_polygon_abs(xi, yi, n);
-}
+    for (i = 1; i < src->count - 1; i++) {
+	struct vertex *v0 = &dst->vertices[dst->count-1];
+	struct vertex *v1 = &src->vertices[i];
+	struct vertex *v2 = &src->vertices[i+1];
 
-static void D_line_raw(double x1, double y1, double x2, double y2)
-{
-    x1 = D_u_to_d_col(x1);
-    y1 = D_u_to_d_row(y1);
-    x2 = D_u_to_d_col(x2);
-    y2 = D_u_to_d_row(y2);
+	if (fabs(v1->x - v0->x) < eps && fabs(v1->y - v0->y) < eps &&
+	    fabs(v1->x - v2->x) < eps && fabs(v1->y - v2->y) < eps &&
+	    v0->mode != P_MOVE && v1->mode != P_MOVE && !v2->mode != P_MOVE)
+	    continue;
 
-    R_line_abs(x1, y1, x2, y2);
+	path_append(dst, v1->x, v1->y, v1->mode);
+    }
 }
 
-static void D_box_raw(double x1, double y1, double x2, double y2)
-{
-    x1 = D_u_to_d_col(x1);
-    x2 = D_u_to_d_col(x2);
-    y1 = D_u_to_d_row(y1);
-    y2 = D_u_to_d_row(y2);
-
-    R_box_abs(x1, y1, x2, y2);
-}
-
 /******************************************************************************/
 
 /*!
@@ -300,6 +174,16 @@
     D_set_clip(t, b, l, r);
 }
 
+void D_set_clip_mode(int mode)
+{
+    clip_mode = mode;
+}
+
+void D_set_reduction(double e)
+{
+    epsilon = e;
+}
+
 void D_line_width(double d)
 {
     R_line_width(d > 0 ? d : 0);
@@ -327,179 +211,270 @@
 
 /******************************************************************************/
 
-void D_polydots_abs(const double *x, const double *y, int n)
+void D_pos_abs(double x, double y)
 {
-    if (!window_set)
-	D_clip_to_map();
+    cur.x = x;
+    cur.y = y;
 
-    if (D_is_lat_lon())
-	ll_wrap_path(x, y, n, D_polydots_raw);
-    else
-	D_polydots_raw(x, y, n);
+    x = D_u_to_d_col(x);
+    y = D_u_to_d_row(y);
+
+    R_pos_abs(x, y);
 }
 
-void D_polyline_abs(const double *x, const double *y, int n)
+void D_pos_rel(double x, double y)
 {
-    if (!window_set)
-	D_clip_to_map();
-
-    if (n < 2)
-	return;
-
-    if (D_is_lat_lon())
-	ll_wrap_path(x, y, n, D_polyline_raw);
-    else
-	D_polyline_raw(x, y, n);
+    D_pos_abs(cur.x + x, cur.y + y);
 }
 
-void D_polygon_abs(const double *x, const double *y, int n)
+/******************************************************************************/
+
+static void do_path(int no_pole)
 {
+    struct path *p = &path;
+    struct clip planes;
+    int i;
+
     if (!window_set)
 	D_clip_to_map();
 
-    if (D_is_lat_lon())
-	ll_wrap_path(x, y, n, D_polygon_raw);
-    else
-	D_polygon_raw(x, y, n);
+    if (D_is_lat_lon()) {
+	ll_wrap_path(&ll_path, p, no_pole);
+	p = &ll_path;
+    }
+
+    switch (clip_mode) {
+    case M_NONE:
+	break;
+    case M_CULL:
+	D__set_clip_planes(&planes, &clip);
+	D__cull_path(&clip_path, p, &planes);
+	p = &clip_path;
+	break;
+    case M_CLIP:
+	D__set_clip_planes(&planes, &clip);
+	D__clip_path(&clip_path, p, &planes);
+	p = &clip_path;
+	break;
+    }
+
+    conv_path(&raw_path, p);
+    p = &raw_path;
+
+    if (epsilon > 0) {
+	reduce_path(&eps_path, p, epsilon);
+	p = &eps_path;
+    }
+
+    R_begin();
+    for (i = 0; i < p->count; i++) {
+	struct vertex *v = &p->vertices[i];
+	switch (v->mode)
+	{
+	case P_MOVE:
+	    R_move(v->x, v->y);
+	    break;
+	case P_CONT:
+	    R_cont(v->x, v->y);
+	    break;
+	case P_CLOSE:
+	    R_close();
+	    break;
+	}
+    }
 }
 
-void D_line_abs(double x1, double y1, double x2, double y2)
+void D_begin(void)
 {
-    if (!window_set)
-	D_clip_to_map();
+    path_begin(&path);
+}
 
-    if (D_is_lat_lon())
-	ll_wrap_line(x1, y1, x2, y2, D_line_raw);
-    else
-	D_line_raw(x1, y1, x2, y2);
+void D_end(void)
+{
 }
 
-void D_box_abs(double x1, double y1, double x2, double y2)
+void D_move_abs(double x, double y)
 {
-    if (!window_set)
-	D_clip_to_map();
+    path_move(&path, x, y);
 
-    if (D_is_lat_lon())
-	ll_wrap_line(x1, y1, x2, y2, D_box_raw);
-    else
-	D_box_raw(x1, y1, x2, y2);
+    cur.x = x;
+    cur.y = y;
 }
 
-/******************************************************************************/
-
-void D_line_rel(double x1, double y1, double x2, double y2)
+void D_cont_abs(double x, double y)
 {
-    cur.x += x1;
-    cur.y += y1;
+    path_cont(&path, x, y);
 
-    x1 = cur.x;
-    y1 = cur.y;
-
-    cur.x += x2;
-    cur.y += y2;
-
-    x2 = cur.x;
-    y2 = cur.y;
-
-    D_line_abs(x1, y1, x2, y2);
+    cur.x = x;
+    cur.y = y;
 }
 
-void D_polydots_rel(const double *x, const double *y, int n)
+void D_close(void)
 {
-    rel_to_abs(&x, &y, n);
-    D_polydots_abs(x, y, n);
-    dealloc_src(&x, &y, 1);
+    path_close(&path);
 }
 
-void D_polyline_rel(const double *x, const double *y, int n)
+void D_stroke(void)
 {
-    rel_to_abs(&x, &y, n);
-    D_polyline_abs(x, y, n);
-    dealloc_src(&x, &y, 1);
+    do_path(0);
+    R_stroke();
 }
 
-void D_polygon_rel(const double *x, const double *y, int n)
+void D_fill(void)
 {
-    rel_to_abs(&x, &y, n);
-    D_polygon_abs(x, y, n);
-    dealloc_src(&x, &y, 1);
+    do_path(1);
+    R_fill();
 }
 
-void D_box_rel(double x2, double y2)
+void D_dots(void)
 {
-    D_box_abs(cur.x, cur.y, cur.x + x2, cur.y + y2);
+    struct path *p = &path;
+    int i;
+
+    if (!window_set)
+	D_clip_to_map();
+
+    for (i = 0; i < p->count; i++) {
+	struct vertex *v = &p->vertices[i];
+	double x = v->x;
+	double y = v->y;
+
+	if (D_is_lat_lon())
+	    x = coerce(x);
+
+	if (clip_mode != M_NONE) {
+	    if (x < clip.left || x > clip.rite)
+		continue;
+	    if (y < clip.bot || y > clip.top)
+		continue;
+	}
+
+	x = D_u_to_d_col(x);
+	y = D_u_to_d_row(y);
+
+	R_point(x, y);
+    }
 }
 
 /******************************************************************************/
 
-static struct path path;
-
-void D_pos_abs(double x, double y)
+static void poly_abs(const double *x, const double *y, int n)
 {
-    cur.x = x;
-    cur.y = y;
+    int i;
 
-    x = D_u_to_d_col(x);
-    y = D_u_to_d_row(y);
+    if (n < 2)
+	return;
 
-    R_pos_abs(x, y);
+    D_begin();
+    D_move_abs(x[0], y[0]);
+    for (i = 1; i < n; i++)
+	D_cont_abs(x[i], y[i]);
 }
 
-void D_pos_rel(double x, double y)
+void D_polyline_abs(const double *x, const double *y, int n)
 {
-    D_pos_abs(cur.x + x, cur.y + y);
+    poly_abs(x, y, n);
+    D_stroke();
 }
 
-void D_move_abs(double x, double y)
+void D_polygon_abs(const double *x, const double *y, int n)
 {
-    path_move(&path, x, y);
+    poly_abs(x, y, n);
+    D_close();
+    D_fill();
+}
 
-    cur.x = x;
-    cur.y = y;
+void D_polydots_abs(const double *x, const double *y, int n)
+{
+    poly_abs(x, y, n);
+    D_dots();
 }
 
-void D_move_rel(double x, double y)
+void D_line_abs(double x1, double y1, double x2, double y2)
 {
-    D_move_abs(cur.x + x, cur.y + y);
+    D_begin();
+    D_move_abs(x1, y1);
+    D_cont_abs(x2, y2);
+    D_end();
+    D_stroke();
 }
 
-void D_cont_abs(double x, double y)
+void D_box_abs(double x1, double y1, double x2, double y2)
 {
-    path_cont(&path, x, y);
+    D_begin();
+    D_move_abs(x1, y1);
+    D_cont_abs(x2, y1);
+    D_cont_abs(x2, y2);
+    D_cont_abs(x1, y2);
+    D_close();
+    D_end();
+    D_fill();
+}
 
-    cur.x = x;
-    cur.y = y;
+/******************************************************************************/
+
+static void poly_rel(const double *x, const double *y, int n)
+{
+    int i;
+
+    if (n < 2)
+	return;
+
+    D_begin();
+    D_move_abs(x[0], y[0]);
+    for (i = 1; i < n; i++)
+	D_cont_rel(x[i], y[i]);
 }
 
+void D_move_rel(double x, double y)
+{
+    D_move_abs(cur.x + x, cur.y + y);
+}
+
 void D_cont_rel(double x, double y)
 {
     D_cont_abs(cur.x + x, cur.y + y);
 }
 
-/******************************************************************************/
-
-void D_begin(void)
+void D_polydots_rel(const double *x, const double *y, int n)
 {
-    path_begin(&path);
+    poly_rel(x, y, n);
+    D_dots();
 }
 
-void D_end(void)
+void D_polyline_rel(const double *x, const double *y, int n)
 {
+    poly_rel(x, y, n);
+    D_stroke();
 }
 
-void D_close(void)
+void D_polygon_rel(const double *x, const double *y, int n)
 {
-    path_close(&path);
+    poly_rel(x, y, n);
+    D_close();
+    D_fill();
 }
 
-void D_stroke(void)
+void D_line_rel(double x1, double y1, double x2, double y2)
 {
-    path_fill(&path, D_polyline_abs);
+    cur.x += x1;
+    cur.y += y1;
+
+    x1 = cur.x;
+    y1 = cur.y;
+
+    cur.x += x2;
+    cur.y += y2;
+
+    x2 = cur.x;
+    y2 = cur.y;
+
+    D_line_abs(x1, y1, x2, y2);
 }
 
-void D_fill(void)
+void D_box_rel(double x2, double y2)
 {
-    path_fill(&path, D_polygon_abs);
+    D_box_abs(cur.x, cur.y, cur.x + x2, cur.y + y2);
 }
 
 /******************************************************************************/

Modified: grass/trunk/lib/display/window.c
===================================================================
--- grass/trunk/lib/display/window.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/display/window.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -21,6 +21,12 @@
     D_use_color(colorindex);
 
     /* Do the plotting */
-    R_box_abs(l, t, r, b);
+    R_begin();
+    R_move(l, b);
+    R_cont(r, b);
+    R_cont(r, t);
+    R_cont(l, t);
+    R_close();
+    R_fill();
 }
 

Modified: grass/trunk/lib/driver/Draw.c
===================================================================
--- grass/trunk/lib/driver/Draw.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/Draw.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -8,14 +8,6 @@
 	(*driver->Bitmap) (ncols, nrows, threshold, buf);
 }
 
-void COM_Line_abs(double x0, double y0, double x1, double y1)
-{
-    COM_Begin();
-    COM_Move(x0, y0);
-    COM_Cont(x1, y1);
-    COM_Stroke();
-}
-
 void COM_Begin(void)
 {
     if (driver->Begin)

Modified: grass/trunk/lib/driver/Get_t_box.c
===================================================================
--- grass/trunk/lib/driver/Get_t_box.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/Get_t_box.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -8,14 +8,9 @@
 	return;
     }
 
-    if (!font_is_freetype()) {
-	soft_text_ext(cur_x, cur_y,
-		      text_size_x, text_size_y, text_rotation, text);
-	get_text_ext(t, b, l, r);
-    }
-    else {
-	soft_text_ext_freetype(cur_x, cur_y,
-			       text_size_x, text_size_y, text_rotation, text);
-	get_text_ext_freetype(t, b, l, r);
-    }
+    if (!font_is_freetype())
+	get_text_ext(text, t, b, l, r);
+    else
+	get_text_ext_freetype(text, t, b, l, r);
 }
+

Deleted: grass/trunk/lib/driver/Polydots.c
===================================================================
--- grass/trunk/lib/driver/Polydots.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/Polydots.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -1,11 +0,0 @@
-#include "driver.h"
-#include "driverlib.h"
-
-void COM_Polydots_abs(const double *xarray, const double *yarray, int number)
-{
-    int i;
-
-    for (i = 0; i < number; i++)
-	COM_Point(xarray[i], yarray[i]);
-}
-

Deleted: grass/trunk/lib/driver/Polygon.c
===================================================================
--- grass/trunk/lib/driver/Polygon.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/Polygon.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -1,17 +0,0 @@
-#include <stdlib.h>
-#include <grass/gis.h>
-#include "driver.h"
-#include "driverlib.h"
-
-void COM_Polygon_abs(const double *xarray, const double *yarray, int number)
-{
-    int i;
-
-    COM_Begin();
-    COM_Move(xarray[0], yarray[0]);
-    for (i = 1; i < number; i++)
-	COM_Cont(xarray[i], yarray[i]);
-    COM_Close();
-    COM_Fill();
-}
-

Deleted: grass/trunk/lib/driver/Polyline.c
===================================================================
--- grass/trunk/lib/driver/Polyline.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/Polyline.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -1,14 +0,0 @@
-#include "driver.h"
-#include "driverlib.h"
-
-void COM_Polyline_abs(const double *xarray, const double *yarray, int number)
-{
-    int i;
-
-    COM_Begin();
-    COM_Move(xarray[0], yarray[0]);
-    for (i = 1; i < number; i++)
-	COM_Cont(xarray[i], yarray[i]);
-    COM_Stroke();
-}
-

Modified: grass/trunk/lib/driver/Text.c
===================================================================
--- grass/trunk/lib/driver/Text.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/Text.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -9,9 +9,8 @@
     }
 
     if (!font_is_freetype())
-	soft_text(cur_x, cur_y, text_size_x, text_size_y, text_rotation,
-		  text);
+	soft_text(text);
     else
-	soft_text_freetype(cur_x, cur_y, text_size_x, text_size_y,
-			   text_rotation, text);
+	soft_text_freetype(text);
 }
+

Modified: grass/trunk/lib/driver/Text_size.c
===================================================================
--- grass/trunk/lib/driver/Text_size.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/Text_size.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -1,3 +1,4 @@
+#include <math.h>
 #include "driver.h"
 #include "driverlib.h"
 
@@ -11,5 +12,7 @@
 void COM_Text_rotation(double val)
 {
     text_rotation = val;
+    text_sinrot = sin(M_PI * text_rotation / 180.0);
+    text_cosrot = cos(M_PI * text_rotation / 180.0);
     matrix_valid = 0;
 }

Modified: grass/trunk/lib/driver/driver.h
===================================================================
--- grass/trunk/lib/driver/driver.h	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/driver.h	2008-12-17 17:09:34 UTC (rev 34916)
@@ -13,6 +13,8 @@
 extern double text_size_x;
 extern double text_size_y;
 extern double text_rotation;
+extern double text_sinrot;
+extern double text_cosrot;
 extern int matrix_valid;
 
 extern struct GFONT_CAP *ftcap;
@@ -86,15 +88,6 @@
 /* Move.c */
 extern void COM_Pos_abs(double, double);
 
-/* Polydots.c */
-extern void COM_Polydots_abs(const double *, const double *, int);
-
-/* Polygon.c */
-extern void COM_Polygon_abs(const double *, const double *, int);
-
-/* Polyline.c */
-extern void COM_Polyline_abs(const double *, const double *, int);
-
 /* Raster.c */
 extern void COM_begin_raster(int, int[2][2], double[2][2]);
 extern int COM_raster(int, int, const unsigned char *,
@@ -117,7 +110,6 @@
 
 /* Draw.c */
 extern void COM_Bitmap(int, int, int, const unsigned char *);
-extern void COM_Line_abs(double, double, double, double);
 extern void COM_Begin(void);
 extern void COM_Move(double, double);
 extern void COM_Cont(double, double);

Modified: grass/trunk/lib/driver/driverlib.h
===================================================================
--- grass/trunk/lib/driver/driverlib.h	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/driverlib.h	2008-12-17 17:09:34 UTC (rev 34916)
@@ -13,16 +13,12 @@
 void font_list(char ***, int *, int);
 
 /* Text2.c */
-void drawchar(double, double, double, double, unsigned char);
-void soft_text_ext(double, double, double, double, double, const char *);
-void get_text_ext(double *, double *, double *, double *);
-void soft_text(double, double, double, double, double, const char *);
-void onechar(double, double, double, double, double, unsigned char);
+void get_text_ext(const char *, double *, double *, double *, double *);
+void soft_text(const char *);
 
 /* Text3.c */
-void soft_text_freetype(double, double, double, double, double, const char *);
-void soft_text_ext_freetype(double, double, double, double, double, const char *);
-void get_text_ext_freetype(double *, double *, double *, double *);
+void soft_text_freetype(const char *);
+void get_text_ext_freetype(const char *, double *, double *, double *, double *);
 
 /* font2.c */
 int font_init(const char *);
@@ -39,22 +35,3 @@
 extern void free_freetypecap(struct GFONT_CAP *);
 extern void free_font_list(char **, int);
 
-/* path.c */
-struct path {
-    double *px, *py;
-    int count;
-    int alloc;
-
-    int cur_offset;
-    int *offsets;
-    int o_count;
-    int o_alloc;
-};
-
-void path_begin(struct path *);
-void path_move(struct path *, double, double);
-void path_cont(struct path *, double, double);
-void path_close(struct path *);
-void path_fill(struct path *, void (*)(const double *, const double *, int));
-void path_stroke(struct path *, void (*)(double, double, double, double));
-void path_reset(struct path *);

Modified: grass/trunk/lib/driver/init.c
===================================================================
--- grass/trunk/lib/driver/init.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/init.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -35,6 +35,8 @@
 double text_size_x;
 double text_size_y;
 double text_rotation;
+double text_sinrot;
+double text_cosrot;
 int matrix_valid;
 
 void LIB_init(const struct driver *drv)

Modified: grass/trunk/lib/driver/path.c
===================================================================
--- grass/trunk/lib/driver/path.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/path.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -1,92 +1,111 @@
 
 #include <grass/gis.h>
-#include "driverlib.h"
+#include "path.h"
 
-static void begin_subpath(struct path *p)
+void path_init(struct path *p)
 {
-    if (p->o_count >= p->o_alloc) {
-	p->o_alloc += 100;
-	p->offsets = G_realloc(p->offsets, p->o_alloc * sizeof(int));
-    }
+    p->vertices = NULL;
+    p->count = 0;
+    p->alloc = 0;
+    p->start = -1;
+}
 
-    p->offsets[p->o_count++] = p->count;
-    p->cur_offset = p->count;
+void path_free(struct path *p)
+{
+    if (p->vertices)
+	G_free(p->vertices);
+
+    p->count = 0;
+    p->alloc = 0;
+    p->start = -1;
 }
 
-static void add_point(struct path *p, double x, double y)
+void path_alloc(struct path *p, int n)
 {
-    if (p->count >= p->alloc) {
-	p->alloc = p->alloc ? p->alloc * 2 : 100;
-	p->px = G_realloc(p->px, p->alloc * sizeof(double));
-	p->py = G_realloc(p->py, p->alloc * sizeof(double));
+    if (p->alloc >= n)
+	return;
+
+    p->alloc = n;
+    p->vertices = G_realloc(p->vertices, p->alloc * sizeof(struct vertex));
+}
+
+void path_reset(struct path *p)
+{
+    p->count = 0;
+    p->start = -1;
+}
+
+void path_append(struct path *p, double x, double y, int mode)
+{
+    struct vertex *v;
+
+    if (p->count >= p->alloc)
+	path_alloc(p, p->alloc ? p->alloc * 2 : 100);
+
+    v = &p->vertices[p->count++];
+
+    v->x = x;
+    v->y = y;
+    v->mode = mode;
+}
+
+void path_copy(struct path *dst, const struct path *src)
+{
+    int i;
+
+    path_reset(dst);
+    path_alloc(dst, src->count);
+
+    for (i = 0; i < src->count; i++) {
+	struct vertex *v = &src->vertices[i];
+	path_append(dst, v->x, v->y, v->mode);
     }
 
-    p->px[p->count] = x;
-    p->py[p->count] = y;
-    p->count++;
+    dst->start = src->start;
 }
 
 void path_begin(struct path *p)
 {
     p->count = 0;
-    p->o_count = 0;
-    begin_subpath(p);
+    p->start = -1;
 }
 
 void path_move(struct path *p, double x, double y)
 {
-    if (p->count > p->cur_offset)
-	begin_subpath(p);
-    add_point(p, x, y);
+    p->start = p->count;
+    path_append(p, x, y, P_MOVE);
 }
 
 void path_cont(struct path *p, double x, double y)
 {
-    add_point(p, x, y);
+    path_append(p, x, y, P_CONT);
 }
 
 void path_close(struct path *p)
 {
-    if (p->count <= p->cur_offset + 2)
+    struct vertex *v;
+
+    if (p->start < 0)
 	return;
 
-    add_point(p, p->px[p->cur_offset], p->py[p->cur_offset]);
-    begin_subpath(p);
+    v = &p->vertices[p->start];
+    path_append(p, v->x, v->y, P_CLOSE);
+
+    p->start = -1;
 }
 
-void path_fill(struct path *p, void (*polygon)(const double *, const double *, int))
+void path_stroke(struct path *p, void (*line)(double, double, double, double))
 {
     int i;
 
-    if (p->count > p->cur_offset)
-	begin_subpath(p);
+    for (i = 1; i < p->count; i++) {
+	struct vertex *v0 = &p->vertices[i-1];
+	struct vertex *v1 = &p->vertices[i];
 
-    for (i = 0; i < p->o_count - 1; i++) {
-	int start = p->offsets[i];
-	int end = p->offsets[i+1];
-	(*polygon)(&p->px[start], &p->py[start], end - start);
+	if (v1->mode != P_MOVE)
+	    (*line)(v0->x, v0->y, v1->x, v1->y);
     }
 
     path_reset(p);
 }
 
-void path_stroke(struct path *p, void (*line)(double, double, double, double))
-{
-    int i, j;
-
-    if (p->count > p->cur_offset)
-	begin_subpath(p);
-
-    for (i = 0; i < p->o_count - 1; i++)
-	for (j = p->offsets[i] + 1; j < p->offsets[i+1]; j++)
-	    (*line)(p->px[j-1], p->py[j-1], p->px[j], p->py[j]);
-
-    path_reset(p);
-}
-
-void path_reset(struct path *p)
-{
-    p->count = 0;
-    p->o_count = 0;
-}
-

Added: grass/trunk/lib/driver/path.h
===================================================================
--- grass/trunk/lib/driver/path.h	                        (rev 0)
+++ grass/trunk/lib/driver/path.h	2008-12-17 17:09:34 UTC (rev 34916)
@@ -0,0 +1,36 @@
+
+#ifndef DRIVERLIB_PATH_H
+#define DRIVERLIB_PATH_H
+
+enum path_mode {
+    P_MOVE,
+    P_CONT,
+    P_CLOSE,
+};
+
+struct vertex {
+    double x, y;
+    int mode;
+};
+
+struct path {
+    struct vertex *vertices;
+    int count;
+    int alloc;
+    int start;
+};
+
+void path_init(struct path *);
+void path_free(struct path *);
+void path_alloc(struct path *, int);
+void path_reset(struct path *);
+void path_append(struct path *, double, double, int);
+void path_copy(struct path *, const struct path *);
+void path_begin(struct path *);
+void path_move(struct path *, double, double);
+void path_cont(struct path *, double, double);
+void path_close(struct path *);
+void path_stroke(struct path *, void (*)(double, double, double, double));
+
+#endif
+

Modified: grass/trunk/lib/driver/text2.c
===================================================================
--- grass/trunk/lib/driver/text2.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/text2.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -4,144 +4,109 @@
 #include "driver.h"
 #include "driverlib.h"
 
-static int dont_draw;
-static double t, b, l, r;
-static double basex, basey;
-static double curx, cury;
-
-static void remember(double x, double y)
+struct rectangle
 {
-    if (x > r)
-	r = x;
-    if (x < l)
-	l = x;
-    if (y > b)
-	b = y;
-    if (y < t)
-	t = y;
+    double t, b, l, r;
+};
 
-    curx = x;
-    cury = y;
-}
-
-static void text_draw(double x, double y)
+static void remember(struct rectangle *box, double x, double y)
 {
-    COM_Line_abs(curx, cury, x, y);
-
-    curx = x;
-    cury = y;
+    if (x > box->r)
+	box->r = x;
+    if (x < box->l)
+	box->l = x;
+    if (y > box->b)
+	box->b = y;
+    if (y < box->t)
+	box->t = y;
 }
 
-static void text_move(double x, double y)
+static void transform(double *x, double *y,
+		      int ix, int iy,
+		      double orig_x, double orig_y)
 {
-    curx = x;
-    cury = y;
+    double ax = text_size_x * ix;
+    double ay = text_size_y * iy;
+    double rx = ax * text_cosrot - ay * text_sinrot;
+    double ry = ax * text_sinrot + ay * text_cosrot;
+    *x = orig_x + rx;
+    *y = orig_y - ry;
 }
 
-void drawchar(double text_size_x, double text_size_y,
-	      double sinrot, double cosrot, unsigned char character)
+static void draw_char(double *px, double *py, unsigned char character, struct rectangle *box)
 {
     unsigned char *X;
     unsigned char *Y;
     int n_vects;
     int i;
-    double ax, ay;
-    double x, y;
-    void (*Do) (double, double);
-    int ix, iy;
+    void (*func)(double, double);
 
-    x = basex;
-    y = basey;
-
     get_char_vects(character, &n_vects, &X, &Y);
 
-    Do = text_move;
+    if (!box)
+	COM_Begin();
 
+    func = COM_Move;
+
     for (i = 1; i < n_vects; i++) {
+	int ix, iy;
+	double x, y;
+
 	if (X[i] == ' ') {
-	    Do = text_move;
+	    func = COM_Move;
 	    continue;
 	}
 
 	ix = 10 + X[i] - 'R';
 	iy = 10 - Y[i] + 'R';
-	ax = text_size_x * ix;
-	ay = text_size_y * iy;
 
-	if (dont_draw) {
-	    remember(x + (ax * cosrot - ay * sinrot),
-		     y - (ax * sinrot + ay * cosrot));
-	}
+	transform(&x, &y, ix, iy, *px, *py);
+
+	if (box)
+	    remember(box, x, y);
 	else {
-	    (*Do) (x + (ax * cosrot - ay * sinrot),
-		   y - (ax * sinrot + ay * cosrot));
-	    Do = text_draw;
+	    (*func)(x, y);
+	    func = COM_Cont;
 	}
     }
-    /*  This seems to do variable spacing
-       ix = 10 + X[i] - 'R';
-     */
-    ix = 20;
-    iy = 0;
-    ax = text_size_x * ix;
-    ay = text_size_y * iy;
 
-    if (!dont_draw)
-	text_move(basex + (ax * cosrot - ay * sinrot),
-		  basey - (ax * sinrot + ay * cosrot));
+    transform(px, py, 20, 0, *px, *py);
+
+    if (box)
+	remember(box, *px, *py);
     else
-	remember(basex + (ax * cosrot - ay * sinrot),
-		 basey - (ax * sinrot + ay * cosrot));
+	COM_Stroke();
 }
 
-void soft_text_ext(double x, double y,
-		   double text_size_x, double text_size_y,
-		   double text_rotation, const char *string)
+static void draw_text(const char *string, struct rectangle *box)
 {
-    t = 999999;
-    b = 0;
-    l = 999999;
-    r = 0;
-    dont_draw = 1;
-    soft_text(x, y, text_size_x, text_size_y, text_rotation, string);
-    dont_draw = 0;
+    double base_x = cur_x;
+    double base_y = cur_y;
+    const unsigned char *p;
+
+    for (p = (const unsigned char *) string; *p; p++)
+	draw_char(&base_x, &base_y, *p, box);
 }
 
-void get_text_ext(double *top, double *bot, double *left, double *rite)
+void get_text_ext(const char *string, double *top, double *bot, double *left, double *rite)
 {
-    *top = t;
-    *bot = b;
-    *left = l;
-    *rite = r;
-}
+    struct rectangle box;
 
-# define RpD ((2 * M_PI) / 360.)	/* radians/degree */
-# define D2R(d) (double)(d * RpD)	/* degrees->radians */
+    box.t = 1e300;
+    box.b = -1e300;
+    box.l = 1e300;
+    box.r = -1e300;
 
-void soft_text(double x, double y,
-	       double text_size_x, double text_size_y, double text_rotation,
-	       const char *string)
-{
-    double sinrot = sin(D2R(text_rotation));
-    double cosrot = cos(D2R(text_rotation));
+    draw_text(string, &box);
 
-    curx = basex = x;
-    cury = basey = y;
-    while (*string) {
-	drawchar(text_size_x, text_size_y, sinrot, cosrot, *string++);
-	basex = curx;
-	basey = cury;
-    }
+    *top = box.t;
+    *bot = box.b;
+    *left = box.l;
+    *rite = box.r;
 }
 
-void onechar(double x, double y,
-	     double text_size_x, double text_size_y, double text_rotation,
-	     unsigned char achar)
+void soft_text(const char *string)
 {
-    double sinrot = sin(D2R(text_rotation));
-    double cosrot = cos(D2R(text_rotation));
-
-    curx = basex = x;
-    cury = basey = y;
-    drawchar(text_size_x, text_size_y, sinrot, cosrot, achar);
+    draw_text(string, NULL);
 }
+

Modified: grass/trunk/lib/driver/text3.c
===================================================================
--- grass/trunk/lib/driver/text3.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/driver/text3.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -20,26 +20,25 @@
 #include "driver.h"
 #include "driverlib.h"
 
-# define RpD ((2 * M_PI) / 360.)	/* radians/degree */
-# define D2R(d) (double)(d * RpD)	/* degrees->radians */
-
 /*#define DEBUG_LOG(S) {FILE *fp = fopen("debug.TXT","a");fputs(S,fp);fclose(fp);} */
 /*#define DEBUG_LOG_INT(D) {FILE *fp = fopen("debug.TXT","a");fprintf(fp,"%d",D);fclose(fp);} */
 /*#define DEBUG_LOG_DOUBLE(D) {FILE *fp = fopen("debug.TXT","a");fprintf(fp,"%f",D);fclose(fp);} */
 
+struct rectangle
+{
+    double t, b, l, r;
+};
+
 #ifdef HAVE_FT2BUILD_H
 static int convert_str(const char *, const char *, unsigned char **);
 static void release_convert_str(unsigned char *);
-static void set_matrix(FT_Matrix *, double);
+static void set_matrix(FT_Matrix *);
 static void draw_text(FT_Face, FT_Vector *, FT_Matrix *,
-		      const unsigned char *, int, int);
+		      const unsigned char *, int, int, struct rectangle *);
 static void draw_bitmap(FT_Bitmap *, FT_Int, FT_Int);
-static void set_text_box(FT_Bitmap *, FT_Int, FT_Int);
+static void set_text_box(FT_Bitmap *, FT_Int, FT_Int, struct rectangle *);
 #endif
 
-static int fdont_draw = 0;
-static double ft, fb, fl, fr;
-
 static const char *font_get_encoding(void)
 {
     if (!encoding)
@@ -47,9 +46,8 @@
     return encoding;
 }
 
-static void draw_main(double x, double y,
-		      double text_size_x, double text_size_y,
-		      double text_rotation, const char *string)
+static void draw_main(double x, double y, const char *string,
+		      struct rectangle *box)
 {
 #ifdef HAVE_FT2BUILD_H
     FT_Library library;
@@ -93,14 +91,11 @@
     /* ans = FT_Set_Char_Size(face,10*64,0,72,0); */
     /* ans = FT_Set_Char_Size(face,text_size_x*64,text_size_y*64,72,72); */
     ans =
-	FT_Set_Char_Size(face, (int)(text_size_x * 64),
-			 (int)(text_size_y * 64), 100, 100);
-    /*
-       ans = FT_Set_Pixel_Sizes(
-       face,
-       0,
-       (int)text_size_y );
-     */
+	FT_Set_Char_Size(face,
+			 (int)(text_size_x * 25 * 64),
+			 (int)(text_size_y * 25 * 64),
+			 100, 100);
+
     if (ans) {
 	/* DEBUG_LOG("Text3 error: ft set size\n"); */
 	FT_Done_Face(face);
@@ -117,9 +112,9 @@
     outlen = convert_str(encoding, string, &out);
 
     /* set matrix */
-    set_matrix(&matrix, D2R(text_rotation));
+    set_matrix(&matrix);
     /* draw */
-    draw_text(face, &pen, &matrix, out, outlen, 0);
+    draw_text(face, &pen, &matrix, out, outlen, 0, box);
 
     /* release */
     release_convert_str(out);
@@ -131,13 +126,13 @@
 }
 
 #ifdef HAVE_FT2BUILD_H
-static void set_matrix(FT_Matrix * matrix, double rotation)
+static void set_matrix(FT_Matrix * matrix)
 {
     /* rotation is in radians */
-    matrix->xx = (FT_Fixed) (cos(rotation) * 0x10000);
-    matrix->xy = (FT_Fixed) (-sin(rotation) * 0x10000);
-    matrix->yx = (FT_Fixed) (sin(rotation) * 0x10000);
-    matrix->yy = (FT_Fixed) (cos(rotation) * 0x10000);
+    matrix->xx = (FT_Fixed) ( text_cosrot * 0x10000);
+    matrix->xy = (FT_Fixed) (-text_sinrot * 0x10000);
+    matrix->yx = (FT_Fixed) ( text_sinrot * 0x10000);
+    matrix->yy = (FT_Fixed) ( text_cosrot * 0x10000);
 }
 
 static int convert_str(const char *from, const char *in, unsigned char **out)
@@ -184,7 +179,8 @@
 }
 
 static void draw_text(FT_Face face, FT_Vector * pen, FT_Matrix * matrix,
-		      const unsigned char *out, int len, int color)
+		      const unsigned char *out, int len, int color,
+		      struct rectangle *box)
 {
     FT_ULong ch;
     FT_Error ans;
@@ -205,12 +201,12 @@
 	if (ans)
 	    continue;
 	/* draw bitmap */
-	if (!fdont_draw)
+	if (!box)
 	    draw_bitmap(&slot->bitmap, slot->bitmap_left,
 			screen_height - slot->bitmap_top);
 	else
 	    set_text_box(&slot->bitmap, slot->bitmap_left,
-			 screen_height - slot->bitmap_top);
+			 screen_height - slot->bitmap_top, box);
 
 	/* increment pen position */
 	pen->x += slot->advance.x;
@@ -218,21 +214,21 @@
     }
 }
 
-static void set_text_box(FT_Bitmap * bitmap, FT_Int x, FT_Int y)
+static void set_text_box(FT_Bitmap *bitmap, FT_Int x, FT_Int y, struct rectangle *box)
 {
     FT_Int xMax = x + bitmap->width;
     FT_Int yMax = y + bitmap->rows;
 
     if ((x == xMax) || (y == yMax))
 	return;
-    if (x < fl)
-	fl = x;
-    if (xMax > fr)
-	fr = xMax;
-    if (y < ft)
-	ft = y;
-    if (yMax > fb)
-	fb = yMax;
+    if (x < box->l)
+	box->l = x;
+    if (xMax > box->r)
+	box->r = xMax;
+    if (y < box->t)
+	box->t = y;
+    if (yMax > box->b)
+	box->b = yMax;
 }
 
 static void draw_bitmap(FT_Bitmap * bitmap, FT_Int x, FT_Int y)
@@ -272,40 +268,25 @@
 }
 #endif
 
-void soft_text_freetype(double x, double y,
-			double text_size_x, double text_size_y,
-			double text_rotation, const char *string)
+void soft_text_freetype(const char *string)
 {
-    text_size_x *= 25.0;
-    text_size_y *= 25.0;
-    draw_main(x, y, text_size_x, text_size_y, text_rotation, string);
+    draw_main(cur_x, cur_y, string, NULL);
 }
 
-void soft_text_ext_freetype(double x, double y,
-			    double text_size_x, double text_size_y,
-			    double text_rotation, const char *string)
+void get_text_ext_freetype(const char *string, double *top, double *bot, double *left, double *rite)
 {
-    fdont_draw = 1;
-    text_size_x *= 25.0;
-    text_size_y *= 25.0;
-    ft = 999999;
-    fb = 0;
-    fl = 999999;
-    fr = 0;
-    /* draw_main(x,y,text_size_x,text_size_y,text_rotation,string); */
-    /* draw_main(0,0,text_size_x,text_size_y,text_rotation,string); */
-    draw_main(0, y, text_size_x, text_size_y, text_rotation, string);
-    /* ft += y; */
-    /* fb += y; */
-    fl += x;
-    fr += x;
-    fdont_draw = 0;
-}
+    struct rectangle box;
 
-void get_text_ext_freetype(double *top, double *bot, double *left, double *rite)
-{
-    *top = ft;
-    *bot = fb;
-    *left = fl;
-    *rite = fr;
+    box.t = 1e300;
+    box.b = -1e300;
+    box.l = 1e300;
+    box.r = -1e300;
+
+    draw_main(cur_x, cur_y, string, &box);
+
+    *top = box.t;
+    *bot = box.b;
+    *left = box.l;
+    *rite = box.r;
 }
+

Modified: grass/trunk/lib/htmldriver/Draw.c
===================================================================
--- grass/trunk/lib/htmldriver/Draw.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/htmldriver/Draw.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -1,6 +1,6 @@
 
 #include <grass/gis.h>
-#include "driverlib.h"
+#include "path.h"
 #include "htmlmap.h"
 
 static struct path path;
@@ -27,7 +27,7 @@
 
 void HTML_Fill(void)
 {
-    path_fill(&path, html_polygon);
+    html_polygon(&path);
 }
 
 void HTML_Stroke(void)

Modified: grass/trunk/lib/htmldriver/Polygon.c
===================================================================
--- grass/trunk/lib/htmldriver/Polygon.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/htmldriver/Polygon.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -51,8 +51,9 @@
 }
 
 
-void html_polygon(const double *px, const double *py, int n)
+void html_polygon(const struct path *p)
 {
+    int n = p->count;
     struct MapPoly *new;
     int i;
     int delta_x, delta_y;
@@ -64,8 +65,8 @@
     int *y = G_malloc(n * sizeof(int));
 
     for (i = 0; i < n; i++) {
-	x[i] = (int) floor(px[i] + 0.5);
-	y[i] = (int) floor(py[i] + 0.5);
+	x[i] = (int) floor(p->vertices[i].x + 0.5);
+	y[i] = (int) floor(p->vertices[i].y + 0.5);
     }
 
     /* 

Modified: grass/trunk/lib/htmldriver/htmlmap.h
===================================================================
--- grass/trunk/lib/htmldriver/htmlmap.h	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/htmldriver/htmlmap.h	2008-12-17 17:09:34 UTC (rev 34916)
@@ -1,5 +1,6 @@
 
 #include <stdio.h>
+#include "path.h"
 
 #define DEF_MINBBOX  2
 #define DEF_MINDIST  2
@@ -59,7 +60,7 @@
 extern void HTML_Box(double, double, double, double);
 
 /* Polygon.c */
-extern void html_polygon(const double *, const double *, int);
+extern void html_polygon(const struct path *);
 
 /* Text.c */
 extern void HTML_Text(const char *);

Modified: grass/trunk/lib/pngdriver/Draw.c
===================================================================
--- grass/trunk/lib/pngdriver/Draw.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/pngdriver/Draw.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -13,6 +13,7 @@
 
 #include <grass/gis.h>
 #include "driverlib.h"
+#include "path.h"
 #include "pngdriver.h"
 
 static struct path path;
@@ -44,6 +45,6 @@
 
 void PNG_Fill(void)
 {
-    path_fill(&path, png_polygon);
+    png_polygon(&path);
 }
 

Modified: grass/trunk/lib/pngdriver/Draw_line.c
===================================================================
--- grass/trunk/lib/pngdriver/Draw_line.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/pngdriver/Draw_line.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -64,7 +64,8 @@
 
 void png_draw_line(double x1, double y1, double x2, double y2)
 {
-    double ax[4], ay[4];
+    struct path path;
+    struct vertex vertices[5];
     double k = png.linewidth / 2;
     int dx, dy;
 
@@ -74,19 +75,26 @@
 	return;
     }
 
+    path.vertices = vertices;
+    path.count = 0;
+    path.alloc = 5;
+    path.start = -1;
+
     if (dy > dx) {
-	ax[0] = x1 - k;	ay[0] = y1;
-	ax[1] = x1 + k;	ay[1] = y1;
-	ax[2] = x2 + k;	ay[2] = y2;
-	ax[3] = x2 - k;	ay[3] = y2;
+	path_move(&path, x1 - k, y1);
+	path_cont(&path, x1 + k, y1);
+	path_cont(&path, x2 + k, y2);
+	path_cont(&path, x2 - k, y2);
+	path_close(&path);
     }
     else {
-	ax[0] = x1;	ay[0] = y1 - k;
-	ax[1] = x1;	ay[1] = y1 + k;
-	ax[2] = x2;	ay[2] = y2 + k;
-	ax[3] = x2;	ay[3] = y2 - k;
+	path_move(&path, x1, y1 - k);
+	path_cont(&path, x1, y1 + k);
+	path_cont(&path, x2, y2 + k);
+	path_cont(&path, x2, y2 - k);
+	path_close(&path);
     }
 
-    png_polygon(ax, ay, 4);
+    png_polygon(&path);
 }
 

Modified: grass/trunk/lib/pngdriver/Polygon.c
===================================================================
--- grass/trunk/lib/pngdriver/Polygon.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/pngdriver/Polygon.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -3,13 +3,9 @@
 #include <math.h>
 #include <grass/gis.h>
 
+#include "path.h"
 #include "pngdriver.h"
 
-struct point
-{
-    double x, y;
-};
-
 static int cmp_double(const void *aa, const void *bb)
 {
     const double *a = aa;
@@ -50,17 +46,17 @@
 	*p++ = png.current_color;
 }
 
-static void line(const struct point *p, int n, double y)
+static void line(const struct vertex *p, int n, double y)
 {
     static double *xs;
     static int max_x;
     int num_x = 0;
     int i;
 
-    for (i = 0; i < n; i++) {
-	const struct point *p0 = &p[i];
-	const struct point *p1 = &p[i + 1];
-	const struct point *tmp;
+    for (i = 1; i < n; i++) {
+	const struct vertex *p0 = &p[i - 1];
+	const struct vertex *p1 = &p[i];
+	const struct vertex *tmp;
 	double x;
 
 	if (p0->y == p1->y)
@@ -92,7 +88,7 @@
 	fill(xs[i], xs[i + 1], y);
 }
 
-static void poly(const struct point *p, int n)
+static void poly(const struct vertex *p, int n)
 {
     double y0, y1, y;
     int i;
@@ -123,27 +119,13 @@
 	line(p, n, y);
 }
 
-void png_polygon(const double *xarray, const double *yarray, int count)
+void png_polygon(struct path *p)
 {
-    static struct point *points;
-    static int max_points;
-    int i;
+    if (p->vertices[p->count - 1].mode != P_CLOSE)
+	path_close(p);
 
-    if (max_points < count + 1) {
-	max_points = count + 1;
-	points = G_realloc(points, sizeof(struct point) * max_points);
-    }
+    poly(p->vertices, p->count);
 
-    for (i = 0; i < count; i++) {
-	points[i].x = xarray[i];
-	points[i].y = yarray[i];
-    }
-
-    points[count].x = xarray[0];
-    points[count].y = yarray[0];
-
-    poly(points, count);
-
     png.modified = 1;
 }
 

Modified: grass/trunk/lib/pngdriver/pngdriver.h
===================================================================
--- grass/trunk/lib/pngdriver/pngdriver.h	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/pngdriver/pngdriver.h	2008-12-17 17:09:34 UTC (rev 34916)
@@ -5,6 +5,7 @@
 
 #include <grass/config.h>
 #include "driver.h"
+#include "path.h"
 
 #define FILE_NAME  "map.png"
 
@@ -46,7 +47,7 @@
 extern unsigned int png_get_color(int, int, int, int);
 extern void png_get_pixel(unsigned int, int *, int *, int *, int *);
 extern void png_draw_line(double, double, double, double);
-extern void png_polygon(const double *, const double *, int);
+extern void png_polygon(struct path *);
 
 extern const struct driver *PNG_Driver(void);
 

Modified: grass/trunk/lib/raster/raster.c
===================================================================
--- grass/trunk/lib/raster/raster.c	2008-12-16 14:59:20 UTC (rev 34915)
+++ grass/trunk/lib/raster/raster.c	2008-12-17 17:09:34 UTC (rev 34916)
@@ -43,6 +43,8 @@
 	R_text_size(s, s);
     }
 
+    R_text_rotation(0);
+
     if (frame) {
 	double t, b, l, r;
 	sscanf(frame, "%lf,%lf,%lf,%lf", &t, &b, &l, &r);
@@ -162,80 +164,6 @@
 }
 
 /*!
- * \brief draw line
- *
- * Draw a line using the current color, selected via <i>R_color</i>, from the 
- * current location to the location specified by <b>x,y.</b> The current location
- * is updated to <b>x,y.</b>
- *
- *  \param x
- *  \param y
- *  \return void
- */
-
-void R_line_abs(double x1, double y1, double x2, double y2)
-{
-    COM_Line_abs(x1, y1, x2, y2);
-}
-
-/*!
- * \brief draw a series of dots
- *
- * Pixels at the <b>num</b> absolute positions in the <b>x</b> and
- * <b>y</b> arrays are turned to the current color. The current location is
- * left updated to the position of the last dot.
- *
- *  \param xarray x
- *  \param yarray y
- *  \param number
- *  \return void
- */
-
-void R_polydots_abs(const double *xarray, const double *yarray, int number)
-{
-    COM_Polydots_abs(xarray, yarray, number);
-}
-
-/*!
- * \brief draw an open polygon
- *
- * The <b>number</b> absolute positions in the <b>x</b> and <b>y</b>
- * arrays are used to generate a multisegment line (often curved). This line is
- * drawn with the current color. The current location is left updated to the
- * position of the last point.
- * <b>Note.</b> It is not assumed that the line is closed, i.e., no line is
- * drawn from the last point to the first point.
- *
- *  \param xarray x
- *  \param yarray y
- *  \param number
- *  \return void
- */
-
-void R_polyline_abs(const double *xarray, const double *yarray, int number)
-{
-    COM_Polyline_abs(xarray, yarray, number);
-}
-
-/*!
- * \brief draw a closed polygon
- *
- * The <b>number</b> absolute positions in the <b>x</b> and <b>y</b> arrays
- * outline a closed polygon which is filled with the current color. The current
- * location is undefined afterwards.
- *
- *  \param xarray x
- *  \param yarray y
- *  \param number
- *  \return void
- */
-
-void R_polygon_abs(const double *xarray, const double *yarray, int number)
-{
-    COM_Polygon_abs(xarray, yarray, number);
-}
-
-/*!
  * \brief fill a box
  *
  * A box is drawn in the current color using the coordinates <b>x1,y1</b> and



More information about the grass-commit mailing list