void pixman_add_trapezoids (pixman_image_t *dst, int x_off, int y_off, const pixman_trapezoid_t *traps, int ntraps) { for (; ntraps; ntraps--, traps++) { if (!xTrapezoidValid (traps)) continue; fbRasterizeTrapezoid (dst, traps, x_off, y_off); } }
/* FIXME -- this could be made more efficient */ void fbAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri, xTriangle *tris) { xPointFixed *top, *left, *right, *tmp; xTrapezoid trap; for (; ntri; ntri--, tris++) { top = &tris->p1; left = &tris->p2; right = &tris->p3; if (_GreaterY (top, left)) { tmp = left; left = top; top = tmp; } if (_GreaterY (top, right)) { tmp = right; right = top; top = tmp; } if (_Clockwise (top, right, left)) { tmp = right; right = left; left = tmp; } /* * Two cases: * * + + * / \ / \ * / \ / \ * / + + \ * / -- -- \ * / -- -- \ * / --- --- \ * +-- --+ */ trap.top = top->y; trap.left.p1 = *top; trap.left.p2 = *left; trap.right.p1 = *top; trap.right.p2 = *right; if (right->y < left->y) trap.bottom = right->y; else trap.bottom = left->y; fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off); if (right->y < left->y) { trap.top = right->y; trap.bottom = left->y; trap.right.p1 = *right; trap.right.p2 = *left; } else { trap.top = left->y; trap.bottom = right->y; trap.left.p1 = *left; trap.left.p2 = *right; } fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off); } }
/* XXX: There are failure cases in this function. Don't we need to * propagate the errors out? */ void pixman_composite_trapezoids (pixman_operator_t op, pixman_image_t *src, pixman_image_t *dst, int xSrc, int ySrc, const pixman_trapezoid_t *traps, int ntraps) { pixman_image_t *image = NULL; pixman_box16_t traps_bounds, dst_bounds, bounds; pixman_region16_t *traps_region, *dst_region; int16_t xDst, yDst; int16_t xRel, yRel; pixman_format_t *format; if (ntraps == 0) return; /* * Check for solid alpha add */ if (op == PIXMAN_OPERATOR_ADD && miIsSolidAlpha (src)) { for (; ntraps; ntraps--, traps++) fbRasterizeTrapezoid (dst, traps, 0, 0); return; } xDst = traps[0].left.p1.x >> 16; yDst = traps[0].left.p1.y >> 16; pixman_trapezoid_bounds (ntraps, traps, &traps_bounds); traps_region = pixman_region_create_simple (&traps_bounds); /* XXX: If the image has a clip region set, we should really be * fetching it here instead, but it looks like we don't yet expose * a pixman_image_get_clip_region function. */ dst_bounds.x1 = 0; dst_bounds.y1 = 0; dst_bounds.x2 = pixman_image_get_width (dst); dst_bounds.y2 = pixman_image_get_height (dst); dst_region = pixman_region_create_simple (&dst_bounds); pixman_region_intersect (traps_region, traps_region, dst_region); bounds = *(pixman_region_extents (traps_region)); pixman_region_destroy (traps_region); pixman_region_destroy (dst_region); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; format = pixman_format_create (PIXMAN_FORMAT_NAME_A8); if (!format) return; image = FbCreateAlphaPicture (dst, format, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); if (!image) { pixman_format_destroy (format); return; } for (; ntraps; ntraps--, traps++) { if (!xTrapezoidValid(traps)) continue; fbRasterizeTrapezoid (image, traps, -bounds.x1, -bounds.y1); } xRel = bounds.x1 + xSrc - xDst; yRel = bounds.y1 + ySrc - yDst; pixman_composite (op, src, image, dst, xRel, yRel, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); pixman_image_destroy (image); pixman_format_destroy (format); }