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

       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                 :     {
     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                 :             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               0 :     }
     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                 :     
     378               0 :     if (image->bits.read_func || image->bits.write_func)
     379               0 :         pixman_rasterize_edges_accessors (image, l, r, t, b);
     380                 :     else
     381               0 :         pixman_rasterize_edges_no_accessors (image, l, r, t, b);
     382                 : }
     383                 : 
     384                 : #endif

Generated by: LCOV version 1.7