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