Add implementation of edge rasterization
[profile/ivi/pixman.git] / pixman / pixman-edge-imp.h
1 /*
2  * $Id$
3  *
4  * Copyright © 2004 Keith Packard
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of Keith Packard not be used in
11  * advertising or publicity pertaining to distribution of the software without
12  * specific, written prior permission.  Keith Packard makes no
13  * representations about the suitability of this software for any purpose.  It
14  * is provided "as is" without express or implied warranty.
15  *
16  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #ifndef rasterizeSpan
26 #endif
27
28 #define GET_IMAGE(image)                        \
29     uint32_t *buf = (image)->bits.bits;         \
30     uint32_t stride = (image)->bits.rowstride;  \
31     uint32_t width = (image)->bits.width;
32
33 static void
34 rasterizeEdges (pixman_image_t  *image,
35                 pixman_edge_t   *l,
36                 pixman_edge_t   *r,
37                 pixman_fixed_t          t,
38                 pixman_fixed_t          b)
39 {
40     pixman_fixed_t  y = t;
41     uint32_t  *line;
42     GET_IMAGE(image);
43     
44     line = buf + pixman_fixed_to_int (y) * (stride / sizeof (uint32_t));
45     
46         for (;;)
47         {
48             pixman_fixed_t      lx;
49             pixman_fixed_t      rx;
50             int lxi;
51             int rxi;
52             
53             /* clip X */
54             lx = l->x;
55             if (lx < 0)
56                 lx = 0;
57             rx = r->x;
58             if (pixman_fixed_to_int (rx) >= width)
59                 rx = pixman_int_to_fixed (width);
60             
61             /* Skip empty (or backwards) sections */
62             if (rx > lx)
63             {
64                 
65                 /* Find pixel bounds for span */
66                 lxi = pixman_fixed_to_int (lx);
67                 rxi = pixman_fixed_to_int (rx);
68                 
69 #if N_BITS == 1
70                 {
71                     uint32_t  *a = line;
72                     uint32_t  startmask;
73                     uint32_t  endmask;
74                     int     nmiddle;
75                     int     width = rxi - lxi;
76                     int     x = lxi;
77                     
78                     a += x >> FB_SHIFT;
79                     x &= FB_MASK;
80                     
81                     ACCESS_MEM(
82                         FbMaskBits (x, width, startmask, nmiddle, endmask);
83                         if (startmask) {
84                             WRITE(a, READ(a) | startmask);
85                             a++;
86                         }
87                         while (nmiddle--)
88                             WRITE(a++, FB_ALLONES);
89                         if (endmask)
90                             WRITE(a, READ(a) | endmask);
91                         );
92                 }
93 #else
94                 {
95                     DefineAlpha(line,lxi);
96                     int     lxs;
97                     int     rxs;
98                     
99                     /* Sample coverage for edge pixels */
100                     lxs = RenderSamplesX (lx, N_BITS);
101                     rxs = RenderSamplesX (rx, N_BITS);
102                     
103                     /* Add coverage across row */
104                     ACCESS_MEM(
105                         if (lxi == rxi)
106                         {
107                             AddAlpha (rxs - lxs);
108                         }
109                         else
110                         {
111                             int xi;
112                             
113                             AddAlpha (N_X_FRAC(N_BITS) - lxs);
114                             StepAlpha;
115                             for (xi = lxi + 1; xi < rxi; xi++)
116                             {
117                                 AddAlpha (N_X_FRAC(N_BITS));
118                                 StepAlpha;
119                             }
120                             /* Do not add in a 0 alpha here. This check is necessary
121                              * to avoid a buffer overrun when rx is exactly on a pixel
122                              * boundary.
123                              */
124                             if (rxs != 0)
125                                 AddAlpha (rxs);
126                         });
127                 }
128 #endif
129             }
130             
131             if (y == b)
132                 break;
133             
134 #if N_BITS > 1
135             if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS))
136             {
137                 RenderEdgeStepSmall (l);
138                 RenderEdgeStepSmall (r);
139                 y += STEP_Y_SMALL(N_BITS);
140             }
141             else
142 #endif
143             {
144                 RenderEdgeStepBig (l);
145                 RenderEdgeStepBig (r);
146                 y += STEP_Y_BIG(N_BITS);
147                 line += stride;
148             }
149         }
150 }
151
152 #undef rasterizeSpan