GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
Loading...
Searching...
No Matches
cairodriver/raster.c
Go to the documentation of this file.
1
/*!
2
\file lib/cairodriver/raster.c
3
4
\brief GRASS cairo display driver - draw raster
5
6
(C) 2007-2014 by Lars Ahlzen 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 Lars Ahlzen <lars ahlzen.com> (original contributor)
12
\author Glynn Clements
13
*/
14
15
#include <math.h>
16
17
#include "
cairodriver.h
"
18
#include <grass/gis.h>
19
#include <grass/glocale.h>
20
21
#define MAX_IMAGE_SIZE 32767
22
23
static
int
src_t, src_b, src_l, src_r, src_w, src_h;
24
static
int
dst_t, dst_b, dst_l, dst_r, dst_w, dst_h;
25
26
static
int
*trans;
27
28
static
cairo_surface_t *src_surf;
29
static
unsigned
char
*src_data;
30
static
int
src_stride, ca_row;
31
32
static
int
masked;
33
34
static
double
scale(
double
k,
int
src_0,
int
src_1,
int
dst_0,
int
dst_1)
35
{
36
return
dst_0 + (double)(k - src_0) * (dst_1 - dst_0) / (src_1 - src_0);
37
}
38
39
static
int
scale_fwd_y(
int
sy)
40
{
41
return
(
int
)floor(scale(sy, src_t, src_b, dst_t, dst_b) + 0.5);
42
}
43
44
static
int
scale_rev_x(
int
dx)
45
{
46
return
(
int
)floor(scale(dx + 0.5, dst_l, dst_r, src_l, src_r));
47
}
48
49
static
int
next_row(
int
sy,
int
dy)
50
{
51
sy++;
52
53
for
(;;) {
54
int
y = scale_fwd_y(sy);
55
56
if
(y > dy)
57
return
sy - 1;
58
sy++;
59
}
60
}
61
62
/*!
63
\brief Start drawing raster
64
65
\todo are top and left swapped?
66
67
\param mask non-zero int for mask
68
\param s source (map) extent (left, right, top, bottom)
69
\param d destination (image) extent (left, right, top, bottom)
70
*/
71
void
Cairo_begin_raster
(
int
mask,
int
s[2][2],
double
d[2][2])
72
{
73
int
i;
74
cairo_status_t status;
75
76
masked = mask;
77
78
src_l = s[0][0];
79
src_r = s[0][1];
80
src_t = s[1][0];
81
src_b = s[1][1];
82
83
src_w = src_r - src_l;
84
src_h = src_b - src_t;
85
86
dst_l = (int)floor(d[0][0] + 0.5);
87
dst_r = (int)floor(d[0][1] + 0.5);
88
dst_t = (int)floor(d[1][0] + 0.5);
89
dst_b = (int)floor(d[1][1] + 0.5);
90
91
dst_w = dst_r - dst_l;
92
dst_h = dst_b - dst_t;
93
94
G_debug
(
95
1,
96
"Cairo_begin_raster(): masked=%d, src_lrtb=%d %d %d %d -> w/h=%d %d, "
97
"dst_lrtb=%d %d %d %d -> w/h=%d %d"
,
98
masked, src_l, src_r, src_t, src_b, src_w, src_h, dst_l, dst_r, dst_t,
99
dst_b, dst_w, dst_h);
100
101
/* create source surface */
102
src_surf =
103
cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
ca
.width,
ca
.height);
104
status = cairo_surface_status(src_surf);
105
if
(status != CAIRO_STATUS_SUCCESS)
106
G_fatal_error
(
"%s - %s - size: %dx%d (cairo limit: %dx%d)"
,
107
_(
"Failed to create cairo surface"
),
108
cairo_status_to_string(status),
ca
.width,
ca
.height,
109
MAX_IMAGE_SIZE
,
MAX_IMAGE_SIZE
);
110
111
src_data = cairo_image_surface_get_data(src_surf);
112
src_stride = cairo_image_surface_get_stride(src_surf);
113
ca_row = 0;
114
115
/* allocate buffer for down-sampling data */
116
trans = G_malloc(dst_w *
sizeof
(
int
));
117
for
(i = 0; i < dst_w; i++)
118
trans[i] = scale_rev_x(dst_l + i);
119
}
120
121
/*!
122
\brief Draw raster row
123
124
\param n number of cells
125
\param row raster row (starting at 0)
126
\param red,grn,blu,nul red,green,blue and null value
127
128
\return next row
129
*/
130
int
Cairo_raster
(
int
n,
int
row,
const
unsigned
char
*red,
131
const
unsigned
char
*grn,
const
unsigned
char
*blu,
132
const
unsigned
char
*nul)
133
{
134
int
d_y0 = scale_fwd_y(row + 0);
135
int
d_y1 = scale_fwd_y(row + 1);
136
int
d_rows = d_y1 - d_y0;
137
int
x0 =
MAX
(0 - dst_l, 0);
138
int
x1 =
MIN
(
ca
.width - dst_l, dst_w);
139
int
y0 =
MAX
(0 - d_y0, 0);
140
int
y1 =
MIN
(
ca
.height - d_y0, d_rows);
141
int
x
, y;
142
143
if
(y1 <= y0)
144
return
next_row(row, d_y1);
145
146
G_debug
(3,
"Cairo_raster(): n=%d row=%d"
, n, row);
147
148
for
(
x
= x0;
x
< x1;
x
++) {
149
int
xx = dst_l +
x
;
150
int
j = trans[
x
];
151
unsigned
int
c;
152
153
if
(masked && nul && nul[j])
154
c = 0;
155
else
{
156
unsigned
int
r
= red[j];
157
unsigned
int
g
= grn[j];
158
unsigned
int
b
= blu[j];
159
unsigned
int
a = 0xFF;
160
161
c = (a << 24) + (
r
<< 16) + (
g
<< 8) + (
b
<< 0);
162
}
163
164
for
(y = y0; y < y1; y++) {
165
int
yy = d_y0 + y;
166
167
*(
unsigned
int
*)(src_data + yy * src_stride + xx * 4) = c;
168
}
169
}
170
171
ca
.modified = 1;
172
ca_row++;
173
174
return
next_row(row, d_y1);
175
}
176
177
/*!
178
\brief Finish drawing raster
179
*/
180
void
Cairo_end_raster
(
void
)
181
{
182
G_debug
(1,
"Cairo_end_raster()"
);
183
184
/* paint source surface onto destination (scaled) */
185
cairo_save(
cairo
);
186
/* cairo_translate(cairo, dst_l, dst_t); */
187
/* cairo_scale(cairo, dst_w / src_w, dst_h / src_h); */
188
cairo_surface_mark_dirty(src_surf);
189
cairo_set_source_surface(
cairo
, src_surf, 0, 0);
190
cairo_pattern_set_filter(cairo_get_source(
cairo
), CAIRO_FILTER_NEAREST);
191
cairo_paint(
cairo
);
192
cairo_restore(
cairo
);
193
194
/* cleanup */
195
G_free
(trans);
196
cairo_surface_destroy(src_surf);
197
ca
.modified = 1;
198
}
G_free
void G_free(void *buf)
Free allocated memory.
Definition
alloc.c:147
Cairo_begin_raster
void Cairo_begin_raster(int mask, int s[2][2], double d[2][2])
Start drawing raster.
Definition
cairodriver/raster.c:71
Cairo_end_raster
void Cairo_end_raster(void)
Finish drawing raster.
Definition
cairodriver/raster.c:180
MAX_IMAGE_SIZE
#define MAX_IMAGE_SIZE
Definition
cairodriver/raster.c:21
Cairo_raster
int Cairo_raster(int n, int row, const unsigned char *red, const unsigned char *grn, const unsigned char *blu, const unsigned char *nul)
Draw raster row.
Definition
cairodriver/raster.c:130
cairodriver.h
GRASS cairo display driver - header file.
ca
struct cairo_state ca
Definition
cairodriver/graph.c:42
cairo
cairo_t * cairo
Definition
cairodriver/graph.c:46
G_debug
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition
debug.c:66
b
double b
Definition
driver/set_window.c:5
r
double r
Definition
driver/set_window.c:5
G_fatal_error
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition
gis/error.c:159
g
float g
Definition
named_colr.c:7
MAX
#define MAX(a, b)
Definition
parson.c:91
MIN
#define MIN(a, b)
Definition
shpopen.c:33
x
#define x
cairodriver
raster.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0