LCOV - code coverage report
Current view: top level - gfx/cairo/libpixman/src - pixman-trap.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 260 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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           0 : pixman_sample_ceil_y (pixman_fixed_t y, int n)
      39             : {
      40           0 :     pixman_fixed_t f = pixman_fixed_frac (y);
      41           0 :     pixman_fixed_t i = pixman_fixed_floor (y);
      42             : 
      43           0 :     f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
      44           0 :         Y_FRAC_FIRST (n);
      45             :     
      46           0 :     if (f > Y_FRAC_LAST (n))
      47             :     {
      48           0 :         if (pixman_fixed_to_int (i) == 0x7fff)
      49             :         {
      50           0 :             f = 0xffff; /* saturate */
      51             :         }
      52             :         else
      53             :         {
      54           0 :             f = Y_FRAC_FIRST (n);
      55           0 :             i += pixman_fixed_1;
      56             :         }
      57             :     }
      58           0 :     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           0 : pixman_sample_floor_y (pixman_fixed_t y,
      67             :                        int            n)
      68             : {
      69           0 :     pixman_fixed_t f = pixman_fixed_frac (y);
      70           0 :     pixman_fixed_t i = pixman_fixed_floor (y);
      71             : 
      72           0 :     f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
      73           0 :         Y_FRAC_FIRST (n);
      74             : 
      75           0 :     if (f < Y_FRAC_FIRST (n))
      76             :     {
      77           0 :         if (pixman_fixed_to_int (i) == 0x8000)
      78             :         {
      79           0 :             f = 0; /* saturate */
      80             :         }
      81             :         else
      82             :         {
      83           0 :             f = Y_FRAC_LAST (n);
      84           0 :             i -= pixman_fixed_1;
      85             :         }
      86             :     }
      87           0 :     return (i | f);
      88             : }
      89             : 
      90             : /*
      91             :  * Step an edge by any amount (including negative values)
      92             :  */
      93             : PIXMAN_EXPORT void
      94           0 : pixman_edge_step (pixman_edge_t *e,
      95             :                   int            n)
      96             : {
      97             :     pixman_fixed_48_16_t ne;
      98             : 
      99           0 :     e->x += n * e->stepx;
     100             : 
     101           0 :     ne = e->e + n * (pixman_fixed_48_16_t) e->dx;
     102             : 
     103           0 :     if (n >= 0)
     104             :     {
     105           0 :         if (ne > 0)
     106             :         {
     107           0 :             int nx = (ne + e->dy - 1) / e->dy;
     108           0 :             e->e = ne - nx * (pixman_fixed_48_16_t) e->dy;
     109           0 :             e->x += nx * e->signdx;
     110             :         }
     111             :     }
     112             :     else
     113             :     {
     114           0 :         if (ne <= -e->dy)
     115             :         {
     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             :         }
     120             :     }
     121           0 : }
     122             : 
     123             : /*
     124             :  * A private routine to initialize the multi-step
     125             :  * elements of an edge structure
     126             :  */
     127             : static void
     128           0 : _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           0 :     ne = n * (pixman_fixed_48_16_t) e->dx;
     137           0 :     stepx = n * e->stepx;
     138             : 
     139           0 :     if (ne > 0)
     140             :     {
     141           0 :         int nx = ne / e->dy;
     142           0 :         ne -= nx * (pixman_fixed_48_16_t)e->dy;
     143           0 :         stepx += nx * e->signdx;
     144             :     }
     145             : 
     146           0 :     *dx_p = ne;
     147           0 :     *stepx_p = stepx;
     148           0 : }
     149             : 
     150             : /*
     151             :  * Initialize one edge structure given the line endpoints and a
     152             :  * starting y value
     153             :  */
     154             : PIXMAN_EXPORT void
     155           0 : 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           0 :     e->x = x_top;
     166           0 :     e->e = 0;
     167           0 :     dx = x_bot - x_top;
     168           0 :     dy = y_bot - y_top;
     169           0 :     e->dy = dy;
     170           0 :     e->dx = 0;
     171             : 
     172           0 :     if (dy)
     173             :     {
     174           0 :         if (dx >= 0)
     175             :         {
     176           0 :             e->signdx = 1;
     177           0 :             e->stepx = dx / dy;
     178           0 :             e->dx = dx % dy;
     179           0 :             e->e = -dy;
     180             :         }
     181             :         else
     182             :         {
     183           0 :             e->signdx = -1;
     184           0 :             e->stepx = -(-dx / dy);
     185           0 :             e->dx = -dx % dy;
     186           0 :             e->e = 0;
     187             :         }
     188             : 
     189           0 :         _pixman_edge_multi_init (e, STEP_Y_SMALL (n),
     190             :                                  &e->stepx_small, &e->dx_small);
     191             : 
     192           0 :         _pixman_edge_multi_init (e, STEP_Y_BIG (n),
     193             :                                  &e->stepx_big, &e->dx_big);
     194             :     }
     195           0 :     pixman_edge_step (e, y_start - y_top);
     196           0 : }
     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           0 : 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           0 :     pixman_fixed_t x_off_fixed = pixman_int_to_fixed (x_off);
     211           0 :     pixman_fixed_t y_off_fixed = pixman_int_to_fixed (y_off);
     212             :     const pixman_point_fixed_t *top, *bot;
     213             : 
     214           0 :     if (line->p1.y <= line->p2.y)
     215             :     {
     216           0 :         top = &line->p1;
     217           0 :         bot = &line->p2;
     218             :     }
     219             :     else
     220             :     {
     221           0 :         top = &line->p2;
     222           0 :         bot = &line->p1;
     223             :     }
     224             :     
     225           0 :     pixman_edge_init (e, n, y,
     226           0 :                       top->x + x_off_fixed,
     227           0 :                       top->y + y_off_fixed,
     228           0 :                       bot->x + x_off_fixed,
     229           0 :                       bot->y + y_off_fixed);
     230           0 : }
     231             : 
     232             : PIXMAN_EXPORT void
     233           0 : 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           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             :     {
     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             :         {
     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             :         }
     284             : 
     285           0 :         traps++;
     286             :     }
     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           0 : 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           0 :     for (i = 0; i < ntraps; ++i)
     331             :     {
     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             :     }
     339             : 
     340             : #if 0
     341             :     dump_image (image, "after");
     342             : #endif
     343           0 : }
     344             : 
     345             : PIXMAN_EXPORT void
     346           0 : 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           0 :     return_if_fail (image->type == BITS);
     359             : 
     360           0 :     _pixman_image_validate (image);
     361             :     
     362           0 :     if (!pixman_trapezoid_valid (trap))
     363           0 :         return;
     364             : 
     365           0 :     height = image->bits.height;
     366           0 :     bpp = PIXMAN_FORMAT_BPP (image->bits.format);
     367             : 
     368           0 :     y_off_fixed = pixman_int_to_fixed (y_off);
     369             : 
     370           0 :     t = trap->top + y_off_fixed;
     371           0 :     if (t < 0)
     372           0 :         t = 0;
     373           0 :     t = pixman_sample_ceil_y (t, bpp);
     374             : 
     375           0 :     b = trap->bottom + y_off_fixed;
     376           0 :     if (pixman_fixed_to_int (b) >= height)
     377           0 :         b = pixman_int_to_fixed (height) - 1;
     378           0 :     b = pixman_sample_floor_y (b, bpp);
     379             :     
     380           0 :     if (b >= t)
     381             :     {
     382             :         /* initialize edge walkers */
     383           0 :         pixman_line_fixed_edge_init (&l, bpp, t, &trap->left, x_off, y_off);
     384           0 :         pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off);
     385             : 
     386           0 :         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           0 : 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           0 :     if (!zero_src_has_no_effect [op])
     419             :     {
     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             :     }
     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             :     {
     434           0 :         const pixman_trapezoid_t *trap = &(traps[i]);
     435             :         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             : #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           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             :     }
     464             :         
     465           0 :     if (box->x1 >= box->x2 || box->y1 >= box->y2)
     466           0 :         return FALSE;
     467             : 
     468           0 :     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           0 : 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           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             :     {
     507           0 :         for (i = 0; i < n_traps; ++i)
     508             :         {
     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             :         }
     516             :     }
     517             :     else
     518             :     {
     519             :         pixman_image_t *tmp;
     520             :         pixman_box32_t box;
     521             :         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             :         {
     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             :         }
     539             :         
     540           0 :         pixman_image_composite (op, src, tmp, dst,
     541           0 :                                 x_src + box.x1, y_src + box.y1,
     542             :                                 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             :     }
     548             : }
     549             : 
     550             : static int
     551           0 : greater_y (const pixman_point_fixed_t *a, const pixman_point_fixed_t *b)
     552             : {
     553           0 :     if (a->y == b->y)
     554           0 :         return a->x > b->x;
     555           0 :     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           0 : 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           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             : }
     577             : 
     578             : static void
     579           0 : 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           0 :     top = &tri->p1;
     584           0 :     left = &tri->p2;
     585           0 :     right = &tri->p3;
     586             : 
     587           0 :     if (greater_y (top, left))
     588             :     {
     589           0 :         tmp = left;
     590           0 :         left = top;
     591           0 :         top = tmp;
     592             :     }
     593             : 
     594           0 :     if (greater_y (top, right))
     595             :     {
     596           0 :         tmp = right;
     597           0 :         right = top;
     598           0 :         top = tmp;
     599             :     }
     600             : 
     601           0 :     if (clockwise (top, right, left))
     602             :     {
     603           0 :         tmp = right;
     604           0 :         right = left;
     605           0 :         left = tmp;
     606             :     }
     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             :     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             :     {
     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             :     }
     643             :     else
     644             :     {
     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             :     }
     650           0 : }
     651             : 
     652             : static pixman_trapezoid_t *
     653           0 : convert_triangles (int n_tris, const pixman_triangle_t *tris)
     654             : {
     655             :     pixman_trapezoid_t *traps;
     656             :     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             : }
     670             : 
     671             : PIXMAN_EXPORT void
     672           0 : 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           0 :     if ((traps = convert_triangles (n_tris, tris)))
     686             :     {
     687           0 :         pixman_composite_trapezoids (op, src, dst, mask_format,
     688             :                                      x_src, y_src, x_dst, y_dst,
     689             :                                      n_tris * 2, traps);
     690             :         
     691           0 :         free (traps);
     692             :     }
     693           0 : }
     694             : 
     695             : PIXMAN_EXPORT void
     696           0 : 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           0 :     if ((traps = convert_triangles (n_tris, tris)))
     705             :     {
     706           0 :         pixman_add_trapezoids (image, x_off, y_off,
     707             :                                n_tris * 2, traps);
     708             : 
     709           0 :         free (traps);
     710             :     }
     711           0 : }

Generated by: LCOV version 1.13