• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef rasterize_span
24 #endif
25 
26 static void
RASTERIZE_EDGES(pixman_image_t * image,pixman_edge_t * l,pixman_edge_t * r,pixman_fixed_t t,pixman_fixed_t b)27 RASTERIZE_EDGES (pixman_image_t  *image,
28 		pixman_edge_t	*l,
29 		pixman_edge_t	*r,
30 		pixman_fixed_t		t,
31 		pixman_fixed_t		b)
32 {
33     pixman_fixed_t  y = t;
34     uint32_t  *line;
35     uint32_t *buf = (image)->bits.bits;
36     int stride = (image)->bits.rowstride;
37     int width = (image)->bits.width;
38 
39     line = buf + pixman_fixed_to_int (y) * stride;
40 
41     for (;;)
42     {
43 	pixman_fixed_t	lx;
44 	pixman_fixed_t      rx;
45 	int	lxi;
46 	int rxi;
47 
48 	lx = l->x;
49 	rx = r->x;
50 #if N_BITS == 1
51 	/* For the non-antialiased case, round the coordinates up, in effect
52 	 * sampling just slightly to the left of the pixel. This is so that
53 	 * when the sample point lies exactly on the line, we round towards
54 	 * north-west.
55 	 *
56 	 * (The AA case does a similar  adjustment in RENDER_SAMPLES_X)
57 	 */
58 	lx += X_FRAC_FIRST(1) - pixman_fixed_e;
59 	rx += X_FRAC_FIRST(1) - pixman_fixed_e;
60 #endif
61 	/* clip X */
62 	if (lx < 0)
63 	    lx = 0;
64 	if (pixman_fixed_to_int (rx) >= width)
65 #if N_BITS == 1
66 	    rx = pixman_int_to_fixed (width);
67 #else
68 	    /* Use the last pixel of the scanline, covered 100%.
69 	     * We can't use the first pixel following the scanline,
70 	     * because accessing it could result in a buffer overrun.
71 	     */
72 	    rx = pixman_int_to_fixed (width) - 1;
73 #endif
74 
75 	/* Skip empty (or backwards) sections */
76 	if (rx > lx)
77 	{
78 
79 	    /* Find pixel bounds for span */
80 	    lxi = pixman_fixed_to_int (lx);
81 	    rxi = pixman_fixed_to_int (rx);
82 
83 #if N_BITS == 1
84 	    {
85 
86 #define LEFT_MASK(x)							\
87 		(((x) & 0x1f) ?						\
88 		 SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0)
89 #define RIGHT_MASK(x)							\
90 		(((32 - (x)) & 0x1f) ?					\
91 		 SCREEN_SHIFT_LEFT (0xffffffff, (32 - (x)) & 0x1f) : 0)
92 
93 #define MASK_BITS(x,w,l,n,r) {						\
94 		    n = (w);						\
95 		    r = RIGHT_MASK ((x) + n);				\
96 		    l = LEFT_MASK (x);					\
97 		    if (l) {						\
98 			n -= 32 - ((x) & 0x1f);				\
99 			if (n < 0) {					\
100 			    n = 0;					\
101 			    l &= r;					\
102 			    r = 0;					\
103 			}						\
104 		    }							\
105 		    n >>= 5;						\
106 		}
107 
108 		uint32_t  *a = line;
109 		uint32_t  startmask;
110 		uint32_t  endmask;
111 		int	    nmiddle;
112 		int	    width = rxi - lxi;
113 		int	    x = lxi;
114 
115 		a += x >> 5;
116 		x &= 0x1f;
117 
118 		MASK_BITS (x, width, startmask, nmiddle, endmask);
119 
120 		if (startmask) {
121 		    WRITE(image, a, READ(image, a) | startmask);
122 		    a++;
123 		}
124 		while (nmiddle--)
125 		    WRITE(image, a++, 0xffffffff);
126 		if (endmask)
127 		    WRITE(image, a, READ(image, a) | endmask);
128 	    }
129 #else
130 	    {
131 		DEFINE_ALPHA(line,lxi);
132 		int	    lxs;
133 		int     rxs;
134 
135 		/* Sample coverage for edge pixels */
136 		lxs = RENDER_SAMPLES_X (lx, N_BITS);
137 		rxs = RENDER_SAMPLES_X (rx, N_BITS);
138 
139 		/* Add coverage across row */
140 		if (lxi == rxi)
141 		{
142 		    ADD_ALPHA (rxs - lxs);
143 		}
144 		else
145 		{
146 		    int	xi;
147 
148 		    ADD_ALPHA (N_X_FRAC(N_BITS) - lxs);
149 		    STEP_ALPHA;
150 		    for (xi = lxi + 1; xi < rxi; xi++)
151 		    {
152 			ADD_ALPHA (N_X_FRAC(N_BITS));
153 			STEP_ALPHA;
154 		    }
155 		    ADD_ALPHA (rxs);
156 		}
157 	    }
158 #endif
159 	}
160 
161 	if (y == b)
162 	    break;
163 
164 #if N_BITS > 1
165 	if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS))
166 	{
167 	    RENDER_EDGE_STEP_SMALL (l);
168 	    RENDER_EDGE_STEP_SMALL (r);
169 	    y += STEP_Y_SMALL(N_BITS);
170 	}
171 	else
172 #endif
173 	{
174 	    RENDER_EDGE_STEP_BIG (l);
175 	    RENDER_EDGE_STEP_BIG (r);
176 	    y += STEP_Y_BIG(N_BITS);
177 	    line += stride;
178 	}
179     }
180 }
181 
182 #undef rasterize_span
183