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