/*
 * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
 * Copyright © 2004 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Keith Packard not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Keith Packard makes no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include "pixman-private.h"

/*
 * Compute the smallest value greater than or equal to y which is on a
 * grid row.
 */

PIXMAN_EXPORT pixman_fixed_t
pixman_sample_ceil_y (pixman_fixed_t y, int n)
{
    pixman_fixed_t f = pixman_fixed_frac (y);
    pixman_fixed_t i = pixman_fixed_floor (y);

    f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
	Y_FRAC_FIRST (n);
    
    if (f > Y_FRAC_LAST (n))
    {
	if (pixman_fixed_to_int (i) == 0x7fff)
	{
	    f = 0xffff; /* saturate */
	}
	else
	{
	    f = Y_FRAC_FIRST (n);
	    i += pixman_fixed_1;
	}
    }
    return (i | f);
}

/*
 * Compute the largest value strictly less than y which is on a
 * grid row.
 */
PIXMAN_EXPORT pixman_fixed_t
pixman_sample_floor_y (pixman_fixed_t y,
                       int            n)
{
    pixman_fixed_t f = pixman_fixed_frac (y);
    pixman_fixed_t i = pixman_fixed_floor (y);

    f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) +
	Y_FRAC_FIRST (n);

    if (f < Y_FRAC_FIRST (n))
    {
	if (pixman_fixed_to_int (i) == 0x8000)
	{
	    f = 0; /* saturate */
	}
	else
	{
	    f = Y_FRAC_LAST (n);
	    i -= pixman_fixed_1;
	}
    }
    return (i | f);
}

/*
 * Step an edge by any amount (including negative values)
 */
PIXMAN_EXPORT void
pixman_edge_step (pixman_edge_t *e,
                  int            n)
{
    pixman_fixed_48_16_t ne;

    e->x += n * e->stepx;

    ne = e->e + n * (pixman_fixed_48_16_t) e->dx;

    if (n >= 0)
    {
	if (ne > 0)
	{
	    int nx = (ne + e->dy - 1) / e->dy;
	    e->e = ne - nx * (pixman_fixed_48_16_t) e->dy;
	    e->x += nx * e->signdx;
	}
    }
    else
    {
	if (ne <= -e->dy)
	{
	    int nx = (-ne) / e->dy;
	    e->e = ne + nx * (pixman_fixed_48_16_t) e->dy;
	    e->x -= nx * e->signdx;
	}
    }
}

/*
 * A private routine to initialize the multi-step
 * elements of an edge structure
 */
static void
_pixman_edge_multi_init (pixman_edge_t * e,
                         int             n,
                         pixman_fixed_t *stepx_p,
                         pixman_fixed_t *dx_p)
{
    pixman_fixed_t stepx;
    pixman_fixed_48_16_t ne;

    ne = n * (pixman_fixed_48_16_t) e->dx;
    stepx = n * e->stepx;

    if (ne > 0)
    {
	int nx = ne / e->dy;
	ne -= nx * (pixman_fixed_48_16_t)e->dy;
	stepx += nx * e->signdx;
    }

    *dx_p = ne;
    *stepx_p = stepx;
}

/*
 * Initialize one edge structure given the line endpoints and a
 * starting y value
 */
PIXMAN_EXPORT void
pixman_edge_init (pixman_edge_t *e,
                  int            n,
                  pixman_fixed_t y_start,
                  pixman_fixed_t x_top,
                  pixman_fixed_t y_top,
                  pixman_fixed_t x_bot,
                  pixman_fixed_t y_bot)
{
    pixman_fixed_t dx, dy;

    e->x = x_top;
    e->e = 0;
    dx = x_bot - x_top;
    dy = y_bot - y_top;
    e->dy = dy;
    e->dx = 0;

    if (dy)
    {
	if (dx >= 0)
	{
	    e->signdx = 1;
	    e->stepx = dx / dy;
	    e->dx = dx % dy;
	    e->e = -dy;
	}
	else
	{
	    e->signdx = -1;
	    e->stepx = -(-dx / dy);
	    e->dx = -dx % dy;
	    e->e = 0;
	}

	_pixman_edge_multi_init (e, STEP_Y_SMALL (n),
				 &e->stepx_small, &e->dx_small);

	_pixman_edge_multi_init (e, STEP_Y_BIG (n),
				 &e->stepx_big, &e->dx_big);
    }
    pixman_edge_step (e, y_start - y_top);
}

/*
 * Initialize one edge structure given a line, starting y value
 * and a pixel offset for the line
 */
PIXMAN_EXPORT void
pixman_line_fixed_edge_init (pixman_edge_t *            e,
                             int                        n,
                             pixman_fixed_t             y,
                             const pixman_line_fixed_t *line,
                             int                        x_off,
                             int                        y_off)
{
    pixman_fixed_t x_off_fixed = pixman_int_to_fixed (x_off);
    pixman_fixed_t y_off_fixed = pixman_int_to_fixed (y_off);
    const pixman_point_fixed_t *top, *bot;

    if (line->p1.y <= line->p2.y)
    {
	top = &line->p1;
	bot = &line->p2;
    }
    else
    {
	top = &line->p2;
	bot = &line->p1;
    }
    
    pixman_edge_init (e, n, y,
                      top->x + x_off_fixed,
                      top->y + y_off_fixed,
                      bot->x + x_off_fixed,
                      bot->y + y_off_fixed);
}

PIXMAN_EXPORT void
pixman_add_traps (pixman_image_t * image,
                  int16_t          x_off,
                  int16_t          y_off,
                  int              ntrap,
                  pixman_trap_t *  traps)
{
    int bpp;
    int height;

    pixman_fixed_t x_off_fixed;
    pixman_fixed_t y_off_fixed;
    pixman_edge_t l, r;
    pixman_fixed_t t, b;

    _pixman_image_validate (image);
    
    height = image->bits.height;
    bpp = PIXMAN_FORMAT_BPP (image->bits.format);

    x_off_fixed = pixman_int_to_fixed (x_off);
    y_off_fixed = pixman_int_to_fixed (y_off);

    while (ntrap--)
    {
	t = traps->top.y + y_off_fixed;
	if (t < 0)
	    t = 0;
	t = pixman_sample_ceil_y (t, bpp);

	b = traps->bot.y + y_off_fixed;
	if (pixman_fixed_to_int (b) >= height)
	    b = pixman_int_to_fixed (height) - 1;
	b = pixman_sample_floor_y (b, bpp);

	if (b >= t)
	{
	    /* initialize edge walkers */
	    pixman_edge_init (&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);

	    pixman_edge_init (&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);

	    pixman_rasterize_edges (image, &l, &r, t, b);
	}

	traps++;
    }
}

#if 0
static void
dump_image (pixman_image_t *image,
            const char *    title)
{
    int i, j;

    if (!image->type == BITS)
	printf ("%s is not a regular image\n", title);

    if (!image->bits.format == PIXMAN_a8)
	printf ("%s is not an alpha mask\n", title);

    printf ("\n\n\n%s: \n", title);

    for (i = 0; i < image->bits.height; ++i)
    {
	uint8_t *line =
	    (uint8_t *)&(image->bits.bits[i * image->bits.rowstride]);

	for (j = 0; j < image->bits.width; ++j)
	    printf ("%c", line[j] ? '#' : ' ');

	printf ("\n");
    }
}
#endif

PIXMAN_EXPORT void
pixman_add_trapezoids (pixman_image_t *          image,
                       int16_t                   x_off,
                       int                       y_off,
                       int                       ntraps,
                       const pixman_trapezoid_t *traps)
{
    int i;

#if 0
    dump_image (image, "before");
#endif

    for (i = 0; i < ntraps; ++i)
    {
	const pixman_trapezoid_t *trap = &(traps[i]);

	if (!pixman_trapezoid_valid (trap))
	    continue;

	pixman_rasterize_trapezoid (image, trap, x_off, y_off);
    }

#if 0
    dump_image (image, "after");
#endif
}

PIXMAN_EXPORT void
pixman_rasterize_trapezoid (pixman_image_t *          image,
                            const pixman_trapezoid_t *trap,
                            int                       x_off,
                            int                       y_off)
{
    int bpp;
    int height;

    pixman_fixed_t y_off_fixed;
    pixman_edge_t l, r;
    pixman_fixed_t t, b;

    return_if_fail (image->type == BITS);

    _pixman_image_validate (image);
    
    if (!pixman_trapezoid_valid (trap))
	return;

    height = image->bits.height;
    bpp = PIXMAN_FORMAT_BPP (image->bits.format);

    y_off_fixed = pixman_int_to_fixed (y_off);

    t = trap->top + y_off_fixed;
    if (t < 0)
	t = 0;
    t = pixman_sample_ceil_y (t, bpp);

    b = trap->bottom + y_off_fixed;
    if (pixman_fixed_to_int (b) >= height)
	b = pixman_int_to_fixed (height) - 1;
    b = pixman_sample_floor_y (b, bpp);
    
    if (b >= t)
    {
	/* initialize edge walkers */
	pixman_line_fixed_edge_init (&l, bpp, t, &trap->left, x_off, y_off);
	pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off);

	pixman_rasterize_edges (image, &l, &r, t, b);
    }
}

/*
 * pixman_composite_trapezoids()
 *
 * All the trapezoids are conceptually rendered to an infinitely big image.
 * The (0, 0) coordinates of this image are then aligned with the (x, y)
 * coordinates of the source image, and then both images are aligned with
 * the (x, y) coordinates of the destination. Then, in principle, compositing
 * of these three images takes place across the entire destination.
 *
 * FIXME: However, there is currently a bug, where we restrict this compositing
 * to the bounding box of the trapezoids. This is incorrect for operators such
 * as SRC and IN where blank source pixels do have an effect on the destination.
 */
PIXMAN_EXPORT void
pixman_composite_trapezoids (pixman_op_t		op,
			     pixman_image_t *		src,
			     pixman_image_t *		dst,
			     pixman_format_code_t	mask_format,
			     int			x_src,
			     int			y_src,
			     int			x_dst,
			     int			y_dst,
			     int			n_traps,
			     const pixman_trapezoid_t *	traps)
{
    int i;

    if (n_traps <= 0)
	return;

    _pixman_image_validate (src);
    _pixman_image_validate (dst);

    if (op == PIXMAN_OP_ADD &&
	(src->common.flags & FAST_PATH_IS_OPAQUE)		&&
	(mask_format == dst->common.extended_format_code)	&&
	!(dst->common.have_clip_region))
    {
	for (i = 0; i < n_traps; ++i)
	{
	    const pixman_trapezoid_t *trap = &(traps[i]);
	    
	    if (!pixman_trapezoid_valid (trap))
		continue;
	    
	    pixman_rasterize_trapezoid (dst, trap, x_dst, y_dst);
	}
    }
    else
    {
	pixman_image_t *tmp;
	pixman_box32_t box;
	
	box.x1 = INT32_MAX;
	box.y1 = INT32_MAX;
	box.x2 = INT32_MIN;
	box.y2 = INT32_MIN;
	
	for (i = 0; i < n_traps; ++i)
	{
	    const pixman_trapezoid_t *trap = &(traps[i]);
	    int y1, y2;
	    
	    if (!pixman_trapezoid_valid (trap))
		continue;
	    
	    y1 = pixman_fixed_to_int (trap->top);
	    if (y1 < box.y1)
		box.y1 = y1;
	    
	    y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom));
	    if (y2 > box.y2)
		box.y2 = y2;
	    
#define EXTEND_MIN(x)							\
	    if (pixman_fixed_to_int ((x)) < box.x1)			\
		box.x1 = pixman_fixed_to_int ((x));
#define EXTEND_MAX(x)							\
	    if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box.x2)	\
		box.x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x)));
	    
#define EXTEND(x)							\
	    EXTEND_MIN(x);						\
	    EXTEND_MAX(x);
	    
	    EXTEND(trap->left.p1.x);
	    EXTEND(trap->left.p2.x);
	    EXTEND(trap->right.p1.x);
	    EXTEND(trap->right.p2.x);
	}
	
	if (box.x1 >= box.x2 || box.y1 >= box.y2)
	    return;
	
	tmp = pixman_image_create_bits (
	    mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1);
	
	for (i = 0; i < n_traps; ++i)
	{
	    const pixman_trapezoid_t *trap = &(traps[i]);
	    
	    if (!pixman_trapezoid_valid (trap))
		continue;
	    
	    pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1);
	}
	
	pixman_image_composite (op, src, tmp, dst,
				x_src + box.x1, y_src + box.y1,
				0, 0,
				x_dst + box.x1, y_dst + box.y1,
				box.x2 - box.x1, box.y2 - box.y1);
	
	pixman_image_unref (tmp);
    }
}

static int
greater_y (const pixman_point_fixed_t *a, const pixman_point_fixed_t *b)
{
    if (a->y == b->y)
	return a->x > b->x;
    return a->y > b->y;
}

/*
 * Note that the definition of this function is a bit odd because
 * of the X coordinate space (y increasing downwards).
 */
static int
clockwise (const pixman_point_fixed_t *ref,
	   const pixman_point_fixed_t *a,
	   const pixman_point_fixed_t *b)
{
    pixman_point_fixed_t	ad, bd;

    ad.x = a->x - ref->x;
    ad.y = a->y - ref->y;
    bd.x = b->x - ref->x;
    bd.y = b->y - ref->y;

    return ((pixman_fixed_32_32_t) bd.y * ad.x -
	    (pixman_fixed_32_32_t) ad.y * bd.x) < 0;
}

static void
triangle_to_trapezoids (const pixman_triangle_t *tri, pixman_trapezoid_t *traps)
{
    const pixman_point_fixed_t *top, *left, *right, *tmp;

    top = &tri->p1;
    left = &tri->p2;
    right = &tri->p3;

    if (greater_y (top, left))
    {
	tmp = left;
	left = top;
	top = tmp;
    }

    if (greater_y (top, right))
    {
	tmp = right;
	right = top;
	top = tmp;
    }

    if (clockwise (top, right, left))
    {
	tmp = right;
	right = left;
	left = tmp;
    }
    
    /*
     * Two cases:
     *
     *		+		+
     *	       / \             / \
     *	      /   \           /	  \
     *	     /     +         +	   \
     *      /    --           --    \
     *     /   --               --   \
     *    / ---                   --- \
     *	 +--                         --+
     */

    traps->top = top->y;
    traps->left.p1 = *top;
    traps->left.p2 = *left;
    traps->right.p1 = *top;
    traps->right.p2 = *right;

    if (right->y < left->y)
	traps->bottom = right->y;
    else
	traps->bottom = left->y;

    traps++;

    *traps = *(traps - 1);
    
    if (right->y < left->y)
    {
	traps->top = right->y;
	traps->bottom = left->y;
	traps->right.p1 = *right;
	traps->right.p2 = *left;
    }
    else
    {
	traps->top = left->y;
	traps->bottom = right->y;
	traps->left.p1 = *left;
	traps->left.p2 = *right;
    }
}

static pixman_trapezoid_t *
convert_triangles (int n_tris, const pixman_triangle_t *tris)
{
    pixman_trapezoid_t *traps;
    int i;

    if (n_tris <= 0)
	return NULL;
    
    traps = pixman_malloc_ab (n_tris, 2 * sizeof (pixman_trapezoid_t));
    if (!traps)
	return NULL;

    for (i = 0; i < n_tris; ++i)
	triangle_to_trapezoids (&(tris[i]), traps + 2 * i);

    return traps;
}

PIXMAN_EXPORT void
pixman_composite_triangles (pixman_op_t			op,
			    pixman_image_t *		src,
			    pixman_image_t *		dst,
			    pixman_format_code_t	mask_format,
			    int				x_src,
			    int				y_src,
			    int				x_dst,
			    int				y_dst,
			    int				n_tris,
			    const pixman_triangle_t *	tris)
{
    pixman_trapezoid_t *traps;

    if ((traps = convert_triangles (n_tris, tris)))
    {
	pixman_composite_trapezoids (op, src, dst, mask_format,
				     x_src, y_src, x_dst, y_dst,
				     n_tris * 2, traps);
	
	free (traps);
    }
}

PIXMAN_EXPORT void
pixman_add_triangles (pixman_image_t          *image,
		      int32_t	               x_off,
		      int32_t	               y_off,
		      int	               n_tris,
		      const pixman_triangle_t *tris)
{
    pixman_trapezoid_t *traps;

    if ((traps = convert_triangles (n_tris, tris)))
    {
	pixman_add_trapezoids (image, x_off, y_off,
			       n_tris * 2, traps);

	free (traps);
    }
}
