void miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box) { box->y1 = MAXSHORT; box->y2 = MINSHORT; box->x1 = MAXSHORT; box->x2 = MINSHORT; for (; ntrap; ntrap--, traps++) { INT16 x1, y1, x2, y2; if (!xTrapezoidValid(traps)) continue; y1 = xFixedToInt (traps->top); if (y1 < box->y1) box->y1 = y1; y2 = xFixedToInt (xFixedCeil (traps->bottom)); if (y2 > box->y2) box->y2 = y2; x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE), miLineFixedX (&traps->left, traps->bottom, FALSE))); if (x1 < box->x1) box->x1 = x1; x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE), miLineFixedX (&traps->right, traps->bottom, TRUE)))); if (x2 > box->x2) box->x2 = x2; } }
static void PictureTransformBounds (BoxPtr b, PictTransformPtr matrix) { PictVector v[4]; int i; int x1, y1, x2, y2; v[0].vector[0] = F (b->x1); v[0].vector[1] = F (b->y1); v[0].vector[2] = F(1); v[1].vector[0] = F (b->x2); v[1].vector[1] = F (b->y1); v[1].vector[2] = F(1); v[2].vector[0] = F (b->x2); v[2].vector[1] = F (b->y2); v[2].vector[2] = F(1); v[3].vector[0] = F (b->x1); v[3].vector[1] = F (b->y2); v[3].vector[2] = F(1); for (i = 0; i < 4; i++) { PictureTransformPoint (matrix, &v[i]); x1 = xFixedToInt (v[i].vector[0]); y1 = xFixedToInt (v[i].vector[1]); x2 = xFixedToInt (xFixedCeil (v[i].vector[0])); y2 = xFixedToInt (xFixedCeil (v[i].vector[1])); if (i == 0) { b->x1 = x1; b->y1 = y1; b->x2 = x2; b->y2 = y2; } else { if (x1 < b->x1) b->x1 = x1; if (y1 < b->y1) b->y1 = y1; if (x2 > b->x2) b->x2 = x2; if (y2 > b->y2) b->y2 = y2; } } }
static void pixman_trapezoid_bounds (int ntrap, const pixman_trapezoid_t *traps, pixman_box16_t *box) { box->y1 = MAXSHORT; box->y2 = MINSHORT; box->x1 = MAXSHORT; box->x2 = MINSHORT; for (; ntrap; ntrap--, traps++) { int16_t x1, y1, x2, y2; if (!xTrapezoidValid(traps)) continue; y1 = xFixedToInt (traps->top); if (y1 < box->y1) box->y1 = y1; y2 = xFixedToInt (xFixedCeil (traps->bottom)); if (y2 > box->y2) box->y2 = y2; x1 = xFixedToInt (MIN (pixman_line_fixed_x (&traps->left, traps->top, 0), pixman_line_fixed_x (&traps->left, traps->bottom, 0))); if (x1 < box->x1) box->x1 = x1; x2 = xFixedToInt (xFixedCeil (MAX (pixman_line_fixed_x (&traps->right, traps->top, 1), pixman_line_fixed_x (&traps->right, traps->bottom, 1)))); if (x2 > box->x2) box->x2 = x2; } }
static Bool convolutionFilterValidateParams(ScreenPtr pScreen, int filter, xFixed * params, int nparams, int *width, int *height) { int w, h; if (nparams < 3) return FALSE; if (xFixedFrac(params[0]) || xFixedFrac(params[1])) return FALSE; w = xFixedToInt(params[0]); h = xFixedToInt(params[1]); nparams -= 2; if (w * h > nparams) return FALSE; *width = w; *height = h; return TRUE; }
void miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds) { bounds->x1 = xFixedToInt (points->x); bounds->x2 = xFixedToInt (xFixedCeil (points->x)); bounds->y1 = xFixedToInt (points->y); bounds->y2 = xFixedToInt (xFixedCeil (points->y)); points++; npoint--; while (npoint-- > 0) { INT16 x1 = xFixedToInt (points->x); INT16 x2 = xFixedToInt (xFixedCeil (points->x)); INT16 y1 = xFixedToInt (points->y); INT16 y2 = xFixedToInt (xFixedCeil (points->y)); if (x1 < bounds->x1) bounds->x1 = x1; else if (x2 > bounds->x2) bounds->x2 = x2; if (y1 < bounds->y1) bounds->y1 = y1; else if (y2 > bounds->y2) bounds->y2 = y2; points++; } }
static Bool convolutionFilterValidateParams (PicturePtr pPicture, int filter, xFixed *params, int nparams) { if (nparams < 3) return FALSE; if (xFixedFrac (params[0]) || xFixedFrac (params[1])) return FALSE; nparams -= 2; if ((xFixedToInt (params[0]) * xFixedToInt (params[1])) > nparams) return FALSE; return TRUE; }
void fbRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap, int x_off, int y_off) { FbBits *buf; int bpp; int width; int stride; int height; int pxoff, pyoff; xFixed x_off_fixed; xFixed y_off_fixed; RenderEdge l, r; xFixed t, b; if (!xTrapezoidValid (trap)) return; fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff); width = pPicture->pDrawable->width; height = pPicture->pDrawable->height; x_off += pxoff; y_off += pyoff; x_off_fixed = IntToxFixed(x_off); y_off_fixed = IntToxFixed(y_off); t = trap->top + y_off_fixed; if (t < 0) t = 0; t = RenderSampleCeilY (t, bpp); b = trap->bottom + y_off_fixed; if (xFixedToInt (b) >= height) b = IntToxFixed (height) - 1; b = RenderSampleFloorY (b, bpp); if (b >= t) { /* initialize edge walkers */ RenderLineFixedEdgeInit (&l, bpp, t, &trap->left, x_off, y_off); RenderLineFixedEdgeInit (&r, bpp, t, &trap->right, x_off, y_off); fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b); } }
void fbAddTraps (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap *traps) { FbBits *buf; int bpp; int width; int stride; int height; int pxoff, pyoff; xFixed x_off_fixed; xFixed y_off_fixed; RenderEdge l, r; xFixed t, b; fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff); width = pPicture->pDrawable->width; height = pPicture->pDrawable->height; x_off += pxoff; y_off += pyoff; x_off_fixed = IntToxFixed(y_off); y_off_fixed = IntToxFixed(y_off); while (ntrap--) { t = traps->top.y + y_off_fixed; if (t < 0) t = 0; t = RenderSampleCeilY (t, bpp); b = traps->bot.y + y_off_fixed; if (xFixedToInt (b) >= height) b = IntToxFixed (height) - 1; b = RenderSampleFloorY (b, bpp); if (b >= t) { /* initialize edge walkers */ RenderEdgeInit (&l, bpp, t, traps->top.l + x_off_fixed, traps->top.y + y_off_fixed, traps->bot.l + x_off_fixed, traps->bot.y + y_off_fixed); RenderEdgeInit (&r, bpp, t, traps->top.r + x_off_fixed, traps->top.y + y_off_fixed, traps->bot.r + x_off_fixed, traps->bot.y + y_off_fixed); fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b); } traps++; } }
/* * We want to detect the case where we add the same value to a long * span of pixels. The triangles on the end are filled in while we * count how many sub-pixel scanlines contribute to the middle section. * * +--------------------------+ * fill_height =| \ / * +------------------+ * |================| * fill_start fill_end */ static void fbRasterizeEdges8 (FbBits *buf, int width, int stride, RenderEdge *l, RenderEdge *r, xFixed t, xFixed b) { xFixed y = t; FbBits *line; int fill_start = -1, fill_end = -1; int fill_size = 0; line = buf + xFixedToInt (y) * stride; for (;;) { CARD8 *ap = (CARD8 *) line; xFixed lx, rx; int lxi, rxi; /* clip X */ lx = l->x; if (lx < 0) lx = 0; rx = r->x; if (xFixedToInt (rx) >= width) rx = IntToxFixed (width); /* Skip empty (or backwards) sections */ if (rx > lx) { int lxs, rxs; /* Find pixel bounds for span. */ lxi = xFixedToInt (lx); rxi = xFixedToInt (rx); /* Sample coverage for edge pixels */ lxs = RenderSamplesX (lx, 8); rxs = RenderSamplesX (rx, 8); /* Add coverage across row */ if (lxi == rxi) { ap[lxi] = clip255 (ap[lxi] + rxs - lxs); } else { ap[lxi] = clip255 (ap[lxi] + N_X_FRAC(8) - lxs); /* Move forward so that lxi/rxi is the pixel span */ lxi++; /* Don't bother trying to optimize the fill unless * the span is longer than 4 pixels. */ if (rxi - lxi > 4) { if (fill_start < 0) { fill_start = lxi; fill_end = rxi; fill_size++; } else { if (lxi >= fill_end || rxi < fill_start) { /* We're beyond what we saved, just fill it */ add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8), fill_end - fill_start); fill_start = lxi; fill_end = rxi; fill_size = 1; } else { /* Update fill_start */ if (lxi > fill_start) { add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8), lxi - fill_start); fill_start = lxi; } else if (lxi < fill_start) { add_saturate_8 (ap + lxi, N_X_FRAC(8), fill_start - lxi); } /* Update fill_end */ if (rxi < fill_end) { add_saturate_8 (ap + rxi, fill_size * N_X_FRAC(8), fill_end - rxi); fill_end = rxi; } else if (fill_end < rxi) { add_saturate_8 (ap + fill_end, N_X_FRAC(8), rxi - fill_end); } fill_size++; } } } else { add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi); } /* 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) ap[rxi] = clip255 (ap[rxi] + rxs); } } if (y == b) { /* We're done, make sure we clean up any remaining fill. */ if (fill_start != fill_end) { if (fill_size == N_Y_FRAC(8)) { memset (ap + fill_start, 0xff, fill_end - fill_start); } else { add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8), fill_end - fill_start); } } break; } if (xFixedFrac (y) != Y_FRAC_LAST(8)) { RenderEdgeStepSmall (l); RenderEdgeStepSmall (r); y += STEP_Y_SMALL(8); } else { RenderEdgeStepBig (l); RenderEdgeStepBig (r); y += STEP_Y_BIG(8); if (fill_start != fill_end) { if (fill_size == N_Y_FRAC(8)) { memset (ap + fill_start, 0xff, fill_end - fill_start); } else { add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8), fill_end - fill_start); } fill_start = fill_end = -1; fill_size = 0; } line += stride; } } }