LCOV - code coverage report
Current view: directory - gfx/cairo/libpixman/src - pixman-trap.c (source / functions) Found Hit Coverage
Test: app.info Lines: 248 0 0.0 %
Date: 2012-06-02 Functions: 16 0 0.0 %

       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 * 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                 :                   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                 : /*
     391                 :  * pixman_composite_trapezoids()
     392                 :  *
     393                 :  * All the trapezoids are conceptually rendered to an infinitely big image.
     394                 :  * The (0, 0) coordinates of this image are then aligned with the (x, y)
     395                 :  * coordinates of the source image, and then both images are aligned with
     396                 :  * the (x, y) coordinates of the destination. Then, in principle, compositing
     397                 :  * of these three images takes place across the entire destination.
     398                 :  *
     399                 :  * FIXME: However, there is currently a bug, where we restrict this compositing
     400                 :  * to the bounding box of the trapezoids. This is incorrect for operators such
     401                 :  * as SRC and IN where blank source pixels do have an effect on the destination.
     402                 :  */
     403                 : PIXMAN_EXPORT void
     404               0 : pixman_composite_trapezoids (pixman_op_t                op,
     405                 :                              pixman_image_t *           src,
     406                 :                              pixman_image_t *           dst,
     407                 :                              pixman_format_code_t       mask_format,
     408                 :                              int                        x_src,
     409                 :                              int                        y_src,
     410                 :                              int                        x_dst,
     411                 :                              int                        y_dst,
     412                 :                              int                        n_traps,
     413                 :                              const pixman_trapezoid_t * traps)
     414                 : {
     415                 :     int i;
     416                 : 
     417               0 :     if (n_traps <= 0)
     418               0 :         return;
     419                 : 
     420               0 :     _pixman_image_validate (src);
     421               0 :     _pixman_image_validate (dst);
     422                 : 
     423               0 :     if (op == PIXMAN_OP_ADD &&
     424               0 :         (src->common.flags & FAST_PATH_IS_OPAQUE)                &&
     425               0 :         (mask_format == dst->common.extended_format_code)    &&
     426               0 :         !(dst->common.have_clip_region))
     427                 :     {
     428               0 :         for (i = 0; i < n_traps; ++i)
     429                 :         {
     430               0 :             const pixman_trapezoid_t *trap = &(traps[i]);
     431                 :             
     432               0 :             if (!pixman_trapezoid_valid (trap))
     433               0 :                 continue;
     434                 :             
     435               0 :             pixman_rasterize_trapezoid (dst, trap, x_dst, y_dst);
     436                 :         }
     437                 :     }
     438                 :     else
     439                 :     {
     440                 :         pixman_image_t *tmp;
     441                 :         pixman_box32_t box;
     442                 :         
     443               0 :         box.x1 = INT32_MAX;
     444               0 :         box.y1 = INT32_MAX;
     445               0 :         box.x2 = INT32_MIN;
     446               0 :         box.y2 = INT32_MIN;
     447                 :         
     448               0 :         for (i = 0; i < n_traps; ++i)
     449                 :         {
     450               0 :             const pixman_trapezoid_t *trap = &(traps[i]);
     451                 :             int y1, y2;
     452                 :             
     453               0 :             if (!pixman_trapezoid_valid (trap))
     454               0 :                 continue;
     455                 :             
     456               0 :             y1 = pixman_fixed_to_int (trap->top);
     457               0 :             if (y1 < box.y1)
     458               0 :                 box.y1 = y1;
     459                 :             
     460               0 :             y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom));
     461               0 :             if (y2 > box.y2)
     462               0 :                 box.y2 = y2;
     463                 :             
     464                 : #define EXTEND_MIN(x)                                                   \
     465                 :             if (pixman_fixed_to_int ((x)) < box.x1)                  \
     466                 :                 box.x1 = pixman_fixed_to_int ((x));
     467                 : #define EXTEND_MAX(x)                                                   \
     468                 :             if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box.x2)      \
     469                 :                 box.x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x)));
     470                 :             
     471                 : #define EXTEND(x)                                                       \
     472                 :             EXTEND_MIN(x);                                              \
     473                 :             EXTEND_MAX(x);
     474                 :             
     475               0 :             EXTEND(trap->left.p1.x);
     476               0 :             EXTEND(trap->left.p2.x);
     477               0 :             EXTEND(trap->right.p1.x);
     478               0 :             EXTEND(trap->right.p2.x);
     479                 :         }
     480                 :         
     481               0 :         if (box.x1 >= box.x2 || box.y1 >= box.y2)
     482               0 :             return;
     483                 :         
     484               0 :         tmp = pixman_image_create_bits (
     485               0 :             mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1);
     486                 :         
     487               0 :         for (i = 0; i < n_traps; ++i)
     488                 :         {
     489               0 :             const pixman_trapezoid_t *trap = &(traps[i]);
     490                 :             
     491               0 :             if (!pixman_trapezoid_valid (trap))
     492               0 :                 continue;
     493                 :             
     494               0 :             pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1);
     495                 :         }
     496                 :         
     497               0 :         pixman_image_composite (op, src, tmp, dst,
     498               0 :                                 x_src + box.x1, y_src + box.y1,
     499                 :                                 0, 0,
     500               0 :                                 x_dst + box.x1, y_dst + box.y1,
     501               0 :                                 box.x2 - box.x1, box.y2 - box.y1);
     502                 :         
     503               0 :         pixman_image_unref (tmp);
     504                 :     }
     505                 : }
     506                 : 
     507                 : static int
     508               0 : greater_y (const pixman_point_fixed_t *a, const pixman_point_fixed_t *b)
     509                 : {
     510               0 :     if (a->y == b->y)
     511               0 :         return a->x > b->x;
     512               0 :     return a->y > b->y;
     513                 : }
     514                 : 
     515                 : /*
     516                 :  * Note that the definition of this function is a bit odd because
     517                 :  * of the X coordinate space (y increasing downwards).
     518                 :  */
     519                 : static int
     520               0 : clockwise (const pixman_point_fixed_t *ref,
     521                 :            const pixman_point_fixed_t *a,
     522                 :            const pixman_point_fixed_t *b)
     523                 : {
     524                 :     pixman_point_fixed_t        ad, bd;
     525                 : 
     526               0 :     ad.x = a->x - ref->x;
     527               0 :     ad.y = a->y - ref->y;
     528               0 :     bd.x = b->x - ref->x;
     529               0 :     bd.y = b->y - ref->y;
     530                 : 
     531               0 :     return ((pixman_fixed_32_32_t) bd.y * ad.x -
     532               0 :             (pixman_fixed_32_32_t) ad.y * bd.x) < 0;
     533                 : }
     534                 : 
     535                 : static void
     536               0 : triangle_to_trapezoids (const pixman_triangle_t *tri, pixman_trapezoid_t *traps)
     537                 : {
     538                 :     const pixman_point_fixed_t *top, *left, *right, *tmp;
     539                 : 
     540               0 :     top = &tri->p1;
     541               0 :     left = &tri->p2;
     542               0 :     right = &tri->p3;
     543                 : 
     544               0 :     if (greater_y (top, left))
     545                 :     {
     546               0 :         tmp = left;
     547               0 :         left = top;
     548               0 :         top = tmp;
     549                 :     }
     550                 : 
     551               0 :     if (greater_y (top, right))
     552                 :     {
     553               0 :         tmp = right;
     554               0 :         right = top;
     555               0 :         top = tmp;
     556                 :     }
     557                 : 
     558               0 :     if (clockwise (top, right, left))
     559                 :     {
     560               0 :         tmp = right;
     561               0 :         right = left;
     562               0 :         left = tmp;
     563                 :     }
     564                 :     
     565                 :     /*
     566                 :      * Two cases:
     567                 :      *
     568                 :      *          +               +
     569                 :      *         / \             / \
     570                 :      *        /   \           /   \
     571                 :      *       /     +         +     \
     572                 :      *      /    --           --    \
     573                 :      *     /   --               --   \
     574                 :      *    / ---                   --- \
     575                 :      *   +--                         --+
     576                 :      */
     577                 : 
     578               0 :     traps->top = top->y;
     579               0 :     traps->left.p1 = *top;
     580               0 :     traps->left.p2 = *left;
     581               0 :     traps->right.p1 = *top;
     582               0 :     traps->right.p2 = *right;
     583                 : 
     584               0 :     if (right->y < left->y)
     585               0 :         traps->bottom = right->y;
     586                 :     else
     587               0 :         traps->bottom = left->y;
     588                 : 
     589               0 :     traps++;
     590                 : 
     591               0 :     *traps = *(traps - 1);
     592                 :     
     593               0 :     if (right->y < left->y)
     594                 :     {
     595               0 :         traps->top = right->y;
     596               0 :         traps->bottom = left->y;
     597               0 :         traps->right.p1 = *right;
     598               0 :         traps->right.p2 = *left;
     599                 :     }
     600                 :     else
     601                 :     {
     602               0 :         traps->top = left->y;
     603               0 :         traps->bottom = right->y;
     604               0 :         traps->left.p1 = *left;
     605               0 :         traps->left.p2 = *right;
     606                 :     }
     607               0 : }
     608                 : 
     609                 : static pixman_trapezoid_t *
     610               0 : convert_triangles (int n_tris, const pixman_triangle_t *tris)
     611                 : {
     612                 :     pixman_trapezoid_t *traps;
     613                 :     int i;
     614                 : 
     615               0 :     if (n_tris <= 0)
     616               0 :         return NULL;
     617                 :     
     618               0 :     traps = pixman_malloc_ab (n_tris, 2 * sizeof (pixman_trapezoid_t));
     619               0 :     if (!traps)
     620               0 :         return NULL;
     621                 : 
     622               0 :     for (i = 0; i < n_tris; ++i)
     623               0 :         triangle_to_trapezoids (&(tris[i]), traps + 2 * i);
     624                 : 
     625               0 :     return traps;
     626                 : }
     627                 : 
     628                 : PIXMAN_EXPORT void
     629               0 : pixman_composite_triangles (pixman_op_t                 op,
     630                 :                             pixman_image_t *            src,
     631                 :                             pixman_image_t *            dst,
     632                 :                             pixman_format_code_t        mask_format,
     633                 :                             int                         x_src,
     634                 :                             int                         y_src,
     635                 :                             int                         x_dst,
     636                 :                             int                         y_dst,
     637                 :                             int                         n_tris,
     638                 :                             const pixman_triangle_t *   tris)
     639                 : {
     640                 :     pixman_trapezoid_t *traps;
     641                 : 
     642               0 :     if ((traps = convert_triangles (n_tris, tris)))
     643                 :     {
     644               0 :         pixman_composite_trapezoids (op, src, dst, mask_format,
     645                 :                                      x_src, y_src, x_dst, y_dst,
     646                 :                                      n_tris * 2, traps);
     647                 :         
     648               0 :         free (traps);
     649                 :     }
     650               0 : }
     651                 : 
     652                 : PIXMAN_EXPORT void
     653               0 : pixman_add_triangles (pixman_image_t          *image,
     654                 :                       int32_t                  x_off,
     655                 :                       int32_t                  y_off,
     656                 :                       int                      n_tris,
     657                 :                       const pixman_triangle_t *tris)
     658                 : {
     659                 :     pixman_trapezoid_t *traps;
     660                 : 
     661               0 :     if ((traps = convert_triangles (n_tris, tris)))
     662                 :     {
     663               0 :         pixman_add_trapezoids (image, x_off, y_off,
     664                 :                                n_tris * 2, traps);
     665                 : 
     666               0 :         free (traps);
     667                 :     }
     668               0 : }

Generated by: LCOV version 1.7