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

          Line data    Source code
       1             : /*
       2             :  * Copyright © 2004 Keith Packard
       3             :  *
       4             :  * Permission to use, copy, modify, distribute, and sell this software and its
       5             :  * documentation for any purpose is hereby granted without fee, provided that
       6             :  * the above copyright notice appear in all copies and that both that
       7             :  * copyright notice and this permission notice appear in supporting
       8             :  * documentation, and that the name of Keith Packard not be used in
       9             :  * advertising or publicity pertaining to distribution of the software without
      10             :  * specific, written prior permission.  Keith Packard makes no
      11             :  * representations about the suitability of this software for any purpose.  It
      12             :  * is provided "as is" without express or implied warranty.
      13             :  *
      14             :  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
      15             :  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
      16             :  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
      17             :  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
      18             :  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
      19             :  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      20             :  * PERFORMANCE OF THIS SOFTWARE.
      21             :  */
      22             : 
      23             : #ifdef HAVE_CONFIG_H
      24             : #include <config.h>
      25             : #endif
      26             : 
      27             : #include <string.h>
      28             : 
      29             : #include "pixman-private.h"
      30             : #include "pixman-accessor.h"
      31             : 
      32             : /*
      33             :  * Step across a small sample grid gap
      34             :  */
      35             : #define RENDER_EDGE_STEP_SMALL(edge)                                    \
      36             :     {                                                                   \
      37             :         edge->x += edge->stepx_small;                                     \
      38             :         edge->e += edge->dx_small;                                        \
      39             :         if (edge->e > 0)                                          \
      40             :         {                                                               \
      41             :             edge->e -= edge->dy;                                  \
      42             :             edge->x += edge->signdx;                                      \
      43             :         }                                                               \
      44             :     }
      45             : 
      46             : /*
      47             :  * Step across a large sample grid gap
      48             :  */
      49             : #define RENDER_EDGE_STEP_BIG(edge)                                      \
      50             :     {                                                                   \
      51             :         edge->x += edge->stepx_big;                                       \
      52             :         edge->e += edge->dx_big;                                  \
      53             :         if (edge->e > 0)                                          \
      54             :         {                                                               \
      55             :             edge->e -= edge->dy;                                  \
      56             :             edge->x += edge->signdx;                                      \
      57             :         }                                                               \
      58             :     }
      59             : 
      60             : #ifdef PIXMAN_FB_ACCESSORS
      61             : #define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_accessors
      62             : #else
      63             : #define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_no_accessors
      64             : #endif
      65             : 
      66             : /*
      67             :  * 4 bit alpha
      68             :  */
      69             : 
      70             : #define N_BITS  4
      71             : #define RASTERIZE_EDGES rasterize_edges_4
      72             : 
      73             : #ifndef WORDS_BIGENDIAN
      74             : #define SHIFT_4(o)      ((o) << 2)
      75             : #else
      76             : #define SHIFT_4(o)      ((1 - (o)) << 2)
      77             : #endif
      78             : 
      79             : #define GET_4(x, o)      (((x) >> SHIFT_4 (o)) & 0xf)
      80             : #define PUT_4(x, o, v)                                                  \
      81             :     (((x) & ~(0xf << SHIFT_4 (o))) | (((v) & 0xf) << SHIFT_4 (o)))
      82             : 
      83             : #define DEFINE_ALPHA(line, x)                                           \
      84             :     uint8_t   *__ap = (uint8_t *) line + ((x) >> 1);                      \
      85             :     int __ao = (x) & 1
      86             : 
      87             : #define STEP_ALPHA      ((__ap += __ao), (__ao ^= 1))
      88             : 
      89             : #define ADD_ALPHA(a)                                                    \
      90             :     {                                                                   \
      91             :         uint8_t __o = READ (image, __ap);                               \
      92             :         uint8_t __a = (a) + GET_4 (__o, __ao);                          \
      93             :         WRITE (image, __ap, PUT_4 (__o, __ao, __a | (0 - ((__a) >> 4)))); \
      94             :     }
      95             : 
      96             : #include "pixman-edge-imp.h"
      97             : 
      98             : #undef ADD_ALPHA
      99             : #undef STEP_ALPHA
     100             : #undef DEFINE_ALPHA
     101             : #undef RASTERIZE_EDGES
     102             : #undef N_BITS
     103             : 
     104             : 
     105             : /*
     106             :  * 1 bit alpha
     107             :  */
     108             : 
     109             : #define N_BITS 1
     110             : #define RASTERIZE_EDGES rasterize_edges_1
     111             : 
     112             : #include "pixman-edge-imp.h"
     113             : 
     114             : #undef RASTERIZE_EDGES
     115             : #undef N_BITS
     116             : 
     117             : /*
     118             :  * 8 bit alpha
     119             :  */
     120             : 
     121             : static force_inline uint8_t
     122             : clip255 (int x)
     123             : {
     124           0 :     if (x > 255)
     125           0 :         return 255;
     126             : 
     127           0 :     return x;
     128             : }
     129             : 
     130             : #define ADD_SATURATE_8(buf, val, length)                                \
     131             :     do                                                                  \
     132             :     {                                                                   \
     133             :         int i__ = (length);                                             \
     134             :         uint8_t *buf__ = (buf);                                         \
     135             :         int val__ = (val);                                              \
     136             :                                                                         \
     137             :         while (i__--)                                                   \
     138             :         {                                                               \
     139             :             WRITE (image, (buf__), clip255 (READ (image, (buf__)) + (val__))); \
     140             :             (buf__)++;                                                  \
     141             :         }                                                               \
     142             :     } while (0)
     143             : 
     144             : /*
     145             :  * We want to detect the case where we add the same value to a long
     146             :  * span of pixels.  The triangles on the end are filled in while we
     147             :  * count how many sub-pixel scanlines contribute to the middle section.
     148             :  *
     149             :  *                 +--------------------------+
     150             :  *  fill_height =|   \                      /
     151             :  *                     +------------------+
     152             :  *                      |================|
     153             :  *                   fill_start       fill_end
     154             :  */
     155             : static void
     156           0 : rasterize_edges_8 (pixman_image_t *image,
     157             :                    pixman_edge_t * l,
     158             :                    pixman_edge_t * r,
     159             :                    pixman_fixed_t  t,
     160             :                    pixman_fixed_t  b)
     161             : {
     162           0 :     pixman_fixed_t y = t;
     163             :     uint32_t  *line;
     164           0 :     int fill_start = -1, fill_end = -1;
     165           0 :     int fill_size = 0;
     166           0 :     uint32_t *buf = (image)->bits.bits;
     167           0 :     int stride = (image)->bits.rowstride;
     168           0 :     int width = (image)->bits.width;
     169             : 
     170           0 :     line = buf + pixman_fixed_to_int (y) * stride;
     171             : 
     172             :     for (;;)
     173           0 :     {
     174           0 :         uint8_t *ap = (uint8_t *) line;
     175             :         pixman_fixed_t lx, rx;
     176             :         int lxi, rxi;
     177             : 
     178             :         /* clip X */
     179           0 :         lx = l->x;
     180           0 :         if (lx < 0)
     181           0 :             lx = 0;
     182             : 
     183           0 :         rx = r->x;
     184             : 
     185           0 :         if (pixman_fixed_to_int (rx) >= width)
     186             :         {
     187             :             /* Use the last pixel of the scanline, covered 100%.
     188             :              * We can't use the first pixel following the scanline,
     189             :              * because accessing it could result in a buffer overrun.
     190             :              */
     191           0 :             rx = pixman_int_to_fixed (width) - 1;
     192             :         }
     193             : 
     194             :         /* Skip empty (or backwards) sections */
     195           0 :         if (rx > lx)
     196             :         {
     197             :             int lxs, rxs;
     198             : 
     199             :             /* Find pixel bounds for span. */
     200           0 :             lxi = pixman_fixed_to_int (lx);
     201           0 :             rxi = pixman_fixed_to_int (rx);
     202             : 
     203             :             /* Sample coverage for edge pixels */
     204           0 :             lxs = RENDER_SAMPLES_X (lx, 8);
     205           0 :             rxs = RENDER_SAMPLES_X (rx, 8);
     206             : 
     207             :             /* Add coverage across row */
     208           0 :             if (lxi == rxi)
     209             :             {
     210           0 :                 WRITE (image, ap + lxi,
     211             :                        clip255 (READ (image, ap + lxi) + rxs - lxs));
     212             :             }
     213             :             else
     214             :             {
     215           0 :                 WRITE (image, ap + lxi,
     216             :                        clip255 (READ (image, ap + lxi) + N_X_FRAC (8) - lxs));
     217             : 
     218             :                 /* Move forward so that lxi/rxi is the pixel span */
     219           0 :                 lxi++;
     220             : 
     221             :                 /* Don't bother trying to optimize the fill unless
     222             :                  * the span is longer than 4 pixels. */
     223           0 :                 if (rxi - lxi > 4)
     224             :                 {
     225           0 :                     if (fill_start < 0)
     226             :                     {
     227           0 :                         fill_start = lxi;
     228           0 :                         fill_end = rxi;
     229           0 :                         fill_size++;
     230             :                     }
     231             :                     else
     232             :                     {
     233           0 :                         if (lxi >= fill_end || rxi < fill_start)
     234             :                         {
     235             :                             /* We're beyond what we saved, just fill it */
     236           0 :                             ADD_SATURATE_8 (ap + fill_start,
     237             :                                             fill_size * N_X_FRAC (8),
     238             :                                             fill_end - fill_start);
     239           0 :                             fill_start = lxi;
     240           0 :                             fill_end = rxi;
     241           0 :                             fill_size = 1;
     242             :                         }
     243             :                         else
     244             :                         {
     245             :                             /* Update fill_start */
     246           0 :                             if (lxi > fill_start)
     247             :                             {
     248           0 :                                 ADD_SATURATE_8 (ap + fill_start,
     249             :                                                 fill_size * N_X_FRAC (8),
     250             :                                                 lxi - fill_start);
     251           0 :                                 fill_start = lxi;
     252             :                             }
     253           0 :                             else if (lxi < fill_start)
     254             :                             {
     255           0 :                                 ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8),
     256             :                                                 fill_start - lxi);
     257             :                             }
     258             : 
     259             :                             /* Update fill_end */
     260           0 :                             if (rxi < fill_end)
     261             :                             {
     262           0 :                                 ADD_SATURATE_8 (ap + rxi,
     263             :                                                 fill_size * N_X_FRAC (8),
     264             :                                                 fill_end - rxi);
     265           0 :                                 fill_end = rxi;
     266             :                             }
     267           0 :                             else if (fill_end < rxi)
     268             :                             {
     269           0 :                                 ADD_SATURATE_8 (ap + fill_end,
     270             :                                                 N_X_FRAC (8),
     271             :                                                 rxi - fill_end);
     272             :                             }
     273           0 :                             fill_size++;
     274             :                         }
     275             :                     }
     276             :                 }
     277             :                 else
     278             :                 {
     279           0 :                     ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8), rxi - lxi);
     280             :                 }
     281             : 
     282           0 :                 WRITE (image, ap + rxi, clip255 (READ (image, ap + rxi) + rxs));
     283             :             }
     284             :         }
     285             : 
     286           0 :         if (y == b)
     287             :         {
     288             :             /* We're done, make sure we clean up any remaining fill. */
     289           0 :             if (fill_start != fill_end)
     290             :             {
     291           0 :                 if (fill_size == N_Y_FRAC (8))
     292             :                 {
     293           0 :                     MEMSET_WRAPPED (image, ap + fill_start,
     294             :                                     0xff, fill_end - fill_start);
     295             :                 }
     296             :                 else
     297             :                 {
     298           0 :                     ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
     299             :                                     fill_end - fill_start);
     300             :                 }
     301             :             }
     302           0 :             break;
     303             :         }
     304             : 
     305           0 :         if (pixman_fixed_frac (y) != Y_FRAC_LAST (8))
     306             :         {
     307           0 :             RENDER_EDGE_STEP_SMALL (l);
     308           0 :             RENDER_EDGE_STEP_SMALL (r);
     309           0 :             y += STEP_Y_SMALL (8);
     310             :         }
     311             :         else
     312             :         {
     313           0 :             RENDER_EDGE_STEP_BIG (l);
     314           0 :             RENDER_EDGE_STEP_BIG (r);
     315           0 :             y += STEP_Y_BIG (8);
     316           0 :             if (fill_start != fill_end)
     317             :             {
     318           0 :                 if (fill_size == N_Y_FRAC (8))
     319             :                 {
     320           0 :                     MEMSET_WRAPPED (image, ap + fill_start,
     321             :                                     0xff, fill_end - fill_start);
     322             :                 }
     323             :                 else
     324             :                 {
     325           0 :                     ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
     326             :                                     fill_end - fill_start);
     327             :                 }
     328             :                 
     329           0 :                 fill_start = fill_end = -1;
     330           0 :                 fill_size = 0;
     331             :             }
     332             :             
     333           0 :             line += stride;
     334             :         }
     335             :     }
     336           0 : }
     337             : 
     338             : #ifndef PIXMAN_FB_ACCESSORS
     339             : static
     340             : #endif
     341             : void
     342           0 : PIXMAN_RASTERIZE_EDGES (pixman_image_t *image,
     343             :                         pixman_edge_t * l,
     344             :                         pixman_edge_t * r,
     345             :                         pixman_fixed_t  t,
     346             :                         pixman_fixed_t  b)
     347             : {
     348           0 :     switch (PIXMAN_FORMAT_BPP (image->bits.format))
     349             :     {
     350             :     case 1:
     351           0 :         rasterize_edges_1 (image, l, r, t, b);
     352           0 :         break;
     353             : 
     354             :     case 4:
     355           0 :         rasterize_edges_4 (image, l, r, t, b);
     356           0 :         break;
     357             : 
     358             :     case 8:
     359           0 :         rasterize_edges_8 (image, l, r, t, b);
     360           0 :         break;
     361             : 
     362             :     default:
     363           0 :         break;
     364             :     }
     365           0 : }
     366             : 
     367             : #ifndef PIXMAN_FB_ACCESSORS
     368             : 
     369             : PIXMAN_EXPORT void
     370           0 : pixman_rasterize_edges (pixman_image_t *image,
     371             :                         pixman_edge_t * l,
     372             :                         pixman_edge_t * r,
     373             :                         pixman_fixed_t  t,
     374             :                         pixman_fixed_t  b)
     375             : {
     376           0 :     return_if_fail (image->type == BITS);
     377           0 :     return_if_fail (PIXMAN_FORMAT_TYPE (image->bits.format) == PIXMAN_TYPE_A);
     378             :     
     379           0 :     if (image->bits.read_func || image->bits.write_func)
     380           0 :         pixman_rasterize_edges_accessors (image, l, r, t, b);
     381             :     else
     382           0 :         pixman_rasterize_edges_no_accessors (image, l, r, t, b);
     383             : }
     384             : 
     385             : #endif

Generated by: LCOV version 1.13