/* SvgArc.c generated by valac 0.56.17, the Vala compiler
 * generated from SvgArc.vala, do not modify */

/*
 * BirdFont code from SVG Salamander
 * 
 * Copyright (c) 2004, Mark McKay
 * Copyright (c) 2014, Johan Mattsson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or 
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 *   - Redistributions of source code must retain the above 
 *     copyright notice, this list of conditions and the following
 *     disclaimer.
 *   - Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials 
 *     provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 * 
 * Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
 * projects can be found at http://www.kitfox.com
 *
 * Created on January 26, 2004, 8:40 PM
 * Adapded to BirdFont on Juli 2, 2014, 5:01 PM
 */

#include "birdfont.h"
#include <glib.h>
#include <float.h>
#include <math.h>
#include <string.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

VALA_EXTERN void bird_font_add_arc_points (BirdFontBezierPoints** bezier_points,
                               gint bezier_points_length1,
                               gint* bi,
                               gdouble x0,
                               gdouble y0,
                               gdouble rx,
                               gdouble ry,
                               gdouble angle,
                               gboolean largeArcFlag,
                               gboolean sweepFlag,
                               gdouble x,
                               gdouble y);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

/** Convert an SVG arc instruction to a Beziér path. */
void
bird_font_add_arc_points (BirdFontBezierPoints** bezier_points,
                          gint bezier_points_length1,
                          gint* bi,
                          gdouble x0,
                          gdouble y0,
                          gdouble rx,
                          gdouble ry,
                          gdouble angle,
                          gboolean largeArcFlag,
                          gboolean sweepFlag,
                          gdouble x,
                          gdouble y)
{
	gdouble dx2 = 0.0;
	gdouble dy2 = 0.0;
	gdouble cosAngle = 0.0;
	gdouble sinAngle = 0.0;
	gdouble x1 = 0.0;
	gdouble y1 = 0.0;
	gdouble Prx = 0.0;
	gdouble Pry = 0.0;
	gdouble Px1 = 0.0;
	gdouble Py1 = 0.0;
	gdouble radiiCheck = 0.0;
	gdouble sign = 0.0;
	gdouble sq = 0.0;
	gdouble coef = 0.0;
	gdouble cx1 = 0.0;
	gdouble cy1 = 0.0;
	gdouble sx2 = 0.0;
	gdouble sy2 = 0.0;
	gdouble cx = 0.0;
	gdouble cy = 0.0;
	gdouble ux = 0.0;
	gdouble uy = 0.0;
	gdouble vx = 0.0;
	gdouble vy = 0.0;
	gdouble p = 0.0;
	gdouble n = 0.0;
	gdouble angleStart = 0.0;
	gdouble angleExtent = 0.0;
	gdouble s = 0.0;
	gdouble step = 0.0;
	gdouble theta = 0.0;
	gint _tmp0_ = 0;
	gdouble _tmp1_ = 0.0;
	gdouble _tmp2_ = 0.0;
	gdouble _tmp3_ = 0.0;
	gboolean _tmp4_ = FALSE;
	gint _tmp6_ = 0;
	BirdFontBezierPoints* _tmp7_;
	BirdFontBezierPoints* _tmp8_;
	BirdFontBezierPoints* _tmp9_;
	BirdFontBezierPoints* _tmp10_;
	gint _tmp11_;
	dx2 = (x0 - x) / 2.0;
	dy2 = (y0 - y) / 2.0;
	angle = (2 * G_PI) * (fmod (angle, 360.0) / 360.0);
	cosAngle = cos (angle);
	sinAngle = sin (angle);
	x1 = (cosAngle * dx2) + (sinAngle * dy2);
	y1 = ((-sinAngle) * dx2) + (cosAngle * dy2);
	rx = fabs (rx);
	ry = fabs (ry);
	Prx = rx * rx;
	Pry = ry * ry;
	Px1 = x1 * x1;
	Py1 = y1 * y1;
	radiiCheck = (Px1 / Prx) + (Py1 / Pry);
	if (radiiCheck > ((gdouble) 1)) {
		rx = sqrt (radiiCheck) * rx;
		ry = sqrt (radiiCheck) * ry;
		Prx = rx * rx;
		Pry = ry * ry;
	}
	if (largeArcFlag == sweepFlag) {
		_tmp0_ = -1;
	} else {
		_tmp0_ = 1;
	}
	sign = (gdouble) _tmp0_;
	sq = (((Prx * Pry) - (Prx * Py1)) - (Pry * Px1)) / ((Prx * Py1) + (Pry * Px1));
	if (sq < ((gdouble) 0)) {
		_tmp1_ = (gdouble) 0;
	} else {
		_tmp1_ = sq;
	}
	sq = _tmp1_;
	coef = sign * sqrt (sq);
	cx1 = coef * ((rx * y1) / ry);
	cy1 = coef * (-((ry * x1) / rx));
	sx2 = (x0 + x) / 2.0;
	sy2 = (y0 + y) / 2.0;
	cx = sx2 - ((cosAngle * cx1) - (sinAngle * cy1));
	cy = sy2 - ((sinAngle * cx1) + (cosAngle * cy1));
	ux = (x1 - cx1) / rx;
	uy = (y1 - cy1) / ry;
	vx = ((-x1) - cx1) / rx;
	vy = ((-y1) - cy1) / ry;
	n = sqrt ((ux * ux) + (uy * uy));
	p = ux;
	if (uy < ((gdouble) 0)) {
		_tmp2_ = -1.;
	} else {
		_tmp2_ = 1.;
	}
	sign = _tmp2_;
	angleStart = sign * acos (p / n);
	n = sqrt (((ux * ux) + (uy * uy)) * ((vx * vx) + (vy * vy)));
	p = (ux * vx) + (uy * vy);
	if (((ux * vy) - (uy * vx)) < ((gdouble) 0)) {
		_tmp3_ = -1.;
	} else {
		_tmp3_ = 1.;
	}
	sign = _tmp3_;
	angleExtent = sign * acos (p / n);
	if (!sweepFlag) {
		_tmp4_ = angleExtent > ((gdouble) 0);
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		angleExtent -= 2 * G_PI;
	} else {
		gboolean _tmp5_ = FALSE;
		if (sweepFlag) {
			_tmp5_ = angleExtent < ((gdouble) 0);
		} else {
			_tmp5_ = FALSE;
		}
		if (_tmp5_) {
			angleExtent += 2 * G_PI;
		}
	}
	angleExtent = fmod (angleExtent, 2 * G_PI);
	angleStart = fmod (angleStart, 2 * G_PI);
	angleExtent *= (gdouble) -1;
	angleStart *= (gdouble) -1;
	if (angleExtent > ((gdouble) 0)) {
		_tmp6_ = 1;
	} else {
		_tmp6_ = -1;
	}
	s = (gdouble) _tmp6_;
	step = fabs (angleExtent) / (2 * fabs (angleExtent));
	theta = (G_PI - angleStart) - angleExtent;
	_tmp7_ = bezier_points[*bi];
	_tmp7_->type = (gunichar) 'L';
	_tmp8_ = bezier_points[*bi];
	_tmp8_->svg_type = (gunichar) 'a';
	_tmp9_ = bezier_points[*bi];
	_tmp9_->x0 = cx + (rx * cos (theta));
	_tmp10_ = bezier_points[*bi];
	_tmp10_->y0 = cy + (ry * sin (theta));
	_tmp11_ = *bi;
	*bi = _tmp11_ + 1;
	{
		gdouble a = 0.0;
		a = (gdouble) 0;
		{
			gboolean _tmp12_ = FALSE;
			_tmp12_ = TRUE;
			while (TRUE) {
				gint _tmp13_;
				BirdFontBezierPoints* _tmp14_;
				BirdFontBezierPoints* _tmp15_;
				BirdFontBezierPoints* _tmp16_;
				BirdFontBezierPoints* _tmp17_;
				BirdFontBezierPoints* _tmp18_;
				BirdFontBezierPoints* _tmp19_;
				BirdFontBezierPoints* _tmp20_;
				BirdFontBezierPoints* _tmp21_;
				gint _tmp22_;
				if (!_tmp12_) {
					a += step;
				}
				_tmp12_ = FALSE;
				if (!(a < fabs (angleExtent))) {
					break;
				}
				theta = ((G_PI - angleStart) - angleExtent) + (s * a);
				_tmp13_ = *bi;
				g_return_if_fail ((0 <= _tmp13_) && (_tmp13_ < bezier_points_length1));
				_tmp14_ = bezier_points[*bi];
				_tmp14_->type = (gunichar) 'S';
				_tmp15_ = bezier_points[*bi];
				_tmp15_->svg_type = (gunichar) 'a';
				_tmp16_ = bezier_points[*bi];
				_tmp16_->x0 = cx + (rx * cos (theta));
				_tmp17_ = bezier_points[*bi];
				_tmp17_->y0 = cy + (ry * sin (theta));
				_tmp18_ = bezier_points[*bi];
				_tmp18_->x1 = cx + (rx * cos (theta + ((1 * step) / 4)));
				_tmp19_ = bezier_points[*bi];
				_tmp19_->y1 = cy + (ry * sin (theta + ((1 * step) / 4)));
				_tmp20_ = bezier_points[*bi];
				_tmp20_->x2 = cx + (rx * cos (theta + ((2 * step) / 4)));
				_tmp21_ = bezier_points[*bi];
				_tmp21_->y2 = cy + (ry * sin (theta + ((2 * step) / 4)));
				_tmp22_ = *bi;
				*bi = _tmp22_ + 1;
			}
		}
	}
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

