[GRASS-SVN] r33225 - in grass/trunk: display/d.geodesic display/d.rhumbline display/d.thematic.area display/d.vect include lib/display

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Sep 2 17:02:14 EDT 2008


Author: glynn
Date: 2008-09-02 17:02:14 -0400 (Tue, 02 Sep 2008)
New Revision: 33225

Modified:
   grass/trunk/display/d.geodesic/local_proto.h
   grass/trunk/display/d.geodesic/main.c
   grass/trunk/display/d.geodesic/plot.c
   grass/trunk/display/d.rhumbline/local_proto.h
   grass/trunk/display/d.rhumbline/main.c
   grass/trunk/display/d.rhumbline/plot.c
   grass/trunk/display/d.thematic.area/area.c
   grass/trunk/display/d.thematic.area/local_proto.h
   grass/trunk/display/d.thematic.area/main.c
   grass/trunk/display/d.thematic.area/plot1.c
   grass/trunk/display/d.vect/area.c
   grass/trunk/display/d.vect/local_proto.h
   grass/trunk/display/d.vect/main.c
   grass/trunk/display/d.vect/plot1.c
   grass/trunk/include/display.h
   grass/trunk/lib/display/draw2.c
Log:
Fix lat/lon wrapping in D_* functions
Fix clipping tests to handle lower-left origin
Replace separate D_*_{cull,clip} functions with D_set_clip_mode()
Eliminate use of G_plot_fx()


Modified: grass/trunk/display/d.geodesic/local_proto.h
===================================================================
--- grass/trunk/display/d.geodesic/local_proto.h	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.geodesic/local_proto.h	2008-09-02 21:02:14 UTC (rev 33225)
@@ -1,6 +1 @@
-/* mouse.c */
-void mouse(int, int);
-
-/* plot.c */
-int setup_plot(void);
-int plot(double, double, double, double, int, int);
+void plot(double, double, double, double, int, int);

Modified: grass/trunk/display/d.geodesic/main.c
===================================================================
--- grass/trunk/display/d.geodesic/main.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.geodesic/main.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -115,9 +115,9 @@
     else
 	text_color = D_translate_color(parm.tcolor->answer);
 
-    setup_plot();
     plot(lon1, lat1, lon2, lat2, line_color, text_color);
 
     R_close_driver();
-    exit(0);
+
+    exit(EXIT_SUCCESS);
 }

Modified: grass/trunk/display/d.geodesic/plot.c
===================================================================
--- grass/trunk/display/d.geodesic/plot.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.geodesic/plot.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -3,136 +3,74 @@
 #include <grass/raster.h>
 #include <grass/gis.h>
 #include <stdio.h>
+#include "local_proto.h"
 
 #define METERS_TO_MILES(x) ((x) * 6.213712e-04)
 
-static int min_range[5], max_range[5];
-static int which_range;
-static int change_range;
-
-static int get_text_x(void);
-static int geodesic(int);
-static int move(int, int);
-static int cont(int, int);
-
-int setup_plot(void)
+void plot(double lon1, double lat1, double lon2, double lat2,
+     int line_color, int text_color)
 {
+    double distance;
+    double text_x, text_y;
     double a, e2;
+    int nsteps = 1000;
+    int i;
 
     /* establish the current graphics window */
-    D_setup_unity(0);
-    D_clip_to_map();
+    D_setup(0);
 
-    /* setup the G plot to use the D routines */
-    G_setup_plot(D_get_d_north(), D_get_d_south(),
-		 D_get_d_west(), D_get_d_east(),
-		 move, cont);
-
     G_get_ellipsoid_parameters(&a, &e2);
     G_begin_geodesic_distance(a, e2);
-    R_text_size(10, 10);
 
-    return 0;
-}
+    D_use_color(line_color);
 
-int
-plot(double lon1, double lat1, double lon2, double lat2, int line_color,
-     int text_color)
-{
-    double distance;
-    char buf[100];
-    int text_x, text_y;
+    G_shortest_way(&lon1, &lon2);
 
-    which_range = -1;
-    change_range = 1;
-    D_use_color(line_color);
     if (lon1 != lon2) {
-	G_shortest_way(&lon1, &lon2);
 	G_begin_geodesic_equation(lon1, lat1, lon2, lat2);
-	G_plot_fx(G_geodesic_lat_from_lon, lon1, lon2);
-	text_x = get_text_x();
-	if (text_x >= 0)
-	    text_y = geodesic(text_x);
-    }
-    else {
-	G_plot_where_xy(lon1, (lat1 + lat2) / 2, &text_x, &text_y);
-	G_plot_line(lon1, lat1, lon2, lat2);
-    }
 
-    distance = G_geodesic_distance(lon1, lat1, lon2, lat2);
-    sprintf(buf, "%.0f miles\n", METERS_TO_MILES(distance));
-    if ((text_x >= 0) && (text_color != -1)) {
-	if (text_y + 10 <= D_get_d_north())
-	    text_y = D_get_d_north() - 10;
-	if (text_x + 10 * strlen(buf) >= D_get_d_east())
-	    text_x = D_get_d_east() - 10 * strlen(buf);
-	D_move_abs(text_x, text_y);
-	D_use_color(text_color);
-	R_text(buf);
-    }
+	for (i = 0; i <= nsteps; i++) {
+	    double lon = lon1 + (lon2 - lon1) * i / nsteps;
+	    double lat = G_geodesic_lat_from_lon(lon);
+	    if (i == 0)
+		D_move_abs(lon, lat);
+	    else
+		D_cont_abs(lon, lat);
+	}
 
-    return 0;
-}
-
-static int cont(int x, int y)
-{
-    if (D_cont_abs_clip(x, y)) {	/* clipped */
-	change_range = 1;
+	text_x = (lon1 + lon2) / 2;
+	text_y = G_geodesic_lat_from_lon(text_x);
     }
-    else {			/* keep track of left,right x for lines drawn in window */
-
-	if (change_range) {
-	    which_range++;
-	    min_range[which_range] = max_range[which_range] = x;
-	    change_range = 0;
-	}
-	else {
-	    if (x < min_range[which_range])
-		min_range[which_range] = x;
-	    else if (x > max_range[which_range])
-		max_range[which_range] = x;
-	}
+    else {
+	D_line_abs(lon1, lat1, lon2, lat2);
+	text_x = (lon1 + lon2) / 2;
+	text_y = (lat1 + lat2) / 2;
     }
 
-    return 0;
-}
+    if (text_color != -1) {
+	double t, b, l, r;
+	char buf[100];
 
-static int move(int x, int y)
-{
-    D_move_abs(x, y);
+	R_text_size(10, 10);
 
-    return 0;
-}
+	distance = G_geodesic_distance(lon1, lat1, lon2, lat2);
+	sprintf(buf, "%.0f miles", METERS_TO_MILES(distance));
 
-static int geodesic(int x)
-{
-    double lon, lat;
+	D_move_abs(text_x, text_y);
+	D_get_text_box(buf, &t, &b, &l, &r);
 
-    lon = D_d_to_u_col((double)x);
-    lat = G_geodesic_lat_from_lon(lon);
-    return (int)D_u_to_d_row(lat);
+	if (t - D_get_u_north() > 0)
+	    text_y -= t - D_get_u_north();
+	if (b - D_get_u_south() < 0)
+	    text_y -= b - D_get_u_south();
+	if (r - D_get_u_east() > 0)
+	    text_x -= r - D_get_u_east();
+	if (l - D_get_u_west() < 0)
+	    text_x -= l - D_get_u_west();
 
-    return 0;
-}
+	D_use_color(text_color);
 
-static int get_text_x(void)
-{
-    int n;
-    int len;
-    int max;
-    int which;
-
-    which = -1;
-    max = 0;
-    for (n = 0; n <= which_range; n++) {
-	len = max_range[n] - min_range[n];
-	if (len >= max) {
-	    max = len;
-	    which = n;
-	}
+	D_move_abs(text_x, text_y);
+	R_text(buf);
     }
-    if (which < 0)
-	return -1;
-
-    return (max_range[which] + min_range[which]) / 2;
 }

Modified: grass/trunk/display/d.rhumbline/local_proto.h
===================================================================
--- grass/trunk/display/d.rhumbline/local_proto.h	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.rhumbline/local_proto.h	2008-09-02 21:02:14 UTC (rev 33225)
@@ -1,6 +1 @@
-/* mouse.c */
-int mouse(int, int);
-
-/* plot.c */
-int setup_plot(void);
-int plot(double, double, double, double, int, int);
+void plot(double, double, double, double, int, int);

Modified: grass/trunk/display/d.rhumbline/main.c
===================================================================
--- grass/trunk/display/d.rhumbline/main.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.rhumbline/main.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -119,9 +119,9 @@
 	text_color = D_translate_color(deftcolor);
 #endif
 
-    setup_plot();
     plot(lon1, lat1, lon2, lat2, line_color, text_color);
 
     R_close_driver();
-    exit(0);
+
+    exit(EXIT_SUCCESS);
 }

Modified: grass/trunk/display/d.rhumbline/plot.c
===================================================================
--- grass/trunk/display/d.rhumbline/plot.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.rhumbline/plot.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -3,56 +3,39 @@
 #include <grass/gis.h>
 #include <grass/display.h>
 #include <grass/raster.h>
+#include "local_proto.h"
 
-static int move(int, int);
-static int cont(int, int);
-
-#define METERS_TO_MILES(x) ((x) * 6.213712e-04)
-
-int setup_plot(void)
+void plot(double lon1, double lat1, double lon2, double lat2,
+	  int line_color, int text_color)
 {
-    /* establish the current graphics window */
-    D_setup_unity(0);
+    int nsteps = 1000;
+    int i;
 
-    /* setup the G plot to use the D routines */
-    G_setup_plot(D_get_d_north(),
-		 D_get_d_south(), D_get_d_west(), D_get_d_east(), move, cont);
+    D_setup(0);
 
-    R_text_size(10, 10);
+    D_use_color(line_color);
 
-    return 0;
-}
+    if (lon1 == lon2) {
+	D_line_abs(lon1, lat1, lon2, lat2);
+	return;
+    }
 
-int
-plot(double lon1, double lat1, double lon2, double lat2, int line_color,
-     int text_color)
-{
-    int text_x, text_y;
-
-    D_use_color(line_color);
-    if (lon1 != lon2) {
-	G_shortest_way(&lon1, &lon2);
-	G_begin_rhumbline_equation(lon1, lat1, lon2, lat2);
-	G_plot_fx(G_rhumbline_lat_from_lon, lon1, lon2);
+    if (lon1 > lon2) {
+	double tmp = lon1;
+	lon1 = lon2;
+	lon2 = tmp;
     }
-    else {
-	G_plot_where_xy(lon1, (lat1 + lat2) / 2, &text_x, &text_y);
-	G_plot_line(lon1, lat1, lon2, lat2);
-    }
 
-    return 0;
-}
+    G_shortest_way(&lon1, &lon2);
 
-static int cont(int x, int y)
-{
-    D_cont_abs(x, y);
+    G_begin_rhumbline_equation(lon1, lat1, lon2, lat2);
 
-    return 0;
+    for (i = 0; i <= nsteps; i++) {
+	double lon = lon1 + (lon2 - lon1) * i / nsteps;
+	double lat = G_rhumbline_lat_from_lon(lon);
+	if (i == 0)
+	    D_move_abs(lon, lat);
+	else
+	    D_cont_abs(lon, lat);
+    }
 }
-
-static int move(int x, int y)
-{
-    D_move_abs(x, y);
-
-    return 0;
-}

Modified: grass/trunk/display/d.thematic.area/area.c
===================================================================
--- grass/trunk/display/d.thematic.area/area.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.thematic.area/area.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -155,7 +155,7 @@
 
 	/* plot polygon in class color */
 	D_RGB_color(colors[i].r, colors[i].g, colors[i].b);
-	plot_polygon(Points->x, Points->y, Points->n_points);
+	D_polygon_abs(Points->x, Points->y, Points->n_points);
 
 	/* XXX rewrite boundary */
 	if (bcolor) {
@@ -164,12 +164,12 @@
 	    Vect_get_area_points(Map, area, Points);
 	    D_RGB_color(bcolor->r, bcolor->g, bcolor->b);
 	    /*use different user defined render methods */
-	    plot_polyline(Points->x, Points->y, Points->n_points);
+	    D_polyline_abs(Points->x, Points->y, Points->n_points);
 	    for (i = 0; i < n_isles; i++) {
 		isle = Vect_get_area_isle(Map, area, i);
 		Vect_get_isle_points(Map, isle, Points);
 		/*use different user defined render methods */
-		plot_polyline(Points->x, Points->y, Points->n_points);
+		D_polyline_abs(Points->x, Points->y, Points->n_points);
 	    }
 	}
     }				/* end for loop over areas */

Modified: grass/trunk/display/d.thematic.area/local_proto.h
===================================================================
--- grass/trunk/display/d.thematic.area/local_proto.h	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.thematic.area/local_proto.h	2008-09-02 21:02:14 UTC (rev 33225)
@@ -10,7 +10,5 @@
 int dareatheme(struct Map_info *, struct cat_list *, dbCatValArray *,
 	       double *, int, const struct color_rgb *,
 	       const struct color_rgb *, int, struct Cell_head *, int);
-void plot_polygon(double *, double *, int);
-void plot_polyline(double *, double *, int);
 
 int dcmp(const void *, const void *);

Modified: grass/trunk/display/d.thematic.area/main.c
===================================================================
--- grass/trunk/display/d.thematic.area/main.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.thematic.area/main.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -53,7 +53,6 @@
     struct Option *bwidth_opt;
     struct Option *where_opt;
     struct Option *field_opt;
-    struct Option *render_opt;
     struct Option *legend_file_opt;
     struct Flag *legend_flag, *algoinfo_flag, *nodraw_flag;
 
@@ -147,20 +146,6 @@
     bcolor_opt->guisection = _("Boundaries");
     bcolor_opt->gisprompt = GISPROMPT_COLOR;
 
-    render_opt = G_define_option();
-    render_opt->key = "render";
-    render_opt->type = TYPE_STRING;
-    render_opt->required = NO;
-    render_opt->multiple = NO;
-    render_opt->answer = "l";
-    render_opt->options = "d,c,l";
-    render_opt->description = _("Rendering method for filled polygons");
-    render_opt->descriptions =
-	_("d;use the display library basic functions (features: polylines);"
-	  "c;use the display library clipping functions (features: clipping);"
-	  "l;use the display library culling functions (features: culling, polylines)");
-
-
     legend_file_opt = G_define_standard_option(G_OPT_F_OUTPUT);
     legend_file_opt->key = "legendfile";
     legend_file_opt->description =
@@ -185,15 +170,6 @@
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
-    if (G_strcasecmp(render_opt->answer, "d") == 0)
-	render = RENDER_DP;
-    else if (G_strcasecmp(render_opt->answer, "c") == 0)
-	render = RENDER_DPC;
-    else if (G_strcasecmp(render_opt->answer, "l") == 0)
-	render = RENDER_DPL;
-    else
-	G_fatal_error(_("Invalid rendering method <%s>"), render_opt->answer);
-
     if (G_verbose() > G_verbose_std())
 	verbose = TRUE;
 

Modified: grass/trunk/display/d.thematic.area/plot1.c
===================================================================
--- grass/trunk/display/d.thematic.area/plot1.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.thematic.area/plot1.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -35,48 +35,9 @@
     {0, 139, 139}		/* 16: dark cyan */
 };
 
-/*global render switch */
-int render;
-
 /* *************************************************************** */
-/* function to use different render methods for polylines ******** */
 /* *************************************************************** */
-void plot_polyline(double *xf, double *yf, int n)
-{
-    switch (render) {
-    case RENDER_DP:
-	D_polyline_abs(xf, yf, n);
-	break;
-    case RENDER_DPC:
-	D_polyline_abs_clip(xf, yf, n);
-	break;
-    case RENDER_DPL:
-	D_polyline_abs_cull(xf, yf, n);
-	break;
-    }
-}
-
 /* *************************************************************** */
-/* function to use different render methods for polygons  ******** */
-/* *************************************************************** */
-void plot_polygon(double *xf, double *yf, int n)
-{
-    switch (render) {
-    case RENDER_DP:
-	D_polygon_abs(xf, yf, n);
-	break;
-    case RENDER_DPC:
-	D_polygon_abs_clip(xf, yf, n);
-	break;
-    case RENDER_DPL:
-	D_polygon_abs_cull(xf, yf, n);
-	break;
-    }
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
 int plot1(struct Map_info *Map, int type, int area, struct cat_list *Clist,
 	  const struct color_rgb *color, const struct color_rgb *fcolor,
 	  int chcat, SYMBOL * Symb, int size, int id_flag,
@@ -447,9 +408,9 @@
 
 	    /* Plot the lines */
 	    if (Points->n_points == 1)	/* line with one coor */
-		D_polydots_abs_clip(x, y, Points->n_points);
+		D_polydots_abs(x, y, Points->n_points);
 	    else		/*use different user defined render methods */
-		plot_polyline(x, y, Points->n_points);
+		D_polyline_abs(x, y, Points->n_points);
 	}
     }
 

Modified: grass/trunk/display/d.vect/area.c
===================================================================
--- grass/trunk/display/d.vect/area.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.vect/area.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -358,7 +358,7 @@
 	if (fcolor || (z_color_flag && Vect_is_3d(Map))) {
 	    if (!table_colors_flag && !cats_color_flag && !z_color_flag) {
 		D_RGB_color(fcolor->r, fcolor->g, fcolor->b);
-		plot_polygon(Points->x, Points->y, Points->n_points);
+		D_polygon_abs(Points->x, Points->y, Points->n_points);
 	    }
 	    else {
 		if (rgb) {
@@ -369,7 +369,7 @@
 		    D_RGB_color(fcolor->r, fcolor->g, fcolor->b);
 		}
 		if (cat >= 0) {
-		    plot_polygon(Points->x, Points->y, Points->n_points);
+		    D_polygon_abs(Points->x, Points->y, Points->n_points);
 		}
 	    }
 	}
@@ -387,12 +387,12 @@
 		D_RGB_color(bcolor->r, bcolor->g, bcolor->b);
 	    }
 	    /*use different user defined render methods */
-	    plot_polyline(Points->x, Points->y, Points->n_points);
+	    D_polyline_abs(Points->x, Points->y, Points->n_points);
 	    for (i = 0; i < n_isles; i++) {
 		isle = Vect_get_area_isle(Map, area, i);
 		Vect_get_isle_points(Map, isle, Points);
 		/*use different user defined render methods */
-		plot_polyline(Points->x, Points->y, Points->n_points);
+		D_polyline_abs(Points->x, Points->y, Points->n_points);
 	    }
 	}
     }				/* end for */

Modified: grass/trunk/display/d.vect/local_proto.h
===================================================================
--- grass/trunk/display/d.vect/local_proto.h	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.vect/local_proto.h	2008-09-02 21:02:14 UTC (rev 33225)
@@ -16,7 +16,5 @@
 int attr(struct Map_info *, int, char *, struct cat_list *, LATTR *, int);
 int zcoor(struct Map_info *, int, LATTR *);
 int test_bg_color(const char *);
-void plot_polygon(double *, double *, int);
-void plot_polyline(double *, double *, int);
 void show_label(double *, double *, LATTR *, const char *);
 void show_label_line(const struct line_pnts *, int, LATTR *, const char *);

Modified: grass/trunk/display/d.vect/main.c
===================================================================
--- grass/trunk/display/d.vect/main.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.vect/main.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -100,8 +100,6 @@
     struct Option *lsize_opt, *font_opt, *enc_opt, *xref_opt, *yref_opt;
     struct Option *attrcol_opt, *maxreg_opt, *minreg_opt;
     struct Option *width_opt, *wcolumn_opt, *wscale_opt;
-    struct Option *render_opt;
-    struct Flag *verbose_flag;	/* please remove before GRASS 7 released */
     struct Flag *id_flag, *table_acolors_flag, *cats_acolors_flag,
 	*zcol_flag;
     struct cat_list *Clist;
@@ -323,24 +321,6 @@
 	_("Maximum region size (average from height and width) "
 	  "when map is displayed");
 
-    render_opt = G_define_option();
-    render_opt->key = "render";
-    render_opt->type = TYPE_STRING;
-    render_opt->required = NO;
-    render_opt->multiple = NO;
-    render_opt->answer = "l";
-    render_opt->options = "d,c,l";
-    render_opt->description = _("Rendering method for filled polygons");
-    render_opt->descriptions =
-	_("d;use the display library basic functions (features: polylines);"
-	  "c;use the display library clipping functions (features: clipping);"
-	  "l;use the display library culling functions (features: culling, polylines)");
-
-    /* please remove before GRASS 7 released */
-    verbose_flag = G_define_flag();
-    verbose_flag->key = 'v';
-    verbose_flag->description = _("Run verbosely");
-
     /* Colors */
     table_acolors_flag = G_define_flag();
     table_acolors_flag->key = 'a';
@@ -369,22 +349,6 @@
     if (G_parser(argc, argv))
 	exit(EXIT_FAILURE);
 
-    if (G_strcasecmp(render_opt->answer, "d") == 0)
-	render = RENDER_DP;
-    else if (G_strcasecmp(render_opt->answer, "c") == 0)
-	render = RENDER_DPC;
-    else if (G_strcasecmp(render_opt->answer, "l") == 0)
-	render = RENDER_DPL;
-    else
-	G_fatal_error(_("Invalid rendering method <%s>"), render_opt->answer);
-
-    /* please remove -v flag before GRASS 7 released */
-    if (verbose_flag->answer) {
-	G_putenv("GRASS_VERBOSE", "3");
-	G_warning(_("The '-v' flag is superseded and will be removed "
-		    "in future. Please use '--verbose' instead."));
-    }
-    /* but keep this */
     if (G_verbose() > G_verbose_std())
 	verbose = TRUE;
 

Modified: grass/trunk/display/d.vect/plot1.c
===================================================================
--- grass/trunk/display/d.vect/plot1.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/display/d.vect/plot1.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -35,48 +35,9 @@
     {0, 139, 139}		/* 16: dark cyan */
 };
 
-/*global render switch */
-int render;
-
 /* *************************************************************** */
-/* function to use different render methods for polylines ******** */
 /* *************************************************************** */
-void plot_polyline(double *xf, double *yf, int n)
-{
-    switch (render) {
-    case RENDER_DP:
-	D_polyline_abs(xf, yf, n);
-	break;
-    case RENDER_DPC:
-	D_polyline_abs_clip(xf, yf, n);
-	break;
-    case RENDER_DPL:
-	D_polyline_abs_cull(xf, yf, n);
-	break;
-    }
-}
-
 /* *************************************************************** */
-/* function to use different render methods for polygons  ******** */
-/* *************************************************************** */
-void plot_polygon(double *xf, double *yf, int n)
-{
-    switch (render) {
-    case RENDER_DP:
-	D_polygon_abs(xf, yf, n);
-	break;
-    case RENDER_DPC:
-	D_polygon_abs_clip(xf, yf, n);
-	break;
-    case RENDER_DPL:
-	D_polygon_abs_cull(xf, yf, n);
-	break;
-    }
-}
-
-/* *************************************************************** */
-/* *************************************************************** */
-/* *************************************************************** */
 int plot1(struct Map_info *Map, int type, int area, struct cat_list *Clist,
 	  const struct color_rgb *color, const struct color_rgb *fcolor,
 	  int chcat, SYMBOL * Symb, int size, int id_flag,
@@ -463,9 +424,9 @@
 
 	    /* Plot the lines */
 	    if (Points->n_points == 1)	/* line with one coor */
-		D_polydots_abs_clip(x, y, Points->n_points);
+		D_polydots_abs(x, y, Points->n_points);
 	    else		/*use different user defined render methods */
-		plot_polyline(x, y, Points->n_points);
+		D_polyline_abs(x, y, Points->n_points);
 	}
     }
 

Modified: grass/trunk/include/display.h
===================================================================
--- grass/trunk/include/display.h	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/include/display.h	2008-09-02 21:02:14 UTC (rev 33225)
@@ -74,32 +74,6 @@
 void D_line_width(double);
 void D_get_text_box(const char *, double *, double *, double *, double *);
 
-int D_cont_abs_cull(double, double);
-int D_cont_rel_cull(double, double);
-int D_line_abs_cull(double, double, double, double);
-int D_line_rel_cull(double, double, double, double);
-void D_polydots_abs_cull(const double *, const double *, int);
-void D_polydots_rel_cull(const double *, const double *, int);
-void D_polyline_abs_cull(const double *, const double *, int);
-void D_polyline_rel_cull(const double *, const double *, int);
-void D_polygon_abs_cull(const double *, const double *, int);
-void D_polygon_rel_cull(const double *, const double *, int);
-void D_box_abs_cull(double, double, double, double);
-void D_box_rel_cull(double, double);
-
-int D_cont_abs_clip(double, double);
-int D_cont_rel_clip(double, double);
-int D_line_abs_clip(double, double, double, double);
-int D_line_rel_clip(double, double, double, double);
-void D_polydots_abs_clip(const double *, const double *, int);
-void D_polydots_rel_clip(const double *, const double *, int);
-void D_polyline_abs_clip(const double *, const double *, int);
-void D_polyline_rel_clip(const double *, const double *, int);
-void D_polygon_abs_clip(const double *, const double *, int);
-void D_polygon_rel_clip(const double *, const double *, int);
-void D_box_abs_clip(double, double, double, double);
-void D_box_rel_clip(double, double);
-
 void D_move_abs(double, double);
 void D_move_rel(double, double);
 void D_cont_abs(double, double);
@@ -115,6 +89,14 @@
 void D_box_abs(double, double, double, double);
 void D_box_rel(double, double);
 
+enum clip_mode {
+    D_MODE_NONE,
+    D_MODE_CULL,
+    D_MODE_CLIP,
+};
+
+void D_set_clip_mode(int);
+
 /* icon.c */
 void D_plot_icon(double, double, int, double, double);
 

Modified: grass/trunk/lib/display/draw2.c
===================================================================
--- grass/trunk/lib/display/draw2.c	2008-09-02 18:50:59 UTC (rev 33224)
+++ grass/trunk/lib/display/draw2.c	2008-09-02 21:02:14 UTC (rev 33225)
@@ -44,6 +44,29 @@
 static double *xf, *yf;
 static int nalloc_f;
 
+struct functions {
+    void (*move_abs)(double x, double y);
+    void (*move_rel)(double x, double y);
+    void (*cont_abs)(double x, double y);
+    void (*cont_rel)(double x, double y);
+    void (*line_abs)(double x1, double y1, double x2, double y2);
+    void (*line_rel)(double x1, double y1, double x2, double y2);
+    void (*polydots_abs)(const double *x, const double *y, int n);
+    void (*polydots_rel)(const double *x, const double *y, int n);
+    void (*polyline_abs)(const double *x, const double *y, int n);
+    void (*polyline_rel)(const double *x, const double *y, int n);
+    void (*polygon_abs)(const double *x, const double *y, int n);
+    void (*polygon_rel)(const double *x, const double *y, int n);
+    void (*box_abs)(double x1, double y1, double x2, double y2);
+    void (*box_rel)(double x2, double y2);
+};
+
+static struct functions raw_functions, cull_functions, clip_functions;
+
+static struct functions *fns = &cull_functions;
+
+/******************************************************************************/
+
 static void alloc_dst(int n)
 {
 
@@ -137,74 +160,6 @@
     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 int clip_plane(struct vector *a, struct vector *b,
-		      const struct plane *p, int *clipped)
-{
-    double ka = dist_plane(a->x, a->y, p);
-    double kb = dist_plane(b->x, b->y, p);
-    double kab;
-
-    /* both outside */
-    if (ka > 0 && kb > 0)
-	return 1;
-
-    /* both inside */
-    if (ka <= 0 && kb <= 0)
-	return 0;
-
-    *clipped = 1;
-
-    /* a outside - swap a and b */
-    if (ka >= 0) {
-	struct vector *t;
-	double kt;
-
-	t = a;
-	a = b;
-	b = t;
-	kt = ka;
-	ka = kb;
-	kb = kt;
-    }
-
-    kab = kb - ka;
-
-    b->x = interpolate(a->x, b->x, ka, kb);
-    b->y = interpolate(a->y, b->y, ka, kb);
-
-    return 0;
-}
-
-static int do_clip(struct vector *a, struct vector *b)
-{
-    int clipped = 0;
-
-    if (a->x < clip.left && b->x < clip.left)
-	return -1;
-    if (a->x > clip.rite && b->x > clip.rite)
-	return -1;
-    if (a->y < clip.bot && b->y < clip.bot)
-	return -1;
-    if (a->y > clip.top && b->y > clip.top)
-	return -1;
-
-    if (clip_plane(a, b, &pl_left, &clipped))
-	return -1;
-    if (clip_plane(a, b, &pl_rite, &clipped))
-	return -1;
-    if (clip_plane(a, b, &pl_bot, &clipped))
-	return -1;
-    if (clip_plane(a, b, &pl_top, &clipped))
-	return -1;
-
-    return clipped;
-}
-
 static int shift_count(double dx)
 {
     return (int)floor(dx / 360);
@@ -275,65 +230,74 @@
     G_free(xx);
 }
 
-/*!
- * \brief set clipping window
- *
- * Sets the clipping window to the pixel window that corresponds
- * to the current database region. This is the default.
- *
- *  \param top
- *  \param bottom
- *  \param left
- *  \param right
- */
+/******************************************************************************/
 
-void D_set_clip(double t, double b, double l, double r)
+static double interpolate(double a, double b, double ka, double kb)
 {
-    clip.left = min(l, r);
-    clip.rite = max(l, r);
-    clip.bot = min(b, t);
-    clip.top = max(b, t);
+    return (a * kb - b * ka) / (kb - ka);
+}
 
-    pl_left.k = clip.left;
-    pl_rite.k = -clip.rite;
-    pl_bot.k = clip.bot;
-    pl_top.k = -clip.top;
+static int clip_plane(struct vector *a, struct vector *b,
+		      const struct plane *p, int *clipped)
+{
+    double ka = dist_plane(a->x, a->y, p);
+    double kb = dist_plane(b->x, b->y, p);
+    double kab;
 
-    window_set = 1;
-}
+    /* both outside */
+    if (ka > 0 && kb > 0)
+	return 1;
 
-/*!
- * \brief set clipping window to map window
- *
- * Sets the clipping window to the pixel window that corresponds to the
- * current database region. This is the default.
- *
- *  \param ~
- */
+    /* both inside */
+    if (ka <= 0 && kb <= 0)
+	return 0;
 
-void D_clip_to_map(void)
-{
-    double t, b, l, r;
+    *clipped = 1;
 
-    D_get_src(&t, &b, &l, &r);
-    D_set_clip(t, b, l, r);
-}
+    /* a outside - swap a and b */
+    if (ka >= 0) {
+	struct vector *t;
+	double kt;
 
-void D_line_width(double d)
-{
-    R_line_width(d > 0 ? d : 0);
+	t = a;
+	a = b;
+	b = t;
+	kt = ka;
+	ka = kb;
+	kb = kt;
+    }
+
+    kab = kb - ka;
+
+    b->x = interpolate(a->x, b->x, ka, kb);
+    b->y = interpolate(a->y, b->y, ka, kb);
+
+    return 0;
 }
 
-void D_get_text_box(const char *text, double *t, double *b, double *l, double *r)
+static int do_clip(struct vector *a, struct vector *b)
 {
-    double T, B, L, R;
+    int clipped = 0;
 
-    R_get_text_box(text, &T, &B, &L, &R);
+    if (a->x < clip.left && b->x < clip.left)
+	return -1;
+    if (a->x > clip.rite && b->x > clip.rite)
+	return -1;
+    if (a->y < clip.bot && b->y < clip.bot)
+	return -1;
+    if (a->y > clip.top && b->y > clip.top)
+	return -1;
 
-    *t = D_d_to_u_row(T);
-    *b = D_d_to_u_row(B);
-    *l = D_d_to_u_col(L);
-    *r = D_d_to_u_col(R);
+    if (clip_plane(a, b, &pl_left, &clipped))
+	return -1;
+    if (clip_plane(a, b, &pl_rite, &clipped))
+	return -1;
+    if (clip_plane(a, b, &pl_bot, &clipped))
+	return -1;
+    if (clip_plane(a, b, &pl_top, &clipped))
+	return -1;
+
+    return clipped;
 }
 
 static int line_clip(double x1, double y1, double x2, double y2)
@@ -381,49 +345,52 @@
     ret = 0;
 
     for (i = lo; i <= hi; i++)
-	ret |= line_clip(ax + i * 360, ay, bx + i * 360, by);
+	ret |= line_clip(ax - i * 360, ay, bx - i * 360, by);
 
     return ret;
 }
 
-static int cull_polyline_plane(int *pn, const double *x, const double *y,
-			       const struct plane *p)
+static void polyline_clip(const double *x, const double *y, int n)
 {
+    int i;
+
+    for (i = 1; i < n; i++)
+	line_clip(x[i - 1], y[i - 1], x[i], y[i]);
+}
+
+static int clip_polygon_plane(int *pn, const double *x, const double *y,
+			      const struct plane *p)
+{
     int n = *pn;
-    int last = -1;
-    int prev = 0;
-    double x0 = x[prev];
-    double y0 = y[prev];
+    double x0 = x[n - 1];
+    double y0 = y[n - 1];
     double d0 = dist_plane(x0, y0, p);
     int i, j;
 
-    for (i = 0, j = 0; i < n; i++) {
+    for (i = j = 0; i < n; i++) {
 	double x1 = x[i];
 	double y1 = y[i];
 	double d1 = dist_plane(x1, y1, p);
 	int in0 = d0 <= 0;
 	int in1 = d1 <= 0;
 
-	if (!in0 && in1 && last != prev) {	/* entering */
+	if (in0 != in1) {	/* edge crossing */
 	    alloc_src(j + 1);
-	    xf[j] = x0;
-	    yf[j] = y0;
+	    xf[j] = interpolate(x0, x1, d0, d1);
+	    yf[j] = interpolate(y0, y1, d0, d1);
 	    j++;
-	    last = prev;
 	}
 
-	if (in1 || in0) {	/* inside or leaving */
+	if (in1) {		/* point inside */
 	    alloc_src(j + 1);
-	    xf[j] = x1;
-	    yf[j] = y1;
+	    xf[j] = x[i];
+	    yf[j] = y[i];
 	    j++;
-	    last = i;
 	}
 
 	x0 = x1;
 	y0 = y1;
 	d0 = d1;
-	prev = i;
     }
 
     *pn = j;
@@ -431,55 +398,108 @@
     return (j == 0);
 }
 
-static void polyline_cull(const double *x, const double *y, int n)
+static void polygon_clip(const double *x, const double *y, int n)
 {
     alloc_src(n + 10);
 
-    if (cull_polyline_plane(&n, x, y, &pl_left))
+    if (clip_polygon_plane(&n, x, y, &pl_left))
 	return;
 
     dealloc_src(&x, &y, 0);
 
-    if (cull_polyline_plane(&n, x, y, &pl_rite))
+    if (clip_polygon_plane(&n, x, y, &pl_rite))
 	return;
 
     dealloc_src(&x, &y, 1);
 
-    if (cull_polyline_plane(&n, x, y, &pl_bot))
+    if (clip_polygon_plane(&n, x, y, &pl_bot))
 	return;
 
     dealloc_src(&x, &y, 1);
 
-    if (cull_polyline_plane(&n, x, y, &pl_top))
+    if (clip_polygon_plane(&n, x, y, &pl_top))
 	return;
 
     dealloc_src(&x, &y, 1);
 
     n = do_convert(x, y, n);
 
-    R_polyline_abs(xi, yi, n);
+    R_polygon_abs(xi, yi, n);
 }
 
-static void polyline_clip(const double *x, const double *y, int n)
+static void polydots_clip(const double *x, const double *y, int n)
 {
-    int i;
+    double ux0 = clip.left;
+    int i, j;
 
-    for (i = 1; i < n; i++)
-	line_clip(x[i - 1], y[i - 1], x[i], y[i]);
+    alloc_src(n);
+
+    for (i = j = 0; i < n; i++) {
+	double xx = x[i];
+	double yy = y[i];
+
+	if (D_is_lat_lon())
+	    xx -= shift_angle(x[i] - ux0);
+
+	if (xx < clip.left || xx > clip.rite)
+	    continue;
+	if (yy < clip.bot || yy > clip.top)
+	    continue;
+
+	xf[j] = xx;
+	yf[j] = yy;
+	j++;
+    }
+
+    n = do_convert(xf, yf, n);
+
+    R_polydots_abs(xi, yi, j);
 }
 
-static int cull_polygon_plane(int *pn, const double *x, const double *y,
-			      const struct plane *p)
+static void box_clip(double x1, double y1, double x2, double y2)
 {
+    x1 = max(clip.left, min(clip.rite, x1));
+    x2 = max(clip.left, min(clip.rite, x2));
+    y1 = max(clip.bot, min(clip.top, y1));
+    y2 = max(clip.bot, min(clip.top, 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);
+}
+
+static void box_clip_ll(double x1, double y1, double x2, double y2)
+{
+    double ux0 = clip.left;
+    double ux1 = clip.rite;
+    int lo, hi, i;
+
+    x2 = x1 + coerce(x2 - x1);
+
+    lo = -shift_count(ux1 - x1);
+    hi = shift_count(x2 - ux0);
+
+    for (i = lo; i <= hi; i++)
+	box_clip(x1 - i * 360, y1, x2 - i * 360, y2);
+}
+
+/******************************************************************************/
+
+static int cull_polyline_plane(int *pn, const double *x, const double *y,
+			       const struct plane *p)
+{
     int n = *pn;
     int last = -1;
-    int prev = n - 1;
+    int prev = 0;
     double x0 = x[prev];
     double y0 = y[prev];
     double d0 = dist_plane(x0, y0, p);
     int i, j;
 
-    for (i = j = 0; i < n; i++) {
+    for (i = 0, j = 0; i < n; i++) {
 	double x1 = x[i];
 	double y1 = y[i];
 	double d1 = dist_plane(x1, y1, p);
@@ -513,41 +533,43 @@
     return (j == 0);
 }
 
-static void polygon_cull(const double *x, const double *y, int n)
+static void polyline_cull(const double *x, const double *y, int n)
 {
     alloc_src(n + 10);
 
-    if (cull_polygon_plane(&n, x, y, &pl_left))
+    if (cull_polyline_plane(&n, x, y, &pl_left))
 	return;
 
     dealloc_src(&x, &y, 0);
 
-    if (cull_polygon_plane(&n, x, y, &pl_rite))
+    if (cull_polyline_plane(&n, x, y, &pl_rite))
 	return;
 
     dealloc_src(&x, &y, 1);
 
-    if (cull_polygon_plane(&n, x, y, &pl_bot))
+    if (cull_polyline_plane(&n, x, y, &pl_bot))
 	return;
 
     dealloc_src(&x, &y, 1);
 
-    if (cull_polygon_plane(&n, x, y, &pl_top))
+    if (cull_polyline_plane(&n, x, y, &pl_top))
 	return;
 
     dealloc_src(&x, &y, 1);
 
     n = do_convert(x, y, n);
 
-    R_polygon_abs(xi, yi, n);
+    R_polyline_abs(xi, yi, n);
 }
 
-static int clip_polygon_plane(int *pn, const double *x, const double *y,
+static int cull_polygon_plane(int *pn, const double *x, const double *y,
 			      const struct plane *p)
 {
     int n = *pn;
-    double x0 = x[n - 1];
-    double y0 = y[n - 1];
+    int last = -1;
+    int prev = n - 1;
+    double x0 = x[prev];
+    double y0 = y[prev];
     double d0 = dist_plane(x0, y0, p);
     int i, j;
 
@@ -558,23 +580,26 @@
 	int in0 = d0 <= 0;
 	int in1 = d1 <= 0;
 
-	if (in0 != in1) {	/* edge crossing */
+	if (!in0 && in1 && last != prev) {	/* entering */
 	    alloc_src(j + 1);
-	    xf[j] = interpolate(x0, x1, d0, d1);
-	    yf[j] = interpolate(y0, y1, d0, d1);
+	    xf[j] = x0;
+	    yf[j] = y0;
 	    j++;
+	    last = prev;
 	}
 
-	if (in1) {		/* point inside */
+	if (in1 || in0) {	/* inside or leaving */
 	    alloc_src(j + 1);
-	    xf[j] = x[i];
-	    yf[j] = y[i];
+	    xf[j] = x1;
+	    yf[j] = y1;
 	    j++;
+	    last = i;
 	}
 
 	x0 = x1;
 	y0 = y1;
 	d0 = d1;
+	prev = i;
     }
 
     *pn = j;
@@ -582,26 +607,26 @@
     return (j == 0);
 }
 
-static void polygon_clip(const double *x, const double *y, int n)
+static void polygon_cull(const double *x, const double *y, int n)
 {
     alloc_src(n + 10);
 
-    if (clip_polygon_plane(&n, x, y, &pl_left))
+    if (cull_polygon_plane(&n, x, y, &pl_left))
 	return;
 
     dealloc_src(&x, &y, 0);
 
-    if (clip_polygon_plane(&n, x, y, &pl_rite))
+    if (cull_polygon_plane(&n, x, y, &pl_rite))
 	return;
 
     dealloc_src(&x, &y, 1);
 
-    if (clip_polygon_plane(&n, x, y, &pl_bot))
+    if (cull_polygon_plane(&n, x, y, &pl_bot))
 	return;
 
     dealloc_src(&x, &y, 1);
 
-    if (clip_polygon_plane(&n, x, y, &pl_top))
+    if (cull_polygon_plane(&n, x, y, &pl_top))
 	return;
 
     dealloc_src(&x, &y, 1);
@@ -611,45 +636,15 @@
     R_polygon_abs(xi, yi, n);
 }
 
-static void box_clip(double x1, double y1, double x2, double y2)
-{
-    x1 = max(clip.left, min(clip.rite, x1));
-    x2 = max(clip.left, min(clip.rite, x2));
-    y1 = max(clip.top, min(clip.bot, y1));
-    y2 = max(clip.top, min(clip.bot, 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);
-}
-
-static void box_clip_ll(double x1, double y1, double x2, double y2)
-{
-    double ux0 = clip.left;
-    double ux1 = clip.rite;
-    int lo, hi, i;
-
-    x2 = x1 + coerce(x2 - x1);
-
-    lo = -shift_count(ux1 - x1);
-    hi = shift_count(x2 - ux0);
-
-    for (i = lo; i <= hi; i++)
-	box_clip(x1 + i * 360, y1, x2 + i * 360, y2);
-}
-
 static void box_cull(double x1, double y1, double x2, double y2)
 {
     if (x1 > clip.rite && x2 > clip.rite)
 	return;
     if (x1 < clip.left && x2 < clip.left)
 	return;
-    if (y1 > clip.bot && y2 > clip.bot)
+    if (y1 > clip.top && y2 > clip.top)
 	return;
-    if (y1 < clip.top && y2 < clip.top)
+    if (y1 < clip.bot && y2 < clip.bot)
 	return;
 
     x1 = D_u_to_d_col(x1);
@@ -672,47 +667,18 @@
     hi = shift_count(x2 - ux0);
 
     for (i = lo; i <= hi; i++)
-	box_clip(x1 + i * 360, y1, x2 + i * 360, y2);
+	box_clip(x1 - i * 360, y1, x2 - i * 360, y2);
 }
 
-static void polydots_cull(const double *x, const double *y, int n)
-{
-    double ux0 = clip.left;
-    int i, j;
-
-    alloc_src(n);
-
-    for (i = j = 0; i < n; i++) {
-	double xx = x[i];
-	double yy = y[i];
-
-	if (D_is_lat_lon())
-	    xx -= shift_angle(x[i] - ux0);
-
-	if (xx < clip.left || xx > clip.rite)
-	    continue;
-	if (yy < clip.bot || yy > clip.top)
-	    continue;
-
-	xf[j] = xx;
-	yf[j] = yy;
-	j++;
-    }
-
-    n = do_convert(xf, yf, n);
-
-    R_polydots_abs(xi, yi, j);
-}
-
 static int line_cull(double x1, double y1, double x2, double y2)
 {
     if (x1 > clip.rite && x2 > clip.rite)
 	return 1;
     if (x1 < clip.left && x2 < clip.left)
 	return 1;
-    if (y1 > clip.bot && y2 > clip.bot)
+    if (y1 > clip.top && y2 > clip.top)
 	return 1;
-    if (y1 < clip.top && y2 < clip.top)
+    if (y1 < clip.bot && y2 < clip.bot)
 	return 1;
 
     x1 = D_u_to_d_col(x1);
@@ -745,13 +711,132 @@
     ret = 1;
 
     for (i = lo; i <= hi; i++)
-	ret &= line_cull(ax + i * 360, ay, bx + i * 360, by);
+	ret &= line_cull(ax - i * 360, ay, bx - i * 360, by);
 
     return ret;
 }
 
-int D_cont_abs_cull(double x, double y)
+/******************************************************************************/
+
+static void D_move_abs_raw(double x, double y)
 {
+    cur.x = x;
+    cur.y = y;
+
+    x = D_u_to_d_col(x);
+    y = D_u_to_d_row(y);
+
+    R_move_abs(x, y);
+}
+
+static void D_move_rel_raw(double x, double y)
+{
+    D_move_abs_raw(cur.x + x, cur.y + y);
+}
+
+static void D_cont_abs_raw(double x, double y)
+{
+    cur.x = x;
+    cur.y = y;
+
+    x = D_u_to_d_col(x);
+    y = D_u_to_d_row(y);
+
+    R_cont_abs(x, y);
+}
+
+static void D_cont_rel_raw(double x, double y)
+{
+    D_cont_abs_raw(cur.x + x, cur.y + y);
+}
+
+static void D_line_abs_raw(double x1, double y1, double x2, double y2)
+{
+    D_move_abs_raw(x1, y1);
+    D_cont_abs_raw(x2, y2);
+}
+
+static void D_line_rel_raw(double x1, double y1, double x2, double y2)
+{
+    D_move_rel_raw(x1, y1);
+    D_cont_rel_raw(x2, y2);
+}
+
+static void D_polydots_abs_raw(const double *x, const double *y, int n)
+{
+    n = do_convert(x, y, n);
+    R_polydots_abs(xi, yi, n);
+}
+
+static void D_polydots_rel_raw(const double *x, const double *y, int n)
+{
+    rel_to_abs(&x, &y, n);
+    D_polydots_abs_raw(x, y, n);
+    dealloc_src(&x, &y, 1);
+}
+
+static void D_polyline_abs_raw(const double *x, const double *y, int n)
+{
+    n = do_convert(x, y, n);
+    R_polyline_abs(xi, yi, n);
+}
+
+static void D_polyline_rel_raw(const double *x, const double *y, int n)
+{
+    rel_to_abs(&x, &y, n);
+    D_polyline_abs_raw(x, y, n);
+    dealloc_src(&x, &y, 1);
+}
+
+static void D_polygon_abs_raw(const double *x, const double *y, int n)
+{
+    n = do_convert(x, y, n);
+    R_polygon_abs(xi, yi, n);
+}
+
+static void D_polygon_rel_raw(const double *x, const double *y, int n)
+{
+    rel_to_abs(&x, &y, n);
+    D_polygon_abs_raw(x, y, n);
+    dealloc_src(&x, &y, 1);
+}
+
+static void D_box_abs_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);
+}
+
+static void D_box_rel_raw(double x2, double y2)
+{
+    D_box_abs_raw(cur.x, cur.y, x2, y2);
+}
+
+static struct functions raw_functions = {
+    D_move_abs_raw,
+    D_move_rel_raw,
+    D_cont_abs_raw,
+    D_cont_rel_raw,
+    D_line_abs_raw,
+    D_line_rel_raw,
+    D_polydots_abs_raw,
+    D_polydots_rel_raw,
+    D_polyline_abs_raw,
+    D_polyline_rel_raw,
+    D_polygon_abs_raw,
+    D_polygon_rel_raw,
+    D_box_abs_raw,
+    D_box_rel_raw,
+};
+
+/******************************************************************************/
+
+static void D_cont_abs_cull(double x, double y)
+{
     int ret;
 
     if (!window_set)
@@ -764,43 +849,41 @@
 
     cur.x = x;
     cur.y = y;
-
-    return ret;
 }
 
-int D_cont_rel_cull(double x, double y)
+static void D_cont_rel_cull(double x, double y)
 {
-    return D_cont_abs_cull(cur.x + x, cur.y + y);
+    D_cont_abs_cull(cur.x + x, cur.y + y);
 }
 
-int D_line_abs_cull(double x1, double y1, double x2, double y2)
+static void D_line_abs_cull(double x1, double y1, double x2, double y2)
 {
     D_move_rel(x1, y1);
-    return D_cont_rel_cull(x2, y2);
+    D_cont_rel_cull(x2, y2);
 }
 
-int D_line_rel_cull(double x1, double y1, double x2, double y2)
+static void D_line_rel_cull(double x1, double y1, double x2, double y2)
 {
     D_move_abs(x1, y1);
-    return D_cont_abs_cull(x2, y2);
+    D_cont_abs_cull(x2, y2);
 }
 
-void D_polydots_abs_cull(const double *x, const double *y, int n)
+static void D_polydots_abs_cull(const double *x, const double *y, int n)
 {
     if (!window_set)
 	D_clip_to_map();
 
-    polydots_cull(x, y, n);
+    polydots_clip(x, y, n);
 }
 
-void D_polydots_rel_cull(const double *x, const double *y, int n)
+static void D_polydots_rel_cull(const double *x, const double *y, int n)
 {
     rel_to_abs(&x, &y, n);
     D_polydots_abs_cull(x, y, n);
     dealloc_src(&x, &y, 1);
 }
 
-void D_polyline_abs_cull(const double *x, const double *y, int n)
+static void D_polyline_abs_cull(const double *x, const double *y, int n)
 {
     if (n < 2)
 	return;
@@ -814,14 +897,14 @@
 	polyline_cull(x, y, n);
 }
 
-void D_polyline_rel_cull(const double *x, const double *y, int n)
+static void D_polyline_rel_cull(const double *x, const double *y, int n)
 {
     rel_to_abs(&x, &y, n);
     D_polyline_abs_cull(x, y, n);
     dealloc_src(&x, &y, 1);
 }
 
-void D_polygon_abs_cull(const double *x, const double *y, int n)
+static void D_polygon_abs_cull(const double *x, const double *y, int n)
 {
     if (!window_set)
 	D_clip_to_map();
@@ -832,14 +915,14 @@
 	polygon_cull(x, y, n);
 }
 
-void D_polygon_rel_cull(const double *x, const double *y, int n)
+static void D_polygon_rel_cull(const double *x, const double *y, int n)
 {
     rel_to_abs(&x, &y, n);
     D_polygon_abs_cull(x, y, n);
     dealloc_src(&x, &y, 1);
 }
 
-void D_box_abs_cull(double x1, double y1, double x2, double y2)
+static void D_box_abs_cull(double x1, double y1, double x2, double y2)
 {
     if (!window_set)
 	D_clip_to_map();
@@ -850,12 +933,31 @@
 	box_cull(x1, y1, x2, y2);
 }
 
-void D_box_rel_cull(double x2, double y2)
+static void D_box_rel_cull(double x2, double y2)
 {
     D_box_abs_cull(cur.x, cur.y, x2, y2);
 }
 
-int D_cont_abs_clip(double x, double y)
+static struct functions cull_functions = {
+    D_move_abs_raw,
+    D_move_rel_raw,
+    D_cont_abs_cull,
+    D_cont_rel_cull,
+    D_line_abs_cull,
+    D_line_rel_cull,
+    D_polydots_abs_cull,
+    D_polydots_rel_cull,
+    D_polyline_abs_cull,
+    D_polyline_rel_cull,
+    D_polygon_abs_cull,
+    D_polygon_rel_cull,
+    D_box_abs_cull,
+    D_box_rel_cull,
+};
+
+/******************************************************************************/
+
+static void D_cont_abs_clip(double x, double y)
 {
     int ret;
 
@@ -869,43 +971,41 @@
 
     cur.x = x;
     cur.y = y;
-
-    return ret;
 }
 
-int D_cont_rel_clip(double x, double y)
+static void D_cont_rel_clip(double x, double y)
 {
-    return D_cont_abs_clip(cur.x + x, cur.y + y);
+    D_cont_abs_clip(cur.x + x, cur.y + y);
 }
 
-int D_line_abs_clip(double x1, double y1, double x2, double y2)
+static void D_line_abs_clip(double x1, double y1, double x2, double y2)
 {
     D_move_abs(x1, y1);
-    return D_cont_abs_clip(x2, y2);
+    D_cont_abs_clip(x2, y2);
 }
 
-int D_line_rel_clip(double x1, double y1, double x2, double y2)
+static void D_line_rel_clip(double x1, double y1, double x2, double y2)
 {
     D_move_rel(x1, y1);
-    return D_cont_rel_clip(x2, y2);
+    D_cont_rel_clip(x2, y2);
 }
 
-void D_polydots_abs_clip(const double *x, const double *y, int n)
+static void D_polydots_abs_clip(const double *x, const double *y, int n)
 {
     if (!window_set)
 	D_clip_to_map();
 
-    polydots_cull(x, y, n);
+    polydots_clip(x, y, n);
 }
 
-void D_polydots_rel_clip(const double *x, const double *y, int n)
+static void D_polydots_rel_clip(const double *x, const double *y, int n)
 {
     rel_to_abs(&x, &y, n);
     D_polydots_abs_clip(x, y, n);
     dealloc_src(&x, &y, 1);
 }
 
-void D_polyline_abs_clip(const double *x, const double *y, int n)
+static void D_polyline_abs_clip(const double *x, const double *y, int n)
 {
     if (!window_set)
 	D_clip_to_map();
@@ -919,14 +1019,14 @@
 	polyline_clip(x, y, n);
 }
 
-void D_polyline_rel_clip(const double *x, const double *y, int n)
+static void D_polyline_rel_clip(const double *x, const double *y, int n)
 {
     rel_to_abs(&x, &y, n);
     D_polyline_abs_clip(x, y, n);
     dealloc_src(&x, &y, 1);
 }
 
-void D_polygon_abs_clip(const double *x, const double *y, int n)
+static void D_polygon_abs_clip(const double *x, const double *y, int n)
 {
     if (!window_set)
 	D_clip_to_map();
@@ -937,14 +1037,14 @@
 	polygon_clip(x, y, n);
 }
 
-void D_polygon_rel_clip(const double *x, const double *y, int n)
+static void D_polygon_rel_clip(const double *x, const double *y, int n)
 {
     rel_to_abs(&x, &y, n);
     D_polygon_abs_clip(x, y, n);
     dealloc_src(&x, &y, 1);
 }
 
-void D_box_abs_clip(double x1, double y1, double x2, double y2)
+static void D_box_abs_clip(double x1, double y1, double x2, double y2)
 {
     if (!window_set)
 	D_clip_to_map();
@@ -955,106 +1055,181 @@
 	box_clip(x1, y1, x2, y2);
 }
 
-void D_box_rel_clip(double x2, double y2)
+static void D_box_rel_clip(double x2, double y2)
 {
     D_box_abs_clip(cur.x, cur.y, x2, y2);
 }
 
-void D_move_abs(double x, double y)
+static struct functions clip_functions = {
+    D_move_abs_raw,
+    D_move_rel_raw,
+    D_cont_abs_clip,
+    D_cont_rel_clip,
+    D_line_abs_clip,
+    D_line_rel_clip,
+    D_polydots_abs_clip,
+    D_polydots_rel_clip,
+    D_polyline_abs_clip,
+    D_polyline_rel_clip,
+    D_polygon_abs_clip,
+    D_polygon_rel_clip,
+    D_box_abs_clip,
+    D_box_rel_clip,
+};
+
+/******************************************************************************/
+
+/*!
+ * \brief set clipping window
+ *
+ * Sets the clipping window to the pixel window that corresponds
+ * to the current database region. This is the default.
+ *
+ *  \param top
+ *  \param bottom
+ *  \param left
+ *  \param right
+ */
+
+void D_set_clip(double t, double b, double l, double r)
 {
-    cur.x = x;
-    cur.y = y;
+    clip.left = min(l, r);
+    clip.rite = max(l, r);
+    clip.bot = min(b, t);
+    clip.top = max(b, t);
 
-    x = D_u_to_d_col(x);
-    y = D_u_to_d_row(y);
+    pl_left.k = clip.left;
+    pl_rite.k = -clip.rite;
+    pl_bot.k = clip.bot;
+    pl_top.k = -clip.top;
 
-    R_move_abs(x, y);
+    window_set = 1;
 }
 
-void D_move_rel(double x, double y)
+/*!
+ * \brief set clipping window to map window
+ *
+ * Sets the clipping window to the pixel window that corresponds to the
+ * current database region. This is the default.
+ *
+ *  \param ~
+ */
+
+void D_clip_to_map(void)
 {
-    D_move_abs(cur.x + x, cur.y + y);
+    double t, b, l, r;
+
+    D_get_src(&t, &b, &l, &r);
+    D_set_clip(t, b, l, r);
 }
 
-void D_cont_abs(double x, double y)
+void D_line_width(double d)
 {
-    cur.x = x;
-    cur.y = y;
+    R_line_width(d > 0 ? d : 0);
+}
 
-    x = D_u_to_d_col(x);
-    y = D_u_to_d_row(y);
+void D_get_text_box(const char *text, double *t, double *b, double *l, double *r)
+{
+    double T, B, L, R;
 
-    R_cont_abs(x, y);
+    R_get_text_box(text, &T, &B, &L, &R);
+
+    *t = D_d_to_u_row(T);
+    *b = D_d_to_u_row(B);
+    *l = D_d_to_u_col(L);
+    *r = D_d_to_u_col(R);
+
+    if (*t < *b) {
+	double tmp = *t; *t = *b; *b = tmp;
+    }
+
+    if (*r < *l) {
+	double tmp = *r; *r = *l; *l = tmp;
+    }
 }
 
+/******************************************************************************/
+
+void D_move_abs(double x, double y)
+{
+	(*fns->move_abs)(x, y);
+}
+
+void D_move_rel(double x, double y)
+{
+	(*fns->move_rel)(x, y);
+}
+
+void D_cont_abs(double x, double y)
+{
+	(*fns->cont_abs)(x, y);
+}
+
 void D_cont_rel(double x, double y)
 {
-    D_cont_abs(cur.x + x, cur.y + y);
+	(*fns->cont_rel)(x, y);
 }
 
 void D_line_abs(double x1, double y1, double x2, double y2)
 {
-    D_move_abs(x1, y1);
-    D_cont_abs(x2, y2);
+	(*fns->line_abs)(x1, y1, x2, y2);
 }
 
 void D_line_rel(double x1, double y1, double x2, double y2)
 {
-    D_move_rel(x1, y1);
-    D_cont_rel(x2, y2);
+	(*fns->line_rel)(x1, y1, x2, y2);
 }
 
 void D_polydots_abs(const double *x, const double *y, int n)
 {
-    n = do_convert(x, y, n);
-    R_polydots_abs(xi, yi, n);
+	(*fns->polydots_abs)(x, y, n);
 }
 
 void D_polydots_rel(const double *x, const double *y, int n)
 {
-    rel_to_abs(&x, &y, n);
-    D_polydots_abs(x, y, n);
-    dealloc_src(&x, &y, 1);
+	(*fns->polydots_rel)(x, y, n);
 }
 
 void D_polyline_abs(const double *x, const double *y, int n)
 {
-    n = do_convert(x, y, n);
-    R_polyline_abs(xi, yi, n);
+	(*fns->polyline_abs)(x, y, n);
 }
 
 void D_polyline_rel(const double *x, const double *y, int n)
 {
-    rel_to_abs(&x, &y, n);
-    D_polyline_abs(x, y, n);
-    dealloc_src(&x, &y, 1);
+	(*fns->polyline_rel)(x, y, n);
 }
 
 void D_polygon_abs(const double *x, const double *y, int n)
 {
-    n = do_convert(x, y, n);
-    R_polygon_abs(xi, yi, n);
+	(*fns->polygon_abs)(x, y, n);
 }
 
 void D_polygon_rel(const double *x, const double *y, int n)
 {
-    rel_to_abs(&x, &y, n);
-    D_polygon_abs(x, y, n);
-    dealloc_src(&x, &y, 1);
+	(*fns->polygon_rel)(x, y, n);
 }
 
 void D_box_abs(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);
+	(*fns->box_abs)(x1, y1, x2, y2);
 }
 
 void D_box_rel(double x2, double y2)
 {
-    D_box_abs(cur.x, cur.y, x2, y2);
+	(*fns->box_rel)(x2, y2);
 }
 
+/******************************************************************************/
+
+void D_set_clip_mode(int mode)
+{
+    switch (mode) {
+    case D_MODE_NONE: fns = &raw_functions;	break;
+    case D_MODE_CULL: fns = &cull_functions;	break;
+    case D_MODE_CLIP: fns = &clip_functions;	break;
+    }
+}
+
+/******************************************************************************/
+



More information about the grass-commit mailing list