Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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
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