Coverage Report

Created: 2025-07-23 08:13

/src/cairo/subprojects/pixman-0.44.2/pixman/pixman-trap.c
Line
Count
Source (jump to first uncovered line)
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 <pixman-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
6
{
40
6
    pixman_fixed_t f = pixman_fixed_frac (y);
41
6
    pixman_fixed_t i = pixman_fixed_floor (y);
42
43
6
    f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
44
6
  Y_FRAC_FIRST (n);
45
    
46
6
    if (f > Y_FRAC_LAST (n))
47
0
    {
48
0
  if (pixman_fixed_to_int (i) == 0x7fff)
49
0
  {
50
0
      f = 0xffff; /* saturate */
51
0
  }
52
0
  else
53
0
  {
54
0
      f = Y_FRAC_FIRST (n);
55
0
      i += pixman_fixed_1;
56
0
  }
57
0
    }
58
6
    return (i | f);
59
6
}
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
6
{
69
6
    pixman_fixed_t f = pixman_fixed_frac (y);
70
6
    pixman_fixed_t i = pixman_fixed_floor (y);
71
72
6
    f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
73
6
  Y_FRAC_FIRST (n);
74
75
6
    if (f < Y_FRAC_FIRST (n))
76
0
    {
77
0
  if (pixman_fixed_to_int (i) == 0xffff8000)
78
0
  {
79
0
      f = 0; /* saturate */
80
0
  }
81
0
  else
82
0
  {
83
0
      f = Y_FRAC_LAST (n);
84
0
      i -= pixman_fixed_1;
85
0
  }
86
0
    }
87
6
    return (i | f);
88
6
}
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
12
{
97
12
    pixman_fixed_48_16_t ne;
98
99
12
    e->x += n * e->stepx;
100
101
12
    ne = e->e + n * (pixman_fixed_48_16_t) e->dx;
102
103
12
    if (n >= 0)
104
12
    {
105
12
  if (ne > 0)
106
10
  {
107
10
      int nx = (ne + e->dy - 1) / e->dy;
108
10
      e->e = ne - nx * (pixman_fixed_48_16_t) e->dy;
109
10
      e->x += nx * e->signdx;
110
10
  }
111
12
    }
112
0
    else
113
0
    {
114
0
  if (ne <= -e->dy)
115
0
  {
116
0
      int nx = (-ne) / e->dy;
117
0
      e->e = ne + nx * (pixman_fixed_48_16_t) e->dy;
118
0
      e->x -= nx * e->signdx;
119
0
  }
120
0
    }
121
12
}
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
24
{
133
24
    pixman_fixed_t stepx;
134
24
    pixman_fixed_48_16_t ne;
135
136
24
    ne = n * (pixman_fixed_48_16_t) e->dx;
137
24
    stepx = n * e->stepx;
138
139
24
    if (ne > 0)
140
20
    {
141
20
  int nx = ne / e->dy;
142
20
  ne -= nx * (pixman_fixed_48_16_t)e->dy;
143
20
  stepx += nx * e->signdx;
144
20
    }
145
146
24
    *dx_p = ne;
147
24
    *stepx_p = stepx;
148
24
}
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
12
{
163
12
    pixman_fixed_t dx, dy;
164
165
12
    e->x = x_top;
166
12
    e->e = 0;
167
12
    dx = x_bot - x_top;
168
12
    dy = y_bot - y_top;
169
12
    e->dy = dy;
170
12
    e->dx = 0;
171
172
12
    if (dy)
173
12
    {
174
12
  if (dx >= 0)
175
10
  {
176
10
      e->signdx = 1;
177
10
      e->stepx = dx / dy;
178
10
      e->dx = dx % dy;
179
10
      e->e = -dy;
180
10
  }
181
2
  else
182
2
  {
183
2
      e->signdx = -1;
184
2
      e->stepx = -(-dx / dy);
185
2
      e->dx = -dx % dy;
186
2
      e->e = 0;
187
2
  }
188
189
12
  _pixman_edge_multi_init (e, STEP_Y_SMALL (n),
190
12
         &e->stepx_small, &e->dx_small);
191
192
12
  _pixman_edge_multi_init (e, STEP_Y_BIG (n),
193
12
         &e->stepx_big, &e->dx_big);
194
12
    }
195
12
    pixman_edge_step (e, y_start - y_top);
196
12
}
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
12
{
210
12
    pixman_fixed_t x_off_fixed = pixman_int_to_fixed (x_off);
211
12
    pixman_fixed_t y_off_fixed = pixman_int_to_fixed (y_off);
212
12
    const pixman_point_fixed_t *top, *bot;
213
214
12
    if (line->p1.y <= line->p2.y)
215
12
    {
216
12
  top = &line->p1;
217
12
  bot = &line->p2;
218
12
    }
219
0
    else
220
0
    {
221
0
  top = &line->p2;
222
0
  bot = &line->p1;
223
0
    }
224
    
225
12
    pixman_edge_init (e, n, y,
226
12
                      top->x + x_off_fixed,
227
12
                      top->y + y_off_fixed,
228
12
                      bot->x + x_off_fixed,
229
12
                      bot->y + y_off_fixed);
230
12
}
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
0
{
239
0
    int bpp;
240
0
    int height;
241
242
0
    pixman_fixed_t x_off_fixed;
243
0
    pixman_fixed_t y_off_fixed;
244
0
    pixman_edge_t l, r;
245
0
    pixman_fixed_t t, b;
246
247
0
    _pixman_image_validate (image);
248
    
249
0
    height = image->bits.height;
250
0
    bpp = PIXMAN_FORMAT_BPP (image->bits.format);
251
252
0
    x_off_fixed = pixman_int_to_fixed (x_off);
253
0
    y_off_fixed = pixman_int_to_fixed (y_off);
254
255
0
    while (ntrap--)
256
0
    {
257
0
  t = traps->top.y + y_off_fixed;
258
0
  if (t < 0)
259
0
      t = 0;
260
0
  t = pixman_sample_ceil_y (t, bpp);
261
262
0
  b = traps->bot.y + y_off_fixed;
263
0
  if (pixman_fixed_to_int (b) >= height)
264
0
      b = pixman_int_to_fixed (height) - 1;
265
0
  b = pixman_sample_floor_y (b, bpp);
266
267
0
  if (b >= t)
268
0
  {
269
      /* initialize edge walkers */
270
0
      pixman_edge_init (&l, bpp, t,
271
0
                        traps->top.l + x_off_fixed,
272
0
                        traps->top.y + y_off_fixed,
273
0
                        traps->bot.l + x_off_fixed,
274
0
                        traps->bot.y + y_off_fixed);
275
276
0
      pixman_edge_init (&r, bpp, t,
277
0
                        traps->top.r + x_off_fixed,
278
0
                        traps->top.y + y_off_fixed,
279
0
                        traps->bot.r + x_off_fixed,
280
0
                        traps->bot.y + y_off_fixed);
281
282
0
      pixman_rasterize_edges (image, &l, &r, t, b);
283
0
  }
284
285
0
  traps++;
286
0
    }
287
0
}
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
0
{
324
0
    int i;
325
326
#if 0
327
    dump_image (image, "before");
328
#endif
329
330
0
    for (i = 0; i < ntraps; ++i)
331
0
    {
332
0
  const pixman_trapezoid_t *trap = &(traps[i]);
333
334
0
  if (!pixman_trapezoid_valid (trap))
335
0
      continue;
336
337
0
  pixman_rasterize_trapezoid (image, trap, x_off, y_off);
338
0
    }
339
340
#if 0
341
    dump_image (image, "after");
342
#endif
343
0
}
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
6
{
351
6
    int bpp;
352
6
    int height;
353
354
6
    pixman_fixed_t y_off_fixed;
355
6
    pixman_edge_t l, r;
356
6
    pixman_fixed_t t, b;
357
358
6
    return_if_fail (image->type == BITS);
359
360
6
    _pixman_image_validate (image);
361
    
362
6
    if (!pixman_trapezoid_valid (trap))
363
0
  return;
364
365
6
    height = image->bits.height;
366
6
    bpp = PIXMAN_FORMAT_BPP (image->bits.format);
367
368
6
    y_off_fixed = pixman_int_to_fixed (y_off);
369
370
6
    t = trap->top + y_off_fixed;
371
6
    if (t < 0)
372
0
  t = 0;
373
6
    t = pixman_sample_ceil_y (t, bpp);
374
375
6
    b = trap->bottom + y_off_fixed;
376
6
    if (pixman_fixed_to_int (b) >= height)
377
0
  b = pixman_int_to_fixed (height) - 1;
378
6
    b = pixman_sample_floor_y (b, bpp);
379
    
380
6
    if (b >= t)
381
6
    {
382
  /* initialize edge walkers */
383
6
  pixman_line_fixed_edge_init (&l, bpp, t, &trap->left, x_off, y_off);
384
6
  pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off);
385
386
6
  pixman_rasterize_edges (image, &l, &r, t, b);
387
6
    }
388
6
}
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
0
{
412
0
    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
0
    if (!zero_src_has_no_effect [op])
419
0
    {
420
0
  box->x1 = 0;
421
0
  box->y1 = 0;
422
0
  box->x2 = dest->bits.width;
423
0
  box->y2 = dest->bits.height;
424
0
  return TRUE;
425
0
    }
426
    
427
0
    box->x1 = INT32_MAX;
428
0
    box->y1 = INT32_MAX;
429
0
    box->x2 = INT32_MIN;
430
0
    box->y2 = INT32_MIN;
431
  
432
0
    for (i = 0; i < n_traps; ++i)
433
0
    {
434
0
  const pixman_trapezoid_t *trap = &(traps[i]);
435
0
  int y1, y2;
436
      
437
0
  if (!pixman_trapezoid_valid (trap))
438
0
      continue;
439
      
440
0
  y1 = pixman_fixed_to_int (trap->top);
441
0
  if (y1 < box->y1)
442
0
      box->y1 = y1;
443
      
444
0
  y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom));
445
0
  if (y2 > box->y2)
446
0
      box->y2 = y2;
447
      
448
0
#define EXTEND_MIN(x)             \
449
0
  if (pixman_fixed_to_int ((x)) < box->x1)     \
450
0
      box->x1 = pixman_fixed_to_int ((x));
451
0
#define EXTEND_MAX(x)             \
452
0
  if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box->x2) \
453
0
      box->x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x)));
454
      
455
0
#define EXTEND(x)             \
456
0
  EXTEND_MIN(x);              \
457
0
  EXTEND_MAX(x);
458
      
459
0
  EXTEND(trap->left.p1.x);
460
0
  EXTEND(trap->left.p2.x);
461
0
  EXTEND(trap->right.p1.x);
462
0
  EXTEND(trap->right.p2.x);
463
0
    }
464
  
465
0
    if (box->x1 >= box->x2 || box->y1 >= box->y2)
466
0
  return FALSE;
467
468
0
    return TRUE;
469
0
}
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
0
{
492
0
    int i;
493
494
0
    return_if_fail (PIXMAN_FORMAT_TYPE (mask_format) == PIXMAN_TYPE_A);
495
    
496
0
    if (n_traps <= 0)
497
0
  return;
498
499
0
    _pixman_image_validate (src);
500
0
    _pixman_image_validate (dst);
501
502
0
    if (op == PIXMAN_OP_ADD &&
503
0
  (src->common.flags & FAST_PATH_IS_OPAQUE)   &&
504
0
  (mask_format == dst->common.extended_format_code)  &&
505
0
  !(dst->common.have_clip_region))
506
0
    {
507
0
  for (i = 0; i < n_traps; ++i)
508
0
  {
509
0
      const pixman_trapezoid_t *trap = &(traps[i]);
510
      
511
0
      if (!pixman_trapezoid_valid (trap))
512
0
    continue;
513
      
514
0
      pixman_rasterize_trapezoid (dst, trap, x_dst, y_dst);
515
0
  }
516
0
    }
517
0
    else
518
0
    {
519
0
  pixman_image_t *tmp;
520
0
  pixman_box32_t box;
521
0
  int i;
522
523
0
  if (!get_trap_extents (op, dst, traps, n_traps, &box))
524
0
      return;
525
  
526
0
  if (!(tmp = pixman_image_create_bits (
527
0
      mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1)))
528
0
      return;
529
  
530
0
  for (i = 0; i < n_traps; ++i)
531
0
  {
532
0
      const pixman_trapezoid_t *trap = &(traps[i]);
533
      
534
0
      if (!pixman_trapezoid_valid (trap))
535
0
    continue;
536
      
537
0
      pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1);
538
0
  }
539
  
540
0
  pixman_image_composite (op, src, tmp, dst,
541
0
        x_src + box.x1, y_src + box.y1,
542
0
        0, 0,
543
0
        x_dst + box.x1, y_dst + box.y1,
544
0
        box.x2 - box.x1, box.y2 - box.y1);
545
  
546
0
  pixman_image_unref (tmp);
547
0
    }
548
0
}
549
550
static int
551
greater_y (const pixman_point_fixed_t *a, const pixman_point_fixed_t *b)
552
0
{
553
0
    if (a->y == b->y)
554
0
  return a->x > b->x;
555
0
    return a->y > b->y;
556
0
}
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
0
{
567
0
    pixman_point_fixed_t  ad, bd;
568
569
0
    ad.x = a->x - ref->x;
570
0
    ad.y = a->y - ref->y;
571
0
    bd.x = b->x - ref->x;
572
0
    bd.y = b->y - ref->y;
573
574
0
    return ((pixman_fixed_32_32_t) bd.y * ad.x -
575
0
      (pixman_fixed_32_32_t) ad.y * bd.x) < 0;
576
0
}
577
578
static void
579
triangle_to_trapezoids (const pixman_triangle_t *tri, pixman_trapezoid_t *traps)
580
0
{
581
0
    const pixman_point_fixed_t *top, *left, *right, *tmp;
582
583
0
    top = &tri->p1;
584
0
    left = &tri->p2;
585
0
    right = &tri->p3;
586
587
0
    if (greater_y (top, left))
588
0
    {
589
0
  tmp = left;
590
0
  left = top;
591
0
  top = tmp;
592
0
    }
593
594
0
    if (greater_y (top, right))
595
0
    {
596
0
  tmp = right;
597
0
  right = top;
598
0
  top = tmp;
599
0
    }
600
601
0
    if (clockwise (top, right, left))
602
0
    {
603
0
  tmp = right;
604
0
  right = left;
605
0
  left = tmp;
606
0
    }
607
    
608
    /*
609
     * Two cases:
610
     *
611
     *    +   +
612
     *         / \             / \
613
     *        /   \           /   \
614
     *       /     +         +     \
615
     *      /    --           --    \
616
     *     /   --               --   \
617
     *    / ---                   --- \
618
     *   +--                         --+
619
     */
620
621
0
    traps->top = top->y;
622
0
    traps->left.p1 = *top;
623
0
    traps->left.p2 = *left;
624
0
    traps->right.p1 = *top;
625
0
    traps->right.p2 = *right;
626
627
0
    if (right->y < left->y)
628
0
  traps->bottom = right->y;
629
0
    else
630
0
  traps->bottom = left->y;
631
632
0
    traps++;
633
634
0
    *traps = *(traps - 1);
635
    
636
0
    if (right->y < left->y)
637
0
    {
638
0
  traps->top = right->y;
639
0
  traps->bottom = left->y;
640
0
  traps->right.p1 = *right;
641
0
  traps->right.p2 = *left;
642
0
    }
643
0
    else
644
0
    {
645
0
  traps->top = left->y;
646
0
  traps->bottom = right->y;
647
0
  traps->left.p1 = *left;
648
0
  traps->left.p2 = *right;
649
0
    }
650
0
}
651
652
static pixman_trapezoid_t *
653
convert_triangles (int n_tris, const pixman_triangle_t *tris)
654
0
{
655
0
    pixman_trapezoid_t *traps;
656
0
    int i;
657
658
0
    if (n_tris <= 0)
659
0
  return NULL;
660
    
661
0
    traps = pixman_malloc_ab (n_tris, 2 * sizeof (pixman_trapezoid_t));
662
0
    if (!traps)
663
0
  return NULL;
664
665
0
    for (i = 0; i < n_tris; ++i)
666
0
  triangle_to_trapezoids (&(tris[i]), traps + 2 * i);
667
668
0
    return traps;
669
0
}
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
0
{
683
0
    pixman_trapezoid_t *traps;
684
685
0
    if ((traps = convert_triangles (n_tris, tris)))
686
0
    {
687
0
  pixman_composite_trapezoids (op, src, dst, mask_format,
688
0
             x_src, y_src, x_dst, y_dst,
689
0
             n_tris * 2, traps);
690
  
691
0
  free (traps);
692
0
    }
693
0
}
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
0
{
702
0
    pixman_trapezoid_t *traps;
703
704
0
    if ((traps = convert_triangles (n_tris, tris)))
705
0
    {
706
0
  pixman_add_trapezoids (image, x_off, y_off,
707
0
             n_tris * 2, traps);
708
709
0
  free (traps);
710
0
    }
711
0
}