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 183