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

/*
Copyright (C) 2012, 2013, 2014 Johan Mattsson

This library 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 3 of the 
License, or (at your option) any later version.

This library 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.
*/

#include "birdfont.h"
#include <glib.h>
#include <glib-object.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include <gee.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

enum  {
	BIRD_FONT_HMTX_TABLE_0_PROPERTY,
	BIRD_FONT_HMTX_TABLE_NUM_PROPERTIES
};
static GParamSpec* bird_font_hmtx_table_properties[BIRD_FONT_HMTX_TABLE_NUM_PROPERTIES];
#define _g_free0(var) ((var == NULL) ? NULL : (var = (g_free (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _BirdFontHmtxTablePrivate {
	guint32 nmetrics;
	guint32 nmonospaced;
	guint16* advance_width;
	guint16* left_side_bearing;
	guint16* left_side_bearing_monospaced;
	BirdFontHeadTable* head_table;
	BirdFontGlyfTable* glyf_table;
};

static gint BirdFontHmtxTable_private_offset;
static gpointer bird_font_hmtx_table_parent_class = NULL;

static void bird_font_hmtx_table_finalize (GObject * obj);
static GType bird_font_hmtx_table_get_type_once (void);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static inline gpointer
bird_font_hmtx_table_get_instance_private (BirdFontHmtxTable* self)
{
	return G_STRUCT_MEMBER_P (self, BirdFontHmtxTable_private_offset);
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

BirdFontHmtxTable*
bird_font_hmtx_table_construct (GType object_type,
                                BirdFontHeadTable* h,
                                BirdFontGlyfTable* gt)
{
	BirdFontHmtxTable * self = NULL;
	BirdFontHeadTable* _tmp0_;
	BirdFontGlyfTable* _tmp1_;
	gchar* _tmp2_;
	g_return_val_if_fail (h != NULL, NULL);
	g_return_val_if_fail (gt != NULL, NULL);
	self = (BirdFontHmtxTable*) bird_font_otf_table_construct (object_type);
	_tmp0_ = _g_object_ref0 (h);
	_g_object_unref0 (self->priv->head_table);
	self->priv->head_table = _tmp0_;
	_tmp1_ = _g_object_ref0 (gt);
	_g_object_unref0 (self->priv->glyf_table);
	self->priv->glyf_table = _tmp1_;
	_tmp2_ = g_strdup ("hmtx");
	_g_free0 (((BirdFontOtfTable*) self)->id);
	((BirdFontOtfTable*) self)->id = _tmp2_;
	return self;
}

BirdFontHmtxTable*
bird_font_hmtx_table_new (BirdFontHeadTable* h,
                          BirdFontGlyfTable* gt)
{
	return bird_font_hmtx_table_construct (BIRD_FONT_TYPE_HMTX_TABLE, h, gt);
}

gdouble
bird_font_hmtx_table_get_advance (BirdFontHmtxTable* self,
                                  guint32 i)
{
	guint16* _tmp6_;
	guint16* _tmp7_;
	guint16 _tmp8_;
	BirdFontHeadTable* _tmp9_;
	gdouble result;
	g_return_val_if_fail (self != NULL, 0.0);
	if (i >= self->priv->nmetrics) {
		gchar* _tmp0_;
		gchar* _tmp1_;
		gchar* _tmp2_;
		gchar* _tmp3_;
		gchar* _tmp4_;
		gchar* _tmp5_;
		_tmp0_ = g_strdup_printf ("%u", i);
		_tmp1_ = _tmp0_;
		_tmp2_ = g_strdup_printf ("%u", self->priv->nmetrics);
		_tmp3_ = _tmp2_;
		_tmp4_ = g_strconcat ("i >= nmetrics ", _tmp1_, " >= ", _tmp3_, NULL);
		_tmp5_ = _tmp4_;
		g_warning ("HmtxTable.vala:52: %s", _tmp5_);
		_g_free0 (_tmp5_);
		_g_free0 (_tmp3_);
		_g_free0 (_tmp1_);
		result = (gdouble) 0;
		return result;
	}
	_tmp6_ = self->priv->advance_width;
	g_return_val_if_fail (_tmp6_ != NULL, 0.0);
	_tmp7_ = self->priv->advance_width;
	_tmp8_ = _tmp7_[i];
	_tmp9_ = self->priv->head_table;
	result = (_tmp8_ * 1000) / bird_font_head_table_get_units_per_em (_tmp9_);
	return result;
}

/** Get left side bearing relative to xmin. */
gdouble
bird_font_hmtx_table_get_lsb (BirdFontHmtxTable* self,
                              guint32 i)
{
	guint16* _tmp0_;
	guint16* _tmp1_;
	guint16 _tmp2_;
	BirdFontHeadTable* _tmp3_;
	gdouble result;
	g_return_val_if_fail (self != NULL, 0.0);
	g_return_val_if_fail (i < self->priv->nmetrics, 0.0);
	_tmp0_ = self->priv->left_side_bearing;
	g_return_val_if_fail (_tmp0_ != NULL, 0.0);
	_tmp1_ = self->priv->left_side_bearing;
	_tmp2_ = _tmp1_[i];
	_tmp3_ = self->priv->head_table;
	result = (_tmp2_ * 1000) / bird_font_head_table_get_units_per_em (_tmp3_);
	return result;
}

void
bird_font_hmtx_table_parse (BirdFontHmtxTable* self,
                            BirdFontFontData* dis,
                            BirdFontHheaTable* hhea_table,
                            BirdFontLocaTable* loca_table,
                            GError** error)
{
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* _tmp9_;
	gchar* _tmp10_;
	gchar* _tmp11_;
	gchar* _tmp12_;
	gchar* _tmp13_;
	guint16* _tmp14_;
	guint16* _tmp15_;
	guint16* _tmp16_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (dis != NULL);
	g_return_if_fail (hhea_table != NULL);
	g_return_if_fail (loca_table != NULL);
	self->priv->nmetrics = (guint32) hhea_table->num_horizontal_metrics;
	self->priv->nmonospaced = loca_table->size - self->priv->nmetrics;
	bird_font_font_data_seek (dis, (guint) ((BirdFontOtfTable*) self)->offset);
	if (self->priv->nmetrics > loca_table->size) {
		gchar* _tmp0_;
		gchar* _tmp1_;
		gchar* _tmp2_;
		gchar* _tmp3_;
		gchar* _tmp4_;
		gchar* _tmp5_;
		_tmp0_ = g_strdup_printf ("%u", self->priv->nmetrics);
		_tmp1_ = _tmp0_;
		_tmp2_ = g_strdup_printf ("%u", loca_table->size);
		_tmp3_ = _tmp2_;
		_tmp4_ = g_strconcat ("(nmetrics > loca_table.size) (", _tmp1_, " > ", _tmp3_, ")", NULL);
		_tmp5_ = _tmp4_;
		g_warning ("HmtxTable.vala:76: %s", _tmp5_);
		_g_free0 (_tmp5_);
		_g_free0 (_tmp3_);
		_g_free0 (_tmp1_);
		return;
	}
	_tmp6_ = g_strdup_printf ("%u", self->priv->nmetrics);
	_tmp7_ = _tmp6_;
	_tmp8_ = g_strconcat ("nmetrics: ", _tmp7_, "\n", NULL);
	_tmp9_ = _tmp8_;
	bird_font_printd (_tmp9_);
	_g_free0 (_tmp9_);
	_g_free0 (_tmp7_);
	_tmp10_ = g_strdup_printf ("%u", loca_table->size);
	_tmp11_ = _tmp10_;
	_tmp12_ = g_strconcat ("loca_table.size: ", _tmp11_, "\n", NULL);
	_tmp13_ = _tmp12_;
	bird_font_printd (_tmp13_);
	_g_free0 (_tmp13_);
	_g_free0 (_tmp11_);
	_tmp14_ = g_new0 (guint16, self->priv->nmetrics);
	self->priv->advance_width = _tmp14_;
	_tmp15_ = g_new0 (guint16, self->priv->nmetrics);
	self->priv->left_side_bearing = _tmp15_;
	_tmp16_ = g_new0 (guint16, self->priv->nmonospaced);
	self->priv->left_side_bearing_monospaced = _tmp16_;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp17_ = FALSE;
			_tmp17_ = TRUE;
			while (TRUE) {
				guint16* _tmp19_;
				gint16 _tmp20_ = 0;
				guint16* _tmp21_;
				if (!_tmp17_) {
					gint _tmp18_;
					_tmp18_ = i;
					i = _tmp18_ + 1;
				}
				_tmp17_ = FALSE;
				if (!(((guint32) i) < self->priv->nmetrics)) {
					break;
				}
				_tmp19_ = self->priv->advance_width;
				_tmp19_[i] = bird_font_font_data_read_ushort (dis);
				_tmp20_ = bird_font_font_data_read_short (dis, &_inner_error0_);
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					g_propagate_error (error, _inner_error0_);
					return;
				}
				_tmp21_ = self->priv->left_side_bearing;
				_tmp21_[i] = (guint16) _tmp20_;
			}
		}
	}
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp22_ = FALSE;
			_tmp22_ = TRUE;
			while (TRUE) {
				gint16 _tmp24_ = 0;
				guint16* _tmp25_;
				if (!_tmp22_) {
					gint _tmp23_;
					_tmp23_ = i;
					i = _tmp23_ + 1;
				}
				_tmp22_ = FALSE;
				if (!(((guint32) i) < self->priv->nmonospaced)) {
					break;
				}
				_tmp24_ = bird_font_font_data_read_short (dis, &_inner_error0_);
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					g_propagate_error (error, _inner_error0_);
					return;
				}
				_tmp25_ = self->priv->left_side_bearing_monospaced;
				_tmp25_[i] = (guint16) _tmp24_;
			}
		}
	}
}

static const gchar*
string_to_string (const gchar* self)
{
	const gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	result = self;
	return result;
}

void
bird_font_hmtx_table_process (BirdFontHmtxTable* self)
{
	BirdFontFontData* fd = NULL;
	BirdFontFontData* _tmp0_;
	gint16 advance = 0;
	gint16 extent = 0;
	gint16 rsb = 0;
	gint16 lsb = 0;
	gint16 left_guide = 0;
	gint16 right_guide = 0;
	gdouble xmin = 0.0;
	gdouble xmax = 0.0;
	gint i = 0;
	BirdFontGlyph* g = NULL;
	guint16* _tmp1_;
	BirdFontGlyfTable* _tmp3_;
	GeeArrayList* _tmp4_;
	gint _tmp5_;
	gint _tmp6_;
	guint16* _tmp7_;
	BirdFontFontData* _tmp47_;
	BirdFontFontData* _tmp48_;
	g_return_if_fail (self != NULL);
	_tmp0_ = bird_font_font_data_new ((guint32) 1024);
	fd = _tmp0_;
	_tmp1_ = self->priv->advance_width;
	if (_tmp1_ != NULL) {
		guint16* _tmp2_;
		g_warning ("HmtxTable.vala:115: advance_width is set");
		_tmp2_ = self->priv->advance_width;
		_g_free0 (_tmp2_);
	}
	_tmp3_ = self->priv->glyf_table;
	_tmp4_ = _tmp3_->glyphs;
	_tmp5_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp4_);
	_tmp6_ = _tmp5_;
	_tmp7_ = g_new0 (guint16, _tmp6_);
	self->priv->advance_width = _tmp7_;
	self->priv->nmetrics = (guint32) 0;
	i = 0;
	{
		GeeArrayList* _gc_list = NULL;
		BirdFontGlyfTable* _tmp8_;
		GeeArrayList* _tmp9_;
		gint _gc_size = 0;
		GeeArrayList* _tmp10_;
		gint _tmp11_;
		gint _tmp12_;
		gint _gc_index = 0;
		_tmp8_ = self->priv->glyf_table;
		_tmp9_ = _tmp8_->glyphs;
		_gc_list = _tmp9_;
		_tmp10_ = _gc_list;
		_tmp11_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp10_);
		_tmp12_ = _tmp11_;
		_gc_size = _tmp12_;
		_gc_index = -1;
		while (TRUE) {
			gint _tmp13_;
			gint _tmp14_;
			BirdFontGlyphCollection* gc = NULL;
			GeeArrayList* _tmp15_;
			gpointer _tmp16_;
			BirdFontGlyphCollection* _tmp17_;
			BirdFontGlyph* _tmp18_;
			BirdFontGlyfTable* _tmp19_;
			GeeArrayList* _tmp20_;
			gint _tmp21_;
			gint _tmp22_;
			gint _tmp23_;
			BirdFontGlyfData* gd = NULL;
			BirdFontGlyfTable* _tmp24_;
			GeeArrayList* _tmp25_;
			gpointer _tmp26_;
			BirdFontGlyfData* _tmp27_;
			BirdFontGlyfData* _tmp28_;
			BirdFontGlyph* _tmp29_;
			gdouble _tmp30_;
			gdouble _tmp31_;
			BirdFontGlyph* _tmp32_;
			gdouble _tmp33_;
			gdouble _tmp34_;
			BirdFontFontData* _tmp35_;
			BirdFontFontData* _tmp36_;
			BirdFontGlyph* _tmp37_;
			guint16* _tmp44_;
			guint32 _tmp45_;
			gint _tmp46_;
			_gc_index = _gc_index + 1;
			_tmp13_ = _gc_index;
			_tmp14_ = _gc_size;
			if (!(_tmp13_ < _tmp14_)) {
				break;
			}
			_tmp15_ = _gc_list;
			_tmp16_ = gee_abstract_list_get ((GeeAbstractList*) _tmp15_, _gc_index);
			gc = (BirdFontGlyphCollection*) _tmp16_;
			_tmp17_ = gc;
			_tmp18_ = bird_font_glyph_collection_get_current (_tmp17_);
			_g_object_unref0 (g);
			g = _tmp18_;
			_tmp19_ = self->priv->glyf_table;
			_tmp20_ = _tmp19_->glyf_data;
			_tmp21_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp20_);
			_tmp22_ = _tmp21_;
			_tmp23_ = i;
			g_return_if_fail ((0 <= _tmp23_) && (_tmp23_ < _tmp22_));
			_tmp24_ = self->priv->glyf_table;
			_tmp25_ = _tmp24_->glyf_data;
			_tmp26_ = gee_abstract_list_get ((GeeAbstractList*) _tmp25_, i);
			gd = (BirdFontGlyfData*) _tmp26_;
			_tmp27_ = gd;
			xmax = (gdouble) _tmp27_->bounding_box_xmax;
			_tmp28_ = gd;
			xmin = (gdouble) _tmp28_->bounding_box_xmin;
			_tmp29_ = g;
			_tmp30_ = bird_font_glyph_get_left_limit (_tmp29_);
			_tmp31_ = _tmp30_;
			left_guide = (gint16) rint (_tmp31_ * bird_font_head_table_UNITS);
			_tmp32_ = g;
			_tmp33_ = bird_font_glyph_get_right_limit (_tmp32_);
			_tmp34_ = _tmp33_;
			right_guide = (gint16) rint (_tmp34_ * bird_font_head_table_UNITS);
			lsb = (gint16) xmin;
			advance = right_guide - left_guide;
			extent = (gint16) xmax;
			rsb = (gint16) rint ((gdouble) (advance - extent));
			_tmp35_ = fd;
			bird_font_font_data_add_u16 (_tmp35_, (guint16) advance);
			_tmp36_ = fd;
			bird_font_font_data_add_16 (_tmp36_, lsb);
			_tmp37_ = g;
			if (!bird_font_glyph_is_empty_ttf (_tmp37_)) {
				if (advance > self->max_advance) {
					self->max_advance = advance;
				}
				if (extent > self->max_extent) {
					self->max_extent = extent;
				}
				if (rsb < self->min_rsb) {
					self->min_rsb = rsb;
				}
				if (lsb < self->min_lsb) {
					self->min_lsb = lsb;
				}
			}
			if (((gint) extent) < 0) {
				BirdFontGlyphCollection* _tmp38_;
				gchar* _tmp39_;
				gchar* _tmp40_;
				const gchar* _tmp41_;
				gchar* _tmp42_;
				gchar* _tmp43_;
				_tmp38_ = gc;
				_tmp39_ = bird_font_glyph_collection_get_name (_tmp38_);
				_tmp40_ = _tmp39_;
				_tmp41_ = string_to_string (_tmp40_);
				_tmp42_ = g_strconcat ("Negative extent in ", _tmp41_, ".", NULL);
				_tmp43_ = _tmp42_;
				g_warning ("HmtxTable.vala:164: %s", _tmp43_);
				_g_free0 (_tmp43_);
				_g_free0 (_tmp40_);
			}
			_tmp44_ = self->priv->advance_width;
			_tmp44_[self->priv->nmetrics] = (guint16) extent;
			_tmp45_ = self->priv->nmetrics;
			self->priv->nmetrics = _tmp45_ + 1;
			_tmp46_ = i;
			i = _tmp46_ + 1;
			_g_object_unref0 (gd);
			_g_object_unref0 (gc);
		}
	}
	_tmp47_ = fd;
	_tmp48_ = _g_object_ref0 (_tmp47_);
	_g_object_unref0 (((BirdFontOtfTable*) self)->font_data);
	((BirdFontOtfTable*) self)->font_data = _tmp48_;
	if (((gint) self->max_advance) == 0) {
		g_warning ("HmtxTable.vala:177: max_advance is zero");
	}
	_g_object_unref0 (g);
	_g_object_unref0 (fd);
}

gint16
bird_font_hmtx_table_get_average_width (BirdFontHmtxTable* self)
{
	gdouble total_width = 0.0;
	guint non_zero_glyphs = 0U;
	gint16 result;
	g_return_val_if_fail (self != NULL, 0);
	total_width = (gdouble) 0;
	non_zero_glyphs = (guint) 0;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint16* _tmp2_;
				guint16 _tmp3_;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = i;
					i = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(((guint32) i) < self->priv->nmetrics)) {
					break;
				}
				_tmp2_ = self->priv->advance_width;
				_tmp3_ = _tmp2_[i];
				if (((gint) _tmp3_) != 0) {
					guint16* _tmp4_;
					guint16 _tmp5_;
					guint _tmp6_;
					_tmp4_ = self->priv->advance_width;
					_tmp5_ = _tmp4_[i];
					total_width += (gdouble) _tmp5_;
					_tmp6_ = non_zero_glyphs;
					non_zero_glyphs = _tmp6_ + 1;
				}
			}
		}
	}
	result = (gint16) rint (total_width / non_zero_glyphs);
	return result;
}

static void
bird_font_hmtx_table_class_init (BirdFontHmtxTableClass * klass,
                                 gpointer klass_data)
{
	bird_font_hmtx_table_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &BirdFontHmtxTable_private_offset);
	G_OBJECT_CLASS (klass)->finalize = bird_font_hmtx_table_finalize;
}

static void
bird_font_hmtx_table_instance_init (BirdFontHmtxTable * self,
                                    gpointer klass)
{
	self->priv = bird_font_hmtx_table_get_instance_private (self);
	self->priv->advance_width = NULL;
	self->priv->left_side_bearing = NULL;
	self->priv->left_side_bearing_monospaced = NULL;
	self->max_advance = (gint16) 0;
	self->max_extent = (gint16) 0;
	self->min_lsb = G_MAXINT16;
	self->min_rsb = G_MAXINT16;
}

static void
bird_font_hmtx_table_finalize (GObject * obj)
{
	BirdFontHmtxTable * self;
	guint16* _tmp0_;
	guint16* _tmp2_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, BIRD_FONT_TYPE_HMTX_TABLE, BirdFontHmtxTable);
	_tmp0_ = self->priv->advance_width;
	if (_tmp0_ != NULL) {
		guint16* _tmp1_;
		_tmp1_ = self->priv->advance_width;
		_g_free0 (_tmp1_);
	}
	_tmp2_ = self->priv->left_side_bearing;
	if (_tmp2_ != NULL) {
		guint16* _tmp3_;
		_tmp3_ = self->priv->left_side_bearing;
		_g_free0 (_tmp3_);
	}
	_g_object_unref0 (self->priv->head_table);
	_g_object_unref0 (self->priv->glyf_table);
	G_OBJECT_CLASS (bird_font_hmtx_table_parent_class)->finalize (obj);
}

static GType
bird_font_hmtx_table_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (BirdFontHmtxTableClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) bird_font_hmtx_table_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BirdFontHmtxTable), 0, (GInstanceInitFunc) bird_font_hmtx_table_instance_init, NULL };
	GType bird_font_hmtx_table_type_id;
	bird_font_hmtx_table_type_id = g_type_register_static (BIRD_FONT_TYPE_OTF_TABLE, "BirdFontHmtxTable", &g_define_type_info, 0);
	BirdFontHmtxTable_private_offset = g_type_add_instance_private (bird_font_hmtx_table_type_id, sizeof (BirdFontHmtxTablePrivate));
	return bird_font_hmtx_table_type_id;
}

GType
bird_font_hmtx_table_get_type (void)
{
	static volatile gsize bird_font_hmtx_table_type_id__once = 0;
	if (g_once_init_enter (&bird_font_hmtx_table_type_id__once)) {
		GType bird_font_hmtx_table_type_id;
		bird_font_hmtx_table_type_id = bird_font_hmtx_table_get_type_once ();
		g_once_init_leave (&bird_font_hmtx_table_type_id__once, bird_font_hmtx_table_type_id);
	}
	return bird_font_hmtx_table_type_id__once;
}

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

