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

/*
Copyright (C) 2013 2015 2017 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-object.h>
#include <glib.h>
#include <gee.h>
#include <stdlib.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

enum  {
	BIRD_FONT_GLYPH_SEQUENCE_0_PROPERTY,
	BIRD_FONT_GLYPH_SEQUENCE_NUM_PROPERTIES
};
static GParamSpec* bird_font_glyph_sequence_properties[BIRD_FONT_GLYPH_SEQUENCE_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _bird_font_glyph_range_unref0(var) ((var == NULL) ? NULL : (var = (bird_font_glyph_range_unref (var), NULL)))
typedef struct _Block19Data Block19Data;
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))

struct _BirdFontGlyphSequencePrivate {
	BirdFontOtfTags* otf_tags;
};

struct _Block19Data {
	int _ref_count_;
	BirdFontGlyphSequence* self;
	BirdFontGlyphSequence* ligature_sequence;
};

static gint BirdFontGlyphSequence_private_offset;
static gpointer bird_font_glyph_sequence_parent_class = NULL;

static Block19Data* block19_data_ref (Block19Data* _data19_);
static void block19_data_unref (void * _userdata_);
static gboolean bird_font_glyph_sequence_replace_contextual (BirdFontGlyphSequence* self,
                                                      BirdFontGlyphSequence* backtrack,
                                                      BirdFontGlyphSequence* input,
                                                      BirdFontGlyphSequence* lookahead,
                                                      BirdFontGlyphSequence* replacement,
                                                      gint* index);
static void __lambda514_ (Block19Data* _data19_,
                   BirdFontGlyphSequence* substitute,
                   BirdFontGlyphSequence* ligature);
static void bird_font_glyph_sequence_replace (BirdFontGlyphSequence* self,
                                       BirdFontGlyphSequence* old,
                                       BirdFontGlyphSequence* replacement);
static void ___lambda514__bird_font_ligatures_single_ligature_iterator (BirdFontGlyphSequence* substitution,
                                                                 BirdFontGlyphSequence* ligature,
                                                                 gpointer self);
static gboolean bird_font_glyph_sequence_starts_with (BirdFontGlyphSequence* self,
                                               BirdFontGlyphSequence* old,
                                               guint index);
static GeeArrayList* bird_font_glyph_sequence_substitute (BirdFontGlyphSequence* self,
                                                   guint index,
                                                   guint length,
                                                   BirdFontGlyphSequence* substitute);
static void bird_font_glyph_sequence_finalize (GObject * obj);
static GType bird_font_glyph_sequence_get_type_once (void);

static inline gpointer
bird_font_glyph_sequence_get_instance_private (BirdFontGlyphSequence* self)
{
	return G_STRUCT_MEMBER_P (self, BirdFontGlyphSequence_private_offset);
}

BirdFontGlyphSequence*
bird_font_glyph_sequence_construct (GType object_type)
{
	BirdFontGlyphSequence * self = NULL;
	GeeArrayList* _tmp0_;
	GeeArrayList* _tmp1_;
	BirdFontOtfTags* _tmp2_;
	self = (BirdFontGlyphSequence*) g_object_new (object_type, NULL);
	_tmp0_ = gee_array_list_new (BIRD_FONT_TYPE_GLYPH, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	_g_object_unref0 (self->glyph);
	self->glyph = _tmp0_;
	_tmp1_ = gee_array_list_new (BIRD_FONT_TYPE_GLYPH_RANGE, (GBoxedCopyFunc) bird_font_glyph_range_ref, (GDestroyNotify) bird_font_glyph_range_unref, NULL, NULL, NULL);
	_g_object_unref0 (self->ranges);
	self->ranges = _tmp1_;
	_tmp2_ = bird_font_otf_tags_new ();
	_g_object_unref0 (self->priv->otf_tags);
	self->priv->otf_tags = _tmp2_;
	return self;
}

BirdFontGlyphSequence*
bird_font_glyph_sequence_new (void)
{
	return bird_font_glyph_sequence_construct (BIRD_FONT_TYPE_GLYPH_SEQUENCE);
}

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

void
bird_font_glyph_sequence_set_otf_tags (BirdFontGlyphSequence* self,
                                       BirdFontOtfTags* tags)
{
	BirdFontOtfTags* _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (tags != NULL);
	_tmp0_ = _g_object_ref0 (tags);
	_g_object_unref0 (self->priv->otf_tags);
	self->priv->otf_tags = _tmp0_;
}

gint
bird_font_glyph_sequence_length (BirdFontGlyphSequence* self)
{
	GeeArrayList* _tmp0_;
	gint _tmp1_;
	gint _tmp2_;
	gint result;
	g_return_val_if_fail (self != NULL, 0);
	_tmp0_ = self->glyph;
	_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
	_tmp2_ = _tmp1_;
	result = _tmp2_;
	return result;
}

void
bird_font_glyph_sequence_add (BirdFontGlyphSequence* self,
                              BirdFontGlyph* g)
{
	GeeArrayList* _tmp0_;
	GeeArrayList* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->glyph;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp0_, g);
	_tmp1_ = self->ranges;
	gee_abstract_collection_add ((GeeAbstractCollection*) _tmp1_, NULL);
}

void
bird_font_glyph_sequence_append (BirdFontGlyphSequence* self,
                                 BirdFontGlyphSequence* c)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (c != NULL);
	{
		GeeArrayList* _g_list = NULL;
		GeeArrayList* _tmp0_;
		gint _g_size = 0;
		GeeArrayList* _tmp1_;
		gint _tmp2_;
		gint _tmp3_;
		gint _g_index = 0;
		_tmp0_ = c->glyph;
		_g_list = _tmp0_;
		_tmp1_ = _g_list;
		_tmp2_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp1_);
		_tmp3_ = _tmp2_;
		_g_size = _tmp3_;
		_g_index = -1;
		while (TRUE) {
			gint _tmp4_;
			gint _tmp5_;
			BirdFontGlyph* g = NULL;
			GeeArrayList* _tmp6_;
			gpointer _tmp7_;
			GeeArrayList* _tmp8_;
			BirdFontGlyph* _tmp9_;
			_g_index = _g_index + 1;
			_tmp4_ = _g_index;
			_tmp5_ = _g_size;
			if (!(_tmp4_ < _tmp5_)) {
				break;
			}
			_tmp6_ = _g_list;
			_tmp7_ = gee_abstract_list_get ((GeeAbstractList*) _tmp6_, _g_index);
			g = (BirdFontGlyph*) _tmp7_;
			_tmp8_ = self->glyph;
			_tmp9_ = g;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp8_, _tmp9_);
			_g_object_unref0 (g);
		}
	}
	{
		GeeArrayList* _r_list = NULL;
		GeeArrayList* _tmp10_;
		gint _r_size = 0;
		GeeArrayList* _tmp11_;
		gint _tmp12_;
		gint _tmp13_;
		gint _r_index = 0;
		_tmp10_ = c->ranges;
		_r_list = _tmp10_;
		_tmp11_ = _r_list;
		_tmp12_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp11_);
		_tmp13_ = _tmp12_;
		_r_size = _tmp13_;
		_r_index = -1;
		while (TRUE) {
			gint _tmp14_;
			gint _tmp15_;
			BirdFontGlyphRange* r = NULL;
			GeeArrayList* _tmp16_;
			gpointer _tmp17_;
			GeeArrayList* _tmp18_;
			BirdFontGlyphRange* _tmp19_;
			_r_index = _r_index + 1;
			_tmp14_ = _r_index;
			_tmp15_ = _r_size;
			if (!(_tmp14_ < _tmp15_)) {
				break;
			}
			_tmp16_ = _r_list;
			_tmp17_ = gee_abstract_list_get ((GeeAbstractList*) _tmp16_, _r_index);
			r = (BirdFontGlyphRange*) _tmp17_;
			_tmp18_ = self->ranges;
			_tmp19_ = r;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp18_, _tmp19_);
			_bird_font_glyph_range_unref0 (r);
		}
	}
}

/** Perform glyph substitution.
 * @param tags enable otf features
 * @return a new sequence with ligatures
 */
static Block19Data*
block19_data_ref (Block19Data* _data19_)
{
	g_atomic_int_inc (&_data19_->_ref_count_);
	return _data19_;
}

static void
block19_data_unref (void * _userdata_)
{
	Block19Data* _data19_;
	_data19_ = (Block19Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data19_->_ref_count_)) {
		BirdFontGlyphSequence* self;
		self = _data19_->self;
		_g_object_unref0 (_data19_->ligature_sequence);
		_g_object_unref0 (self);
		g_slice_free (Block19Data, _data19_);
	}
}

static void
__lambda514_ (Block19Data* _data19_,
              BirdFontGlyphSequence* substitute,
              BirdFontGlyphSequence* ligature)
{
	BirdFontGlyphSequence* self;
	BirdFontGlyphSequence* _tmp0_;
	self = _data19_->self;
	g_return_if_fail (substitute != NULL);
	g_return_if_fail (ligature != NULL);
	_tmp0_ = _data19_->ligature_sequence;
	bird_font_glyph_sequence_replace (_tmp0_, substitute, ligature);
}

static void
___lambda514__bird_font_ligatures_single_ligature_iterator (BirdFontGlyphSequence* substitution,
                                                            BirdFontGlyphSequence* ligature,
                                                            gpointer self)
{
	__lambda514_ (self, substitution, ligature);
}

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

BirdFontGlyphSequence*
bird_font_glyph_sequence_process_ligatures (BirdFontGlyphSequence* self,
                                            BirdFontFont* font)
{
	Block19Data* _data19_;
	BirdFontGlyphSequence* _tmp0_;
	gboolean has_range = FALSE;
	BirdFontLigatures* ligatures = NULL;
	BirdFontLigatures* _tmp26_;
	BirdFontLigatures* _tmp57_;
	BirdFontGlyphSequence* _tmp110_;
	GeeArrayList* _tmp111_;
	BirdFontGlyphSequence* _tmp120_;
	BirdFontGlyphSequence* _tmp121_;
	BirdFontGlyphSequence* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (font != NULL, NULL);
	_data19_ = g_slice_new0 (Block19Data);
	_data19_->_ref_count_ = 1;
	_data19_->self = g_object_ref (self);
	_tmp0_ = bird_font_glyph_sequence_new ();
	_data19_->ligature_sequence = _tmp0_;
	has_range = FALSE;
	{
		GeeArrayList* _g_list = NULL;
		GeeArrayList* _tmp1_;
		gint _g_size = 0;
		GeeArrayList* _tmp2_;
		gint _tmp3_;
		gint _tmp4_;
		gint _g_index = 0;
		_tmp1_ = self->glyph;
		_g_list = _tmp1_;
		_tmp2_ = _g_list;
		_tmp3_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp2_);
		_tmp4_ = _tmp3_;
		_g_size = _tmp4_;
		_g_index = -1;
		while (TRUE) {
			gint _tmp5_;
			gint _tmp6_;
			BirdFontGlyph* g = NULL;
			GeeArrayList* _tmp7_;
			gpointer _tmp8_;
			BirdFontGlyphSequence* _tmp9_;
			GeeArrayList* _tmp10_;
			BirdFontGlyph* _tmp11_;
			_g_index = _g_index + 1;
			_tmp5_ = _g_index;
			_tmp6_ = _g_size;
			if (!(_tmp5_ < _tmp6_)) {
				break;
			}
			_tmp7_ = _g_list;
			_tmp8_ = gee_abstract_list_get ((GeeAbstractList*) _tmp7_, _g_index);
			g = (BirdFontGlyph*) _tmp8_;
			_tmp9_ = _data19_->ligature_sequence;
			_tmp10_ = _tmp9_->glyph;
			_tmp11_ = g;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp10_, _tmp11_);
			_g_object_unref0 (g);
		}
	}
	{
		GeeArrayList* _r_list = NULL;
		GeeArrayList* _tmp12_;
		gint _r_size = 0;
		GeeArrayList* _tmp13_;
		gint _tmp14_;
		gint _tmp15_;
		gint _r_index = 0;
		_tmp12_ = self->ranges;
		_r_list = _tmp12_;
		_tmp13_ = _r_list;
		_tmp14_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp13_);
		_tmp15_ = _tmp14_;
		_r_size = _tmp15_;
		_r_index = -1;
		while (TRUE) {
			gint _tmp16_;
			gint _tmp17_;
			BirdFontGlyphRange* r = NULL;
			GeeArrayList* _tmp18_;
			gpointer _tmp19_;
			BirdFontGlyphSequence* _tmp20_;
			GeeArrayList* _tmp21_;
			BirdFontGlyphRange* _tmp22_;
			BirdFontGlyphRange* _tmp23_;
			_r_index = _r_index + 1;
			_tmp16_ = _r_index;
			_tmp17_ = _r_size;
			if (!(_tmp16_ < _tmp17_)) {
				break;
			}
			_tmp18_ = _r_list;
			_tmp19_ = gee_abstract_list_get ((GeeAbstractList*) _tmp18_, _r_index);
			r = (BirdFontGlyphRange*) _tmp19_;
			_tmp20_ = _data19_->ligature_sequence;
			_tmp21_ = _tmp20_->ranges;
			_tmp22_ = r;
			gee_abstract_collection_add ((GeeAbstractCollection*) _tmp21_, _tmp22_);
			_tmp23_ = r;
			if (_tmp23_ != NULL) {
				has_range = TRUE;
			}
			_bird_font_glyph_range_unref0 (r);
		}
	}
	if (has_range) {
		BirdFontGlyphSequence* _tmp24_;
		BirdFontGlyphSequence* _tmp25_;
		_tmp24_ = _data19_->ligature_sequence;
		_tmp25_ = _g_object_ref0 (_tmp24_);
		result = _tmp25_;
		_g_object_unref0 (ligatures);
		block19_data_unref (_data19_);
		_data19_ = NULL;
		return result;
	}
	_tmp26_ = bird_font_font_get_ligatures (font);
	_g_object_unref0 (ligatures);
	ligatures = _tmp26_;
	{
		gint index = 0;
		index = 0;
		{
			gboolean _tmp27_ = FALSE;
			_tmp27_ = TRUE;
			while (TRUE) {
				GeeArrayList* _tmp29_;
				gint _tmp30_;
				gint _tmp31_;
				gboolean found = FALSE;
				if (!_tmp27_) {
					gint _tmp28_;
					_tmp28_ = index;
					index = _tmp28_ + 1;
				}
				_tmp27_ = FALSE;
				_tmp29_ = self->glyph;
				_tmp30_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp29_);
				_tmp31_ = _tmp30_;
				if (!(index < _tmp31_)) {
					break;
				}
				found = FALSE;
				{
					GeeArrayList* _c_list = NULL;
					BirdFontLigatures* _tmp32_;
					GeeArrayList* _tmp33_;
					gint _c_size = 0;
					GeeArrayList* _tmp34_;
					gint _tmp35_;
					gint _tmp36_;
					gint _c_index = 0;
					_tmp32_ = ligatures;
					_tmp33_ = _tmp32_->contextual_ligatures;
					_c_list = _tmp33_;
					_tmp34_ = _c_list;
					_tmp35_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp34_);
					_tmp36_ = _tmp35_;
					_c_size = _tmp36_;
					_c_index = -1;
					while (TRUE) {
						gint _tmp37_;
						gint _tmp38_;
						BirdFontContextualLigature* c = NULL;
						GeeArrayList* _tmp39_;
						gpointer _tmp40_;
						BirdFontContextualLigature* _tmp41_;
						_c_index = _c_index + 1;
						_tmp37_ = _c_index;
						_tmp38_ = _c_size;
						if (!(_tmp37_ < _tmp38_)) {
							break;
						}
						_tmp39_ = _c_list;
						_tmp40_ = gee_abstract_list_get ((GeeAbstractList*) _tmp39_, _c_index);
						c = (BirdFontContextualLigature*) _tmp40_;
						_tmp41_ = c;
						if (bird_font_contextual_ligature_is_valid (_tmp41_)) {
							BirdFontGlyphSequence* _tmp42_;
							BirdFontContextualLigature* _tmp43_;
							BirdFontGlyphSequence* _tmp44_;
							BirdFontGlyphSequence* _tmp45_;
							BirdFontContextualLigature* _tmp46_;
							BirdFontGlyphSequence* _tmp47_;
							BirdFontGlyphSequence* _tmp48_;
							BirdFontContextualLigature* _tmp49_;
							BirdFontGlyphSequence* _tmp50_;
							BirdFontGlyphSequence* _tmp51_;
							BirdFontContextualLigature* _tmp52_;
							BirdFontGlyphSequence* _tmp53_;
							BirdFontGlyphSequence* _tmp54_;
							gboolean _tmp55_;
							_tmp42_ = _data19_->ligature_sequence;
							_tmp43_ = c;
							_tmp44_ = bird_font_contextual_ligature_get_backtrack (_tmp43_);
							_tmp45_ = _tmp44_;
							_tmp46_ = c;
							_tmp47_ = bird_font_contextual_ligature_get_input (_tmp46_);
							_tmp48_ = _tmp47_;
							_tmp49_ = c;
							_tmp50_ = bird_font_contextual_ligature_get_lookahead (_tmp49_);
							_tmp51_ = _tmp50_;
							_tmp52_ = c;
							_tmp53_ = bird_font_contextual_ligature_get_ligature_sequence (_tmp52_);
							_tmp54_ = _tmp53_;
							_tmp55_ = bird_font_glyph_sequence_replace_contextual (_tmp42_, _tmp45_, _tmp48_, _tmp51_, _tmp54_, &index);
							found = _tmp55_;
							_g_object_unref0 (_tmp54_);
							_g_object_unref0 (_tmp51_);
							_g_object_unref0 (_tmp48_);
							_g_object_unref0 (_tmp45_);
							if (found) {
								gint _tmp56_;
								_tmp56_ = index;
								index = _tmp56_ - 1;
								_g_object_unref0 (c);
								break;
							}
						}
						_g_object_unref0 (c);
					}
				}
			}
		}
	}
	_tmp57_ = ligatures;
	bird_font_ligatures_get_single_substitution_ligatures (_tmp57_, ___lambda514__bird_font_ligatures_single_ligature_iterator, _data19_);
	{
		GeeArrayList* _tag_list = NULL;
		BirdFontOtfTags* _tmp58_;
		GeeArrayList* _tmp59_;
		gint _tag_size = 0;
		GeeArrayList* _tmp60_;
		gint _tmp61_;
		gint _tmp62_;
		gint _tag_index = 0;
		_tmp58_ = self->priv->otf_tags;
		_tmp59_ = _tmp58_->elements;
		_tag_list = _tmp59_;
		_tmp60_ = _tag_list;
		_tmp61_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp60_);
		_tmp62_ = _tmp61_;
		_tag_size = _tmp62_;
		_tag_index = -1;
		while (TRUE) {
			gint _tmp63_;
			gint _tmp64_;
			gchar* tag = NULL;
			GeeArrayList* _tmp65_;
			gpointer _tmp66_;
			GeeArrayList* alternates = NULL;
			BirdFontAlternateSets* _tmp67_;
			const gchar* _tmp68_;
			GeeArrayList* _tmp69_;
			_tag_index = _tag_index + 1;
			_tmp63_ = _tag_index;
			_tmp64_ = _tag_size;
			if (!(_tmp63_ < _tmp64_)) {
				break;
			}
			_tmp65_ = _tag_list;
			_tmp66_ = gee_abstract_list_get ((GeeAbstractList*) _tmp65_, _tag_index);
			tag = (gchar*) _tmp66_;
			_tmp67_ = font->alternates;
			_tmp68_ = tag;
			_tmp69_ = bird_font_alternate_sets_get_alt (_tmp67_, _tmp68_);
			_g_object_unref0 (alternates);
			alternates = _tmp69_;
			{
				GeeArrayList* _a_list = NULL;
				GeeArrayList* _tmp70_;
				gint _a_size = 0;
				GeeArrayList* _tmp71_;
				gint _tmp72_;
				gint _tmp73_;
				gint _a_index = 0;
				_tmp70_ = alternates;
				_a_list = _tmp70_;
				_tmp71_ = _a_list;
				_tmp72_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp71_);
				_tmp73_ = _tmp72_;
				_a_size = _tmp73_;
				_a_index = -1;
				while (TRUE) {
					gint _tmp74_;
					gint _tmp75_;
					BirdFontAlternate* a = NULL;
					GeeArrayList* _tmp76_;
					gpointer _tmp77_;
					BirdFontGlyphSequence* old = NULL;
					BirdFontGlyphSequence* _tmp78_;
					BirdFontGlyph* g = NULL;
					BirdFontAlternate* _tmp79_;
					const gchar* _tmp80_;
					BirdFontGlyph* _tmp81_;
					BirdFontGlyph* _tmp82_;
					_a_index = _a_index + 1;
					_tmp74_ = _a_index;
					_tmp75_ = _a_size;
					if (!(_tmp74_ < _tmp75_)) {
						break;
					}
					_tmp76_ = _a_list;
					_tmp77_ = gee_abstract_list_get ((GeeAbstractList*) _tmp76_, _a_index);
					a = (BirdFontAlternate*) _tmp77_;
					_tmp78_ = bird_font_glyph_sequence_new ();
					old = _tmp78_;
					_tmp79_ = a;
					_tmp80_ = _tmp79_->glyph_name;
					_tmp81_ = bird_font_font_get_glyph_by_name (font, _tmp80_);
					g = _tmp81_;
					_tmp82_ = g;
					if (_tmp82_ != NULL) {
						BirdFontGlyphSequence* _tmp83_;
						BirdFontGlyph* _tmp84_;
						BirdFontAlternate* _tmp85_;
						GeeArrayList* _tmp86_;
						gint _tmp87_;
						gint _tmp88_;
						_tmp83_ = old;
						_tmp84_ = g;
						bird_font_glyph_sequence_add (_tmp83_, _tmp84_);
						_tmp85_ = a;
						_tmp86_ = _tmp85_->alternates;
						_tmp87_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp86_);
						_tmp88_ = _tmp87_;
						if (_tmp88_ > 0) {
							gchar* alt_name = NULL;
							BirdFontAlternate* _tmp89_;
							GeeArrayList* _tmp90_;
							gpointer _tmp91_;
							BirdFontGlyph* alt = NULL;
							const gchar* _tmp92_;
							BirdFontGlyph* _tmp93_;
							BirdFontGlyph* _tmp94_;
							_tmp89_ = a;
							_tmp90_ = _tmp89_->alternates;
							_tmp91_ = gee_abstract_list_get ((GeeAbstractList*) _tmp90_, 0);
							alt_name = (gchar*) _tmp91_;
							_tmp92_ = alt_name;
							_tmp93_ = bird_font_font_get_glyph_by_name (font, _tmp92_);
							alt = _tmp93_;
							_tmp94_ = alt;
							if (_tmp94_ != NULL) {
								BirdFontGlyphSequence* replacement = NULL;
								BirdFontGlyphSequence* _tmp95_;
								BirdFontGlyphSequence* _tmp96_;
								BirdFontGlyph* _tmp97_;
								BirdFontGlyphSequence* _tmp98_;
								BirdFontGlyphSequence* _tmp99_;
								BirdFontGlyphSequence* _tmp100_;
								_tmp95_ = bird_font_glyph_sequence_new ();
								replacement = _tmp95_;
								_tmp96_ = replacement;
								_tmp97_ = alt;
								bird_font_glyph_sequence_add (_tmp96_, _tmp97_);
								_tmp98_ = _data19_->ligature_sequence;
								_tmp99_ = old;
								_tmp100_ = replacement;
								bird_font_glyph_sequence_replace (_tmp98_, _tmp99_, _tmp100_);
								_g_object_unref0 (replacement);
							} else {
								const gchar* _tmp101_;
								const gchar* _tmp102_;
								gchar* _tmp103_;
								gchar* _tmp104_;
								_tmp101_ = alt_name;
								_tmp102_ = string_to_string (_tmp101_);
								_tmp103_ = g_strconcat ("Alternate does not exist: ", _tmp102_, NULL);
								_tmp104_ = _tmp103_;
								g_warning ("GlyphSequence.vala:127: %s", _tmp104_);
								_g_free0 (_tmp104_);
							}
							_g_object_unref0 (alt);
							_g_free0 (alt_name);
						}
					} else {
						BirdFontAlternate* _tmp105_;
						const gchar* _tmp106_;
						const gchar* _tmp107_;
						gchar* _tmp108_;
						gchar* _tmp109_;
						_tmp105_ = a;
						_tmp106_ = _tmp105_->glyph_name;
						_tmp107_ = string_to_string (_tmp106_);
						_tmp108_ = g_strconcat ("Alternative for a missing glyph: ", _tmp107_, NULL);
						_tmp109_ = _tmp108_;
						g_warning ("GlyphSequence.vala:131: %s", _tmp109_);
						_g_free0 (_tmp109_);
					}
					_g_object_unref0 (g);
					_g_object_unref0 (old);
					_g_object_unref0 (a);
				}
			}
			_g_object_unref0 (alternates);
			_g_free0 (tag);
		}
	}
	_tmp110_ = _data19_->ligature_sequence;
	_tmp111_ = _tmp110_->ranges;
	gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp111_);
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp112_ = FALSE;
			_tmp112_ = TRUE;
			while (TRUE) {
				BirdFontGlyphSequence* _tmp114_;
				GeeArrayList* _tmp115_;
				gint _tmp116_;
				gint _tmp117_;
				BirdFontGlyphSequence* _tmp118_;
				GeeArrayList* _tmp119_;
				if (!_tmp112_) {
					gint _tmp113_;
					_tmp113_ = i;
					i = _tmp113_ + 1;
				}
				_tmp112_ = FALSE;
				_tmp114_ = _data19_->ligature_sequence;
				_tmp115_ = _tmp114_->glyph;
				_tmp116_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp115_);
				_tmp117_ = _tmp116_;
				if (!(i < _tmp117_)) {
					break;
				}
				_tmp118_ = _data19_->ligature_sequence;
				_tmp119_ = _tmp118_->ranges;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp119_, NULL);
			}
		}
	}
	_tmp120_ = _data19_->ligature_sequence;
	_tmp121_ = _g_object_ref0 (_tmp120_);
	result = _tmp121_;
	_g_object_unref0 (ligatures);
	block19_data_unref (_data19_);
	_data19_ = NULL;
	return result;
}

static void
bird_font_glyph_sequence_replace (BirdFontGlyphSequence* self,
                                  BirdFontGlyphSequence* old,
                                  BirdFontGlyphSequence* replacement)
{
	gint i = 0;
	g_return_if_fail (self != NULL);
	g_return_if_fail (old != NULL);
	g_return_if_fail (replacement != NULL);
	i = 0;
	while (TRUE) {
		GeeArrayList* _tmp0_;
		gint _tmp1_;
		gint _tmp2_;
		_tmp0_ = self->glyph;
		_tmp1_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp0_);
		_tmp2_ = _tmp1_;
		if (!(i < _tmp2_)) {
			break;
		}
		if (bird_font_glyph_sequence_starts_with (self, old, (guint) i)) {
			GeeArrayList* _tmp3_;
			gint _tmp4_;
			gint _tmp5_;
			GeeArrayList* _tmp6_;
			_tmp3_ = old->glyph;
			_tmp4_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp3_);
			_tmp5_ = _tmp4_;
			_tmp6_ = bird_font_glyph_sequence_substitute (self, (guint) i, (guint) _tmp5_, replacement);
			_g_object_unref0 (self->glyph);
			self->glyph = _tmp6_;
			i += bird_font_glyph_sequence_length (replacement);
		} else {
			gint _tmp7_;
			_tmp7_ = i;
			i = _tmp7_ + 1;
		}
	}
}

static gboolean
bird_font_glyph_sequence_replace_contextual (BirdFontGlyphSequence* self,
                                             BirdFontGlyphSequence* backtrack,
                                             BirdFontGlyphSequence* input,
                                             BirdFontGlyphSequence* lookahead,
                                             BirdFontGlyphSequence* replacement,
                                             gint* index)
{
	gboolean start = FALSE;
	gboolean middle = FALSE;
	gboolean end = FALSE;
	gint advance = 0;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (backtrack != NULL, FALSE);
	g_return_val_if_fail (input != NULL, FALSE);
	g_return_val_if_fail (lookahead != NULL, FALSE);
	g_return_val_if_fail (replacement != NULL, FALSE);
	advance = 0;
	start = bird_font_glyph_sequence_starts_with (self, backtrack, (guint) (*index));
	middle = bird_font_glyph_sequence_starts_with (self, input, (guint) ((*index) + bird_font_glyph_sequence_length (backtrack)));
	end = bird_font_glyph_sequence_starts_with (self, lookahead, (guint) (((*index) + bird_font_glyph_sequence_length (backtrack)) + bird_font_glyph_sequence_length (input)));
	if (start) {
		_tmp1_ = middle;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_tmp0_ = end;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		GeeArrayList* _tmp2_;
		_tmp2_ = bird_font_glyph_sequence_substitute (self, (guint) ((*index) + bird_font_glyph_sequence_length (backtrack)), (guint) bird_font_glyph_sequence_length (input), replacement);
		_g_object_unref0 (self->glyph);
		self->glyph = _tmp2_;
		advance = bird_font_glyph_sequence_length (backtrack) + bird_font_glyph_sequence_length (replacement);
		*index = (*index) + advance;
		if (advance <= 0) {
			g_warning ("GlyphSequence.vala:172: No advancement.");
			result = FALSE;
			return result;
		}
		result = TRUE;
		return result;
	}
	result = FALSE;
	return result;
}

static gboolean
bird_font_glyph_sequence_starts_with (BirdFontGlyphSequence* self,
                                      BirdFontGlyphSequence* old,
                                      guint index)
{
	BirdFontGlyph* gl = NULL;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (old != NULL, FALSE);
	{
		GeeArrayList* _g_list = NULL;
		GeeArrayList* _tmp0_;
		gint _g_size = 0;
		GeeArrayList* _tmp1_;
		gint _tmp2_;
		gint _tmp3_;
		gint _g_index = 0;
		_tmp0_ = old->glyph;
		_g_list = _tmp0_;
		_tmp1_ = _g_list;
		_tmp2_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp1_);
		_tmp3_ = _tmp2_;
		_g_size = _tmp3_;
		_g_index = -1;
		while (TRUE) {
			gint _tmp4_;
			gint _tmp5_;
			BirdFontGlyph* g = NULL;
			GeeArrayList* _tmp6_;
			gpointer _tmp7_;
			GeeArrayList* _tmp8_;
			gint _tmp9_;
			gint _tmp10_;
			GeeArrayList* _tmp11_;
			gpointer _tmp12_;
			BirdFontGlyph* _tmp13_;
			BirdFontGlyph* _tmp14_;
			guint _tmp15_;
			_g_index = _g_index + 1;
			_tmp4_ = _g_index;
			_tmp5_ = _g_size;
			if (!(_tmp4_ < _tmp5_)) {
				break;
			}
			_tmp6_ = _g_list;
			_tmp7_ = gee_abstract_list_get ((GeeAbstractList*) _tmp6_, _g_index);
			g = (BirdFontGlyph*) _tmp7_;
			_tmp8_ = self->glyph;
			_tmp9_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp8_);
			_tmp10_ = _tmp9_;
			if (index >= ((guint) _tmp10_)) {
				result = FALSE;
				_g_object_unref0 (g);
				_g_object_unref0 (gl);
				return result;
			}
			_tmp11_ = self->glyph;
			_tmp12_ = gee_abstract_list_get ((GeeAbstractList*) _tmp11_, (gint) index);
			_g_object_unref0 (gl);
			gl = (BirdFontGlyph*) _tmp12_;
			_tmp13_ = g;
			_tmp14_ = gl;
			if (_tmp13_ != _tmp14_) {
				result = FALSE;
				_g_object_unref0 (g);
				_g_object_unref0 (gl);
				return result;
			}
			_tmp15_ = index;
			index = _tmp15_ + 1;
			_g_object_unref0 (g);
		}
	}
	result = TRUE;
	_g_object_unref0 (gl);
	return result;
}

static GeeArrayList*
bird_font_glyph_sequence_substitute (BirdFontGlyphSequence* self,
                                     guint index,
                                     guint length,
                                     BirdFontGlyphSequence* substitute)
{
	GeeArrayList* new_list = NULL;
	GeeArrayList* _tmp0_;
	gint i = 0;
	GeeArrayList* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (substitute != NULL, NULL);
	_tmp0_ = gee_array_list_new (BIRD_FONT_TYPE_GLYPH, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
	new_list = _tmp0_;
	i = 0;
	{
		GeeArrayList* _g_list = NULL;
		GeeArrayList* _tmp1_;
		gint _g_size = 0;
		GeeArrayList* _tmp2_;
		gint _tmp3_;
		gint _tmp4_;
		gint _g_index = 0;
		_tmp1_ = self->glyph;
		_g_list = _tmp1_;
		_tmp2_ = _g_list;
		_tmp3_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp2_);
		_tmp4_ = _tmp3_;
		_g_size = _tmp4_;
		_g_index = -1;
		while (TRUE) {
			gint _tmp5_;
			gint _tmp6_;
			BirdFontGlyph* g = NULL;
			GeeArrayList* _tmp7_;
			gpointer _tmp8_;
			gboolean _tmp19_ = FALSE;
			gint _tmp22_;
			_g_index = _g_index + 1;
			_tmp5_ = _g_index;
			_tmp6_ = _g_size;
			if (!(_tmp5_ < _tmp6_)) {
				break;
			}
			_tmp7_ = _g_list;
			_tmp8_ = gee_abstract_list_get ((GeeAbstractList*) _tmp7_, _g_index);
			g = (BirdFontGlyph*) _tmp8_;
			if (((guint) i) == index) {
				{
					GeeArrayList* _gn_list = NULL;
					GeeArrayList* _tmp9_;
					gint _gn_size = 0;
					GeeArrayList* _tmp10_;
					gint _tmp11_;
					gint _tmp12_;
					gint _gn_index = 0;
					_tmp9_ = substitute->glyph;
					_gn_list = _tmp9_;
					_tmp10_ = _gn_list;
					_tmp11_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp10_);
					_tmp12_ = _tmp11_;
					_gn_size = _tmp12_;
					_gn_index = -1;
					while (TRUE) {
						gint _tmp13_;
						gint _tmp14_;
						BirdFontGlyph* gn = NULL;
						GeeArrayList* _tmp15_;
						gpointer _tmp16_;
						GeeArrayList* _tmp17_;
						BirdFontGlyph* _tmp18_;
						_gn_index = _gn_index + 1;
						_tmp13_ = _gn_index;
						_tmp14_ = _gn_size;
						if (!(_tmp13_ < _tmp14_)) {
							break;
						}
						_tmp15_ = _gn_list;
						_tmp16_ = gee_abstract_list_get ((GeeAbstractList*) _tmp15_, _gn_index);
						gn = (BirdFontGlyph*) _tmp16_;
						_tmp17_ = new_list;
						_tmp18_ = gn;
						gee_abstract_collection_add ((GeeAbstractCollection*) _tmp17_, _tmp18_);
						_g_object_unref0 (gn);
					}
				}
			}
			if (((guint) i) >= index) {
				_tmp19_ = ((guint) i) < (index + length);
			} else {
				_tmp19_ = FALSE;
			}
			if (!_tmp19_) {
				GeeArrayList* _tmp20_;
				BirdFontGlyph* _tmp21_;
				_tmp20_ = new_list;
				_tmp21_ = g;
				gee_abstract_collection_add ((GeeAbstractCollection*) _tmp20_, _tmp21_);
			}
			_tmp22_ = i;
			i = _tmp22_ + 1;
			_g_object_unref0 (g);
		}
	}
	result = new_list;
	return result;
}

static gchar*
g_unichar_to_string (gunichar self)
{
	gchar* str = NULL;
	gchar* _tmp0_;
	gchar* result;
	_tmp0_ = g_new0 (gchar, 7);
	str = (gchar*) _tmp0_;
	g_unichar_to_utf8 (self, str);
	result = str;
	return result;
}

gchar*
bird_font_glyph_sequence_to_string (BirdFontGlyphSequence* self)
{
	GString* s = NULL;
	GString* _tmp0_;
	GString* _tmp24_;
	const gchar* _tmp25_;
	gchar* _tmp26_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_string_new ("");
	s = _tmp0_;
	{
		GeeArrayList* _g_list = NULL;
		GeeArrayList* _tmp1_;
		gint _g_size = 0;
		GeeArrayList* _tmp2_;
		gint _tmp3_;
		gint _tmp4_;
		gint _g_index = 0;
		_tmp1_ = self->glyph;
		_g_list = _tmp1_;
		_tmp2_ = _g_list;
		_tmp3_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp2_);
		_tmp4_ = _tmp3_;
		_g_size = _tmp4_;
		_g_index = -1;
		while (TRUE) {
			gint _tmp5_;
			gint _tmp6_;
			BirdFontGlyph* g = NULL;
			GeeArrayList* _tmp7_;
			gpointer _tmp8_;
			BirdFontGlyph* _tmp9_;
			_g_index = _g_index + 1;
			_tmp5_ = _g_index;
			_tmp6_ = _g_size;
			if (!(_tmp5_ < _tmp6_)) {
				break;
			}
			_tmp7_ = _g_list;
			_tmp8_ = gee_abstract_list_get ((GeeAbstractList*) _tmp7_, _g_index);
			g = (BirdFontGlyph*) _tmp8_;
			_tmp9_ = g;
			if (_tmp9_ != NULL) {
				BirdFontGlyph* gl = NULL;
				BirdFontGlyph* _tmp10_;
				BirdFontGlyph* _tmp11_;
				BirdFontGlyph* _tmp12_;
				_tmp10_ = g;
				_tmp11_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp10_, BIRD_FONT_TYPE_GLYPH, BirdFontGlyph));
				gl = _tmp11_;
				_tmp12_ = gl;
				if (_tmp12_->unichar_code == ((gunichar) '\0')) {
					GString* _tmp13_;
					BirdFontGlyph* _tmp14_;
					const gchar* _tmp15_;
					const gchar* _tmp16_;
					gchar* _tmp17_;
					gchar* _tmp18_;
					_tmp13_ = s;
					_tmp14_ = gl;
					_tmp15_ = _tmp14_->name;
					_tmp16_ = string_to_string (_tmp15_);
					_tmp17_ = g_strconcat ("[", _tmp16_, "]", NULL);
					_tmp18_ = _tmp17_;
					g_string_append (_tmp13_, _tmp18_);
					_g_free0 (_tmp18_);
				} else {
					gchar* unichar_code = NULL;
					BirdFontGlyph* _tmp19_;
					gchar* _tmp20_;
					GString* _tmp21_;
					const gchar* _tmp22_;
					_tmp19_ = gl;
					_tmp20_ = g_unichar_to_string (_tmp19_->unichar_code);
					unichar_code = (gchar*) _tmp20_;
					_tmp21_ = s;
					_tmp22_ = unichar_code;
					g_string_append (_tmp21_, _tmp22_);
					_g_free0 (unichar_code);
				}
				_g_object_unref0 (gl);
			} else {
				GString* _tmp23_;
				_tmp23_ = s;
				g_string_append (_tmp23_, "[null]");
			}
			_g_object_unref0 (g);
		}
	}
	_tmp24_ = s;
	_tmp25_ = _tmp24_->str;
	_tmp26_ = g_strdup (_tmp25_);
	result = _tmp26_;
	_g_string_free0 (s);
	return result;
}

static void
bird_font_glyph_sequence_class_init (BirdFontGlyphSequenceClass * klass,
                                     gpointer klass_data)
{
	bird_font_glyph_sequence_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &BirdFontGlyphSequence_private_offset);
	G_OBJECT_CLASS (klass)->finalize = bird_font_glyph_sequence_finalize;
}

static void
bird_font_glyph_sequence_instance_init (BirdFontGlyphSequence * self,
                                        gpointer klass)
{
	self->priv = bird_font_glyph_sequence_get_instance_private (self);
}

static void
bird_font_glyph_sequence_finalize (GObject * obj)
{
	BirdFontGlyphSequence * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, BIRD_FONT_TYPE_GLYPH_SEQUENCE, BirdFontGlyphSequence);
	_g_object_unref0 (self->glyph);
	_g_object_unref0 (self->ranges);
	_g_object_unref0 (self->priv->otf_tags);
	G_OBJECT_CLASS (bird_font_glyph_sequence_parent_class)->finalize (obj);
}

static GType
bird_font_glyph_sequence_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (BirdFontGlyphSequenceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) bird_font_glyph_sequence_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (BirdFontGlyphSequence), 0, (GInstanceInitFunc) bird_font_glyph_sequence_instance_init, NULL };
	GType bird_font_glyph_sequence_type_id;
	bird_font_glyph_sequence_type_id = g_type_register_static (G_TYPE_OBJECT, "BirdFontGlyphSequence", &g_define_type_info, 0);
	BirdFontGlyphSequence_private_offset = g_type_add_instance_private (bird_font_glyph_sequence_type_id, sizeof (BirdFontGlyphSequencePrivate));
	return bird_font_glyph_sequence_type_id;
}

GType
bird_font_glyph_sequence_get_type (void)
{
	static volatile gsize bird_font_glyph_sequence_type_id__once = 0;
	if (g_once_init_enter (&bird_font_glyph_sequence_type_id__once)) {
		GType bird_font_glyph_sequence_type_id;
		bird_font_glyph_sequence_type_id = bird_font_glyph_sequence_get_type_once ();
		g_once_init_leave (&bird_font_glyph_sequence_type_id__once, bird_font_glyph_sequence_type_id);
	}
	return bird_font_glyph_sequence_type_id__once;
}

