Пример #1
0
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);
    }
}
Пример #2
0
/* 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);
    }
}
Пример #3
0
/* 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);
}