/*
- * $Id$
- *
* Copyright © 2004 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef rasterizeSpan
+#ifndef rasterize_span
#endif
static void
-rasterizeEdges (pixman_image_t *image,
+RASTERIZE_EDGES (pixman_image_t *image,
pixman_edge_t *l,
pixman_edge_t *r,
pixman_fixed_t t,
int lxi;
int rxi;
- /* clip X */
lx = l->x;
+ rx = r->x;
+#if N_BITS == 1
+ /* For the non-antialiased case, round the coordinates up, in effect
+ * sampling just slightly to the left of the pixel. This is so that
+ * when the sample point lies exactly on the line, we round towards
+ * north-west.
+ *
+ * (The AA case does a similar adjustment in RENDER_SAMPLES_X)
+ */
+ lx += X_FRAC_FIRST(1) - pixman_fixed_e;
+ rx += X_FRAC_FIRST(1) - pixman_fixed_e;
+#endif
+ /* clip X */
if (lx < 0)
lx = 0;
- rx = r->x;
if (pixman_fixed_to_int (rx) >= width)
+#if N_BITS == 1
rx = pixman_int_to_fixed (width);
+#else
+ /* Use the last pixel of the scanline, covered 100%.
+ * We can't use the first pixel following the scanline,
+ * because accessing it could result in a buffer overrun.
+ */
+ rx = pixman_int_to_fixed (width) - 1;
+#endif
/* Skip empty (or backwards) sections */
if (rx > lx)
#if N_BITS == 1
{
+
+#define LEFT_MASK(x) \
+ (((x) & 0x1f) ? \
+ SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0)
+#define RIGHT_MASK(x) \
+ (((32 - (x)) & 0x1f) ? \
+ SCREEN_SHIFT_LEFT (0xffffffff, (32 - (x)) & 0x1f) : 0)
+
+#define MASK_BITS(x,w,l,n,r) { \
+ n = (w); \
+ r = RIGHT_MASK ((x) + n); \
+ l = LEFT_MASK (x); \
+ if (l) { \
+ n -= 32 - ((x) & 0x1f); \
+ if (n < 0) { \
+ n = 0; \
+ l &= r; \
+ r = 0; \
+ } \
+ } \
+ n >>= 5; \
+ }
+
uint32_t *a = line;
uint32_t startmask;
uint32_t endmask;
int nmiddle;
int width = rxi - lxi;
int x = lxi;
-
- a += x >> FB_SHIFT;
- x &= FB_MASK;
-
- FbMaskBits (x, width, startmask, nmiddle, endmask);
- if (startmask) {
- WRITE(image, a, READ(image, a) | startmask);
- a++;
- }
- while (nmiddle--)
- WRITE(image, a++, FB_ALLONES);
- if (endmask)
- WRITE(image, a, READ(image, a) | endmask);
+
+ a += x >> 5;
+ x &= 0x1f;
+
+ MASK_BITS (x, width, startmask, nmiddle, endmask);
+
+ if (startmask) {
+ WRITE(image, a, READ(image, a) | startmask);
+ a++;
+ }
+ while (nmiddle--)
+ WRITE(image, a++, 0xffffffff);
+ if (endmask)
+ WRITE(image, a, READ(image, a) | endmask);
}
#else
{
- DefineAlpha(line,lxi);
+ DEFINE_ALPHA(line,lxi);
int lxs;
int rxs;
/* Sample coverage for edge pixels */
- lxs = RenderSamplesX (lx, N_BITS);
- rxs = RenderSamplesX (rx, N_BITS);
+ lxs = RENDER_SAMPLES_X (lx, N_BITS);
+ rxs = RENDER_SAMPLES_X (rx, N_BITS);
/* Add coverage across row */
if (lxi == rxi)
{
- AddAlpha (rxs - lxs);
+ ADD_ALPHA (rxs - lxs);
}
else
{
int xi;
- AddAlpha (N_X_FRAC(N_BITS) - lxs);
- StepAlpha;
+ ADD_ALPHA (N_X_FRAC(N_BITS) - lxs);
+ STEP_ALPHA;
for (xi = lxi + 1; xi < rxi; xi++)
{
- AddAlpha (N_X_FRAC(N_BITS));
- StepAlpha;
+ ADD_ALPHA (N_X_FRAC(N_BITS));
+ STEP_ALPHA;
}
- /* Do not add in a 0 alpha here. This check is necessary
- * to avoid a buffer overrun when rx is exactly on a pixel
- * boundary.
- */
- if (rxs != 0)
- AddAlpha (rxs);
+ ADD_ALPHA (rxs);
}
}
#endif
#if N_BITS > 1
if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS))
{
- RenderEdgeStepSmall (l);
- RenderEdgeStepSmall (r);
+ RENDER_EDGE_STEP_SMALL (l);
+ RENDER_EDGE_STEP_SMALL (r);
y += STEP_Y_SMALL(N_BITS);
}
else
#endif
{
- RenderEdgeStepBig (l);
- RenderEdgeStepBig (r);
+ RENDER_EDGE_STEP_BIG (l);
+ RENDER_EDGE_STEP_BIG (r);
y += STEP_Y_BIG(N_BITS);
line += stride;
}
}
}
-#undef rasterizeSpan
+#undef rasterize_span