/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre
 *			Copyright (c) Telecom ParisTech 2000-2023
 *					All rights reserved
 *
 *  This file is part of GPAC / common tools sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */


#include <gpac/path2d.h>

#if !defined(GPAC_DISABLE_EVG) || defined(GPAC_HAS_FREETYPE)

GF_EXPORT
GF_Path *gf_path_new()
{
	GF_Path *gp;
	GF_SAFEALLOC(gp, GF_Path);
	if (!gp) return NULL;
	gp->fineness = FIX_ONE;
	return gp;
}

GF_EXPORT
void gf_path_reset(GF_Path *gp)
{
	Fixed fineness;
	u32 flags;
	if (!gp) return;
	if (gp->contours) gf_free(gp->contours);
	if (gp->tags) gf_free(gp->tags);
	if (gp->points) gf_free(gp->points);
	fineness = gp->fineness ? gp->fineness : FIX_ONE;
	flags = gp->flags;
	memset(gp, 0, sizeof(GF_Path));
	gp->flags = flags | GF_PATH_FLATTENED | GF_PATH_BBOX_DIRTY;
	gp->fineness = fineness;
}

GF_EXPORT
GF_Path *gf_path_clone(GF_Path *gp)
{
	GF_Path *dst;
	GF_SAFEALLOC(dst, GF_Path);
	if (!dst) return NULL;
	dst->contours = (u32 *)gf_malloc(sizeof(u32)*gp->n_contours);
	if (!dst->contours) {
		gf_free(dst);
		return NULL;
	}
	dst->points = (GF_Point2D *) gf_malloc(sizeof(GF_Point2D)*gp->n_points);
	if (!dst->points) {
		gf_free(dst->contours);
		gf_free(dst);
		return NULL;
	}
	dst->tags = (u8 *) gf_malloc(sizeof(u8)*gp->n_points);
	if (!dst->tags) {
		gf_free(dst->points);
		gf_free(dst->contours);
		gf_free(dst);
		return NULL;
	}
	memcpy(dst->contours, gp->contours, sizeof(u32)*gp->n_contours);
	dst->n_contours = gp->n_contours;
	memcpy(dst->points, gp->points, sizeof(GF_Point2D)*gp->n_points);
	memcpy(dst->tags, gp->tags, sizeof(u8)*gp->n_points);
	dst->n_alloc_points = dst->n_points = gp->n_points;
	dst->flags = gp->flags;
	dst->bbox = gp->bbox;
	dst->fineness = gp->fineness;
	return dst;
}

GF_EXPORT
void gf_path_del(GF_Path *gp)
{
	if (!gp) return;
	if (gp->contours) gf_free(gp->contours);
	if (gp->tags) gf_free(gp->tags);
	if (gp->points) gf_free(gp->points);
	gf_free(gp);
}

#define GF_2D_REALLOC(_gp)	\
	if (_gp->n_alloc_points < _gp->n_points+3) {	\
		_gp->n_alloc_points = (_gp->n_alloc_points<5) ? 10 : (_gp->n_alloc_points*2);	\
		_gp->points = (GF_Point2D *)gf_realloc(_gp->points, sizeof(GF_Point2D)*(_gp->n_alloc_points));	\
		_gp->tags = (u8 *) gf_realloc(_gp->tags, sizeof(u8)*(_gp->n_alloc_points));	\
	}	\
 

GF_EXPORT
GF_Err gf_path_add_move_to(GF_Path *gp, Fixed x, Fixed y)
{
	if (!gp) return GF_BAD_PARAM;

#if 0
	/*skip empty paths*/
	if ((gp->n_contours>=2) && (gp->contours[gp->n_contours-2]+1==gp->contours[gp->n_contours-1])) {
		gp->points[gp->n_points].x = x;
		gp->points[gp->n_points].y = y;
		return GF_OK;
	}
#endif

	gp->contours = (u32 *) gf_realloc(gp->contours, sizeof(u32)*(gp->n_contours+1));
	GF_2D_REALLOC(gp)

	gp->points[gp->n_points].x = x;
	gp->points[gp->n_points].y = y;
	gp->tags[gp->n_points] = 1;
	/*set end point*/
	gp->contours[gp->n_contours] = gp->n_points;
	/*new contour*/
	gp->n_contours++;
	gp->n_points++;
	gp->flags |= GF_PATH_BBOX_DIRTY;
	return GF_OK;
}

GF_EXPORT
GF_Err gf_path_add_move_to_vec(GF_Path *gp, GF_Point2D *pt) {
	return gf_path_add_move_to(gp, pt->x, pt->y);
}

GF_EXPORT
GF_Err gf_path_add_line_to(GF_Path *gp, Fixed x, Fixed y)
{
	if (!gp || !gp->n_contours) return GF_BAD_PARAM;
	/*we allow line to same point as move (seen in SVG sequences) - striking will make a point*/

	GF_2D_REALLOC(gp)
	gp->points[gp->n_points].x = x;
	gp->points[gp->n_points].y = y;
	gp->tags[gp->n_points] = 1;
	/*set end point*/
	gp->contours[gp->n_contours-1] = gp->n_points;
	gp->n_points++;
	gp->flags |= GF_PATH_BBOX_DIRTY;
	return GF_OK;
}

GF_EXPORT
GF_Err gf_path_add_line_to_vec(GF_Path *gp, GF_Point2D *pt) {
	return gf_path_add_line_to(gp, pt->x, pt->y);
}

GF_EXPORT
GF_Err gf_path_close(GF_Path *gp)
{
	GF_Point2D start, end;
	if (!gp || !gp->n_contours) return GF_BAD_PARAM;

	if (gp->n_contours<=1) start = gp->points[0];
	else start = gp->points[gp->contours[gp->n_contours-2] + 1];
	end = gp->points[gp->n_points-1];
	end.x -= start.x;
	end.y -= start.y;
	if (FIX_ONE/100 < ABS(end.x) || FIX_ONE/100 < ABS(end.y)) {
		GF_Err e = gf_path_add_line_to(gp, start.x, start.y);
		if (e) return e;
	}
	gp->tags[gp->n_points-1] = GF_PATH_CLOSE;
	return GF_OK;
}

GF_EXPORT
GF_Err gf_path_add_cubic_to(GF_Path *gp, Fixed c1_x, Fixed c1_y, Fixed c2_x, Fixed c2_y, Fixed x, Fixed y)
{
	if (!gp || !gp->n_contours) return GF_BAD_PARAM;
	GF_2D_REALLOC(gp)
	gp->points[gp->n_points].x = c1_x;
	gp->points[gp->n_points].y = c1_y;
	gp->tags[gp->n_points] = GF_PATH_CURVE_CUBIC;
	gp->n_points++;
	gp->points[gp->n_points].x = c2_x;
	gp->points[gp->n_points].y = c2_y;
	gp->tags[gp->n_points] = GF_PATH_CURVE_CUBIC;
	gp->n_points++;
	gp->points[gp->n_points].x = x;
	gp->points[gp->n_points].y = y;
	gp->tags[gp->n_points] = GF_PATH_CURVE_ON;
	/*set end point*/
	gp->contours[gp->n_contours-1] = gp->n_points;
	gp->n_points++;
	gp->flags |= GF_PATH_BBOX_DIRTY;
	gp->flags &= ~GF_PATH_FLATTENED;
	return GF_OK;
}

GF_EXPORT
GF_Err gf_path_add_cubic_to_vec(GF_Path *gp, GF_Point2D *c1, GF_Point2D *c2, GF_Point2D *pt)
{
	return gf_path_add_cubic_to(gp, c1->x, c1->y, c2->x, c2->y, pt->x, pt->y);
}


GF_EXPORT
GF_Err gf_path_add_quadratic_to(GF_Path *gp, Fixed c_x, Fixed c_y, Fixed x, Fixed y)
{
	if (!gp || !gp->n_contours) return GF_BAD_PARAM;
	GF_2D_REALLOC(gp)
	gp->points[gp->n_points].x = c_x;
	gp->points[gp->n_points].y = c_y;
	gp->tags[gp->n_points] = GF_PATH_CURVE_CONIC;
	gp->n_points++;
	gp->points[gp->n_points].x = x;
	gp->points[gp->n_points].y = y;
	gp->tags[gp->n_points] = GF_PATH_CURVE_ON;
	/*set end point*/
	gp->contours[gp->n_contours-1] = gp->n_points;
	gp->n_points++;
	gp->flags |= GF_PATH_BBOX_DIRTY;
	gp->flags &= ~GF_PATH_FLATTENED;
	return GF_OK;
}
GF_EXPORT
GF_Err gf_path_add_quadratic_to_vec(GF_Path *gp, GF_Point2D *c, GF_Point2D *pt)
{
	return gf_path_add_quadratic_to(gp, c->x, c->y, pt->x, pt->y);
}

/*adds rectangle centered on cx, cy*/
GF_EXPORT
GF_Err gf_path_add_rect_center(GF_Path *gp, Fixed cx, Fixed cy, Fixed w, Fixed h)
{
	GF_Err e = gf_path_add_move_to(gp, cx - w/2, cy - h/2);
	if (e) return e;
	e = gf_path_add_line_to(gp, cx + w/2, cy - h/2);
	if (e) return e;
	e = gf_path_add_line_to(gp, cx + w/2, cy + h/2);
	if (e) return e;
	e = gf_path_add_line_to(gp, cx - w/2, cy + h/2);
	if (e) return e;
	return gf_path_close(gp);
}

GF_EXPORT
GF_Err gf_path_add_rect(GF_Path *gp, Fixed ox, Fixed oy, Fixed w, Fixed h)
{
	GF_Err e = gf_path_add_move_to(gp, ox, oy);
	if (e) return e;
	e = gf_path_add_line_to(gp, ox + w, oy);
	if (e) return e;
	e = gf_path_add_line_to(gp, ox+w, oy-h);
	if (e) return e;
	e = gf_path_add_line_to(gp, ox, oy-h);
	if (e) return e;
	return gf_path_close(gp);
}

#define GF_2D_DEFAULT_RES	64

GF_EXPORT
GF_Err gf_path_add_ellipse(GF_Path *gp, Fixed cx, Fixed cy, Fixed a_axis, Fixed b_axis)
{
	GF_Err e;
	Fixed _vx, _vy, cur;
	u32 i;
	a_axis /= 2;
	b_axis /= 2;
	e = gf_path_add_move_to(gp, cx+a_axis, cy);
	if (e) return e;
	for (i=1; i<GF_2D_DEFAULT_RES; i++) {
		cur = GF_2PI*i/GF_2D_DEFAULT_RES;
		_vx = gf_mulfix(a_axis, gf_cos(cur) );
		_vy = gf_mulfix(b_axis, gf_sin(cur) );
		e = gf_path_add_line_to(gp, _vx + cx, _vy + cy);
		if (e) return e;
	}
	return gf_path_close(gp);
}

GF_Err gf_path_add_subpath(GF_Path *gp, GF_Path *src, GF_Matrix2D *mx)
{
	u32 i;
	if (!src) return GF_OK;
	gp->contours = (u32*)gf_realloc(gp->contours, sizeof(u32) * (gp->n_contours + src->n_contours));
	if (!gp->contours) return GF_OUT_OF_MEM;
	for (i=0; i<src->n_contours; i++) {
		gp->contours[i+gp->n_contours] = src->contours[i] + gp->n_points;
	}
	gp->n_contours += src->n_contours;
	gp->n_alloc_points += src->n_alloc_points;
	gp->points = (GF_Point2D*)gf_realloc(gp->points, sizeof(GF_Point2D)*gp->n_alloc_points);
	if (!gp->points) return GF_OUT_OF_MEM;
	gp->tags = (u8*)gf_realloc(gp->tags, sizeof(u8)*gp->n_alloc_points);
	if (!gp->tags) return GF_OUT_OF_MEM;
	if (src->n_points) {
		memcpy(gp->points + gp->n_points, src->points, sizeof(GF_Point2D)*src->n_points);
		if (mx) {
			for (i=0; i<src->n_points; i++) {
				gf_mx2d_apply_coords(mx, &gp->points[i+gp->n_points].x, &gp->points[i+gp->n_points].y);
			}
		}
		memcpy(gp->tags + gp->n_points, src->tags, sizeof(u8)*src->n_points);
		gp->n_points += src->n_points;
	}
	gf_rect_union(&gp->bbox, &src->bbox);
	if (!(src->flags & GF_PATH_FLATTENED)) gp->flags &= ~GF_PATH_FLATTENED;
	if (src->flags & GF_PATH_BBOX_DIRTY) gp->flags |= GF_PATH_BBOX_DIRTY;
	return GF_OK;
}

/*generic N-bezier*/
static void NBezier(GF_Point2D *pts, s32 n, Double mu, GF_Point2D *pt_out)
{
	s32 k,kn,nn,nkn;
	Double blend, muk, munk;
	pt_out->x = pt_out->y = 0;

	muk = 1;
	munk = pow(1-mu,(Double)n);
	for (k=0; k<=n; k++) {
		nn = n;
		kn = k;
		nkn = n - k;
		blend = muk * munk;
		muk *= mu;
		munk /= (1-mu);
		while (nn >= 1) {
			blend *= nn;
			nn--;
			if (kn > 1) {
				blend /= (double)kn;
				kn--;
			}
			if (nkn > 1) {
				blend /= (double)nkn;
				nkn--;
			}
		}
		pt_out->x += gf_mulfix(pts[k].x, FLT2FIX(blend));
		pt_out->y += gf_mulfix(pts[k].y, FLT2FIX(blend));
	}
}

static void gf_add_n_bezier(GF_Path *gp, GF_Point2D *newpts, u32 nbPoints)
{
	Double mu;
	u32 numPoints, i;
	GF_Point2D end;
	numPoints = (u32) FIX2INT(GF_2D_DEFAULT_RES * gp->fineness);
	mu = 0.0;
	if (numPoints) mu = 1/(Double)numPoints;
	for (i=1; i<numPoints; i++) {
		NBezier(newpts, nbPoints - 1, i*mu, &end);
		gf_path_add_line_to(gp, end.x, end.y);
	}
	gf_path_add_line_to(gp, newpts[nbPoints-1].x, newpts[nbPoints-1].y);
}

GF_EXPORT
GF_Err gf_path_add_bezier(GF_Path *gp, GF_Point2D *pts, u32 nbPoints)
{
	GF_Point2D *newpts;
	if (!gp->n_points) return GF_BAD_PARAM;

	newpts = (GF_Point2D *) gf_malloc(sizeof(GF_Point2D) * (nbPoints+1));
	newpts[0] = gp->points[gp->n_points-1];
	memcpy(&newpts[1], pts, sizeof(GF_Point2D) * nbPoints);

	gf_add_n_bezier(gp, newpts, nbPoints + 1);

	gf_free(newpts);
	return GF_OK;
}

GF_EXPORT
GF_Err gf_path_add_arc_to(GF_Path *gp, Fixed end_x, Fixed end_y, Fixed fa_x, Fixed fa_y, Fixed fb_x, Fixed fb_y, Bool cw)
{
	GF_Matrix2D mat, inv;
	Fixed angle, start_angle, end_angle, sweep, axis_w, axis_h, tmp, cx, cy, _vx, _vy, start_x, start_y;
	s32 i, num_steps;

	if (!gp->n_points) return GF_BAD_PARAM;

	start_x = gp->points[gp->n_points-1].x;
	start_y = gp->points[gp->n_points-1].y;

	cx = (fb_x + fa_x)/2;
	cy = (fb_y + fa_y)/2;

	angle = gf_atan2(fb_y-fa_y, fb_x-fa_x);
	gf_mx2d_init(mat);
	gf_mx2d_add_rotation(&mat, 0, 0, angle);
	gf_mx2d_add_translation(&mat, cx, cy);

	gf_mx2d_copy(inv, mat);
	gf_mx2d_inverse(&inv);
	gf_mx2d_apply_coords(&inv, &start_x, &start_y);
	gf_mx2d_apply_coords(&inv, &end_x, &end_y);
	gf_mx2d_apply_coords(&inv, &fa_x, &fa_y);
	gf_mx2d_apply_coords(&inv, &fb_x, &fb_y);

	//start angle and end angle
	start_angle = gf_atan2(start_y, start_x);
	end_angle = gf_atan2(end_y, end_x);
	tmp = gf_mulfix((start_x - fa_x), (start_x - fa_x)) + gf_mulfix((start_y - fa_y), (start_y - fa_y));
	axis_w = gf_sqrt(tmp);
	tmp = gf_mulfix((start_x - fb_x) , (start_x - fb_x)) + gf_mulfix((start_y - fb_y), (start_y - fb_y));
	axis_w += gf_sqrt(tmp);
	axis_w /= 2;
	axis_h = gf_sqrt(gf_mulfix(axis_w, axis_w) - gf_mulfix(fa_x,fa_x));
	sweep = end_angle - start_angle;

	if (cw) {
		if (sweep>0) sweep -= 2*GF_PI;
	} else {
		if (sweep<0) sweep += 2*GF_PI;
	}
	num_steps = GF_2D_DEFAULT_RES/2;
	for (i=1; i<=num_steps; i++) {
		angle = start_angle + sweep*i/num_steps;
		_vx = gf_mulfix(axis_w, gf_cos(angle));
		_vy = gf_mulfix(axis_h, gf_sin(angle));
		/*re-invert*/
		gf_mx2d_apply_coords(&mat, &_vx, &_vy);
		gf_path_add_line_to(gp, _vx, _vy);
	}
	return GF_OK;
}



GF_EXPORT
GF_Err gf_path_add_svg_arc_to(GF_Path *gp, Fixed end_x, Fixed end_y, Fixed r_x, Fixed r_y, Fixed x_axis_rotation, Bool large_arc_flag, Bool sweep_flag)
{
	Fixed start_x, start_y;
	Fixed xmid,ymid;
	Fixed xmidp,ymidp;
	Fixed xmidpsq,ymidpsq;
	Fixed phi, cos_phi, sin_phi;
	Fixed c_x, c_y;
	Fixed cxp, cyp;
	Fixed scale;
	Fixed rxsq, rysq;
	Fixed start_angle, sweep_angle;
	Fixed radius_scale;
	Fixed vx, vy, normv;
	Fixed ux, uy, normu;
	Fixed sign;
	u32 i, num_steps;

	if (!gp->n_points) return GF_BAD_PARAM;

	if (!r_x || !r_y) {
		gf_path_add_line_to(gp, end_x, end_y);
		return GF_OK;
	}

	if (r_x < 0) r_x = -r_x;
	if (r_y < 0) r_y = -r_y;

	start_x = gp->points[gp->n_points-1].x;
	start_y = gp->points[gp->n_points-1].y;

	phi = gf_mulfix(x_axis_rotation/180, GF_PI);
	cos_phi = gf_cos(phi);
	sin_phi = gf_sin(phi);
	xmid = (start_x - end_x)/2;
	ymid = (start_y - end_y)/2;
	if (!xmid && !ymid) {
		gf_path_add_line_to(gp, end_x, end_y);
		return GF_OK;
	}

	xmidp = gf_mulfix(cos_phi, xmid) + gf_mulfix(sin_phi, ymid);
	ymidp = gf_mulfix(-sin_phi, xmid) + gf_mulfix(cos_phi, ymid);
	xmidpsq = gf_mulfix(xmidp, xmidp);
	ymidpsq = gf_mulfix(ymidp, ymidp);

	rxsq = gf_mulfix(r_x, r_x);
	rysq = gf_mulfix(r_y, r_y);
	gf_assert(rxsq && rysq);

	radius_scale = gf_divfix(xmidpsq, rxsq) + gf_divfix(ymidpsq, rysq);
	if (radius_scale > FIX_ONE) {
		r_x = gf_mulfix(gf_sqrt(radius_scale), r_x);
		r_y = gf_mulfix(gf_sqrt(radius_scale), r_y);
		rxsq = gf_mulfix(r_x, r_x);
		rysq = gf_mulfix(r_y, r_y);
	}

#if 0
	/* Old code with overflow problems in fixed point,
	   sign was sometimes negative (cf tango SVG icons appointment-new.svg)*/

	sign = gf_mulfix(rxsq,ymidpsq) + gf_mulfix(rysq, xmidpsq);
	scale = FIX_ONE;
	/*FIXME - what if scale is 0 ??*/
	if (sign) scale = gf_divfix(
		                      (gf_mulfix(rxsq,rysq) - gf_mulfix(rxsq, ymidpsq) - gf_mulfix(rysq,xmidpsq)),
		                      sign
		                  );
#else
	/* New code: the sign variable computation is split into simpler cases and
	   the expression is divided by rxsq to reduce the range */
	if ((rxsq == 0 || ymidpsq ==0) && (rysq == 0 || xmidpsq == 0)) {
		scale = FIX_ONE;
	} else if (rxsq == 0 || ymidpsq ==0) {
		scale = gf_divfix(rxsq,xmidpsq) - FIX_ONE;
	} else if (rysq == 0 || xmidpsq == 0) {
		scale = gf_divfix(rysq,ymidpsq) - FIX_ONE;
	} else {
		Fixed tmp;
		tmp = gf_mulfix(gf_divfix(rysq, rxsq), xmidpsq);
		sign = ymidpsq + tmp;
		scale = gf_divfix((rysq - ymidpsq - tmp),sign);
	}
#endif
	/* precision problem may lead to negative value around zero, we need to take care of it before sqrt */
	scale = gf_sqrt(ABS(scale));

	cxp = gf_mulfix(scale, gf_divfix(gf_mulfix(r_x, ymidp),r_y));
	cyp = gf_mulfix(scale, -gf_divfix(gf_mulfix(r_y, xmidp),r_x));
	cxp = (large_arc_flag == sweep_flag ? - cxp : cxp);
	cyp = (large_arc_flag == sweep_flag ? - cyp : cyp);

	c_x = gf_mulfix(cos_phi, cxp) - gf_mulfix(sin_phi, cyp) + (start_x + end_x)/2;
	c_y = gf_mulfix(sin_phi, cxp) + gf_mulfix(cos_phi, cyp) + (start_y + end_y)/2;

	vx = gf_divfix(xmidp-cxp,r_x);
	vy = gf_divfix(ymidp-cyp,r_y);
	normv = gf_sqrt(gf_mulfix(vx, vx) + gf_mulfix(vy,vy));

	sign = vy;
	start_angle = gf_acos(gf_divfix(vx,normv));
	start_angle = (sign > 0 ? start_angle: -start_angle);

	ux = vx;
	uy = vy;

	vx = gf_divfix(-xmidp-cxp,r_x);
	vy = gf_divfix(-ymidp-cyp,r_y);
	normu = gf_sqrt(gf_mulfix(ux, ux) + gf_mulfix(uy,uy));

	sign = gf_mulfix(ux, vy) - gf_mulfix(uy, vx);
	sweep_angle = gf_divfix( gf_mulfix(ux,vx) + gf_mulfix(uy, vy), gf_mulfix(normu, normv) );
	/*numerical stability safety*/
	sweep_angle = MAX(-FIX_ONE, MIN(sweep_angle, FIX_ONE));
	sweep_angle = gf_acos(sweep_angle);
	sweep_angle = (sign > 0 ? sweep_angle: -sweep_angle);
	if (sweep_flag == 0) {
		if (sweep_angle > 0) sweep_angle -= GF_2PI;
	} else {
		if (sweep_angle < 0) sweep_angle += GF_2PI;
	}

	num_steps = GF_2D_DEFAULT_RES/2;
	for (i=1; i<=num_steps; i++) {
		Fixed _vx, _vy;
		Fixed _vxp, _vyp;
		Fixed angle = start_angle + sweep_angle*(s32)i/(s32)num_steps;
		_vx = gf_mulfix(r_x, gf_cos(angle));
		_vy = gf_mulfix(r_y, gf_sin(angle));
		_vxp = gf_mulfix(cos_phi, _vx) - gf_mulfix(sin_phi, _vy) + c_x;
		_vyp = gf_mulfix(sin_phi, _vx) + gf_mulfix(cos_phi, _vy) + c_y;
		gf_path_add_line_to(gp, _vxp, _vyp);
	}
	return GF_OK;
}

GF_EXPORT
GF_Err gf_path_add_arc(GF_Path *gp, Fixed radius, Fixed start_angle, Fixed end_angle, GF_Path2DArcCloseType close_type)
{
	GF_Err e;
	Fixed _vx, _vy, step, cur;
	s32 i, do_run;

	step = (end_angle - start_angle) / (GF_2D_DEFAULT_RES);
	radius *= 2;

	/*pie*/
	i=0;
	if (close_type==GF_PATH2D_ARC_PIE) {
		gf_path_add_move_to(gp, 0, 0);
		i=1;
	}
	do_run = 1;
	cur=start_angle;
	while (do_run) {
		if (cur>=end_angle) {
			do_run = 0;
			cur = end_angle;
		}
		_vx = gf_mulfix(radius, gf_cos(cur));
		_vy = gf_mulfix(radius, gf_sin(cur));
		if (!i) {
			e = gf_path_add_move_to(gp, _vx, _vy);
			i = 1;
		} else {
			e = gf_path_add_line_to(gp, _vx, _vy);
		}
		if (e) return e;
		cur+=step;
	}
	if (close_type!=GF_PATH2D_ARC_OPEN) e = gf_path_close(gp);
	return e;
}


GF_EXPORT
GF_Err gf_path_get_control_bounds(GF_Path *gp, GF_Rect *rc)
{
	GF_Point2D *pt, *end;
	Fixed xMin, xMax, yMin, yMax;
	if (!gp || !rc) return GF_BAD_PARAM;

	if (!gp->n_points) {
		rc->x = rc->y = rc->width = rc->height = 0;
		return GF_OK;
	}
	pt = gp->points;
	end = pt + gp->n_points;
	xMin = xMax = pt->x;
	yMin = yMax = pt->y;
	pt++;
	for ( ; pt < end; pt++ ) {
		Fixed v;
		v = pt->x;
		if (v < xMin) xMin = v;
		if (v > xMax) xMax = v;
		v = pt->y;
		if (v < yMin) yMin = v;
		if (v > yMax) yMax = v;
	}
	rc->x = xMin;
	rc->y = yMax;
	rc->width = xMax - xMin;
	rc->height = yMax - yMin;

#if 0
	/*take care of straight line path by adding a default width if height and vice-versa*/
	if (rc->height && !rc->width) {
		rc->width = 2*FIX_ONE;
		rc->x -= FIX_ONE;
	}
	else if (!rc->height && rc->width) {
		rc->height = 2*FIX_ONE;
		rc->y += FIX_ONE;
	}
#endif
	return GF_OK;
}

/*
 *	conic bbox computing taken from freetype
 *		Copyright 1996-2001, 2002, 2004 by
 *		David Turner, Robert Wilhelm, and Werner Lemberg.
 *	License: FTL or GPL
 */
static void gf_conic_check(Fixed y1, Fixed y2, Fixed y3, Fixed *min, Fixed *max)
{
	/* flat arc */
	if ((y1 <= y3) && (y2 == y1)) goto Suite;

	if ( y1 < y3 ) {
		/* ascending arc */
		if ((y2 >= y1) && (y2 <= y3)) goto Suite;
	} else {
		/* descending arc */
		if ((y2 >= y3) && (y2 <= y1)) {
			y2 = y1;
			y1 = y3;
			y3 = y2;
			goto Suite;
		}
	}
	y1 = y3 = y1 - gf_muldiv(y2 - y1, y2 - y1, y1 - 2*y2 + y3);

Suite:
	if ( y1 < *min ) *min = y1;
	if ( y3 > *max ) *max = y3;
}


/*
 *	cubic bbox computing taken from freetype
 *		Copyright 1996-2001, 2002, 2004 by
 *		David Turner, Robert Wilhelm, and Werner Lemberg.
 *	License: FTL or GPL

 *	Note: we're using the decomposition method, not the equation one which is not usable with Floats (only 16.16 fixed)
*/
static void gf_cubic_check(Fixed p1, Fixed p2, Fixed p3, Fixed p4, Fixed *min, Fixed *max)
{
	Fixed stack[32*3 + 1], *arc;
	arc = stack;
	arc[0] = p1;
	arc[1] = p2;
	arc[2] = p3;
	arc[3] = p4;

	do {
		Fixed y1 = arc[0];
		Fixed y2 = arc[1];
		Fixed y3 = arc[2];
		Fixed y4 = arc[3];

		if (ABS(y1)<FIX_EPSILON) arc[0] = y1 = 0;
		if (ABS(y2)<FIX_EPSILON) arc[1] = y2 = 0;
		if (ABS(y3)<FIX_EPSILON) arc[2] = y3 = 0;
		if (ABS(y4)<FIX_EPSILON) arc[3] = y4 = 0;

		if ( y1 == y4 ) {
			/* flat */
			if ((y1 == y2) && (y1 == y3)) goto Test;
		}
		else if ( y1 < y4 ) {
			/* ascending */
			if ((y2 >= y1) && (y2 <= y4) && (y3 >= y1) && (y3 <= y4)) goto Test;
		} else {
			/* descending */
			if ((y2 >= y4) && (y2 <= y1) && (y3 >= y4) && (y3 <= y1)) {
				y2 = y1;
				y1 = y4;
				y4 = y2;
				goto Test;
			}
		}
		/* unknown direction -- split the arc in two */
		arc[6] = y4;
		arc[1] = y1 = ( y1 + y2 ) / 2;
		arc[5] = y4 = ( y4 + y3 ) / 2;
		y2 = ( y2 + y3 ) / 2;
		arc[2] = y1 = ( y1 + y2 ) / 2;
		arc[4] = y4 = ( y4 + y2 ) / 2;
		arc[3] = ( y1 + y4 ) / 2;

		arc += 3;
		goto Suite;

Test:
		if ( y1 < *min ) *min = y1;
		if ( y4 > *max ) *max = y4;
		arc -= 3;
Suite:
		;
	}
	while ( arc >= stack );
}


GF_EXPORT
GF_Err gf_path_get_bounds(GF_Path *gp, GF_Rect *rc)
{
	u32 i;
	GF_Point2D *pt, *end;
	Fixed xMin, xMax, yMin, yMax, cxMin, cxMax, cyMin, cyMax;
	if (!gp || !rc) return GF_BAD_PARAM;

	if (!(gp->flags & GF_PATH_BBOX_DIRTY)) {
		*rc = gp->bbox;
		return GF_OK;
	}
	/*no curves in path*/
	if (gp->flags & GF_PATH_FLATTENED) {
		GF_Err e;
		gp->flags &= ~GF_PATH_BBOX_DIRTY;
		e = gf_path_get_control_bounds(gp, &gp->bbox);
		*rc = gp->bbox;
		return e;
	}

	gp->flags &= ~GF_PATH_BBOX_DIRTY;

	if (!gp->n_points) {
		gp->bbox.x = gp->bbox.y = gp->bbox.width = gp->bbox.height = 0;
		*rc = gp->bbox;
		return GF_OK;
	}
	pt = gp->points;
	xMin = xMax = cxMin = cxMax = pt->x;
	yMin = yMax = cyMin = cyMax = pt->y;
	pt++;
	for (i=1 ; i < gp->n_points; i++ ) {
		Fixed x, y;
		x = pt->x;
		y = pt->y;
		if (x < cxMin) cxMin = x;
		if (x > cxMax) cxMax = x;
		if (y < cyMin) cyMin = y;
		if (y > cyMax) cyMax = y;
		/*point on curve, update*/
		if (gp->tags[i] & GF_PATH_CURVE_ON) {
			if (x < xMin) xMin = x;
			if (x > xMax) xMax = x;
			if (y < yMin) yMin = y;
			if (y > yMax) yMax = y;
		}
		pt++;
	}

	/*control box is bigger than box , decompose curves*/
	if ((cxMin < xMin) || (cxMax > xMax) || (cyMin < yMin) || (cyMax > yMax)) {
		GF_Point2D *ctrl1, *ctrl2;
		/*decompose all control points*/
		pt = gp->points;
		for (i=1 ; i < gp->n_points; ) {
			switch (gp->tags[i]) {
			case GF_PATH_CURVE_ON:
			case GF_PATH_CLOSE:
				pt = &gp->points[i];
				i++;
				break;
			case GF_PATH_CURVE_CONIC:
				/*decompose*/
				ctrl1 = &gp->points[i];
				end = &gp->points[i+1];
				if ((ctrl1->x < xMin) || (ctrl1->x > xMax))
					gf_conic_check(pt->x, ctrl1->x, end->x, &xMin, &xMax);

				if ((ctrl1->y < yMin) || (ctrl1->y > yMax))
					gf_conic_check(pt->y, ctrl1->y, end->y, &yMin, &yMax);

				/*and move*/
				pt = end;
				i+=2;
				break;
			case GF_PATH_CURVE_CUBIC:
				/*decompose*/
				ctrl1 = &gp->points[i];
				ctrl2 = &gp->points[i+1];
				end = &gp->points[i+2];
				if ((ctrl1->x < xMin) || (ctrl1->x > xMax) || (ctrl2->x < xMin) || (ctrl2->x > xMax))
					gf_cubic_check(pt->x, ctrl1->x, ctrl2->x, end->x, &xMin, &xMax);

				if ((ctrl1->y < yMin) || (ctrl1->y > yMax) || (ctrl2->y < yMin) || (ctrl2->y > yMax))
					gf_cubic_check(pt->y, ctrl1->y, ctrl2->y, end->y, &yMin, &yMax);

				/*and move*/
				pt = end;
				i+=3;
				break;
			}
		}
	}
	gp->bbox.x = xMin;
	gp->bbox.y = yMax;
	gp->bbox.width = xMax - xMin;
	gp->bbox.height = yMax - yMin;
	*rc = gp->bbox;
	return GF_OK;
}

/*flattening algo taken from libart but passed to sqrt tests for line distance to avoid 16.16 fixed overflow*/
static GF_Err gf_subdivide_cubic(GF_Path *gp, Fixed x0, Fixed y0, Fixed x1, Fixed y1, Fixed x2, Fixed y2, Fixed x3, Fixed y3, Fixed fineness)
{
	GF_Point2D pt;
	Fixed x3_0, y3_0, z3_0, z1_0, z1_dot, z2_dot, z1_perp, z2_perp;
	Fixed max_perp;
	Fixed x_m, y_m, xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2;
	GF_Err e;

	pt.x = x3_0 = x3 - x0;
	pt.y = y3_0 = y3 - y0;

	/*z3_0 is dist z0-z3*/
	z3_0 = gf_v2d_len(&pt);

	pt.x = x1 - x0;
	pt.y = y1 - y0;
	z1_0 = gf_v2d_len(&pt);

	if ((z3_0*100 < FIX_ONE) && (z1_0*100 < FIX_ONE))
		goto nosubdivide;

	/* perp is distance from line, multiplied by dist z0-z3 */
	max_perp = gf_mulfix(fineness, z3_0);

	z1_perp = gf_mulfix((y1 - y0), x3_0) - gf_mulfix((x1 - x0), y3_0);
	if (ABS(z1_perp) > max_perp)
		goto subdivide;

	z2_perp = gf_mulfix((y3 - y2), x3_0) - gf_mulfix((x3 - x2), y3_0);
	if (ABS(z2_perp) > max_perp)
		goto subdivide;

	z1_dot = gf_mulfix((x1 - x0), x3_0) + gf_mulfix((y1 - y0), y3_0);
	if ((z1_dot < 0) && (ABS(z1_dot) > max_perp))
		goto subdivide;

	z2_dot = gf_mulfix((x3 - x2), x3_0) + gf_mulfix((y3 - y2), y3_0);
	if ((z2_dot < 0) && (ABS(z2_dot) > max_perp))
		goto subdivide;

	if (gf_divfix(z1_dot + z1_dot, z3_0) > z3_0)
		goto subdivide;

	if (gf_divfix(z2_dot + z2_dot, z3_0) > z3_0)
		goto subdivide;

nosubdivide:
	/* don't subdivide */
	return gf_path_add_line_to(gp, x3, y3);

subdivide:
	xa1 = (x0 + x1) / 2;
	ya1 = (y0 + y1) / 2;
	xa2 = (x0 + 2 * x1 + x2) / 4;
	ya2 = (y0 + 2 * y1 + y2) / 4;
	xb1 = (x1 + 2 * x2 + x3) / 4;
	yb1 = (y1 + 2 * y2 + y3) / 4;
	xb2 = (x2 + x3) / 2;
	yb2 = (y2 + y3) / 2;
	x_m = (xa2 + xb1) / 2;
	y_m = (ya2 + yb1) / 2;
	/*safeguard for numerical stability*/
	if ( (ABS(x_m-x0) < FIX_EPSILON) && (ABS(y_m-y0) < FIX_EPSILON))
		return gf_path_add_line_to(gp, x3, y3);
	if ( (ABS(x3-x_m) < FIX_EPSILON) && (ABS(y3-y_m) < FIX_EPSILON))
		return gf_path_add_line_to(gp, x3, y3);

	e = gf_subdivide_cubic(gp, x0, y0, xa1, ya1, xa2, ya2, x_m, y_m, fineness);
	if (e) return e;
	return gf_subdivide_cubic(gp, x_m, y_m, xb1, yb1, xb2, yb2, x3, y3, fineness);
}

GF_EXPORT
GF_Path *gf_path_get_flatten(GF_Path *gp)
{
	GF_Path *ngp;
	Fixed fineness;
	u32 i, *countour;
	GF_Point2D *pt;
	if (!gp || !gp->n_points) return NULL;

	if (gp->flags & GF_PATH_FLATTENED) return gf_path_clone(gp);

	/*avoid too high precision */
	fineness = MAX(FIX_ONE - gp->fineness, FIX_ONE / 100);

	ngp = gf_path_new();
	pt = &gp->points[0];
	gf_path_add_move_to_vec(ngp, pt);
	countour = gp->contours;
	for (i=1; i<gp->n_points; ) {
		switch (gp->tags[i]) {
		case GF_PATH_CURVE_ON:
		case GF_PATH_CLOSE:
			pt = &gp->points[i];
			if (*countour == i-1) {
				gf_path_add_move_to_vec(ngp, pt);
				countour++;
			} else {
				gf_path_add_line_to_vec(ngp, pt);
			}
			if (gp->tags[i]==GF_PATH_CLOSE) gf_path_close(ngp);
			i++;
			break;
		case GF_PATH_CURVE_CONIC:
		{
			GF_Point2D *ctl, *end, c1, c2;
			ctl = &gp->points[i];
			end = &gp->points[i+1];
			c1.x = pt->x + 2*(ctl->x - pt->x)/3;
			c1.y = pt->y + 2*(ctl->y - pt->y)/3;
			c2.x = c1.x + (end->x - pt->x) / 3;
			c2.y = c1.y + (end->y - pt->y) / 3;

			gf_subdivide_cubic(ngp, pt->x, pt->y, c1.x, c1.y, c2.x, c2.y, end->x, end->y, fineness);
			pt = end;
			if (gp->tags[i+1]==GF_PATH_CLOSE) gf_path_close(ngp);
			i+=2;
		}
		break;
		case GF_PATH_CURVE_CUBIC:
			gf_subdivide_cubic(ngp, pt->x, pt->y, gp->points[i].x, gp->points[i].y, gp->points[i+1].x, gp->points[i+1].y, gp->points[i+2].x, gp->points[i+2].y, fineness);
			pt = &gp->points[i+2];
			if (gp->tags[i+2]==GF_PATH_CLOSE) gf_path_close(ngp);
			i+=3;
			break;
		}
	}
	if (gp->flags & GF_PATH_FILL_ZERO_NONZERO) ngp->flags |= GF_PATH_FILL_ZERO_NONZERO;
	ngp->flags |= (GF_PATH_BBOX_DIRTY | GF_PATH_FLATTENED);
	return ngp;
}

GF_EXPORT
void gf_path_flatten(GF_Path *gp)
{
	GF_Path *res;
	u32 flags = gp->flags;
	if (gp->flags & GF_PATH_FLATTENED) return;
	if (!gp->n_points) return;
	res = gf_path_get_flatten(gp);
	if (gp->contours) gf_free(gp->contours);
	if (gp->points) gf_free(gp->points);
	if (gp->tags) gf_free(gp->tags);
	memcpy(gp, res, sizeof(GF_Path));
	gp->flags |= (flags & (GF_PATH_FILL_ZERO_NONZERO|GF_PATH_FILL_EVEN));
	gf_free(res);
}



#define isLeft(P0, P1, P2) \
	( gf_mulfix((P1.x - P0.x), (P2.y - P0.y)) - gf_mulfix((P2.x - P0.x), (P1.y - P0.y)) )


static void gf_subdivide_cubic_hit_test(Fixed h_x, Fixed h_y, Fixed x0, Fixed y0, Fixed x1, Fixed y1, Fixed x2, Fixed y2, Fixed x3, Fixed y3, s32 *wn)
{
	GF_Point2D s, e, pt;
	Fixed x_m, y_m, xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2, y_min, y_max;

	/*if hit line doesn't intersects control box abort*/
	y_min = MIN(y0, MIN(y1, MIN(y2, y3)));
	y_max = MAX(y0, MAX(y1, MAX(y2, y3)));
	if ((h_y<y_min) || (h_y>y_max) ) return;

	/*if vert diff between end points larger than 1 pixels, subdivide (we need pixel accuracy for is_over)*/
	if (y_max - y_min > FIX_ONE) {
		xa1 = (x0 + x1) / 2;
		ya1 = (y0 + y1) / 2;
		xa2 = (x0 + 2 * x1 + x2) / 4;
		ya2 = (y0 + 2 * y1 + y2) / 4;
		xb1 = (x1 + 2 * x2 + x3) / 4;
		yb1 = (y1 + 2 * y2 + y3) / 4;
		xb2 = (x2 + x3) / 2;
		yb2 = (y2 + y3) / 2;
		x_m = (xa2 + xb1) / 2;
		y_m = (ya2 + yb1) / 2;

		gf_subdivide_cubic_hit_test(h_x, h_y, x0, y0, xa1, ya1, xa2, ya2, x_m, y_m, wn);
		gf_subdivide_cubic_hit_test(h_x, h_y, x_m, y_m, xb1, yb1, xb2, yb2, x3, y3, wn);
		return;
	}

	s.x = x0;
	s.y = y0;
	e.x = x3;
	e.y = y3;
	pt.x = h_x;
	pt.y= h_y;

	if (s.y<=pt.y) {
		if (e.y>pt.y) {
			if (isLeft(s, e, pt) > 0)
				(*wn)++;
		}
	}
	else if (e.y<=pt.y) {
		if (isLeft(s, e, pt) < 0)
			(*wn)--;
	}
}

GF_EXPORT
Bool gf_path_point_over(GF_Path *gp, Fixed x, Fixed y)
{
	u32 i, *contour, start_idx;
	s32 wn;
	GF_Point2D start, s, e, pt;
	GF_Rect rc;
	GF_Err err;

	/*check if not in bounds*/
	err = gf_path_get_bounds(gp, &rc);
	if (err) return GF_FALSE;
	if ((x<rc.x) || (y>rc.y) || (x>rc.x+rc.width) || (y<rc.y-rc.height)) return GF_FALSE;

	if (!gp || (gp->n_points<2)) return GF_FALSE;

	pt.x = x;
	pt.y = y;
	wn = 0;
	s = start = gp->points[0];
	start_idx = 0;
	contour = gp->contours;
	for (i=1; i<gp->n_points; ) {
		switch (gp->tags[i]) {
		case GF_PATH_CURVE_ON:
		case GF_PATH_CLOSE:
			e = gp->points[i];
			if (s.y<=pt.y) {
				if (e.y>pt.y) {
					if (isLeft(s, e, pt) > 0) wn++;
				}
			}
			else if (e.y<=pt.y) {
				if (isLeft(s, e, pt) < 0) wn--;
			}
			s = e;
			i++;
			break;
		case GF_PATH_CURVE_CONIC:
		{
			GF_Point2D *ctl, *end, c1, c2;
			ctl = &gp->points[i];
			end = &gp->points[i+1];
			c1.x = s.x + 2*(ctl->x - s.x) / 3;
			c1.y = s.y + 2*(ctl->y - s.y) / 3;
			c2.x = c1.x + (end->x - s.x) / 3;
			c2.y = c1.y + (end->y - s.y) / 3;
			gf_subdivide_cubic_hit_test(x, y, s.x, s.y, c1.x, c1.y, c2.x, c2.y, end->x, end->y, &wn);
			s = *end;
		}
		i+=2;
		break;
		case GF_PATH_CURVE_CUBIC:
			gf_subdivide_cubic_hit_test(x, y, s.x, s.y, gp->points[i].x, gp->points[i].y, gp->points[i+1].x, gp->points[i+1].y, gp->points[i+2].x, gp->points[i+2].y, &wn);
			s = gp->points[i+2];
			i+=3;
			break;
		}
		/*end of subpath*/
		if (*contour==i-1) {
			/*close path if needed, but don't test for lines...*/
			if ((i-start_idx > 2) && (pt.y<s.y)) {
				if ((start.x != s.x) || (start.y != s.y)) {
					e = start;
					if (s.x<=pt.x) {
						if (e.y>pt.y) {
							if (isLeft(s, e, pt) > 0) wn++;
						}
					}
					else if (e.y<=pt.y) {
						if (isLeft(s, e, pt) < 0) wn--;
					}
				}
			}
			if ( i < gp->n_points )
				s = start = gp->points[i];
			i++;
		}
	}
	if (gp->flags & GF_PATH_FILL_ZERO_NONZERO) return wn ? GF_TRUE : GF_FALSE;
	return (wn%2) ? GF_TRUE : GF_FALSE;
}

GF_EXPORT
Bool gf_path_is_empty(GF_Path *gp)
{
	if (gp && gp->contours) return GF_FALSE;
	return GF_TRUE;
}

/*iteration info*/
typedef struct
{
	Fixed len;
	Fixed dx, dy;
	Fixed start_x, start_y;
} IterInfo;

struct _path_iterator
{
	u32 num_seg;
	IterInfo *seg;
	Fixed length;
};

GF_EXPORT
GF_PathIterator *gf_path_iterator_new(GF_Path *gp)
{
	GF_Path *flat;
	GF_PathIterator *it;
	u32 i, j, cur;
	GF_Point2D start, end;

	GF_SAFEALLOC(it, GF_PathIterator);
	if (!it) return NULL;
	flat = gf_path_get_flatten(gp);
	if (!flat) {
		gf_free(it);
		return NULL;
	}
	it->seg = (IterInfo *) gf_malloc(sizeof(IterInfo) * flat->n_points);
	it->num_seg = 0;
	it->length = 0;
	cur = 0;
	for (i=0; i<flat->n_contours; i++) {
		Fixed dx, dy;
		u32 nb_pts = 1+flat->contours[i]-cur;
		start = flat->points[cur];
		for (j=1; j<nb_pts; j++) {
			end = flat->points[cur+j];
			it->seg[it->num_seg].start_x = start.x;
			it->seg[it->num_seg].start_y = start.y;
			dx = it->seg[it->num_seg].dx = end.x - start.x;
			dy = it->seg[it->num_seg].dy = end.y - start.y;
			it->seg[it->num_seg].len = gf_sqrt(gf_mulfix(dx, dx) + gf_mulfix(dy, dy));
			it->length += it->seg[it->num_seg].len;
			start = end;
			it->num_seg++;
		}
		cur += nb_pts;
	}
	gf_path_del(flat);
	return it;
}

GF_EXPORT
Fixed gf_path_iterator_get_length(GF_PathIterator *it)
{
	return it ? it->length : 0;
}

GF_EXPORT
Bool gf_path_iterator_get_transform(GF_PathIterator *path, Fixed offset, Bool follow_tangent, GF_Matrix2D *mat, Bool smooth_edges, Fixed length_after_point)
{
	GF_Matrix2D final, rot;
	Bool tang = GF_FALSE;
	Fixed res, angle, angleNext;
	u32 i;
	Fixed curLen = 0;
	if (!path) return GF_FALSE;

	for (i=0; i<path->num_seg; i++) {
		if (curLen + path->seg[i].len >= offset) goto found;
		curLen += path->seg[i].len;
	}
	if (!follow_tangent) return GF_FALSE;
	tang = GF_TRUE;
	i--;

found:
	gf_mx2d_init(final);

	res = gf_divfix(offset - curLen, path->seg[i].len);
	if (tang) res += 1;

	/*move to current point*/
	gf_mx2d_add_translation(&final, path->seg[i].start_x + gf_mulfix(path->seg[i].dx, res), path->seg[i].start_y + gf_mulfix(path->seg[i].dy, res));

	if (!path->seg[i].dx) {
		angle = GF_PI2;
	} else {
		angle = gf_acos( gf_divfix(path->seg[i].dx , path->seg[i].len) );
	}
	if (path->seg[i].dy<0) angle *= -1;

	if (smooth_edges) {
		if (offset + length_after_point > curLen + path->seg[i].len) {
			Fixed ratio = gf_divfix(curLen + path->seg[i].len-offset, length_after_point);
			if (i < path->num_seg - 1) {
				if (!path->seg[i+1].dx) {
					angleNext = GF_PI2;
				} else {
					angleNext = gf_acos( gf_divfix(path->seg[i+1].dx, path->seg[i+1].len) );
				}
				if (path->seg[i+1].dy<0) angleNext *= -1;

				if (angle<0 && angleNext>0) {
					angle = gf_mulfix(FIX_ONE-ratio, angleNext) - gf_mulfix(ratio, angle);
				} else {
					angle = gf_mulfix(ratio, angle) + gf_mulfix(FIX_ONE-ratio, angleNext);
				}
			}
		}
	}
	/*handle res=0 case for rotation (point on line join)*/
	else if (res==1) {
		if (i < path->num_seg - 1) {
			if (!path->seg[i+1].dx) {
				angleNext = GF_PI2;
			} else {
				angleNext = gf_acos( gf_divfix(path->seg[i+1].dx, path->seg[i+1].len) );
			}
			if (path->seg[i+1].dy<0) angleNext *= -1;
			angle = ( angle + angleNext) / 2;
		}
	}

	gf_mx2d_init(rot);
	gf_mx2d_add_rotation(&rot, 0, 0, angle);
	gf_mx2d_add_matrix(mat, &rot);
	gf_mx2d_add_matrix(mat, &final);
	return GF_TRUE;
}

GF_EXPORT
void gf_path_iterator_del(GF_PathIterator *it)
{
	if (it->seg) gf_free(it->seg);
	gf_free(it);
}


#define ConvexCompare(delta)	\
    ( (delta.x > 0) ? -1 :		\
      (delta.x < 0) ?	1 :		\
      (delta.y > 0) ? -1 :		\
      (delta.y < 0) ?	1 :	\
      0 )

#define ConvexGetPointDelta(delta, pprev, pcur )			\
    /* Given a previous point 'pprev', read a new point into 'pcur' */	\
    /* and return delta in 'delta'.				    */	\
    pcur = pts[iread++];						\
    delta.x = pcur.x - pprev.x;					\
    delta.y = pcur.y - pprev.y;					\
 
#define ConvexCross(p, q) gf_mulfix(p.x,q.y) - gf_mulfix(p.y,q.x);

#define ConvexCheckTriple						\
    if ( (thisDir = ConvexCompare(dcur)) == -curDir ) {			\
	  ++dirChanges;							\
	  /* if ( dirChanges > 2 ) return NotConvex;		     */ \
    }									\
    curDir = thisDir;							\
    cross = ConvexCross(dprev, dcur);					\
    if ( cross > 0 ) { \
		if ( angleSign == -1 ) return GF_POLYGON_COMPLEX_CW;		\
		angleSign = 1;					\
	}							\
    else if (cross < 0) {	\
		if (angleSign == 1) return GF_POLYGON_COMPLEX_CCW;		\
		angleSign = -1;				\
	}						\
    pSecond = pThird;		\
    dprev.x = dcur.x;		\
    dprev.y = dcur.y;							\
 
GF_EXPORT
u32 gf_polygone2d_get_convexity(GF_Point2D *pts, u32 len)
{
	s32 curDir, thisDir = 0, dirChanges = 0, angleSign = 0;
	u32 iread;
	Fixed cross;
	GF_Point2D pSecond, pThird, pSaveSecond;
	GF_Point2D dprev, dcur;

	/* Get different point, return if less than 3 diff points. */
	if (len < 3 ) return GF_POLYGON_CONVEX_LINE;
	iread = 1;
	ConvexGetPointDelta(dprev, (pts[0]), pSecond);
	pSaveSecond = pSecond;
	/*initial direction */
	curDir = ConvexCompare(dprev);
	while ( iread < len) {
		/* Get different point, break if no more points */
		ConvexGetPointDelta(dcur, pSecond, pThird );
		if ( (dcur.x == 0) && (dcur.y == 0) ) continue;
		/* Check current three points */
		ConvexCheckTriple;
	}

	/* Must check for direction changes from last vertex back to first */
	/* Prepare for 'ConvexCheckTriple' */
	pThird = pts[0];
	dcur.x = pThird.x - pSecond.x;
	dcur.y = pThird.y - pSecond.y;
	if ( ConvexCompare(dcur) ) {
		ConvexCheckTriple;
	}
	/* and check for direction changes back to second vertex */
	dcur.x = pSaveSecond.x - pSecond.x;
	dcur.y = pSaveSecond.y - pSecond.y;
	/* Don't care about 'pThird' now */
	ConvexCheckTriple;

	/* Decide on polygon type given accumulated status */
	if ( dirChanges > 2 ) return GF_POLYGON_COMPLEX;
	if ( angleSign > 0 ) return GF_POLYGON_CONVEX_CCW;
	if ( angleSign < 0 ) return GF_POLYGON_CONVEX_CW;
	return GF_POLYGON_CONVEX_LINE;
}

#endif // !defined(GPAC_DISABLE_EVG) || defined(GPAC_HAS_FREETYPE)
