GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
display/draw.c
Go to the documentation of this file.
1 
2 /****************************************************************************
3  *
4  * MODULE: display
5  * AUTHOR(S): CERL (original contributors)
6  * Bernhard Reiter <bernhard intevation.de>,
7  * Markus Neteler <neteler itc.it>,
8  * Glynn Clements <glynn gclements.plus.com>,
9  * Hamish Bowman <hamish_b yahoo.com>
10  * PURPOSE:
11  * COPYRIGHT: (C) 1999-2007 by the GRASS Development Team
12  *
13  * This program is free software under the GNU General Public
14  * License (>=v2). Read the file COPYING that comes with GRASS
15  * for details.
16  *
17  *****************************************************************************/
18 
19 /*******************************************************************
20  * Line drawing in the current window.
21  *
22  * Clip window:
23  * D_set_clip_window (top, bottom ,left, right)
24  * establish clipping region for subseqent line drawing.
25  * D_set_clip_window_to_map_window ()
26  * set clipping to pixels corresponding to the current map region
27  * (default)
28  * D_set_clip_window_to_screen_window ()
29  * set clipping to full extent of the window (ie disables clipping on screen)
30  *
31  * Moves.
32  * D_move_abs(x,y) move to x,y.
33  * D_move_rel(x,y) move to +x,+y.
34  * Set current position. Position is not clipped.
35  *
36  * Draw line
37  * D_cont_abs(x,y) draw to x,y.
38  * D_cont_rel(x,y) draw to +x,+y.
39  * Line draw from current position. New postion is not clipped.
40  * The lines drawn are clipped however.
41  * Return values indicate the nature of the clipping:
42  * 0 no clipping
43  * 1 part of the line is drawn
44  * -1 none of the line is drawn
45  *
46  *
47  */
48 #include <grass/raster.h>
49 #include <grass/gis.h>
50 #include <grass/display.h>
51 
52 static int clip(void);
53 static int line_eq(int, int, int, int, int, int);
54 
55 static int curx, cury;
56 static int left, right, top, bottom; /* window edges */
57 static int x1, y1, x2, y2;
58 
59 static int window_set = 0;
60 
61 #define swap(x,y) {int t; t=x; x=y; y=t;}
62 #define limit(a,x,b) x<a?a:(x>b?b:x)
63 
64 
78 int D_set_clip_window(int Top, int Bottom, int Left, int Right)
79 {
80  /* make sure top is above bottom, left is left of right */
81  if (Top > Bottom)
82  swap(Top, Bottom);
83  if (Left > Right)
84  swap(Left, Right);
85 
86  /* make sure edges are within the true window edges */
87  D_get_screen_window(&top, &bottom, &left, &right);
88  Top = limit(top, Top, bottom);
89  Bottom = limit(top, Bottom, bottom);
90  Left = limit(left, Left, right);
91  Right = limit(left, Right, right);
92 
93  /* set the window */
94  top = Top;
95  bottom = Bottom;
96  left = Left;
97  right = Right;
98 
99  window_set = 1;
100 
101  R_move_abs(left, top);
102 
103  return 0;
104 }
105 
106 
118 {
120  (int)D_get_d_south(),
121  (int)D_get_d_west(), (int)D_get_d_east()
122  );
123 
124  return 0;
125 }
126 
127 
139 {
140  D_get_screen_window(&top, &bottom, &left, &right);
141  D_set_clip_window(top, bottom, left, right);
142 
143  return 0;
144 }
145 
146 
162 int D_cont_abs(int x, int y)
163 {
164  int clipped;
165 
166  x1 = curx;
167  y1 = cury;
168  x2 = x;
169  y2 = y;
170  curx = x;
171  cury = y;
172 
173  if (!window_set)
175 
176  clipped = clip();
177  if (clipped >= 0) {
178  R_move_abs(x1, y1);
179  R_cont_abs(x2, y2);
180  }
181 
182  return clipped;
183 }
184 
185 
198 int D_cont_rel(int x, int y)
199 {
200  return D_cont_abs(curx + x, cury + y);
201 }
202 
203 
215 int D_move_abs(int x, int y)
216 {
217  curx = x;
218  cury = y;
219  return 0;
220 }
221 
222 
235 int D_move_rel(int x, int y)
236 {
237  curx += x;
238  cury += y;
239  return 0;
240 }
241 
242 /*********************************************************************
243  * this code is the window clipping for D_cont_abs()
244  *********************************************************************/
245 
246 #define Y(x) line_eq(x,x0,y0,dx,dy,xround)
247 
248 #define X(y) line_eq(y,y0,x0,dy,dx,yround)
249 
250 
251 static int clip(void)
252 {
253  register int x0, y0;
254  register int dx, dy;
255  int xround;
256  int yround;
257  int clipped;
258 
259  /*
260  * quick check for line above,below,left,or right of window
261  */
262  if (x1 < left && x2 < left)
263  return -1;
264  if (x1 > right && x2 > right)
265  return -1;
266 
267  if (y1 < top && y2 < top)
268  return -1;
269  if (y1 > bottom && y2 > bottom)
270  return -1;
271 
272  /*
273  * setup line equations variables
274  */
275  x0 = x1;
276  y0 = y1;
277 
278  dx = x2 - x1;
279  dy = y2 - y1;
280 
281  if ((xround = dx / 2) < 0)
282  xround = -xround;
283  if ((yround = dy / 2) < 0)
284  yround = -yround;
285 
286  /*
287  * clipping
288  *
289  * if x of endpoint 1 doesn't fall within the window
290  * move x to the nearest edge
291  * recalculate the y
292  * if the new y doesn't fall within the window then
293  * the line doesn't cross into the window
294  *
295  * if y of endpoint 1 doesn't fall within the window
296  * move y to the nearest edge
297  * recalculate the x
298  * if the new x doesn't fall within the window then
299  * the line doesn't cross into the window
300  *
301  * repeat for the second endpoint
302  *
303  */
304 
305  clipped = 0;
306  if (x1 < left || x1 > right) {
307  if (dx == 0)
308  return -1;
309 
310  x1 = x1 < left ? left : right;
311  y1 = Y(x1);
312 
313  if (y1 < top || y1 > bottom) {
314  if (dy == 0)
315  return -1;
316 
317  y1 = y1 < top ? top : bottom;
318  x1 = X(y1);
319 
320  if (x1 < left || x1 > right)
321  return -1;
322  }
323  clipped = 1;
324  }
325  if (y1 < top || y1 > bottom) {
326  if (dy == 0)
327  return -1;
328  y1 = y1 < top ? top : bottom;
329  x1 = X(y1);
330 
331  if (x1 < left || x1 > right) {
332  if (dx == 0)
333  return -1;
334 
335  x1 = x1 < left ? left : right;
336  y1 = Y(x1);
337 
338  if (y1 < top || y1 > bottom)
339  return -1;
340  }
341  clipped = 1;
342  }
343 
344  if (x2 < left || x2 > right) {
345  if (dx == 0)
346  return -1;
347 
348  x2 = x2 < left ? left : right;
349  y2 = Y(x2);
350 
351  if (y2 < top || y2 > bottom) {
352  if (dy == 0)
353  return -1;
354 
355  y2 = y2 < top ? top : bottom;
356  x2 = X(y2);
357 
358  if (x2 < left || x2 > right)
359  return -1;
360  }
361  clipped = 1;
362  }
363  if (y2 < top || y2 > bottom) {
364  if (dy == 0)
365  return -1;
366 
367  y2 = y2 < top ? top : bottom;
368  x2 = X(y2);
369 
370  if (x2 < left || x2 > right) {
371  if (dx == 0)
372  return -1;
373 
374  x2 = x2 < left ? left : right;
375  y2 = Y(x2);
376 
377  if (y2 < top || y2 > bottom)
378  return -1;
379  }
380  clipped = 1;
381  }
382 
383  return clipped;
384 }
385 
386 static int line_eq(int x, int x0, int y0, int dx, int dy, int round)
387 {
388  register int t;
389 
390  if ((t = dy * (x - x0)) < 0)
391  t -= round;
392  else
393  t += round;;
394 
395  return (y0 + t / dx);
396 }
int D_set_clip_window(int Top, int Bottom, int Left, int Right)
set clipping window
Definition: display/draw.c:78
int D_cont_rel(int x, int y)
line to x,y
Definition: display/draw.c:198
#define swap(x, y)
Definition: display/draw.c:61
int D_move_abs(int x, int y)
move to pixel
Definition: display/draw.c:215
#define Y(x)
Definition: display/draw.c:246
#define X(y)
Definition: display/draw.c:248
int y
Definition: plot.c:34
double D_get_d_west(void)
Definition: cnversions.c:219
void R_cont_abs(int x, int y)
draw line
Definition: com_proto.c:190
double D_get_d_east(void)
Definition: cnversions.c:223
double D_get_d_north(void)
Definition: cnversions.c:227
#define limit(a, x, b)
Definition: display/draw.c:62
void R_move_abs(int x, int y)
move current location
Definition: com_proto.c:153
int D_move_rel(int x, int y)
move to pixel
Definition: display/draw.c:235
int D_set_clip_window_to_screen_window(void)
set clipping window to screen window
Definition: display/draw.c:138
int D_cont_abs(int x, int y)
line to x,y
Definition: display/draw.c:162
double D_get_d_south(void)
Definition: cnversions.c:231
int D_set_clip_window_to_map_window(void)
set clipping window to map window
Definition: display/draw.c:117
int D_get_screen_window(int *t, int *b, int *l, int *r)
retrieve current frame coordinates
#define round(x)
Definition: draw2.c:71