~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to lib/pngdriver/polygon.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
22
static int cmp_double(const void *aa, const void *bb)
 
23
{
 
24
    const double *a = aa;
 
25
    const double *b = bb;
 
26
 
 
27
    return
 
28
        *a > *b ?  1 :
 
29
        *a < *b ? -1 :
 
30
        0;
 
31
}
 
32
 
 
33
static void fill(double x0, double x1, double y)
 
34
{
 
35
    int yi = (int) floor(y);
 
36
    int xi0 = (int) floor(x0 + 0.5);
 
37
    int xi1 = (int) floor(x1 + 0.5);
 
38
    unsigned int *p;
 
39
    int x;
 
40
 
 
41
    if (yi >= png.clip_bot || yi < png.clip_top)
 
42
        return;
 
43
 
 
44
    if (xi0 > png.clip_rite)
 
45
        return;
 
46
 
 
47
    if (xi1 < png.clip_left)
 
48
        return;
 
49
 
 
50
    if (xi0 < png.clip_left)
 
51
        xi0 = png.clip_left;
 
52
 
 
53
    if (xi1 > png.clip_rite)
 
54
        xi1 = png.clip_rite;
 
55
 
 
56
    p = &png.grid[yi * png.width + xi0];
 
57
 
 
58
    for (x = xi0; x < xi1; x++)
 
59
        *p++ = png.current_color;
 
60
}
 
61
 
 
62
static void line(const struct vertex *p, int n, double y)
 
63
{
 
64
    static double *xs;
 
65
    static int max_x;
 
66
    int num_x = 0;
 
67
    int i;
 
68
 
 
69
    for (i = 1; i < n; i++) {
 
70
        const struct vertex *p0 = &p[i - 1];
 
71
        const struct vertex *p1 = &p[i];
 
72
        const struct vertex *tmp;
 
73
        double x;
 
74
 
 
75
        if (p0->y == p1->y)
 
76
            continue;
 
77
 
 
78
        if (p0->y > p1->y)
 
79
            tmp = p0, p0 = p1, p1 = tmp;
 
80
 
 
81
        if (p0->y > y)
 
82
            continue;
 
83
 
 
84
        if (p1->y <= y)
 
85
            continue;
 
86
 
 
87
        x = p1->x * (y - p0->y) + p0->x * (p1->y - y);
 
88
        x /= p1->y - p0->y;
 
89
 
 
90
        if (num_x >= max_x) {
 
91
            max_x += 20;
 
92
            xs = G_realloc(xs, max_x * sizeof(double));
 
93
        }
 
94
 
 
95
        xs[num_x++] = x;
 
96
    }
 
97
 
 
98
    qsort(xs, num_x, sizeof(double), cmp_double);
 
99
 
 
100
    for (i = 0; i + 1 < num_x; i += 2)
 
101
        fill(xs[i], xs[i + 1], y);
 
102
}
 
103
 
 
104
static void poly(const struct vertex *p, int n)
 
105
{
 
106
    double y0, y1, y;
 
107
    int i;
 
108
 
 
109
    if (n < 3)
 
110
        return;
 
111
 
 
112
    y0 = y1 = p[0].y;
 
113
 
 
114
    for (i = 1; i < n; i++) {
 
115
        if (y0 > p[i].y)
 
116
            y0 = p[i].y;
 
117
 
 
118
        if (y1 < p[i].y)
 
119
            y1 = p[i].y;
 
120
    }
 
121
 
 
122
    if (y0 > png.clip_bot || y1 < png.clip_top)
 
123
        return;
 
124
 
 
125
    if (y0 < png.clip_top)
 
126
        y0 = png.clip_top;
 
127
 
 
128
    if (y1 > png.clip_bot)
 
129
        y1 = png.clip_bot;
 
130
 
 
131
    for (y = floor(y0 + 0.5) + 0.5; y < y1; y++)
 
132
        line(p, n, y);
 
133
}
 
134
 
 
135
/*!
 
136
  \brief Draw polygon
 
137
*/
 
138
void png_polygon(struct path *p)
 
139
{
 
140
    if (p->vertices[p->count - 1].mode != P_CLOSE)
 
141
        path_close(p);
 
142
 
 
143
    poly(p->vertices, p->count);
 
144
 
 
145
    png.modified = 1;
 
146
}
 
147