Loading...
Searching...
No Matches
pngdriver/polygon.c
Go to the documentation of this file.
/*!
\file lib/pngdriver/polygon.c
\brief GRASS png display driver - draw polygon
(C) 2003-2014 by Per Henrik Johansen and the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
\author Per Henrik Johansen (original contributor)
\author Glynn Clements
*/
#include <stdlib.h>
#include <math.h>
#include <grass/gis.h>
#include "path.h"
#include "pngdriver.h"
static int cmp_double(const void *aa, const void *bb)
{
const double *a = aa;
const double *b = bb;
return *a > *b ? 1 : *a < *b ? -1 : 0;
}
static void fill(double x0, double x1, double y)
{
int yi = (int)floor(y);
int xi0 = (int)floor(x0 + 0.5);
int xi1 = (int)floor(x1 + 0.5);
unsigned int *p;
int x;
if (yi >= png.clip_bot || yi < png.clip_top)
return;
if (xi0 > png.clip_rite)
return;
if (xi1 < png.clip_left)
return;
if (xi0 < png.clip_left)
xi0 = png.clip_left;
if (xi1 > png.clip_rite)
xi1 = png.clip_rite;
p = &png.grid[yi * png.width + xi0];
for (x = xi0; x < xi1; x++)
*p++ = png.current_color;
}
static void line(const struct vertex *p, int n, double y)
{
static double *xs;
static int max_x;
int num_x = 0;
int i;
for (i = 1; i < n; i++) {
const struct vertex *p0 = &p[i - 1];
const struct vertex *p1 = &p[i];
const struct vertex *tmp;
double x;
if (p0->y == p1->y)
continue;
if (p0->y > p1->y)
tmp = p0, p0 = p1, p1 = tmp;
if (p0->y > y)
continue;
if (p1->y <= y)
continue;
x = p1->x * (y - p0->y) + p0->x * (p1->y - y);
x /= p1->y - p0->y;
if (num_x >= max_x) {
max_x += 20;
xs = G_realloc(xs, max_x * sizeof(double));
}
xs[num_x++] = x;
}
qsort(xs, num_x, sizeof(double), cmp_double);
for (i = 0; i + 1 < num_x; i += 2)
fill(xs[i], xs[i + 1], y);
}
static void poly(const struct vertex *p, int n)
{
double y0, y1, y;
int i;
if (n < 3)
return;
y0 = y1 = p[0].y;
for (i = 1; i < n; i++) {
if (y0 > p[i].y)
y0 = p[i].y;
if (y1 < p[i].y)
y1 = p[i].y;
}
if (y0 > png.clip_bot || y1 < png.clip_top)
return;
if (y0 < png.clip_top)
y0 = png.clip_top;
if (y1 > png.clip_bot)
y1 = png.clip_bot;
for (y = floor(y0 + 0.5) + 0.5; y < y1; y++)
line(p, n, y);
}
/*!
\brief Draw polygon
*/
void png_polygon(struct path *p)
{
if (p->vertices[p->count - 1].mode != P_CLOSE)
path_close(p);
poly(p->vertices, p->count);
png.modified = 1;
}
b
double b
Definition driver/set_window.c:5
path_close
void path_close(struct path *p)
Definition path.c:83
path.h
P_CLOSE
@ P_CLOSE
Definition path.h:7
png
struct png_state png
Definition pngdriver/graph_set.c:32
png_polygon
void png_polygon(struct path *p)
Draw polygon.
Definition pngdriver/polygon.c:135
pngdriver.h
GRASS png display driver - header file.
path
Definition path.h:15
path::count
int count
Definition path.h:17
path::vertices
struct vertex * vertices
Definition path.h:16
vertex
Definition path.h:10
vertex::mode
int mode
Definition path.h:12
vertex::y
double y
Definition path.h:11
x
#define x