Fix bug in rasterizeEdges() where the stride was treated as if in
[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 static void
29 rasterizeEdges (pixman_image_t  *image,
30                 pixman_edge_t   *l,
31                 pixman_edge_t   *r,
32                 pixman_fixed_t          t,
33                 pixman_fixed_t          b)
34 {
35     pixman_fixed_t  y = t;
36     uint32_t  *line;
37     uint32_t *buf = (image)->bits.bits;
38     uint32_t stride = (image)->bits.rowstride;
39     uint32_t width = (image)->bits.width;
40     
41     line = buf + pixman_fixed_to_int (y) * stride;
42     
43     for (;;)
44     {
45         pixman_fixed_t  lx;
46         pixman_fixed_t      rx;
47         int     lxi;
48         int rxi;
49         
50         /* clip X */
51         lx = l->x;
52         if (lx < 0)
53             lx = 0;
54         rx = r->x;
55         if (pixman_fixed_to_int (rx) >= width)
56             rx = pixman_int_to_fixed (width);
57         
58         /* Skip empty (or backwards) sections */
59         if (rx > lx)
60         {
61             
62             /* Find pixel bounds for span */
63             lxi = pixman_fixed_to_int (lx);
64             rxi = pixman_fixed_to_int (rx);
65             
66 #if N_BITS == 1
67             {
68                 uint32_t  *a = line;
69                 uint32_t  startmask;
70                 uint32_t  endmask;
71                 int         nmiddle;
72                 int         width = rxi - lxi;
73                 int         x = lxi;
74                 
75                 a += x >> FB_SHIFT;
76                 x &= FB_MASK;
77                 
78                 FbMaskBits (x, width, startmask, nmiddle, endmask);
79                 ACCESS_MEM(
80                     if (startmask) {
81                         WRITE(a, READ(a) | startmask);
82                         a++;
83                     }
84                     while (nmiddle--)
85                         WRITE(a++, FB_ALLONES);
86                     if (endmask)
87                         WRITE(a, READ(a) | endmask);
88                     );
89             }
90 #else
91             {
92                 DefineAlpha(line,lxi);
93                 int         lxs;
94                 int     rxs;
95                 
96                 /* Sample coverage for edge pixels */
97                 lxs = RenderSamplesX (lx, N_BITS);
98                 rxs = RenderSamplesX (rx, N_BITS);
99                 
100                 /* Add coverage across row */
101                 ACCESS_MEM(
102                     if (lxi == rxi)
103                     {
104                         AddAlpha (rxs - lxs);
105                     }
106                     else
107                     {
108                         int     xi;
109                         
110                         AddAlpha (N_X_FRAC(N_BITS) - lxs);
111                         StepAlpha;
112                         for (xi = lxi + 1; xi < rxi; xi++)
113                         {
114                             AddAlpha (N_X_FRAC(N_BITS));
115                             StepAlpha;
116                         }
117                         /* Do not add in a 0 alpha here. This check is necessary
118                          * to avoid a buffer overrun when rx is exactly on a pixel
119                          * boundary.
120                          */
121                         if (rxs != 0)
122                             AddAlpha (rxs);
123                     });
124             }
125 #endif
126         }
127         
128         if (y == b)
129             break;
130         
131 #if N_BITS > 1
132         if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS))
133         {
134             RenderEdgeStepSmall (l);
135             RenderEdgeStepSmall (r);
136             y += STEP_Y_SMALL(N_BITS);
137         }
138         else
139 #endif
140         {
141             RenderEdgeStepBig (l);
142             RenderEdgeStepBig (r);
143             y += STEP_Y_BIG(N_BITS);
144             line += stride;
145         }
146     }
147 }
148
149 #undef rasterizeSpan