/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
/*
 *
 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
 * Copyright © 2000 SuSE, Inc.
 *             2005 Lars Knoll & Zack Rusin, Trolltech
 * Copyright © 2007 Red Hat, Inc.
 *
 *
 * 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 <math.h>
#include "pixman-private.h"

static inline pixman_fixed_32_32_t
dot (pixman_fixed_48_16_t x1,
     pixman_fixed_48_16_t y1,
     pixman_fixed_48_16_t z1,
     pixman_fixed_48_16_t x2,
     pixman_fixed_48_16_t y2,
     pixman_fixed_48_16_t z2)
{
    /*
     * Exact computation, assuming that the input values can
     * be represented as pixman_fixed_16_16_t
     */
    return x1 * x2 + y1 * y2 + z1 * z2;
}

static inline double
fdot (double x1,
      double y1,
      double z1,
      double x2,
      double y2,
      double z2)
{
    /*
     * Error can be unbound in some special cases.
     * Using clever dot product algorithms (for example compensated
     * dot product) would improve this but make the code much less
     * obvious
     */
    return x1 * x2 + y1 * y2 + z1 * z2;
}

static uint32_t
radial_compute_color (double                    a,
		      double                    b,
		      double                    c,
		      double                    inva,
		      double                    dr,
		      double                    mindr,
		      pixman_gradient_walker_t *walker,
		      pixman_repeat_t           repeat)
{
    /*
     * In this function error propagation can lead to bad results:
     *  - discr can have an unbound error (if b*b-a*c is very small),
     *    potentially making it the opposite sign of what it should have been
     *    (thus clearing a pixel that would have been colored or vice-versa)
     *    or propagating the error to sqrtdiscr;
     *    if discr has the wrong sign or b is very small, this can lead to bad
     *    results
     *
     *  - the algorithm used to compute the solutions of the quadratic
     *    equation is not numerically stable (but saves one division compared
     *    to the numerically stable one);
     *    this can be a problem if a*c is much smaller than b*b
     *
     *  - the above problems are worse if a is small (as inva becomes bigger)
     */
    double discr;

    if (a == 0)
    {
	double t;

	if (b == 0)
	    return 0;

	t = pixman_fixed_1 / 2 * c / b;
	if (repeat == PIXMAN_REPEAT_NONE)
	{
	    if (0 <= t && t <= pixman_fixed_1)
		return _pixman_gradient_walker_pixel (walker, t);
	}
	else
	{
	    if (t * dr >= mindr)
		return _pixman_gradient_walker_pixel (walker, t);
	}

	return 0;
    }

    discr = fdot (b, a, 0, b, -c, 0);
    if (discr >= 0)
    {
	double sqrtdiscr, t0, t1;

	sqrtdiscr = sqrt (discr);
	t0 = (b + sqrtdiscr) * inva;
	t1 = (b - sqrtdiscr) * inva;

	/*
	 * The root that must be used is the biggest one that belongs
	 * to the valid range ([0,1] for PIXMAN_REPEAT_NONE, any
	 * solution that results in a positive radius otherwise).
	 *
	 * If a > 0, t0 is the biggest solution, so if it is valid, it
	 * is the correct result.
	 *
	 * If a < 0, only one of the solutions can be valid, so the
	 * order in which they are tested is not important.
	 */
	if (repeat == PIXMAN_REPEAT_NONE)
	{
	    if (0 <= t0 && t0 <= pixman_fixed_1)
		return _pixman_gradient_walker_pixel (walker, t0);
	    else if (0 <= t1 && t1 <= pixman_fixed_1)
		return _pixman_gradient_walker_pixel (walker, t1);
	}
	else
	{
	    if (t0 * dr >= mindr)
		return _pixman_gradient_walker_pixel (walker, t0);
	    else if (t1 * dr >= mindr)
		return _pixman_gradient_walker_pixel (walker, t1);
	}
    }

    return 0;
}

static uint32_t *
radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
{
    /*
     * Implementation of radial gradients following the PDF specification.
     * See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference
     * Manual (PDF 32000-1:2008 at the time of this writing).
     *
     * In the radial gradient problem we are given two circles (c₁,r₁) and
     * (c₂,r₂) that define the gradient itself.
     *
     * Mathematically the gradient can be defined as the family of circles
     *
     *     ((1-t)·c₁ + t·(c₂), (1-t)·r₁ + t·r₂)
     *
     * excluding those circles whose radius would be < 0. When a point
     * belongs to more than one circle, the one with a bigger t is the only
     * one that contributes to its color. When a point does not belong
     * to any of the circles, it is transparent black, i.e. RGBA (0, 0, 0, 0).
     * Further limitations on the range of values for t are imposed when
     * the gradient is not repeated, namely t must belong to [0,1].
     *
     * The graphical result is the same as drawing the valid (radius > 0)
     * circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient
     * is not repeated) using SOURCE operator composition.
     *
     * It looks like a cone pointing towards the viewer if the ending circle
     * is smaller than the starting one, a cone pointing inside the page if
     * the starting circle is the smaller one and like a cylinder if they
     * have the same radius.
     *
     * What we actually do is, given the point whose color we are interested
     * in, compute the t values for that point, solving for t in:
     *
     *     length((1-t)·c₁ + t·(c₂) - p) = (1-t)·r₁ + t·r₂
     *
     * Let's rewrite it in a simpler way, by defining some auxiliary
     * variables:
     *
     *     cd = c₂ - c₁
     *     pd = p - c₁
     *     dr = r₂ - r₁
     *     length(t·cd - pd) = r₁ + t·dr
     *
     * which actually means
     *
     *     hypot(t·cdx - pdx, t·cdy - pdy) = r₁ + t·dr
     *
     * or
     *
     *     ⎷((t·cdx - pdx)² + (t·cdy - pdy)²) = r₁ + t·dr.
     *
     * If we impose (as stated earlier) that r₁ + t·dr >= 0, it becomes:
     *
     *     (t·cdx - pdx)² + (t·cdy - pdy)² = (r₁ + t·dr)²
     *
     * where we can actually expand the squares and solve for t:
     *
     *     t²cdx² - 2t·cdx·pdx + pdx² + t²cdy² - 2t·cdy·pdy + pdy² =
     *       = r₁² + 2·r₁·t·dr + t²·dr²
     *
     *     (cdx² + cdy² - dr²)t² - 2(cdx·pdx + cdy·pdy + r₁·dr)t +
     *         (pdx² + pdy² - r₁²) = 0
     *
     *     A = cdx² + cdy² - dr²
     *     B = pdx·cdx + pdy·cdy + r₁·dr
     *     C = pdx² + pdy² - r₁²
     *     At² - 2Bt + C = 0
     *
     * The solutions (unless the equation degenerates because of A = 0) are:
     *
     *     t = (B ± ⎷(B² - A·C)) / A
     *
     * The solution we are going to prefer is the bigger one, unless the
     * radius associated to it is negative (or it falls outside the valid t
     * range).
     *
     * Additional observations (useful for optimizations):
     * A does not depend on p
     *
     * A < 0 <=> one of the two circles completely contains the other one
     *   <=> for every p, the radiuses associated with the two t solutions
     *       have opposite sign
     */
    pixman_image_t *image = iter->image;
    int x = iter->x;
    int y = iter->y;
    int width = iter->width;
    uint32_t *buffer = iter->buffer;

    gradient_t *gradient = (gradient_t *)image;
    radial_gradient_t *radial = (radial_gradient_t *)image;
    uint32_t *end = buffer + width;
    pixman_gradient_walker_t walker;
    pixman_vector_t v, unit;

    /* 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;

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

    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;
    }

    if (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1)
    {
	/*
	 * Given:
	 *
	 * t = (B ± ⎷(B² - A·C)) / A
	 *
	 * where
	 *
	 * A = cdx² + cdy² - dr²
	 * B = pdx·cdx + pdy·cdy + r₁·dr
	 * C = pdx² + pdy² - r₁²
	 * det = B² - A·C
	 *
	 * Since we have an affine transformation, we know that (pdx, pdy)
	 * increase linearly with each pixel,
	 *
	 * pdx = pdx₀ + n·ux,
	 * pdy = pdy₀ + n·uy,
	 *
	 * we can then express B, C and det through multiple differentiation.
	 */
	pixman_fixed_32_32_t b, db, c, dc, ddc;

	/* warning: this computation may overflow */
	v.vector[0] -= radial->c1.x;
	v.vector[1] -= radial->c1.y;

	/*
	 * B and C are computed and updated exactly.
	 * If fdot was used instead of dot, in the worst case it would
	 * lose 11 bits of precision in each of the multiplication and
	 * summing up would zero out all the bit that were preserved,
	 * thus making the result 0 instead of the correct one.
	 * This would mean a worst case of unbound relative error or
	 * about 2^10 absolute error
	 */
	b = dot (v.vector[0], v.vector[1], radial->c1.radius,
		 radial->delta.x, radial->delta.y, radial->delta.radius);
	db = dot (unit.vector[0], unit.vector[1], 0,
		  radial->delta.x, radial->delta.y, 0);

	c = dot (v.vector[0], v.vector[1],
		 -((pixman_fixed_48_16_t) radial->c1.radius),
		 v.vector[0], v.vector[1], radial->c1.radius);
	dc = dot (2 * (pixman_fixed_48_16_t) v.vector[0] + unit.vector[0],
		  2 * (pixman_fixed_48_16_t) v.vector[1] + unit.vector[1],
		  0,
		  unit.vector[0], unit.vector[1], 0);
	ddc = 2 * dot (unit.vector[0], unit.vector[1], 0,
		       unit.vector[0], unit.vector[1], 0);

	while (buffer < end)
	{
	    if (!mask || *mask++)
	    {
		*buffer = radial_compute_color (radial->a, b, c,
						radial->inva,
						radial->delta.radius,
						radial->mindr,
						&walker,
						image->common.repeat);
	    }

	    b += db;
	    c += dc;
	    dc += ddc;
	    ++buffer;
	}
    }
    else
    {
	/* projective */
	/* Warning:
	 * error propagation guarantees are much looser than in the affine case
	 */
	while (buffer < end)
	{
	    if (!mask || *mask++)
	    {
		if (v.vector[2] != 0)
		{
		    double pdx, pdy, invv2, b, c;

		    invv2 = 1. * pixman_fixed_1 / v.vector[2];

		    pdx = v.vector[0] * invv2 - radial->c1.x;
		    /*    / pixman_fixed_1 */

		    pdy = v.vector[1] * invv2 - radial->c1.y;
		    /*    / pixman_fixed_1 */

		    b = fdot (pdx, pdy, radial->c1.radius,
			      radial->delta.x, radial->delta.y,
			      radial->delta.radius);
		    /*  / pixman_fixed_1 / pixman_fixed_1 */

		    c = fdot (pdx, pdy, -radial->c1.radius,
			      pdx, pdy, radial->c1.radius);
		    /*  / pixman_fixed_1 / pixman_fixed_1 */

		    *buffer = radial_compute_color (radial->a, b, c,
						    radial->inva,
						    radial->delta.radius,
						    radial->mindr,
						    &walker,
						    image->common.repeat);
		}
		else
		{
		    *buffer = 0;
		}
	    }

	    ++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 *
radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
{
    uint32_t *buffer = radial_get_scanline_narrow (iter, NULL);

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

    return buffer;
}

void
_pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
{
    if (iter->iter_flags & ITER_NARROW)
	iter->get_scanline = radial_get_scanline_narrow;
    else
	iter->get_scanline = radial_get_scanline_wide;
}

PIXMAN_EXPORT pixman_image_t *
pixman_image_create_radial_gradient (const pixman_point_fixed_t *  inner,
                                     const pixman_point_fixed_t *  outer,
                                     pixman_fixed_t                inner_radius,
                                     pixman_fixed_t                outer_radius,
                                     const pixman_gradient_stop_t *stops,
                                     int                           n_stops)
{
    pixman_image_t *image;
    radial_gradient_t *radial;

    image = _pixman_image_allocate ();

    if (!image)
	return NULL;

    radial = &image->radial;

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

    image->type = RADIAL;

    radial->c1.x = inner->x;
    radial->c1.y = inner->y;
    radial->c1.radius = inner_radius;
    radial->c2.x = outer->x;
    radial->c2.y = outer->y;
    radial->c2.radius = outer_radius;

    /* warning: this computations may overflow */
    radial->delta.x = radial->c2.x - radial->c1.x;
    radial->delta.y = radial->c2.y - radial->c1.y;
    radial->delta.radius = radial->c2.radius - radial->c1.radius;

    /* computed exactly, then cast to double -> every bit of the double
       representation is correct (53 bits) */
    radial->a = dot (radial->delta.x, radial->delta.y, -radial->delta.radius,
		     radial->delta.x, radial->delta.y, radial->delta.radius);
    if (radial->a != 0)
	radial->inva = 1. * pixman_fixed_1 / radial->a;

    radial->mindr = -1. * pixman_fixed_1 * radial->c1.radius;

    return image;
}
