1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/libpixman/src/pixman-edge-imp.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,182 @@ 1.4 +/* 1.5 + * Copyright © 2004 Keith Packard 1.6 + * 1.7 + * Permission to use, copy, modify, distribute, and sell this software and its 1.8 + * documentation for any purpose is hereby granted without fee, provided that 1.9 + * the above copyright notice appear in all copies and that both that 1.10 + * copyright notice and this permission notice appear in supporting 1.11 + * documentation, and that the name of Keith Packard not be used in 1.12 + * advertising or publicity pertaining to distribution of the software without 1.13 + * specific, written prior permission. Keith Packard makes no 1.14 + * representations about the suitability of this software for any purpose. It 1.15 + * is provided "as is" without express or implied warranty. 1.16 + * 1.17 + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1.18 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1.19 + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1.20 + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1.21 + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1.22 + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 1.23 + * PERFORMANCE OF THIS SOFTWARE. 1.24 + */ 1.25 + 1.26 +#ifndef rasterize_span 1.27 +#endif 1.28 + 1.29 +static void 1.30 +RASTERIZE_EDGES (pixman_image_t *image, 1.31 + pixman_edge_t *l, 1.32 + pixman_edge_t *r, 1.33 + pixman_fixed_t t, 1.34 + pixman_fixed_t b) 1.35 +{ 1.36 + pixman_fixed_t y = t; 1.37 + uint32_t *line; 1.38 + uint32_t *buf = (image)->bits.bits; 1.39 + int stride = (image)->bits.rowstride; 1.40 + int width = (image)->bits.width; 1.41 + 1.42 + line = buf + pixman_fixed_to_int (y) * stride; 1.43 + 1.44 + for (;;) 1.45 + { 1.46 + pixman_fixed_t lx; 1.47 + pixman_fixed_t rx; 1.48 + int lxi; 1.49 + int rxi; 1.50 + 1.51 + lx = l->x; 1.52 + rx = r->x; 1.53 +#if N_BITS == 1 1.54 + /* For the non-antialiased case, round the coordinates up, in effect 1.55 + * sampling just slightly to the left of the pixel. This is so that 1.56 + * when the sample point lies exactly on the line, we round towards 1.57 + * north-west. 1.58 + * 1.59 + * (The AA case does a similar adjustment in RENDER_SAMPLES_X) 1.60 + */ 1.61 + lx += X_FRAC_FIRST(1) - pixman_fixed_e; 1.62 + rx += X_FRAC_FIRST(1) - pixman_fixed_e; 1.63 +#endif 1.64 + /* clip X */ 1.65 + if (lx < 0) 1.66 + lx = 0; 1.67 + if (pixman_fixed_to_int (rx) >= width) 1.68 +#if N_BITS == 1 1.69 + rx = pixman_int_to_fixed (width); 1.70 +#else 1.71 + /* Use the last pixel of the scanline, covered 100%. 1.72 + * We can't use the first pixel following the scanline, 1.73 + * because accessing it could result in a buffer overrun. 1.74 + */ 1.75 + rx = pixman_int_to_fixed (width) - 1; 1.76 +#endif 1.77 + 1.78 + /* Skip empty (or backwards) sections */ 1.79 + if (rx > lx) 1.80 + { 1.81 + 1.82 + /* Find pixel bounds for span */ 1.83 + lxi = pixman_fixed_to_int (lx); 1.84 + rxi = pixman_fixed_to_int (rx); 1.85 + 1.86 +#if N_BITS == 1 1.87 + { 1.88 + 1.89 +#define LEFT_MASK(x) \ 1.90 + (((x) & 0x1f) ? \ 1.91 + SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0) 1.92 +#define RIGHT_MASK(x) \ 1.93 + (((32 - (x)) & 0x1f) ? \ 1.94 + SCREEN_SHIFT_LEFT (0xffffffff, (32 - (x)) & 0x1f) : 0) 1.95 + 1.96 +#define MASK_BITS(x,w,l,n,r) { \ 1.97 + n = (w); \ 1.98 + r = RIGHT_MASK ((x) + n); \ 1.99 + l = LEFT_MASK (x); \ 1.100 + if (l) { \ 1.101 + n -= 32 - ((x) & 0x1f); \ 1.102 + if (n < 0) { \ 1.103 + n = 0; \ 1.104 + l &= r; \ 1.105 + r = 0; \ 1.106 + } \ 1.107 + } \ 1.108 + n >>= 5; \ 1.109 + } 1.110 + 1.111 + uint32_t *a = line; 1.112 + uint32_t startmask; 1.113 + uint32_t endmask; 1.114 + int nmiddle; 1.115 + int width = rxi - lxi; 1.116 + int x = lxi; 1.117 + 1.118 + a += x >> 5; 1.119 + x &= 0x1f; 1.120 + 1.121 + MASK_BITS (x, width, startmask, nmiddle, endmask); 1.122 + 1.123 + if (startmask) { 1.124 + WRITE(image, a, READ(image, a) | startmask); 1.125 + a++; 1.126 + } 1.127 + while (nmiddle--) 1.128 + WRITE(image, a++, 0xffffffff); 1.129 + if (endmask) 1.130 + WRITE(image, a, READ(image, a) | endmask); 1.131 + } 1.132 +#else 1.133 + { 1.134 + DEFINE_ALPHA(line,lxi); 1.135 + int lxs; 1.136 + int rxs; 1.137 + 1.138 + /* Sample coverage for edge pixels */ 1.139 + lxs = RENDER_SAMPLES_X (lx, N_BITS); 1.140 + rxs = RENDER_SAMPLES_X (rx, N_BITS); 1.141 + 1.142 + /* Add coverage across row */ 1.143 + if (lxi == rxi) 1.144 + { 1.145 + ADD_ALPHA (rxs - lxs); 1.146 + } 1.147 + else 1.148 + { 1.149 + int xi; 1.150 + 1.151 + ADD_ALPHA (N_X_FRAC(N_BITS) - lxs); 1.152 + STEP_ALPHA; 1.153 + for (xi = lxi + 1; xi < rxi; xi++) 1.154 + { 1.155 + ADD_ALPHA (N_X_FRAC(N_BITS)); 1.156 + STEP_ALPHA; 1.157 + } 1.158 + ADD_ALPHA (rxs); 1.159 + } 1.160 + } 1.161 +#endif 1.162 + } 1.163 + 1.164 + if (y == b) 1.165 + break; 1.166 + 1.167 +#if N_BITS > 1 1.168 + if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS)) 1.169 + { 1.170 + RENDER_EDGE_STEP_SMALL (l); 1.171 + RENDER_EDGE_STEP_SMALL (r); 1.172 + y += STEP_Y_SMALL(N_BITS); 1.173 + } 1.174 + else 1.175 +#endif 1.176 + { 1.177 + RENDER_EDGE_STEP_BIG (l); 1.178 + RENDER_EDGE_STEP_BIG (r); 1.179 + y += STEP_Y_BIG(N_BITS); 1.180 + line += stride; 1.181 + } 1.182 + } 1.183 +} 1.184 + 1.185 +#undef rasterize_span