11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/* 21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Copyright © 2004 Keith Packard 31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Permission to use, copy, modify, distribute, and sell this software and its 51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * documentation for any purpose is hereby granted without fee, provided that 61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * the above copyright notice appear in all copies and that both that 71176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * copyright notice and this permission notice appear in supporting 81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * documentation, and that the name of Keith Packard not be used in 91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * advertising or publicity pertaining to distribution of the software without 101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * specific, written prior permission. Keith Packard makes no 111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * representations about the suitability of this software for any purpose. It 121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * is provided "as is" without express or implied warranty. 131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * PERFORMANCE OF THIS SOFTWARE. 211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#ifndef rasterize_span 241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 261176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void 271176bdada62cabc6ec4b0308a930e83b679d5d36John ReckRASTERIZE_EDGES (pixman_image_t *image, 281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_edge_t *l, 291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_edge_t *r, 301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t t, 311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t b) 321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{ 331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t y = t; 341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t *line; 351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t *buf = (image)->bits.bits; 361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int stride = (image)->bits.rowstride; 371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = (image)->bits.width; 381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck line = buf + pixman_fixed_to_int (y) * stride; 401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (;;) 421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t lx; 441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck pixman_fixed_t rx; 451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int lxi; 461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int rxi; 471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck lx = l->x; 491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck rx = r->x; 501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if N_BITS == 1 511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* For the non-antialiased case, round the coordinates up, in effect 521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * sampling just slightly to the left of the pixel. This is so that 531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * when the sample point lies exactly on the line, we round towards 541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * north-west. 551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * 561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * (The AA case does a similar adjustment in RENDER_SAMPLES_X) 571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck lx += X_FRAC_FIRST(1) - pixman_fixed_e; 591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck rx += X_FRAC_FIRST(1) - pixman_fixed_e; 601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* clip X */ 621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (lx < 0) 631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck lx = 0; 641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (pixman_fixed_to_int (rx) >= width) 651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if N_BITS == 1 661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck rx = pixman_int_to_fixed (width); 671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#else 681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Use the last pixel of the scanline, covered 100%. 691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * We can't use the first pixel following the scanline, 701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * because accessing it could result in a buffer overrun. 711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */ 721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck rx = pixman_int_to_fixed (width) - 1; 731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Skip empty (or backwards) sections */ 761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (rx > lx) 771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Find pixel bounds for span */ 801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck lxi = pixman_fixed_to_int (lx); 811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck rxi = pixman_fixed_to_int (rx); 821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if N_BITS == 1 841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define LEFT_MASK(x) \ 871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (((x) & 0x1f) ? \ 881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0) 891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define RIGHT_MASK(x) \ 901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck (((32 - (x)) & 0x1f) ? \ 911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck SCREEN_SHIFT_LEFT (0xffffffff, (32 - (x)) & 0x1f) : 0) 921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define MASK_BITS(x,w,l,n,r) { \ 941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck n = (w); \ 951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck r = RIGHT_MASK ((x) + n); \ 961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck l = LEFT_MASK (x); \ 971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (l) { \ 981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck n -= 32 - ((x) & 0x1f); \ 991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (n < 0) { \ 1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck n = 0; \ 1011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck l &= r; \ 1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck r = 0; \ 1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 1041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } \ 1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck n >>= 5; \ 1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t *a = line; 1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t startmask; 1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck uint32_t endmask; 1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int nmiddle; 1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int width = rxi - lxi; 1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int x = lxi; 1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck a += x >> 5; 1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck x &= 0x1f; 1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck MASK_BITS (x, width, startmask, nmiddle, endmask); 1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (startmask) { 1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck WRITE(image, a, READ(image, a) | startmask); 1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck a++; 1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck while (nmiddle--) 1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck WRITE(image, a++, 0xffffffff); 1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (endmask) 1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck WRITE(image, a, READ(image, a) | endmask); 1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#else 1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck DEFINE_ALPHA(line,lxi); 1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int lxs; 1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int rxs; 1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Sample coverage for edge pixels */ 1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck lxs = RENDER_SAMPLES_X (lx, N_BITS); 1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck rxs = RENDER_SAMPLES_X (rx, N_BITS); 1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck /* Add coverage across row */ 1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (lxi == rxi) 1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ADD_ALPHA (rxs - lxs); 1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck int xi; 1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ADD_ALPHA (N_X_FRAC(N_BITS) - lxs); 1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck STEP_ALPHA; 1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck for (xi = lxi + 1; xi < rxi; xi++) 1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ADD_ALPHA (N_X_FRAC(N_BITS)); 1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck STEP_ALPHA; 1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck ADD_ALPHA (rxs); 1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (y == b) 1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck break; 1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if N_BITS > 1 1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS)) 1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck RENDER_EDGE_STEP_SMALL (l); 1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck RENDER_EDGE_STEP_SMALL (r); 1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y += STEP_Y_SMALL(N_BITS); 1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck else 1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif 1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck { 1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck RENDER_EDGE_STEP_BIG (l); 1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck RENDER_EDGE_STEP_BIG (r); 1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck y += STEP_Y_BIG(N_BITS); 1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck line += stride; 1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck } 1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck} 1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck 1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#undef rasterize_span 183