2 * Copyright © 2004 Keith Packard
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.
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.
23 #ifndef rasterize_span
27 RASTERIZE_EDGES (pixman_image_t
*image
,
35 uint32_t *buf
= (image
)->bits
.bits
;
36 int stride
= (image
)->bits
.rowstride
;
37 int width
= (image
)->bits
.width
;
39 line
= buf
+ pixman_fixed_to_int (y
) * stride
;
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
56 * (The AA case does a similar adjustment in RENDER_SAMPLES_X)
58 lx
+= X_FRAC_FIRST(1) - pixman_fixed_e
;
59 rx
+= X_FRAC_FIRST(1) - pixman_fixed_e
;
64 if (pixman_fixed_to_int (rx
) >= width
)
66 rx
= pixman_int_to_fixed (width
);
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.
72 rx
= pixman_int_to_fixed (width
) - 1;
75 /* Skip empty (or backwards) sections */
79 /* Find pixel bounds for span */
80 lxi
= pixman_fixed_to_int (lx
);
81 rxi
= pixman_fixed_to_int (rx
);
86 #define LEFT_MASK(x) \
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)
93 #define MASK_BITS(x,w,l,n,r) { \
95 r = RIGHT_MASK ((x) + n); \
98 n -= 32 - ((x) & 0x1f); \
112 int width
= rxi
- lxi
;
118 MASK_BITS (x
, width
, startmask
, nmiddle
, endmask
);
121 WRITE(image
, a
, READ(image
, a
) | startmask
);
125 WRITE(image
, a
++, 0xffffffff);
127 WRITE(image
, a
, READ(image
, a
) | endmask
);
131 DEFINE_ALPHA(line
,lxi
);
135 /* Sample coverage for edge pixels */
136 lxs
= RENDER_SAMPLES_X (lx
, N_BITS
);
137 rxs
= RENDER_SAMPLES_X (rx
, N_BITS
);
139 /* Add coverage across row */
142 ADD_ALPHA (rxs
- lxs
);
148 ADD_ALPHA (N_X_FRAC(N_BITS
) - lxs
);
150 for (xi
= lxi
+ 1; xi
< rxi
; xi
++)
152 ADD_ALPHA (N_X_FRAC(N_BITS
));
165 if (pixman_fixed_frac (y
) != Y_FRAC_LAST(N_BITS
))
167 RENDER_EDGE_STEP_SMALL (l
);
168 RENDER_EDGE_STEP_SMALL (r
);
169 y
+= STEP_Y_SMALL(N_BITS
);
174 RENDER_EDGE_STEP_BIG (l
);
175 RENDER_EDGE_STEP_BIG (r
);
176 y
+= STEP_Y_BIG(N_BITS
);
182 #undef rasterize_span