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
|
#include "cairodriver.h"
static int src_t, src_b, src_l, src_r, src_w, src_h;
static int dst_t, dst_b, dst_l, dst_r, dst_w, dst_h;
static cairo_surface_t *src_surf;
static unsigned char *src_data;
static int src_stride;
static int masked;
void Cairo_begin_scaled_raster(int mask, int s[2][2], int d[2][2])
{
G_debug(1, "Cairo_begin_scaled_raster: %d %d %d %d %d %d %d %d %d",
mask, s[0][0], s[0][1], s[1][0], s[1][1], d[0][0], d[0][1],
d[1][0], d[1][1]);
masked = mask;
/* TODO: are top and left swapped? */
src_l = s[0][0];
src_r = s[0][1];
src_t = s[1][0];
src_b = s[1][1];
src_w = src_r - src_l;
src_h = src_b - src_t;
dst_l = d[0][0];
dst_r = d[0][1];
dst_t = d[1][0];
dst_b = d[1][1];
dst_w = dst_r - dst_l;
dst_h = dst_b - dst_t;
G_debug(1, " src (TBLR): %d %d %d %d, dst (TBLR) %d %d %d %d",
src_t, src_b, src_l, src_r, dst_t, dst_b, dst_l, dst_r);
/* create source surface */
src_surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, src_w, src_h);
if (cairo_surface_status(src_surf) != CAIRO_STATUS_SUCCESS)
G_fatal_error("Cairo_begin_scaled_raster: Failed to create surface");
src_data = cairo_image_surface_get_data(src_surf);
src_stride = cairo_image_surface_get_stride(src_surf);
}
int Cairo_scaled_raster(int n, int row,
const unsigned char *red, const unsigned char *grn,
const unsigned char *blu, const unsigned char *nul)
{
unsigned int *dst =
(unsigned int *)(src_data + (row - src_t) * src_stride);
int i;
G_debug(3, "Cairo_scaled_raster: %d %d", n, row);
for (i = 0; i < n; i++) {
if (masked && nul && nul[i])
*dst++ = 0;
else {
unsigned int r = red[i];
unsigned int g = grn[i];
unsigned int b = blu[i];
unsigned int a = 0xFF;
*dst++ = (a << 24) + (r << 16) + (g << 8) + (b << 0);
}
}
return row + 1;
}
void Cairo_end_scaled_raster(void)
{
G_debug(1, "Cairo_end_scaled_raster");
/* paint source surface onto dstination (scaled) */
cairo_save(cairo);
cairo_translate(cairo, dst_l, dst_t);
cairo_scale(cairo, (double)dst_w / (double)src_w,
(double)dst_h / (double)src_h);
cairo_surface_mark_dirty(src_surf);
cairo_set_source_surface(cairo, src_surf, 0, 0);
cairo_paint(cairo);
cairo_restore(cairo);
/* cleanup */
cairo_surface_destroy(src_surf);
modified = 1;
}
|