/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
/*
 * Copyright © 2000 SuSE, Inc.
 * Copyright © 2007 Red Hat, Inc.
 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
 *             2005 Lars Knoll & Zack Rusin, Trolltech
 *
 * 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.
 *
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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 <stdlib.h>
#include "pixman-private.h"

static pixman_bool_t
linear_gradient_is_horizontal (pixman_image_t *image,
			       int             x,
			       int             y,
			       int             width,
			       int             height)
{
    linear_gradient_t *linear = (linear_gradient_t *)image;
    pixman_vector_t v;
    pixman_fixed_32_32_t l;
    pixman_fixed_48_16_t dx, dy;
    double inc;

    if (image->common.transform)
    {
	/* projective transformation */
	if (image->common.transform->matrix[2][0] != 0 ||
	    image->common.transform->matrix[2][1] != 0 ||
	    image->common.transform->matrix[2][2] == 0)
	{
	    return FALSE;
	}

	v.vector[0] = image->common.transform->matrix[0][1];
	v.vector[1] = image->common.transform->matrix[1][1];
	v.vector[2] = image->common.transform->matrix[2][2];
    }
    else
    {
	v.vector[0] = 0;
	v.vector[1] = pixman_fixed_1;
	v.vector[2] = pixman_fixed_1;
    }

    dx = linear->p2.x - linear->p1.x;
    dy = linear->p2.y - linear->p1.y;

    l = dx * dx + dy * dy;

    if (l == 0)
	return FALSE;

    /*
     * compute how much the input of the gradient walked changes
     * when moving vertically through the whole image
     */
    inc = height * (double) pixman_fixed_1 * pixman_fixed_1 *
	(dx * v.vector[0] + dy * v.vector[1]) /
	(v.vector[2] * (double) l);

    /* check that casting to integer would result in 0 */
    if (-1 < inc && inc < 1)
	return TRUE;

    return FALSE;
}

static uint32_t *
linear_get_scanline_narrow (pixman_iter_t  *iter,
			    const uint32_t *mask)
{
    pixman_image_t *image  = iter->image;
    int             x      = iter->x;
    int             y      = iter->y;
    int             width  = iter->width;
    uint32_t *      buffer = iter->buffer;

    pixman_vector_t v, unit;
    pixman_fixed_32_32_t l;
    pixman_fixed_48_16_t dx, dy;
    gradient_t *gradient = (gradient_t *)image;
    linear_gradient_t *linear = (linear_gradient_t *)image;
    uint32_t *end = buffer + width;
    pixman_gradient_walker_t walker;

    _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);

    /* reference point is the center of the pixel */
    v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
    v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
    v.vector[2] = pixman_fixed_1;

    if (image->common.transform)
    {
	if (!pixman_transform_point_3d (image->common.transform, &v))
	    return iter->buffer;

	unit.vector[0] = image->common.transform->matrix[0][0];
	unit.vector[1] = image->common.transform->matrix[1][0];
	unit.vector[2] = image->common.transform->matrix[2][0];
    }
    else
    {
	unit.vector[0] = pixman_fixed_1;
	unit.vector[1] = 0;
	unit.vector[2] = 0;
    }

    dx = linear->p2.x - linear->p1.x;
    dy = linear->p2.y - linear->p1.y;

    l = dx * dx + dy * dy;

    if (l == 0 || unit.vector[2] == 0)
    {
	/* affine transformation only */
        pixman_fixed_32_32_t t, next_inc;
	double inc;

	if (l == 0 || v.vector[2] == 0)
	{
	    t = 0;
	    inc = 0;
	}
	else
	{
	    double invden, v2;

	    invden = pixman_fixed_1 * (double) pixman_fixed_1 /
		(l * (double) v.vector[2]);
	    v2 = v.vector[2] * (1. / pixman_fixed_1);
	    t = ((dx * v.vector[0] + dy * v.vector[1]) - 
		 (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
	    inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden;
	}
	next_inc = 0;

	if (((pixman_fixed_32_32_t )(inc * width)) == 0)
	{
	    register uint32_t color;

	    color = _pixman_gradient_walker_pixel (&walker, t);
	    while (buffer < end)
		*buffer++ = color;
	}
	else
	{
	    int i;

	    i = 0;
	    while (buffer < end)
	    {
		if (!mask || *mask++)
		{
		    *buffer = _pixman_gradient_walker_pixel (&walker,
							     t + next_inc);
		}
		i++;
		next_inc = inc * i;
		buffer++;
	    }
	}
    }
    else
    {
	/* projective transformation */
        double t;

	t = 0;

	while (buffer < end)
	{
	    if (!mask || *mask++)
	    {
	        if (v.vector[2] != 0)
		{
		    double invden, v2;

		    invden = pixman_fixed_1 * (double) pixman_fixed_1 /
			(l * (double) v.vector[2]);
		    v2 = v.vector[2] * (1. / pixman_fixed_1);
		    t = ((dx * v.vector[0] + dy * v.vector[1]) - 
			 (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
		}

		*buffer = _pixman_gradient_walker_pixel (&walker, t);
	    }

	    ++buffer;

	    v.vector[0] += unit.vector[0];
	    v.vector[1] += unit.vector[1];
	    v.vector[2] += unit.vector[2];
	}
    }

    iter->y++;

    return iter->buffer;
}

static uint32_t *
linear_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
{
    uint32_t *buffer = linear_get_scanline_narrow (iter, NULL);

    pixman_expand_to_float (
	(argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);

    return buffer;
}

void
_pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t  *iter)
{
    if (linear_gradient_is_horizontal (
	    iter->image, iter->x, iter->y, iter->width, iter->height))
    {
	if (iter->iter_flags & ITER_NARROW)
	    linear_get_scanline_narrow (iter, NULL);
	else
	    linear_get_scanline_wide (iter, NULL);

	iter->get_scanline = _pixman_iter_get_scanline_noop;
    }
    else
    {
	if (iter->iter_flags & ITER_NARROW)
	    iter->get_scanline = linear_get_scanline_narrow;
	else
	    iter->get_scanline = linear_get_scanline_wide;
    }
}

PIXMAN_EXPORT pixman_image_t *
pixman_image_create_linear_gradient (const pixman_point_fixed_t *  p1,
                                     const pixman_point_fixed_t *  p2,
                                     const pixman_gradient_stop_t *stops,
                                     int                           n_stops)
{
    pixman_image_t *image;
    linear_gradient_t *linear;

    image = _pixman_image_allocate ();

    if (!image)
	return NULL;

    linear = &image->linear;

    if (!_pixman_init_gradient (&linear->common, stops, n_stops))
    {
	free (image);
	return NULL;
    }

    linear->p1 = *p1;
    linear->p2 = *p2;

    image->type = LINEAR;

    return image;
}

