GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-25961a86c2
draw_line.c
Go to the documentation of this file.
1 /*
2  * draw a line between two given points in the current color.
3  *
4  * Called by:
5  * Cont_abs() in ../lib/Cont_abs.c
6  */
7 
8 #include <stdlib.h>
9 #include <math.h>
10 
11 #include "pngdriver.h"
12 
13 static void store_xy(double x, double y)
14 {
15  int xi = (int)floor(x);
16  int yi = (int)floor(y);
17 
18  if (x < png.clip_left || x >= png.clip_rite || y < png.clip_top ||
19  y >= png.clip_bot)
20  return;
21 
22  png.grid[yi * png.width + xi] = png.current_color;
23 }
24 
25 static void swap(double *a, double *b)
26 {
27  double t = *a;
28 
29  *a = *b;
30  *b = t;
31 }
32 
33 static void draw_line(double x1, double y1, double x2, double y2)
34 {
35  double x, y;
36  double dx, dy;
37 
38  if (fabs(y1 - y2) > fabs(x1 - x2)) {
39  if (y1 > y2) {
40  swap(&y1, &y2);
41  swap(&x1, &x2);
42  }
43 
44  dy = y2 - y1;
45  dx = x2 - x1;
46 
47  for (y = floor(y1) + 0.5; y < y2; y++) {
48  x = x1 + (y - y1) * dx / dy;
49  store_xy(x, y);
50  }
51  }
52  else {
53  if (x1 > x2) {
54  swap(&x1, &x2);
55  swap(&y1, &y2);
56  }
57 
58  dx = x2 - x1;
59  dy = y2 - y1;
60 
61  for (x = floor(x1) + 0.5; x < x2; x++) {
62  y = y1 + (x - x1) * dy / dx;
63  store_xy(x, y);
64  }
65  }
66 }
67 
68 void png_draw_line(double x1, double y1, double x2, double y2)
69 {
70  struct path path;
71  struct vertex vertices[5];
72  double k = png.linewidth / 2;
73  double dx, dy;
74 
75  if (png.linewidth <= 1) {
76  draw_line(x1, y1, x2, y2);
77  png.modified = 1;
78  return;
79  }
80 
81  path.vertices = vertices;
82  path.count = 0;
83  path.alloc = 5;
84  path.start = -1;
85 
86  /* FIXME: rendering issues (#1283) */
87  dx = fabs(x2 - x1);
88  dy = fabs(y2 - y1);
89 
90  if (dy > dx) {
91  path_move(&path, x1 - k, y1);
92  path_cont(&path, x1 + k, y1);
93  path_cont(&path, x2 + k, y2);
94  path_cont(&path, x2 - k, y2);
95  path_close(&path);
96  }
97  else {
98  path_move(&path, x1, y1 - k);
99  path_cont(&path, x1, y1 + k);
100  path_cont(&path, x2, y2 + k);
101  path_cont(&path, x2, y2 - k);
102  path_close(&path);
103  }
104 
105  png_polygon(&path);
106 }
void png_draw_line(double x1, double y1, double x2, double y2)
Definition: draw_line.c:68
void path_close(struct path *p)
Definition: driver/path.c:83
void path_cont(struct path *p, double x, double y)
Definition: driver/path.c:78
void path_move(struct path *p, double x, double y)
Definition: driver/path.c:72
struct png_state png
GRASS png display driver - header file.
void png_polygon(struct path *)
Draw polygon.
double b
Definition: r_raster.c:39
double t
Definition: r_raster.c:39
Definition: path.h:15
int count
Definition: path.h:17
int start
Definition: path.h:19
struct vertex * vertices
Definition: path.h:16
int alloc
Definition: path.h:18
double clip_bot
Definition: pngdriver.h:41
double clip_top
Definition: pngdriver.h:41
int current_color
Definition: pngdriver.h:33
unsigned int * grid
Definition: pngdriver.h:43
int width
Definition: pngdriver.h:42
double clip_rite
Definition: pngdriver.h:41
int linewidth
Definition: pngdriver.h:48
int modified
Definition: pngdriver.h:46
Definition: path.h:10
#define x