Merge branch 'master' of git+ssh://git.freedesktop.org/git/pixman into yuv-porting
[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     int stride = (image)->bits.rowstride;
39     int 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                     if (startmask) {
80                         WRITE(image, a, READ(image, a) | startmask);
81                         a++;
82                     }
83                     while (nmiddle--)
84                         WRITE(image, a++, FB_ALLONES);
85                     if (endmask)
86                         WRITE(image, a, READ(image, a) | endmask);
87             }
88 #else
89             {
90                 DefineAlpha(line,lxi);
91                 int         lxs;
92                 int     rxs;
93
94                 /* Sample coverage for edge pixels */
95                 lxs = RenderSamplesX (lx, N_BITS);
96                 rxs = RenderSamplesX (rx, N_BITS);
97
98                 /* Add coverage across row */
99                 if (lxi == rxi)
100                 {
101                     AddAlpha (rxs - lxs);
102                 }
103                 else
104                 {
105                     int xi;
106
107                     AddAlpha (N_X_FRAC(N_BITS) - lxs);
108                     StepAlpha;
109                     for (xi = lxi + 1; xi < rxi; xi++)
110                     {
111                         AddAlpha (N_X_FRAC(N_BITS));
112                         StepAlpha;
113                     }
114                     /* Do not add in a 0 alpha here. This check is necessary
115                      * to avoid a buffer overrun when rx is exactly on a pixel
116                      * boundary.
117                      */
118                     if (rxs != 0)
119                         AddAlpha (rxs);
120                 }
121             }
122 #endif
123         }
124
125         if (y == b)
126             break;
127
128 #if N_BITS > 1
129         if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS))
130         {
131             RenderEdgeStepSmall (l);
132             RenderEdgeStepSmall (r);
133             y += STEP_Y_SMALL(N_BITS);
134         }
135         else
136 #endif
137         {
138             RenderEdgeStepBig (l);
139             RenderEdgeStepBig (r);
140             y += STEP_Y_BIG(N_BITS);
141             line += stride;
142         }
143     }
144 }
145
146 #undef rasterizeSpan