1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/libpixman/src/pixman-trap.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,711 @@ 1.4 +/* 1.5 + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. 1.6 + * Copyright © 2004 Keith Packard 1.7 + * 1.8 + * Permission to use, copy, modify, distribute, and sell this software and its 1.9 + * documentation for any purpose is hereby granted without fee, provided that 1.10 + * the above copyright notice appear in all copies and that both that 1.11 + * copyright notice and this permission notice appear in supporting 1.12 + * documentation, and that the name of Keith Packard not be used in 1.13 + * advertising or publicity pertaining to distribution of the software without 1.14 + * specific, written prior permission. Keith Packard makes no 1.15 + * representations about the suitability of this software for any purpose. It 1.16 + * is provided "as is" without express or implied warranty. 1.17 + * 1.18 + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1.19 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1.20 + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1.21 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1.22 + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1.23 + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 1.24 + * PERFORMANCE OF THIS SOFTWARE. 1.25 + */ 1.26 + 1.27 +#ifdef HAVE_CONFIG_H 1.28 +#include <config.h> 1.29 +#endif 1.30 + 1.31 +#include <stdio.h> 1.32 +#include <stdlib.h> 1.33 +#include "pixman-private.h" 1.34 + 1.35 +/* 1.36 + * Compute the smallest value greater than or equal to y which is on a 1.37 + * grid row. 1.38 + */ 1.39 + 1.40 +PIXMAN_EXPORT pixman_fixed_t 1.41 +pixman_sample_ceil_y (pixman_fixed_t y, int n) 1.42 +{ 1.43 + pixman_fixed_t f = pixman_fixed_frac (y); 1.44 + pixman_fixed_t i = pixman_fixed_floor (y); 1.45 + 1.46 + f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) + 1.47 + Y_FRAC_FIRST (n); 1.48 + 1.49 + if (f > Y_FRAC_LAST (n)) 1.50 + { 1.51 + if (pixman_fixed_to_int (i) == 0x7fff) 1.52 + { 1.53 + f = 0xffff; /* saturate */ 1.54 + } 1.55 + else 1.56 + { 1.57 + f = Y_FRAC_FIRST (n); 1.58 + i += pixman_fixed_1; 1.59 + } 1.60 + } 1.61 + return (i | f); 1.62 +} 1.63 + 1.64 +/* 1.65 + * Compute the largest value strictly less than y which is on a 1.66 + * grid row. 1.67 + */ 1.68 +PIXMAN_EXPORT pixman_fixed_t 1.69 +pixman_sample_floor_y (pixman_fixed_t y, 1.70 + int n) 1.71 +{ 1.72 + pixman_fixed_t f = pixman_fixed_frac (y); 1.73 + pixman_fixed_t i = pixman_fixed_floor (y); 1.74 + 1.75 + f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) + 1.76 + Y_FRAC_FIRST (n); 1.77 + 1.78 + if (f < Y_FRAC_FIRST (n)) 1.79 + { 1.80 + if (pixman_fixed_to_int (i) == 0x8000) 1.81 + { 1.82 + f = 0; /* saturate */ 1.83 + } 1.84 + else 1.85 + { 1.86 + f = Y_FRAC_LAST (n); 1.87 + i -= pixman_fixed_1; 1.88 + } 1.89 + } 1.90 + return (i | f); 1.91 +} 1.92 + 1.93 +/* 1.94 + * Step an edge by any amount (including negative values) 1.95 + */ 1.96 +PIXMAN_EXPORT void 1.97 +pixman_edge_step (pixman_edge_t *e, 1.98 + int n) 1.99 +{ 1.100 + pixman_fixed_48_16_t ne; 1.101 + 1.102 + e->x += n * e->stepx; 1.103 + 1.104 + ne = e->e + n * (pixman_fixed_48_16_t) e->dx; 1.105 + 1.106 + if (n >= 0) 1.107 + { 1.108 + if (ne > 0) 1.109 + { 1.110 + int nx = (ne + e->dy - 1) / e->dy; 1.111 + e->e = ne - nx * (pixman_fixed_48_16_t) e->dy; 1.112 + e->x += nx * e->signdx; 1.113 + } 1.114 + } 1.115 + else 1.116 + { 1.117 + if (ne <= -e->dy) 1.118 + { 1.119 + int nx = (-ne) / e->dy; 1.120 + e->e = ne + nx * (pixman_fixed_48_16_t) e->dy; 1.121 + e->x -= nx * e->signdx; 1.122 + } 1.123 + } 1.124 +} 1.125 + 1.126 +/* 1.127 + * A private routine to initialize the multi-step 1.128 + * elements of an edge structure 1.129 + */ 1.130 +static void 1.131 +_pixman_edge_multi_init (pixman_edge_t * e, 1.132 + int n, 1.133 + pixman_fixed_t *stepx_p, 1.134 + pixman_fixed_t *dx_p) 1.135 +{ 1.136 + pixman_fixed_t stepx; 1.137 + pixman_fixed_48_16_t ne; 1.138 + 1.139 + ne = n * (pixman_fixed_48_16_t) e->dx; 1.140 + stepx = n * e->stepx; 1.141 + 1.142 + if (ne > 0) 1.143 + { 1.144 + int nx = ne / e->dy; 1.145 + ne -= nx * (pixman_fixed_48_16_t)e->dy; 1.146 + stepx += nx * e->signdx; 1.147 + } 1.148 + 1.149 + *dx_p = ne; 1.150 + *stepx_p = stepx; 1.151 +} 1.152 + 1.153 +/* 1.154 + * Initialize one edge structure given the line endpoints and a 1.155 + * starting y value 1.156 + */ 1.157 +PIXMAN_EXPORT void 1.158 +pixman_edge_init (pixman_edge_t *e, 1.159 + int n, 1.160 + pixman_fixed_t y_start, 1.161 + pixman_fixed_t x_top, 1.162 + pixman_fixed_t y_top, 1.163 + pixman_fixed_t x_bot, 1.164 + pixman_fixed_t y_bot) 1.165 +{ 1.166 + pixman_fixed_t dx, dy; 1.167 + 1.168 + e->x = x_top; 1.169 + e->e = 0; 1.170 + dx = x_bot - x_top; 1.171 + dy = y_bot - y_top; 1.172 + e->dy = dy; 1.173 + e->dx = 0; 1.174 + 1.175 + if (dy) 1.176 + { 1.177 + if (dx >= 0) 1.178 + { 1.179 + e->signdx = 1; 1.180 + e->stepx = dx / dy; 1.181 + e->dx = dx % dy; 1.182 + e->e = -dy; 1.183 + } 1.184 + else 1.185 + { 1.186 + e->signdx = -1; 1.187 + e->stepx = -(-dx / dy); 1.188 + e->dx = -dx % dy; 1.189 + e->e = 0; 1.190 + } 1.191 + 1.192 + _pixman_edge_multi_init (e, STEP_Y_SMALL (n), 1.193 + &e->stepx_small, &e->dx_small); 1.194 + 1.195 + _pixman_edge_multi_init (e, STEP_Y_BIG (n), 1.196 + &e->stepx_big, &e->dx_big); 1.197 + } 1.198 + pixman_edge_step (e, y_start - y_top); 1.199 +} 1.200 + 1.201 +/* 1.202 + * Initialize one edge structure given a line, starting y value 1.203 + * and a pixel offset for the line 1.204 + */ 1.205 +PIXMAN_EXPORT void 1.206 +pixman_line_fixed_edge_init (pixman_edge_t * e, 1.207 + int n, 1.208 + pixman_fixed_t y, 1.209 + const pixman_line_fixed_t *line, 1.210 + int x_off, 1.211 + int y_off) 1.212 +{ 1.213 + pixman_fixed_t x_off_fixed = pixman_int_to_fixed (x_off); 1.214 + pixman_fixed_t y_off_fixed = pixman_int_to_fixed (y_off); 1.215 + const pixman_point_fixed_t *top, *bot; 1.216 + 1.217 + if (line->p1.y <= line->p2.y) 1.218 + { 1.219 + top = &line->p1; 1.220 + bot = &line->p2; 1.221 + } 1.222 + else 1.223 + { 1.224 + top = &line->p2; 1.225 + bot = &line->p1; 1.226 + } 1.227 + 1.228 + pixman_edge_init (e, n, y, 1.229 + top->x + x_off_fixed, 1.230 + top->y + y_off_fixed, 1.231 + bot->x + x_off_fixed, 1.232 + bot->y + y_off_fixed); 1.233 +} 1.234 + 1.235 +PIXMAN_EXPORT void 1.236 +pixman_add_traps (pixman_image_t * image, 1.237 + int16_t x_off, 1.238 + int16_t y_off, 1.239 + int ntrap, 1.240 + const pixman_trap_t *traps) 1.241 +{ 1.242 + int bpp; 1.243 + int height; 1.244 + 1.245 + pixman_fixed_t x_off_fixed; 1.246 + pixman_fixed_t y_off_fixed; 1.247 + pixman_edge_t l, r; 1.248 + pixman_fixed_t t, b; 1.249 + 1.250 + _pixman_image_validate (image); 1.251 + 1.252 + height = image->bits.height; 1.253 + bpp = PIXMAN_FORMAT_BPP (image->bits.format); 1.254 + 1.255 + x_off_fixed = pixman_int_to_fixed (x_off); 1.256 + y_off_fixed = pixman_int_to_fixed (y_off); 1.257 + 1.258 + while (ntrap--) 1.259 + { 1.260 + t = traps->top.y + y_off_fixed; 1.261 + if (t < 0) 1.262 + t = 0; 1.263 + t = pixman_sample_ceil_y (t, bpp); 1.264 + 1.265 + b = traps->bot.y + y_off_fixed; 1.266 + if (pixman_fixed_to_int (b) >= height) 1.267 + b = pixman_int_to_fixed (height) - 1; 1.268 + b = pixman_sample_floor_y (b, bpp); 1.269 + 1.270 + if (b >= t) 1.271 + { 1.272 + /* initialize edge walkers */ 1.273 + pixman_edge_init (&l, bpp, t, 1.274 + traps->top.l + x_off_fixed, 1.275 + traps->top.y + y_off_fixed, 1.276 + traps->bot.l + x_off_fixed, 1.277 + traps->bot.y + y_off_fixed); 1.278 + 1.279 + pixman_edge_init (&r, bpp, t, 1.280 + traps->top.r + x_off_fixed, 1.281 + traps->top.y + y_off_fixed, 1.282 + traps->bot.r + x_off_fixed, 1.283 + traps->bot.y + y_off_fixed); 1.284 + 1.285 + pixman_rasterize_edges (image, &l, &r, t, b); 1.286 + } 1.287 + 1.288 + traps++; 1.289 + } 1.290 +} 1.291 + 1.292 +#if 0 1.293 +static void 1.294 +dump_image (pixman_image_t *image, 1.295 + const char * title) 1.296 +{ 1.297 + int i, j; 1.298 + 1.299 + if (!image->type == BITS) 1.300 + printf ("%s is not a regular image\n", title); 1.301 + 1.302 + if (!image->bits.format == PIXMAN_a8) 1.303 + printf ("%s is not an alpha mask\n", title); 1.304 + 1.305 + printf ("\n\n\n%s: \n", title); 1.306 + 1.307 + for (i = 0; i < image->bits.height; ++i) 1.308 + { 1.309 + uint8_t *line = 1.310 + (uint8_t *)&(image->bits.bits[i * image->bits.rowstride]); 1.311 + 1.312 + for (j = 0; j < image->bits.width; ++j) 1.313 + printf ("%c", line[j] ? '#' : ' '); 1.314 + 1.315 + printf ("\n"); 1.316 + } 1.317 +} 1.318 +#endif 1.319 + 1.320 +PIXMAN_EXPORT void 1.321 +pixman_add_trapezoids (pixman_image_t * image, 1.322 + int16_t x_off, 1.323 + int y_off, 1.324 + int ntraps, 1.325 + const pixman_trapezoid_t *traps) 1.326 +{ 1.327 + int i; 1.328 + 1.329 +#if 0 1.330 + dump_image (image, "before"); 1.331 +#endif 1.332 + 1.333 + for (i = 0; i < ntraps; ++i) 1.334 + { 1.335 + const pixman_trapezoid_t *trap = &(traps[i]); 1.336 + 1.337 + if (!pixman_trapezoid_valid (trap)) 1.338 + continue; 1.339 + 1.340 + pixman_rasterize_trapezoid (image, trap, x_off, y_off); 1.341 + } 1.342 + 1.343 +#if 0 1.344 + dump_image (image, "after"); 1.345 +#endif 1.346 +} 1.347 + 1.348 +PIXMAN_EXPORT void 1.349 +pixman_rasterize_trapezoid (pixman_image_t * image, 1.350 + const pixman_trapezoid_t *trap, 1.351 + int x_off, 1.352 + int y_off) 1.353 +{ 1.354 + int bpp; 1.355 + int height; 1.356 + 1.357 + pixman_fixed_t y_off_fixed; 1.358 + pixman_edge_t l, r; 1.359 + pixman_fixed_t t, b; 1.360 + 1.361 + return_if_fail (image->type == BITS); 1.362 + 1.363 + _pixman_image_validate (image); 1.364 + 1.365 + if (!pixman_trapezoid_valid (trap)) 1.366 + return; 1.367 + 1.368 + height = image->bits.height; 1.369 + bpp = PIXMAN_FORMAT_BPP (image->bits.format); 1.370 + 1.371 + y_off_fixed = pixman_int_to_fixed (y_off); 1.372 + 1.373 + t = trap->top + y_off_fixed; 1.374 + if (t < 0) 1.375 + t = 0; 1.376 + t = pixman_sample_ceil_y (t, bpp); 1.377 + 1.378 + b = trap->bottom + y_off_fixed; 1.379 + if (pixman_fixed_to_int (b) >= height) 1.380 + b = pixman_int_to_fixed (height) - 1; 1.381 + b = pixman_sample_floor_y (b, bpp); 1.382 + 1.383 + if (b >= t) 1.384 + { 1.385 + /* initialize edge walkers */ 1.386 + pixman_line_fixed_edge_init (&l, bpp, t, &trap->left, x_off, y_off); 1.387 + pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off); 1.388 + 1.389 + pixman_rasterize_edges (image, &l, &r, t, b); 1.390 + } 1.391 +} 1.392 + 1.393 +static const pixman_bool_t zero_src_has_no_effect[PIXMAN_N_OPERATORS] = 1.394 +{ 1.395 + FALSE, /* Clear 0 0 */ 1.396 + FALSE, /* Src 1 0 */ 1.397 + TRUE, /* Dst 0 1 */ 1.398 + TRUE, /* Over 1 1-Aa */ 1.399 + TRUE, /* OverReverse 1-Ab 1 */ 1.400 + FALSE, /* In Ab 0 */ 1.401 + FALSE, /* InReverse 0 Aa */ 1.402 + FALSE, /* Out 1-Ab 0 */ 1.403 + TRUE, /* OutReverse 0 1-Aa */ 1.404 + TRUE, /* Atop Ab 1-Aa */ 1.405 + FALSE, /* AtopReverse 1-Ab Aa */ 1.406 + TRUE, /* Xor 1-Ab 1-Aa */ 1.407 + TRUE, /* Add 1 1 */ 1.408 +}; 1.409 + 1.410 +static pixman_bool_t 1.411 +get_trap_extents (pixman_op_t op, pixman_image_t *dest, 1.412 + const pixman_trapezoid_t *traps, int n_traps, 1.413 + pixman_box32_t *box) 1.414 +{ 1.415 + int i; 1.416 + 1.417 + /* When the operator is such that a zero source has an 1.418 + * effect on the underlying image, we have to 1.419 + * composite across the entire destination 1.420 + */ 1.421 + if (!zero_src_has_no_effect [op]) 1.422 + { 1.423 + box->x1 = 0; 1.424 + box->y1 = 0; 1.425 + box->x2 = dest->bits.width; 1.426 + box->y2 = dest->bits.height; 1.427 + return TRUE; 1.428 + } 1.429 + 1.430 + box->x1 = INT32_MAX; 1.431 + box->y1 = INT32_MAX; 1.432 + box->x2 = INT32_MIN; 1.433 + box->y2 = INT32_MIN; 1.434 + 1.435 + for (i = 0; i < n_traps; ++i) 1.436 + { 1.437 + const pixman_trapezoid_t *trap = &(traps[i]); 1.438 + int y1, y2; 1.439 + 1.440 + if (!pixman_trapezoid_valid (trap)) 1.441 + continue; 1.442 + 1.443 + y1 = pixman_fixed_to_int (trap->top); 1.444 + if (y1 < box->y1) 1.445 + box->y1 = y1; 1.446 + 1.447 + y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom)); 1.448 + if (y2 > box->y2) 1.449 + box->y2 = y2; 1.450 + 1.451 +#define EXTEND_MIN(x) \ 1.452 + if (pixman_fixed_to_int ((x)) < box->x1) \ 1.453 + box->x1 = pixman_fixed_to_int ((x)); 1.454 +#define EXTEND_MAX(x) \ 1.455 + if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box->x2) \ 1.456 + box->x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x))); 1.457 + 1.458 +#define EXTEND(x) \ 1.459 + EXTEND_MIN(x); \ 1.460 + EXTEND_MAX(x); 1.461 + 1.462 + EXTEND(trap->left.p1.x); 1.463 + EXTEND(trap->left.p2.x); 1.464 + EXTEND(trap->right.p1.x); 1.465 + EXTEND(trap->right.p2.x); 1.466 + } 1.467 + 1.468 + if (box->x1 >= box->x2 || box->y1 >= box->y2) 1.469 + return FALSE; 1.470 + 1.471 + return TRUE; 1.472 +} 1.473 + 1.474 +/* 1.475 + * pixman_composite_trapezoids() 1.476 + * 1.477 + * All the trapezoids are conceptually rendered to an infinitely big image. 1.478 + * The (0, 0) coordinates of this image are then aligned with the (x, y) 1.479 + * coordinates of the source image, and then both images are aligned with 1.480 + * the (x, y) coordinates of the destination. Then these three images are 1.481 + * composited across the entire destination. 1.482 + */ 1.483 +PIXMAN_EXPORT void 1.484 +pixman_composite_trapezoids (pixman_op_t op, 1.485 + pixman_image_t * src, 1.486 + pixman_image_t * dst, 1.487 + pixman_format_code_t mask_format, 1.488 + int x_src, 1.489 + int y_src, 1.490 + int x_dst, 1.491 + int y_dst, 1.492 + int n_traps, 1.493 + const pixman_trapezoid_t * traps) 1.494 +{ 1.495 + int i; 1.496 + 1.497 + return_if_fail (PIXMAN_FORMAT_TYPE (mask_format) == PIXMAN_TYPE_A); 1.498 + 1.499 + if (n_traps <= 0) 1.500 + return; 1.501 + 1.502 + _pixman_image_validate (src); 1.503 + _pixman_image_validate (dst); 1.504 + 1.505 + if (op == PIXMAN_OP_ADD && 1.506 + (src->common.flags & FAST_PATH_IS_OPAQUE) && 1.507 + (mask_format == dst->common.extended_format_code) && 1.508 + !(dst->common.have_clip_region)) 1.509 + { 1.510 + for (i = 0; i < n_traps; ++i) 1.511 + { 1.512 + const pixman_trapezoid_t *trap = &(traps[i]); 1.513 + 1.514 + if (!pixman_trapezoid_valid (trap)) 1.515 + continue; 1.516 + 1.517 + pixman_rasterize_trapezoid (dst, trap, x_dst, y_dst); 1.518 + } 1.519 + } 1.520 + else 1.521 + { 1.522 + pixman_image_t *tmp; 1.523 + pixman_box32_t box; 1.524 + int i; 1.525 + 1.526 + if (!get_trap_extents (op, dst, traps, n_traps, &box)) 1.527 + return; 1.528 + 1.529 + if (!(tmp = pixman_image_create_bits ( 1.530 + mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1))) 1.531 + return; 1.532 + 1.533 + for (i = 0; i < n_traps; ++i) 1.534 + { 1.535 + const pixman_trapezoid_t *trap = &(traps[i]); 1.536 + 1.537 + if (!pixman_trapezoid_valid (trap)) 1.538 + continue; 1.539 + 1.540 + pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1); 1.541 + } 1.542 + 1.543 + pixman_image_composite (op, src, tmp, dst, 1.544 + x_src + box.x1, y_src + box.y1, 1.545 + 0, 0, 1.546 + x_dst + box.x1, y_dst + box.y1, 1.547 + box.x2 - box.x1, box.y2 - box.y1); 1.548 + 1.549 + pixman_image_unref (tmp); 1.550 + } 1.551 +} 1.552 + 1.553 +static int 1.554 +greater_y (const pixman_point_fixed_t *a, const pixman_point_fixed_t *b) 1.555 +{ 1.556 + if (a->y == b->y) 1.557 + return a->x > b->x; 1.558 + return a->y > b->y; 1.559 +} 1.560 + 1.561 +/* 1.562 + * Note that the definition of this function is a bit odd because 1.563 + * of the X coordinate space (y increasing downwards). 1.564 + */ 1.565 +static int 1.566 +clockwise (const pixman_point_fixed_t *ref, 1.567 + const pixman_point_fixed_t *a, 1.568 + const pixman_point_fixed_t *b) 1.569 +{ 1.570 + pixman_point_fixed_t ad, bd; 1.571 + 1.572 + ad.x = a->x - ref->x; 1.573 + ad.y = a->y - ref->y; 1.574 + bd.x = b->x - ref->x; 1.575 + bd.y = b->y - ref->y; 1.576 + 1.577 + return ((pixman_fixed_32_32_t) bd.y * ad.x - 1.578 + (pixman_fixed_32_32_t) ad.y * bd.x) < 0; 1.579 +} 1.580 + 1.581 +static void 1.582 +triangle_to_trapezoids (const pixman_triangle_t *tri, pixman_trapezoid_t *traps) 1.583 +{ 1.584 + const pixman_point_fixed_t *top, *left, *right, *tmp; 1.585 + 1.586 + top = &tri->p1; 1.587 + left = &tri->p2; 1.588 + right = &tri->p3; 1.589 + 1.590 + if (greater_y (top, left)) 1.591 + { 1.592 + tmp = left; 1.593 + left = top; 1.594 + top = tmp; 1.595 + } 1.596 + 1.597 + if (greater_y (top, right)) 1.598 + { 1.599 + tmp = right; 1.600 + right = top; 1.601 + top = tmp; 1.602 + } 1.603 + 1.604 + if (clockwise (top, right, left)) 1.605 + { 1.606 + tmp = right; 1.607 + right = left; 1.608 + left = tmp; 1.609 + } 1.610 + 1.611 + /* 1.612 + * Two cases: 1.613 + * 1.614 + * + + 1.615 + * / \ / \ 1.616 + * / \ / \ 1.617 + * / + + \ 1.618 + * / -- -- \ 1.619 + * / -- -- \ 1.620 + * / --- --- \ 1.621 + * +-- --+ 1.622 + */ 1.623 + 1.624 + traps->top = top->y; 1.625 + traps->left.p1 = *top; 1.626 + traps->left.p2 = *left; 1.627 + traps->right.p1 = *top; 1.628 + traps->right.p2 = *right; 1.629 + 1.630 + if (right->y < left->y) 1.631 + traps->bottom = right->y; 1.632 + else 1.633 + traps->bottom = left->y; 1.634 + 1.635 + traps++; 1.636 + 1.637 + *traps = *(traps - 1); 1.638 + 1.639 + if (right->y < left->y) 1.640 + { 1.641 + traps->top = right->y; 1.642 + traps->bottom = left->y; 1.643 + traps->right.p1 = *right; 1.644 + traps->right.p2 = *left; 1.645 + } 1.646 + else 1.647 + { 1.648 + traps->top = left->y; 1.649 + traps->bottom = right->y; 1.650 + traps->left.p1 = *left; 1.651 + traps->left.p2 = *right; 1.652 + } 1.653 +} 1.654 + 1.655 +static pixman_trapezoid_t * 1.656 +convert_triangles (int n_tris, const pixman_triangle_t *tris) 1.657 +{ 1.658 + pixman_trapezoid_t *traps; 1.659 + int i; 1.660 + 1.661 + if (n_tris <= 0) 1.662 + return NULL; 1.663 + 1.664 + traps = pixman_malloc_ab (n_tris, 2 * sizeof (pixman_trapezoid_t)); 1.665 + if (!traps) 1.666 + return NULL; 1.667 + 1.668 + for (i = 0; i < n_tris; ++i) 1.669 + triangle_to_trapezoids (&(tris[i]), traps + 2 * i); 1.670 + 1.671 + return traps; 1.672 +} 1.673 + 1.674 +PIXMAN_EXPORT void 1.675 +pixman_composite_triangles (pixman_op_t op, 1.676 + pixman_image_t * src, 1.677 + pixman_image_t * dst, 1.678 + pixman_format_code_t mask_format, 1.679 + int x_src, 1.680 + int y_src, 1.681 + int x_dst, 1.682 + int y_dst, 1.683 + int n_tris, 1.684 + const pixman_triangle_t * tris) 1.685 +{ 1.686 + pixman_trapezoid_t *traps; 1.687 + 1.688 + if ((traps = convert_triangles (n_tris, tris))) 1.689 + { 1.690 + pixman_composite_trapezoids (op, src, dst, mask_format, 1.691 + x_src, y_src, x_dst, y_dst, 1.692 + n_tris * 2, traps); 1.693 + 1.694 + free (traps); 1.695 + } 1.696 +} 1.697 + 1.698 +PIXMAN_EXPORT void 1.699 +pixman_add_triangles (pixman_image_t *image, 1.700 + int32_t x_off, 1.701 + int32_t y_off, 1.702 + int n_tris, 1.703 + const pixman_triangle_t *tris) 1.704 +{ 1.705 + pixman_trapezoid_t *traps; 1.706 + 1.707 + if ((traps = convert_triangles (n_tris, tris))) 1.708 + { 1.709 + pixman_add_trapezoids (image, x_off, y_off, 1.710 + n_tris * 2, traps); 1.711 + 1.712 + free (traps); 1.713 + } 1.714 +}