Home | History | Annotate | Download | only in pixman
      1 /*
      2  * Copyright  2002 Keith Packard, member of The XFree86 Project, Inc.
      3  * Copyright  2004 Keith Packard
      4  *
      5  * Permission to use, copy, modify, distribute, and sell this software and its
      6  * documentation for any purpose is hereby granted without fee, provided that
      7  * the above copyright notice appear in all copies and that both that
      8  * copyright notice and this permission notice appear in supporting
      9  * documentation, and that the name of Keith Packard not be used in
     10  * advertising or publicity pertaining to distribution of the software without
     11  * specific, written prior permission.  Keith Packard makes no
     12  * representations about the suitability of this software for any purpose.  It
     13  * is provided "as is" without express or implied warranty.
     14  *
     15  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     17  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     21  * PERFORMANCE OF THIS SOFTWARE.
     22  */
     23 
     24 #ifdef HAVE_CONFIG_H
     25 #include <config.h>
     26 #endif
     27 
     28 #include <stdio.h>
     29 #include <stdlib.h>
     30 #include "pixman-private.h"
     31 
     32 /*
     33  * Compute the smallest value greater than or equal to y which is on a
     34  * grid row.
     35  */
     36 
     37 PIXMAN_EXPORT pixman_fixed_t
     38 pixman_sample_ceil_y (pixman_fixed_t y, int n)
     39 {
     40     pixman_fixed_t f = pixman_fixed_frac (y);
     41     pixman_fixed_t i = pixman_fixed_floor (y);
     42 
     43     f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
     44 	Y_FRAC_FIRST (n);
     45 
     46     if (f > Y_FRAC_LAST (n))
     47     {
     48 	if (pixman_fixed_to_int (i) == 0x7fff)
     49 	{
     50 	    f = 0xffff; /* saturate */
     51 	}
     52 	else
     53 	{
     54 	    f = Y_FRAC_FIRST (n);
     55 	    i += pixman_fixed_1;
     56 	}
     57     }
     58     return (i | f);
     59 }
     60 
     61 /*
     62  * Compute the largest value strictly less than y which is on a
     63  * grid row.
     64  */
     65 PIXMAN_EXPORT pixman_fixed_t
     66 pixman_sample_floor_y (pixman_fixed_t y,
     67                        int            n)
     68 {
     69     pixman_fixed_t f = pixman_fixed_frac (y);
     70     pixman_fixed_t i = pixman_fixed_floor (y);
     71 
     72     f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
     73 	Y_FRAC_FIRST (n);
     74 
     75     if (f < Y_FRAC_FIRST (n))
     76     {
     77 	if (pixman_fixed_to_int (i) == 0x8000)
     78 	{
     79 	    f = 0; /* saturate */
     80 	}
     81 	else
     82 	{
     83 	    f = Y_FRAC_LAST (n);
     84 	    i -= pixman_fixed_1;
     85 	}
     86     }
     87     return (i | f);
     88 }
     89 
     90 /*
     91  * Step an edge by any amount (including negative values)
     92  */
     93 PIXMAN_EXPORT void
     94 pixman_edge_step (pixman_edge_t *e,
     95                   int            n)
     96 {
     97     pixman_fixed_48_16_t ne;
     98 
     99     e->x += n * e->stepx;
    100 
    101     ne = e->e + n * (pixman_fixed_48_16_t) e->dx;
    102 
    103     if (n >= 0)
    104     {
    105 	if (ne > 0)
    106 	{
    107 	    int nx = (ne + e->dy - 1) / e->dy;
    108 	    e->e = ne - nx * (pixman_fixed_48_16_t) e->dy;
    109 	    e->x += nx * e->signdx;
    110 	}
    111     }
    112     else
    113     {
    114 	if (ne <= -e->dy)
    115 	{
    116 	    int nx = (-ne) / e->dy;
    117 	    e->e = ne + nx * (pixman_fixed_48_16_t) e->dy;
    118 	    e->x -= nx * e->signdx;
    119 	}
    120     }
    121 }
    122 
    123 /*
    124  * A private routine to initialize the multi-step
    125  * elements of an edge structure
    126  */
    127 static void
    128 _pixman_edge_multi_init (pixman_edge_t * e,
    129                          int             n,
    130                          pixman_fixed_t *stepx_p,
    131                          pixman_fixed_t *dx_p)
    132 {
    133     pixman_fixed_t stepx;
    134     pixman_fixed_48_16_t ne;
    135 
    136     ne = n * (pixman_fixed_48_16_t) e->dx;
    137     stepx = n * e->stepx;
    138 
    139     if (ne > 0)
    140     {
    141 	int nx = ne / e->dy;
    142 	ne -= nx * (pixman_fixed_48_16_t)e->dy;
    143 	stepx += nx * e->signdx;
    144     }
    145 
    146     *dx_p = ne;
    147     *stepx_p = stepx;
    148 }
    149 
    150 /*
    151  * Initialize one edge structure given the line endpoints and a
    152  * starting y value
    153  */
    154 PIXMAN_EXPORT void
    155 pixman_edge_init (pixman_edge_t *e,
    156                   int            n,
    157                   pixman_fixed_t y_start,
    158                   pixman_fixed_t x_top,
    159                   pixman_fixed_t y_top,
    160                   pixman_fixed_t x_bot,
    161                   pixman_fixed_t y_bot)
    162 {
    163     pixman_fixed_t dx, dy;
    164 
    165     e->x = x_top;
    166     e->e = 0;
    167     dx = x_bot - x_top;
    168     dy = y_bot - y_top;
    169     e->dy = dy;
    170     e->dx = 0;
    171 
    172     if (dy)
    173     {
    174 	if (dx >= 0)
    175 	{
    176 	    e->signdx = 1;
    177 	    e->stepx = dx / dy;
    178 	    e->dx = dx % dy;
    179 	    e->e = -dy;
    180 	}
    181 	else
    182 	{
    183 	    e->signdx = -1;
    184 	    e->stepx = -(-dx / dy);
    185 	    e->dx = -dx % dy;
    186 	    e->e = 0;
    187 	}
    188 
    189 	_pixman_edge_multi_init (e, STEP_Y_SMALL (n),
    190 				 &e->stepx_small, &e->dx_small);
    191 
    192 	_pixman_edge_multi_init (e, STEP_Y_BIG (n),
    193 				 &e->stepx_big, &e->dx_big);
    194     }
    195     pixman_edge_step (e, y_start - y_top);
    196 }
    197 
    198 /*
    199  * Initialize one edge structure given a line, starting y value
    200  * and a pixel offset for the line
    201  */
    202 PIXMAN_EXPORT void
    203 pixman_line_fixed_edge_init (pixman_edge_t *            e,
    204                              int                        n,
    205                              pixman_fixed_t             y,
    206                              const pixman_line_fixed_t *line,
    207                              int                        x_off,
    208                              int                        y_off)
    209 {
    210     pixman_fixed_t x_off_fixed = pixman_int_to_fixed (x_off);
    211     pixman_fixed_t y_off_fixed = pixman_int_to_fixed (y_off);
    212     const pixman_point_fixed_t *top, *bot;
    213 
    214     if (line->p1.y <= line->p2.y)
    215     {
    216 	top = &line->p1;
    217 	bot = &line->p2;
    218     }
    219     else
    220     {
    221 	top = &line->p2;
    222 	bot = &line->p1;
    223     }
    224 
    225     pixman_edge_init (e, n, y,
    226                       top->x + x_off_fixed,
    227                       top->y + y_off_fixed,
    228                       bot->x + x_off_fixed,
    229                       bot->y + y_off_fixed);
    230 }
    231 
    232 PIXMAN_EXPORT void
    233 pixman_add_traps (pixman_image_t *     image,
    234                   int16_t              x_off,
    235                   int16_t              y_off,
    236                   int                  ntrap,
    237                   const pixman_trap_t *traps)
    238 {
    239     int bpp;
    240     int height;
    241 
    242     pixman_fixed_t x_off_fixed;
    243     pixman_fixed_t y_off_fixed;
    244     pixman_edge_t l, r;
    245     pixman_fixed_t t, b;
    246 
    247     _pixman_image_validate (image);
    248 
    249     height = image->bits.height;
    250     bpp = PIXMAN_FORMAT_BPP (image->bits.format);
    251 
    252     x_off_fixed = pixman_int_to_fixed (x_off);
    253     y_off_fixed = pixman_int_to_fixed (y_off);
    254 
    255     while (ntrap--)
    256     {
    257 	t = traps->top.y + y_off_fixed;
    258 	if (t < 0)
    259 	    t = 0;
    260 	t = pixman_sample_ceil_y (t, bpp);
    261 
    262 	b = traps->bot.y + y_off_fixed;
    263 	if (pixman_fixed_to_int (b) >= height)
    264 	    b = pixman_int_to_fixed (height) - 1;
    265 	b = pixman_sample_floor_y (b, bpp);
    266 
    267 	if (b >= t)
    268 	{
    269 	    /* initialize edge walkers */
    270 	    pixman_edge_init (&l, bpp, t,
    271 	                      traps->top.l + x_off_fixed,
    272 	                      traps->top.y + y_off_fixed,
    273 	                      traps->bot.l + x_off_fixed,
    274 	                      traps->bot.y + y_off_fixed);
    275 
    276 	    pixman_edge_init (&r, bpp, t,
    277 	                      traps->top.r + x_off_fixed,
    278 	                      traps->top.y + y_off_fixed,
    279 	                      traps->bot.r + x_off_fixed,
    280 	                      traps->bot.y + y_off_fixed);
    281 
    282 	    pixman_rasterize_edges (image, &l, &r, t, b);
    283 	}
    284 
    285 	traps++;
    286     }
    287 }
    288 
    289 #if 0
    290 static void
    291 dump_image (pixman_image_t *image,
    292             const char *    title)
    293 {
    294     int i, j;
    295 
    296     if (!image->type == BITS)
    297 	printf ("%s is not a regular image\n", title);
    298 
    299     if (!image->bits.format == PIXMAN_a8)
    300 	printf ("%s is not an alpha mask\n", title);
    301 
    302     printf ("\n\n\n%s: \n", title);
    303 
    304     for (i = 0; i < image->bits.height; ++i)
    305     {
    306 	uint8_t *line =
    307 	    (uint8_t *)&(image->bits.bits[i * image->bits.rowstride]);
    308 
    309 	for (j = 0; j < image->bits.width; ++j)
    310 	    printf ("%c", line[j] ? '#' : ' ');
    311 
    312 	printf ("\n");
    313     }
    314 }
    315 #endif
    316 
    317 PIXMAN_EXPORT void
    318 pixman_add_trapezoids (pixman_image_t *          image,
    319                        int16_t                   x_off,
    320                        int                       y_off,
    321                        int                       ntraps,
    322                        const pixman_trapezoid_t *traps)
    323 {
    324     int i;
    325 
    326 #if 0
    327     dump_image (image, "before");
    328 #endif
    329 
    330     for (i = 0; i < ntraps; ++i)
    331     {
    332 	const pixman_trapezoid_t *trap = &(traps[i]);
    333 
    334 	if (!pixman_trapezoid_valid (trap))
    335 	    continue;
    336 
    337 	pixman_rasterize_trapezoid (image, trap, x_off, y_off);
    338     }
    339 
    340 #if 0
    341     dump_image (image, "after");
    342 #endif
    343 }
    344 
    345 PIXMAN_EXPORT void
    346 pixman_rasterize_trapezoid (pixman_image_t *          image,
    347                             const pixman_trapezoid_t *trap,
    348                             int                       x_off,
    349                             int                       y_off)
    350 {
    351     int bpp;
    352     int height;
    353 
    354     pixman_fixed_t y_off_fixed;
    355     pixman_edge_t l, r;
    356     pixman_fixed_t t, b;
    357 
    358     return_if_fail (image->type == BITS);
    359 
    360     _pixman_image_validate (image);
    361 
    362     if (!pixman_trapezoid_valid (trap))
    363 	return;
    364 
    365     height = image->bits.height;
    366     bpp = PIXMAN_FORMAT_BPP (image->bits.format);
    367 
    368     y_off_fixed = pixman_int_to_fixed (y_off);
    369 
    370     t = trap->top + y_off_fixed;
    371     if (t < 0)
    372 	t = 0;
    373     t = pixman_sample_ceil_y (t, bpp);
    374 
    375     b = trap->bottom + y_off_fixed;
    376     if (pixman_fixed_to_int (b) >= height)
    377 	b = pixman_int_to_fixed (height) - 1;
    378     b = pixman_sample_floor_y (b, bpp);
    379 
    380     if (b >= t)
    381     {
    382 	/* initialize edge walkers */
    383 	pixman_line_fixed_edge_init (&l, bpp, t, &trap->left, x_off, y_off);
    384 	pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off);
    385 
    386 	pixman_rasterize_edges (image, &l, &r, t, b);
    387     }
    388 }
    389 
    390 static const pixman_bool_t zero_src_has_no_effect[PIXMAN_N_OPERATORS] =
    391 {
    392     FALSE,	/* Clear		0			0    */
    393     FALSE,	/* Src			1			0    */
    394     TRUE,	/* Dst			0			1    */
    395     TRUE,	/* Over			1			1-Aa */
    396     TRUE,	/* OverReverse		1-Ab			1    */
    397     FALSE,	/* In			Ab			0    */
    398     FALSE,	/* InReverse		0			Aa   */
    399     FALSE,	/* Out			1-Ab			0    */
    400     TRUE,	/* OutReverse		0			1-Aa */
    401     TRUE,	/* Atop			Ab			1-Aa */
    402     FALSE,	/* AtopReverse		1-Ab			Aa   */
    403     TRUE,	/* Xor			1-Ab			1-Aa */
    404     TRUE,	/* Add			1			1    */
    405 };
    406 
    407 static pixman_bool_t
    408 get_trap_extents (pixman_op_t op, pixman_image_t *dest,
    409 		  const pixman_trapezoid_t *traps, int n_traps,
    410 		  pixman_box32_t *box)
    411 {
    412     int i;
    413 
    414     /* When the operator is such that a zero source has an
    415      * effect on the underlying image, we have to
    416      * composite across the entire destination
    417      */
    418     if (!zero_src_has_no_effect [op])
    419     {
    420 	box->x1 = 0;
    421 	box->y1 = 0;
    422 	box->x2 = dest->bits.width;
    423 	box->y2 = dest->bits.height;
    424 	return TRUE;
    425     }
    426 
    427     box->x1 = INT32_MAX;
    428     box->y1 = INT32_MAX;
    429     box->x2 = INT32_MIN;
    430     box->y2 = INT32_MIN;
    431 
    432     for (i = 0; i < n_traps; ++i)
    433     {
    434 	const pixman_trapezoid_t *trap = &(traps[i]);
    435 	int y1, y2;
    436 
    437 	if (!pixman_trapezoid_valid (trap))
    438 	    continue;
    439 
    440 	y1 = pixman_fixed_to_int (trap->top);
    441 	if (y1 < box->y1)
    442 	    box->y1 = y1;
    443 
    444 	y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom));
    445 	if (y2 > box->y2)
    446 	    box->y2 = y2;
    447 
    448 #define EXTEND_MIN(x)							\
    449 	if (pixman_fixed_to_int ((x)) < box->x1)			\
    450 	    box->x1 = pixman_fixed_to_int ((x));
    451 #define EXTEND_MAX(x)							\
    452 	if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box->x2)	\
    453 	    box->x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x)));
    454 
    455 #define EXTEND(x)							\
    456 	EXTEND_MIN(x);							\
    457 	EXTEND_MAX(x);
    458 
    459 	EXTEND(trap->left.p1.x);
    460 	EXTEND(trap->left.p2.x);
    461 	EXTEND(trap->right.p1.x);
    462 	EXTEND(trap->right.p2.x);
    463     }
    464 
    465     if (box->x1 >= box->x2 || box->y1 >= box->y2)
    466 	return FALSE;
    467 
    468     return TRUE;
    469 }
    470 
    471 /*
    472  * pixman_composite_trapezoids()
    473  *
    474  * All the trapezoids are conceptually rendered to an infinitely big image.
    475  * The (0, 0) coordinates of this image are then aligned with the (x, y)
    476  * coordinates of the source image, and then both images are aligned with
    477  * the (x, y) coordinates of the destination. Then these three images are
    478  * composited across the entire destination.
    479  */
    480 PIXMAN_EXPORT void
    481 pixman_composite_trapezoids (pixman_op_t		op,
    482 			     pixman_image_t *		src,
    483 			     pixman_image_t *		dst,
    484 			     pixman_format_code_t	mask_format,
    485 			     int			x_src,
    486 			     int			y_src,
    487 			     int			x_dst,
    488 			     int			y_dst,
    489 			     int			n_traps,
    490 			     const pixman_trapezoid_t *	traps)
    491 {
    492     int i;
    493 
    494     return_if_fail (PIXMAN_FORMAT_TYPE (mask_format) == PIXMAN_TYPE_A);
    495 
    496     if (n_traps <= 0)
    497 	return;
    498 
    499     _pixman_image_validate (src);
    500     _pixman_image_validate (dst);
    501 
    502     if (op == PIXMAN_OP_ADD &&
    503 	(src->common.flags & FAST_PATH_IS_OPAQUE)		&&
    504 	(mask_format == dst->common.extended_format_code)	&&
    505 	!(dst->common.have_clip_region))
    506     {
    507 	for (i = 0; i < n_traps; ++i)
    508 	{
    509 	    const pixman_trapezoid_t *trap = &(traps[i]);
    510 
    511 	    if (!pixman_trapezoid_valid (trap))
    512 		continue;
    513 
    514 	    pixman_rasterize_trapezoid (dst, trap, x_dst, y_dst);
    515 	}
    516     }
    517     else
    518     {
    519 	pixman_image_t *tmp;
    520 	pixman_box32_t box;
    521 	int i;
    522 
    523 	if (!get_trap_extents (op, dst, traps, n_traps, &box))
    524 	    return;
    525 
    526 	if (!(tmp = pixman_image_create_bits (
    527 		  mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1)))
    528 	    return;
    529 
    530 	for (i = 0; i < n_traps; ++i)
    531 	{
    532 	    const pixman_trapezoid_t *trap = &(traps[i]);
    533 
    534 	    if (!pixman_trapezoid_valid (trap))
    535 		continue;
    536 
    537 	    pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1);
    538 	}
    539 
    540 	pixman_image_composite (op, src, tmp, dst,
    541 				x_src + box.x1, y_src + box.y1,
    542 				0, 0,
    543 				x_dst + box.x1, y_dst + box.y1,
    544 				box.x2 - box.x1, box.y2 - box.y1);
    545 
    546 	pixman_image_unref (tmp);
    547     }
    548 }
    549 
    550 static int
    551 greater_y (const pixman_point_fixed_t *a, const pixman_point_fixed_t *b)
    552 {
    553     if (a->y == b->y)
    554 	return a->x > b->x;
    555     return a->y > b->y;
    556 }
    557 
    558 /*
    559  * Note that the definition of this function is a bit odd because
    560  * of the X coordinate space (y increasing downwards).
    561  */
    562 static int
    563 clockwise (const pixman_point_fixed_t *ref,
    564 	   const pixman_point_fixed_t *a,
    565 	   const pixman_point_fixed_t *b)
    566 {
    567     pixman_point_fixed_t	ad, bd;
    568 
    569     ad.x = a->x - ref->x;
    570     ad.y = a->y - ref->y;
    571     bd.x = b->x - ref->x;
    572     bd.y = b->y - ref->y;
    573 
    574     return ((pixman_fixed_32_32_t) bd.y * ad.x -
    575 	    (pixman_fixed_32_32_t) ad.y * bd.x) < 0;
    576 }
    577 
    578 static void
    579 triangle_to_trapezoids (const pixman_triangle_t *tri, pixman_trapezoid_t *traps)
    580 {
    581     const pixman_point_fixed_t *top, *left, *right, *tmp;
    582 
    583     top = &tri->p1;
    584     left = &tri->p2;
    585     right = &tri->p3;
    586 
    587     if (greater_y (top, left))
    588     {
    589 	tmp = left;
    590 	left = top;
    591 	top = tmp;
    592     }
    593 
    594     if (greater_y (top, right))
    595     {
    596 	tmp = right;
    597 	right = top;
    598 	top = tmp;
    599     }
    600 
    601     if (clockwise (top, right, left))
    602     {
    603 	tmp = right;
    604 	right = left;
    605 	left = tmp;
    606     }
    607 
    608     /*
    609      * Two cases:
    610      *
    611      *		+		+
    612      *	       / \             / \
    613      *	      /   \           /	  \
    614      *	     /     +         +	   \
    615      *      /    --           --    \
    616      *     /   --               --   \
    617      *    / ---                   --- \
    618      *	 +--                         --+
    619      */
    620 
    621     traps->top = top->y;
    622     traps->left.p1 = *top;
    623     traps->left.p2 = *left;
    624     traps->right.p1 = *top;
    625     traps->right.p2 = *right;
    626 
    627     if (right->y < left->y)
    628 	traps->bottom = right->y;
    629     else
    630 	traps->bottom = left->y;
    631 
    632     traps++;
    633 
    634     *traps = *(traps - 1);
    635 
    636     if (right->y < left->y)
    637     {
    638 	traps->top = right->y;
    639 	traps->bottom = left->y;
    640 	traps->right.p1 = *right;
    641 	traps->right.p2 = *left;
    642     }
    643     else
    644     {
    645 	traps->top = left->y;
    646 	traps->bottom = right->y;
    647 	traps->left.p1 = *left;
    648 	traps->left.p2 = *right;
    649     }
    650 }
    651 
    652 static pixman_trapezoid_t *
    653 convert_triangles (int n_tris, const pixman_triangle_t *tris)
    654 {
    655     pixman_trapezoid_t *traps;
    656     int i;
    657 
    658     if (n_tris <= 0)
    659 	return NULL;
    660 
    661     traps = pixman_malloc_ab (n_tris, 2 * sizeof (pixman_trapezoid_t));
    662     if (!traps)
    663 	return NULL;
    664 
    665     for (i = 0; i < n_tris; ++i)
    666 	triangle_to_trapezoids (&(tris[i]), traps + 2 * i);
    667 
    668     return traps;
    669 }
    670 
    671 PIXMAN_EXPORT void
    672 pixman_composite_triangles (pixman_op_t			op,
    673 			    pixman_image_t *		src,
    674 			    pixman_image_t *		dst,
    675 			    pixman_format_code_t	mask_format,
    676 			    int				x_src,
    677 			    int				y_src,
    678 			    int				x_dst,
    679 			    int				y_dst,
    680 			    int				n_tris,
    681 			    const pixman_triangle_t *	tris)
    682 {
    683     pixman_trapezoid_t *traps;
    684 
    685     if ((traps = convert_triangles (n_tris, tris)))
    686     {
    687 	pixman_composite_trapezoids (op, src, dst, mask_format,
    688 				     x_src, y_src, x_dst, y_dst,
    689 				     n_tris * 2, traps);
    690 
    691 	free (traps);
    692     }
    693 }
    694 
    695 PIXMAN_EXPORT void
    696 pixman_add_triangles (pixman_image_t          *image,
    697 		      int32_t	               x_off,
    698 		      int32_t	               y_off,
    699 		      int	               n_tris,
    700 		      const pixman_triangle_t *tris)
    701 {
    702     pixman_trapezoid_t *traps;
    703 
    704     if ((traps = convert_triangles (n_tris, tris)))
    705     {
    706 	pixman_add_trapezoids (image, x_off, y_off,
    707 			       n_tris * 2, traps);
    708 
    709 	free (traps);
    710     }
    711 }
    712