GRASS GIS 8 Programmer's Manual 8.3.2(2024)-exported
Loading...
Searching...
No Matches
pngdriver/polygon.c
Go to the documentation of this file.
1/*!
2 \file lib/pngdriver/polygon.c
3
4 \brief GRASS png display driver - draw polygon
5
6 (C) 2003-2014 by Per Henrik Johansen and the GRASS Development Team
7
8 This program is free software under the GNU General Public License
9 (>=v2). Read the file COPYING that comes with GRASS for details.
10
11 \author Per Henrik Johansen (original contributor)
12 \author Glynn Clements
13 */
14
15#include <stdlib.h>
16#include <math.h>
17#include <grass/gis.h>
18
19#include "path.h"
20#include "pngdriver.h"
21
22static int cmp_double(const void *aa, const void *bb)
23{
24 const double *a = aa;
25 const double *b = bb;
26
27 return *a > *b ? 1 : *a < *b ? -1 : 0;
28}
29
30static void fill(double x0, double x1, double y)
31{
32 int yi = (int)floor(y);
33 int xi0 = (int)floor(x0 + 0.5);
34 int xi1 = (int)floor(x1 + 0.5);
35 unsigned int *p;
36 int x;
37
38 if (yi >= png.clip_bot || yi < png.clip_top)
39 return;
40
41 if (xi0 > png.clip_rite)
42 return;
43
44 if (xi1 < png.clip_left)
45 return;
46
47 if (xi0 < png.clip_left)
48 xi0 = png.clip_left;
49
50 if (xi1 > png.clip_rite)
51 xi1 = png.clip_rite;
52
53 p = &png.grid[yi * png.width + xi0];
54
55 for (x = xi0; x < xi1; x++)
56 *p++ = png.current_color;
57}
58
59static void line(const struct vertex *p, int n, double y)
60{
61 static double *xs;
62 static int max_x;
63 int num_x = 0;
64 int i;
65
66 for (i = 1; i < n; i++) {
67 const struct vertex *p0 = &p[i - 1];
68 const struct vertex *p1 = &p[i];
69 const struct vertex *tmp;
70 double x;
71
72 if (p0->y == p1->y)
73 continue;
74
75 if (p0->y > p1->y)
76 tmp = p0, p0 = p1, p1 = tmp;
77
78 if (p0->y > y)
79 continue;
80
81 if (p1->y <= y)
82 continue;
83
84 x = p1->x * (y - p0->y) + p0->x * (p1->y - y);
85 x /= p1->y - p0->y;
86
87 if (num_x >= max_x) {
88 max_x += 20;
89 xs = G_realloc(xs, max_x * sizeof(double));
90 }
91
92 xs[num_x++] = x;
93 }
94
95 qsort(xs, num_x, sizeof(double), cmp_double);
96
97 for (i = 0; i + 1 < num_x; i += 2)
98 fill(xs[i], xs[i + 1], y);
99}
100
101static void poly(const struct vertex *p, int n)
102{
103 double y0, y1, y;
104 int i;
105
106 if (n < 3)
107 return;
108
109 y0 = y1 = p[0].y;
110
111 for (i = 1; i < n; i++) {
112 if (y0 > p[i].y)
113 y0 = p[i].y;
114
115 if (y1 < p[i].y)
116 y1 = p[i].y;
117 }
118
119 if (y0 > png.clip_bot || y1 < png.clip_top)
120 return;
121
122 if (y0 < png.clip_top)
123 y0 = png.clip_top;
124
125 if (y1 > png.clip_bot)
126 y1 = png.clip_bot;
127
128 for (y = floor(y0 + 0.5) + 0.5; y < y1; y++)
129 line(p, n, y);
130}
131
132/*!
133 \brief Draw polygon
134 */
135void png_polygon(struct path *p)
136{
137 if (p->vertices[p->count - 1].mode != P_CLOSE)
138 path_close(p);
139
140 poly(p->vertices, p->count);
141
142 png.modified = 1;
143}
double b
void path_close(struct path *p)
Definition path.c:83
@ P_CLOSE
Definition path.h:7
struct png_state png
void png_polygon(struct path *p)
Draw polygon.
GRASS png display driver - header file.
Definition path.h:15
double clip_left
Definition pngdriver.h:41
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 modified
Definition pngdriver.h:46
Definition path.h:10
double x
Definition path.h:11
double y
Definition path.h:11
#define x