Clone in a terminal:
Commit 162acf0
Johan Mattsson - 2015-05-29T17:08:37+00:00
162acf025f04c9a4139cb8dbe8411979b0ca65ccjohan.mattsson.m@gmail.com

Merge branch 'master' of https://github.com/johanmattssonm/birdfont

Changed files (16)

Diff

diff --git a/README.md b/README.mdindex 2ccea37..66703b1 100644--- a/README.md+++ b/README.md@@ -17,6 +17,7 @@ packages with a -dev or -devel affix:      valac     font-roboto+    libxmlbird     libgee-dev     libglib2.0-dev      libgtk-3-dev diff --git a/configure b/configureindex ccf9685..997ca9d 100755--- a/configure+++ b/configure@@ -72,7 +72,8 @@ def configure (gtk, libbgee, posixvala): 				'webkitgtk-3.0',  				'libsoup-2.4', 				'libnotify',-				'sqlite3'+				'sqlite3',+				'xmlbird' 				] 	else: 		libs = [@@ -80,7 +81,8 @@ def configure (gtk, libbgee, posixvala): 				'gio-2.0',  				'glib-2.0',  				'sqlite3',-				'fontconfig'+				'fontconfig',+				'xmlbird' 				]  	for lib in libs:diff --git a/dodo.py b/dodo.pyindex 6882daa..871ee90 100644--- a/dodo.py+++ b/dodo.py@@ -32,7 +32,6 @@ DOIT_CONFIG = {     'default_tasks': [         'build',         'libbirdgems', 	-        'libbirdxml',         'libbirdfont',         'birdfont',         'birdfont_autotrace',@@ -53,18 +52,8 @@ LIBS = [     'gdk-pixbuf-2.0',     'webkitgtk-3.0',     config.GEE,-    'libnotify'-    ]--if not config.POSIXVALA:-    LIBBIRD_XML_LIBS = [-        'glib-2.0',-	'posix'-    ]-else:-    LIBBIRD_XML_LIBS = [-        'posix',-	'posixtypes'+    'libnotify',+    'xmlbird'     ]  LIBBIRD_LIBS = [@@ -105,24 +94,6 @@ valac_options = [   if "bsd" in sys.platform:-    LIBBIRDXML_SO_VERSION='${LIBbirdxml_VERSION}'-else:-    LIBBIRDXML_SO_VERSION=version.LIBBIRDXML_SO_VERSION--libbirdxml = Vala(src='libbirdxml', build='build', library='birdxml', so_version=LIBBIRDXML_SO_VERSION, pkg_libs=LIBBIRD_XML_LIBS)-def task_libbirdxml():--    if config.POSIXVALA == True:-        yield libbirdxml.gen_c(valac_options + ['--profile posix'])-    else:-        yield libbirdxml.gen_c(valac_options)--    yield libbirdxml.gen_o(['-fPIC'])-    yield libbirdxml.gen_so()-    yield libbirdxml.gen_ln()-    --if "bsd" in sys.platform:     LIBBIRDGEMS_SO_VERSION='${LIBbirdgems_VERSION}' else:     LIBBIRDGEMS_SO_VERSION=version.LIBBIRDGEMS_SO_VERSION@@ -139,7 +110,7 @@ if "bsd" in sys.platform: else:     SO_VERSION=version.SO_VERSION -libbird = Vala(src='libbirdfont', build='build', library='birdfont', so_version=SO_VERSION, pkg_libs=LIBS, vala_deps=[libbirdgems, libbirdxml])+libbird = Vala(src='libbirdfont', build='build', library='birdfont', so_version=SO_VERSION, pkg_libs=LIBS, vala_deps=[libbirdgems]) def task_libbirdfont():     yield libbird.gen_c(valac_options)     yield libbird.gen_o(['-fPIC -I./build/', """-D 'GETTEXT_PACKAGE="birdfont"'"""])@@ -148,25 +119,25 @@ def task_libbirdfont():   def task_birdfont():-    bird = Vala(src='birdfont', build='build', pkg_libs=LIBS, vala_deps=[libbird, libbirdxml, libbirdgems])+    bird = Vala(src='birdfont', build='build', pkg_libs=LIBS, vala_deps=[libbird, libbirdgems])     yield bird.gen_c(valac_options)     yield bird.gen_bin(["""-D 'GETTEXT_PACKAGE="birdfont"' """])   def task_birdfont_autotrace():-     exp = Vala(src='birdfont-autotrace', build='build', pkg_libs=LIBS, vala_deps=[libbird, libbirdxml, libbirdgems])+     exp = Vala(src='birdfont-autotrace', build='build', pkg_libs=LIBS, vala_deps=[libbird, libbirdgems])      yield exp.gen_c(valac_options)      yield exp.gen_bin(["""-D 'GETTEXT_PACKAGE="birdfont"' """])   def task_birdfont_export():-     exp = Vala(src='birdfont-export', build='build', pkg_libs=LIBS, vala_deps=[libbird, libbirdxml, libbirdgems])+     exp = Vala(src='birdfont-export', build='build', pkg_libs=LIBS, vala_deps=[libbird, libbirdgems])      yield exp.gen_c(valac_options)      yield exp.gen_bin(["""-D 'GETTEXT_PACKAGE="birdfont"' """])   def task_birdfont_import():-     exp = Vala(src='birdfont-import', build='build', pkg_libs=LIBS, vala_deps=[libbird, libbirdxml, libbirdgems])+     exp = Vala(src='birdfont-import', build='build', pkg_libs=LIBS, vala_deps=[libbird, libbirdgems])      yield exp.gen_c(valac_options)      yield exp.gen_bin(["""-D 'GETTEXT_PACKAGE="birdfont"' """]) diff --git a/libbirdfont/Expander.vala b/libbirdfont/Expander.valaindex f614e2c..093965f 100644--- a/libbirdfont/Expander.vala+++ b/libbirdfont/Expander.vala@@ -19,7 +19,7 @@ namespace BirdFont {  public class Expander : GLib.Object { -	private static const double HEADLINE_MARGIN = 6;+	private static const double HEADLINE_MARGIN = 4; 		 	public double x = 7; 	public double y = 5;@@ -45,6 +45,7 @@ public class Expander : GLib.Object { 	Text title; 			 	public bool visible = true;+	Surface? cached = null; 	 	public Expander (string? headline = null) { 		this.headline = headline;@@ -188,6 +189,10 @@ public class Expander : GLib.Object { 			tool.insert (position, t); 		} 		+		t.redraw_tool.connect (() => {+			cached = null;+		});+		 		update_tool_position (); 		 		t.select_action.connect ((selected) => {@@ -234,26 +239,53 @@ public class Expander : GLib.Object { 		active = a; 		return r; 	}-	-	public void draw (int wd, int hd, Context cr) {-		double yt = y + scroll + 2; -		if (tool.size > 0) {-			if (headline != null) {-				Theme.text_color (title, "Text Tool Box");-				title.use_cache (false);-				title.set_font_size (17 * Toolbox.get_scale ());+	public void draw (Context cr) {+		Surface cache;+	+		if (unlikely (cached == null)) {+			Context cc;+			+			double text_height = 17 * Toolbox.get_scale ();+			double offset_y = 0; 		-				title.draw_at_baseline (cr, x, yt + HEADLINE_MARGIN + 13  * Toolbox.get_scale ());+			cache = new Surface.similar (cr.get_target (), Cairo.Content.COLOR_ALPHA, Toolbox.allocation_width, (int) (h + content_height));+			cc = new Context (cache);+		+			if (tool.size > 0 && headline != null) {+				Theme.text_color (title, "Text Tool Box");+				title.set_font_size (text_height);+				title.draw_at_top (cc, 0, 0);+				offset_y = text_height + HEADLINE_MARGIN; 			}+			+			draw_content (cc, offset_y);+			cached = (!) cache;+		}+		+		if (cached != null) {+			cache = (!) cached;+			cr.save ();+			cr.set_antialias (Cairo.Antialias.NONE);+			cr.set_source_surface (cache, (int) x, (int) (y + scroll));+			cr.paint ();+			cr.restore (); 		} 	}-	-	public void draw_content (int w, int h, Context cr) {+		+	public void draw_content (Context cr, double text_end) {+		double offset_y = 0;+		double offset_x = 0;+		+		if (tool.size > 0) {+			offset_x = tool.get (0).x;+			offset_y = tool.get (0).y - text_end;+		}+		 		cr.save (); 		foreach (Tool t in tool) { 			if (t.tool_is_visible ()) {-				t.draw (cr);+				t.draw_tool (cr, offset_x, offset_y); 			} 		} 		cr.restore ();diff --git a/libbirdfont/FontName.vala b/libbirdfont/FontName.valaindex fc82996..52442b7 100644--- a/libbirdfont/FontName.vala+++ b/libbirdfont/FontName.vala@@ -30,12 +30,14 @@ public class FontName : Tool { 		}); 	} 	-	public override void draw (Context cr) {+	public override void draw_tool (Context cr, double px, double py) { 		Text font_name; 		double text_height; 		double extent; 		double width = Toolbox.allocation_width * Toolbox.get_scale (); 		double max_width;+		double x = this.x - px;+		double y = this.y - py; 		 		cr.save (); 		// tab label@@ -52,7 +54,7 @@ public class FontName : Tool { 		 		Theme.text_color (font_name, "Font Name"); 		font_name.set_font_size (text_height);-		font_name.draw_at_baseline (cr, x, y + 13 * Toolbox.get_scale ());+		font_name.draw_at_top (cr, x, y); 		cr.restore (); 	} }diff --git a/libbirdfont/SpinButton.vala b/libbirdfont/SpinButton.valaindex 1dd24e2..712891a 100644--- a/libbirdfont/SpinButton.vala+++ b/libbirdfont/SpinButton.vala@@ -482,12 +482,6 @@ public class SpinButton : Tool { 			text.draw (cr); 		} 	}-	-	public void redraw () {-		if (!is_null (MainWindow.get_toolbox ())) {-			MainWindow.get_toolbox ().redraw ((int) x, (int) y, 70, 70);-		}-	} }  }diff --git a/libbirdfont/Tool.vala b/libbirdfont/Tool.valaindex 0ba6f92..d2df08e 100644--- a/libbirdfont/Tool.vala+++ b/libbirdfont/Tool.vala@@ -82,6 +82,8 @@ public class Tool : Widget { 	 	public string icon_color = ""; 	+	public signal void redraw_tool ();+	 	/** Create tool with a certain name and load icon "name".png */ 	public Tool (string? name = null, string tip = "") { 		this.tip = tip;@@ -101,21 +103,39 @@ public class Tool : Widget { 		next_id++; 		 		panel_press_action.connect ((self, button, x, y) => {+			if (is_active ()) {+				redraw ();+			} 		}); 		+		select_action.connect ((self) => {+			redraw ();+		});++		deselect_action.connect ((self) => {+			redraw ();+		});+						 		move_out_action.connect ((self) => { 			MainWindow.get_toolbox ().hide_tooltip (); 			active_tooltip.showing_this_tooltip = false;+			redraw (); 		}); 		 		panel_move_action.connect ((self, x, y) => { 			if (is_active ()) { 				wait_for_tooltip ();+				redraw (); 			} 			return false; 		}); 	} +	public void redraw () {+		redraw_tool ();+		Toolbox.redraw_tool_box ();+	}+ 	public override double get_height () { 		return 33 * scale; 	}@@ -250,8 +270,12 @@ public class Tool : Widget { 	} 	 	public override void draw (Context cr) {-		double xt = x;-		double yt = y;+		draw_tool (cr,0, 0);+	}+	+	public virtual void draw_tool (Context cr, double px, double py) {+		double xt = x - px;+		double yt = y - py; 		 		double bgx, bgy; 		double iconx, icony;@@ -261,7 +285,6 @@ public class Tool : Widget { 		 		double scale = Toolbox.get_scale ();	 	-		printd (@"scale: $scale\n"); 		cr.save (); 			 		bgx = xt;diff --git a/libbirdfont/Toolbox.vala b/libbirdfont/Toolbox.valaindex 43a6bcb..903b71f 100644--- a/libbirdfont/Toolbox.vala+++ b/libbirdfont/Toolbox.vala@@ -447,13 +447,20 @@ public class Toolbox : GLib.Object  { 	private void draw_expanders (int w, int h, Context cr) { 		foreach (Expander e in current_set.get_expanders ()) { 			if (e.visible) {-				e.draw (w, h, cr);-				e.draw_content (w, h, cr);+				e.draw (cr); 			} 		} 	} 	 	public void draw (int w, int h, Context cr) { +		Test t = new Test.time ("Toolbox drawing");+		for (int i = 0; i < 30; i++) {+			draw_single (w, h, cr);+		}+		t.print ();+	}+	+	public void draw_single (int w, int h, Context cr) {  		cr.save (); 			 		Theme.color (cr, "Default Background");@@ -461,7 +468,7 @@ public class Toolbox : GLib.Object  { 		cr.rectangle (0, 0, w, h); 		cr.set_line_width (0); 		cr.fill ();-					+				 		draw_expanders (w, h, cr); 	 		cr.restore ();diff --git a/libbirdfont/ZoomBar.vala b/libbirdfont/ZoomBar.valaindex dc6bb02..27f1353 100644--- a/libbirdfont/ZoomBar.vala+++ b/libbirdfont/ZoomBar.vala@@ -80,23 +80,24 @@ public class ZoomBar : Tool { 		} 		 		FontDisplay.dirty_scrollbar = true;+		redraw (); 	} 	-	public override void draw (Context cr) {+	public override void draw_tool (Context cr, double px, double py) { 		double margin = w * margin_percent; 		double bar_width = w - margin - x; 		 		// filled 		cr.save (); 		Theme.color (cr, "Button Border 1");-		draw_bar (cr);+		draw_bar (cr, px, py); 		cr.fill (); 		cr.restore (); 		 		// remove non filled parts 		cr.save (); 		Theme.color (cr, "Default Background");-		cr.rectangle (x + bar_width * zoom_level, y, w, h);+		cr.rectangle (x + bar_width * zoom_level - px, y - py, w, h); 		cr.fill (); 		cr.restore (); 		@@ -104,16 +105,19 @@ public class ZoomBar : Tool { 		cr.save (); 		Theme.color (cr, "Zoom Bar Border"); 		cr.set_line_width (0.8);-		draw_bar (cr);+		draw_bar (cr, px, py); 		cr.stroke (); 		cr.restore (); 	} 	-	void draw_bar (Context cr) {+	void draw_bar (Context cr, double px, double py) {+		double x = this.x - px;+		double y = this.y - py;+		double w = this.w - px; 		double height = h; 		double radius = height / 2; 		double margin = w * margin_percent;-	+		 		cr.move_to (x + radius, y + height); 		cr.arc (x + radius, y + radius, radius, PI / 2, 3 * (PI / 2)); 		cr.line_to (w - margin - radius, y);diff --git a/libbirdxml/Attribute.vala b/libbirdxml/Attribute.valadeleted file mode 100644index a86fe17..0000000--- a/libbirdxml/Attribute.vala+++ /dev/null@@ -1,61 +0,0 @@-/*-    Copyright (C) 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.-*/-namespace B {--/** - * Representation of one XML attribute.- */-public class Attribute : GLib.Object {-	-	public XmlString ns;-	public XmlString name;-	public XmlString content;--	public int refcount = 1;-	-	internal Attribute (XmlString ns, XmlString name, XmlString content) {-		this.ns = ns;-		this.name = name;-		this.content = content;-	}--	internal Attribute.empty () {-		this.ns = new XmlString ("", 0);-		this.name = new XmlString ("", 0);-		this.content = new XmlString ("", 0);-	}-	-	/** -	 * @return namespace part for this attribute.-	 */-	public string get_namespace () {-		return ns.to_string ();-	}-	-	/**-	 * @return the name of this attribute. -	 */-	public string get_name () {-		return name.to_string ();-	}--	/** -	 * @return the value of this attribute.-	 */-	public string get_content () {-		return content.to_string ();-	}-}--}diff --git a/libbirdxml/Attributes.vala b/libbirdxml/Attributes.valadeleted file mode 100644index d3ffc57..0000000--- a/libbirdxml/Attributes.vala+++ /dev/null@@ -1,64 +0,0 @@-/*-    Copyright (C) 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.-*/-namespace B {--/** - * Iterator for XML attributes. - */-public class Attributes : GLib.Object {-	-	public Tag tag;-	public int refcount = 1;-			-	internal Attributes (Tag t) {-		tag = t;-	}-	-	public Iterator iterator () {-		return new Iterator (tag);-	}--	public class Iterator : GLib.Object {-		public Tag tag;-		public Attribute? next_attribute;-		public int iterator_refcount = 1;-		-		internal Iterator (Tag t) {-			tag = t;-			next_attribute = null;-			tag.reparse_attributes ();-		}--		public bool next () {-			if (tag.has_more_attributes ()) {-				next_attribute = tag.get_next_attribute ();-			} else {-				next_attribute = null;-			}-			-			return next_attribute != null;-		}--		public new Attribute get () {-			if (next_attribute == null) {-				XmlParser.warning ("No attribute is parsed yet.");-				return new Attribute.empty ();-			}-			-			return (!) next_attribute;-		}-	}-}--}diff --git a/libbirdxml/Tag.vala b/libbirdxml/Tag.valadeleted file mode 100644index a3749d4..0000000--- a/libbirdxml/Tag.vala+++ /dev/null@@ -1,502 +0,0 @@-/*-    Copyright (C) 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.-*/--namespace B {--/**- * Representation of one XML tag.- */-public class Tag : GLib.Object {-	internal XmlData entire_file;-	-	public int tag_index; -	public int attribute_index;-	-	public bool has_tags;-	public bool has_attributes;-	-	public XmlString name;-	public XmlString data;-	public XmlString attributes;-	-	public Tag? next_tag = null;-	public Attribute? next_attribute = null;-	-	public bool error = false;-	public int log_level = WARNINGS;-	-	public int refcount = 1;-	-	internal Tag (XmlString name, XmlString attributes, XmlString content,-		int log_level, XmlData entire_file) {-		-		this.entire_file = entire_file;-		this.log_level = log_level;-		this.name = name;-		this.data = content;-		this.attributes = attributes;-		-		reparse ();-		reparse_attributes ();-	}-	-	internal Tag.empty () {-		entire_file = new XmlData ("", 0);-		data = new XmlString ("", 0);-		attributes = new XmlString ("", 0);-		name = new XmlString ("", 0);-	}-	-	/** -	 * Get tag attributes for this tag. -	 * @return a container with all the attributes-	 */-	public Attributes get_attributes () {-		return new Attributes (this);-	}--	/** -	 * Iterate over all tags inside of this tag.-	 */-	public Iterator iterator () {-		return new Iterator(this);-	}--	/** -	 * Reset the parser and start from the beginning XML tag.-	 */-	public void reparse () {-		tag_index = 0;-		next_tag = obtain_next_tag ();-	}--	internal void reparse_attributes () {-		attribute_index = 0;-		next_attribute = obtain_next_attribute ();-	}-	-	/** -	 * Obtain the name of the tag.-	 * @return the name of this tag. -	 */ -	public string get_name () {-		return name.to_string ();-	}--	/** -	 * Obtain tag content.-	 * @return data between the start and end tags.-	 */-	public string get_content () {-		return data.to_string ();-	}--	/** -	 * @return true if there is one more tags left-	 */-	internal bool has_more_tags () {-		return has_tags;-	}-	-	/** @return the next tag. **/-	internal Tag get_next_tag () {-		Tag r = next_tag == null ? new Tag.empty () : (!) next_tag;-		next_tag = obtain_next_tag ();-		return r;-	}--	/** @return true is there is one or more attributes to obtain with get_next_attribute */-	internal bool has_more_attributes () {-		return has_attributes;-	}-	-	/** @return next attribute. */-	internal Attribute get_next_attribute () {-		Attribute r = next_attribute == null ? new Attribute.empty () : (!) next_attribute;-		next_attribute = obtain_next_attribute ();-		return r;-	}-	-	internal bool has_failed () {-		return error;-	}-	-	Tag obtain_next_tag () {-		int end_tag_index;-		Tag tag;-		-		tag = find_next_tag (tag_index, out end_tag_index);--		if (end_tag_index != -1) {-			tag_index = end_tag_index;-			has_tags = true;-			return tag;-		}-		-		has_tags = false;-		return new Tag.empty ();-	}-	-	Tag find_next_tag (int start, out int end_tag_index) {-		int index;-		unichar c;-		int separator;-		int end;-		int closing_tag;-		XmlString? d;--		XmlString name;-		XmlString attributes;-		XmlString content;--		end_tag_index = -1;-			-		if (start < 0) {-			warn ("Negative index.");-			return new Tag.empty ();-		}-	-		index = start;--		d = data;-		if (d == null) {-			warn ("No data in xml string.");-			return new Tag.empty ();-		}-			-		while (data.get_next_ascii_char (ref index, out c)) {-		-			if (c == '<') {-				separator = find_next_separator (index);--				if (separator < 0) {-					error = true;-					warn ("Expecting a separator.");-					return new Tag.empty ();-				}-				-				name = data.substring (index, separator - index);-				-				if (name.has_prefix ("!")) {-					continue;-				}-				-				end = data.index_of (">", start);-				attributes = data.substring (separator, end - separator);-				-				if (attributes.has_suffix ("/")) {-					content = new XmlString ("", 0);-					end_tag_index = data.index_of (">", index);-					data.get_next_ascii_char (ref end_tag_index, out c);-				} else {-					if (!data.get_next_ascii_char (ref end, out c)) {; // skip >-						warn ("Unexpected end of data.");-						error = true;-						break;-					}-					-					if (c != '>') {-						warn ("Expecting '>'");-						error = true;-						break;-					}-					-					closing_tag = find_closing_tag (name, end);-					-					if (closing_tag == -1) {-						warn ("No closing tag.");-						error = true;-						break;-					}-					-					content = data.substring (end, closing_tag - end);-					end_tag_index = data.index_of (">", closing_tag);-					data.get_next_ascii_char (ref end_tag_index, out c);-				}-				-				return new Tag (name, attributes, content, log_level, entire_file);	-			}-		}-		-		return new Tag.empty ();-	}-	-	int find_next_separator (int start) {-		int index = start;-		int previous_index = start;-		unichar c;-		-		while (true) {-			-			previous_index = index;-			if (!data.get_next_ascii_char (ref index, out c)) {-				break;-			}-			-			if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '>' || c == '/') {-				return previous_index;-			}-		}-		-		return -1;-	}-	-	int find_closing_tag (XmlString name, int start) {-		int index = start;-		int slash_index = start;-		int previous_index;-		unichar c, slash;-		int start_count = 1;-		int next_tag;-		-		if (name.length == 0) {-			error = true;-			warn ("No name for tag.");-			return -1;-		}-	-		index = entire_file.get_index (data) + start;-		while (true) {-			while (!entire_file.substring (index).has_prefix ("</")) {-				index = entire_file.find_next_tag_token (index + 1);-				-				if (index == -1) {-					warning (@"No end tag for $(name)");-					return -1;-				}-			}--			previous_index = index - entire_file.get_index (data);-			-			if (!entire_file.get_next_ascii_char (ref index, out c)) {-				warn ("Unexpected end of file");-				break;-			}-			-			if (c == '<') {-				slash_index = index;-				entire_file.get_next_ascii_char (ref slash_index, out slash);--				if (slash == '/' && is_tag (entire_file, name, slash_index)) {-					if (start_count == 1) {-						return previous_index;-					} else {-						start_count--;-						if (start_count == 0) {-							return previous_index;-						}-					}-				} else if (is_tag (entire_file, name, slash_index)) {-					start_count++;-				}-			}-		}-		-		error = true;-		warn (@"No closing tag for $(name.to_string ())");-		-		return -1;-	}-	-	bool is_tag (XmlString tag, XmlString name, int start) {-		int index = 0;-		int data_index = start;-		unichar c;-		unichar c_data;-		-		while (name.get_next_ascii_char (ref index, out c)) {-			if (tag.get_next_ascii_char (ref data_index, out c_data)) {-				if (c_data != c) {-					return false;-				}-			}-		}-		-		if (tag.get_next_ascii_char (ref data_index, out c_data)) {-			return c_data == '>' || c_data == ' ' || c_data == '\t' -				|| c_data == '\n' || c_data == '\r' || c_data == '/';-		}-		-		return false;-	}--	internal Attribute obtain_next_attribute () {-		int previous_index;-		int index = attribute_index;-		int name_start;-		XmlString attribute_name;		-		XmlString ns;-		XmlString content;-		int ns_separator;-		int content_start;-		int content_stop;-		unichar quote;-		unichar c;-		-		// skip space and other separators-		while (true) {-			previous_index = index;-			-			if (!attributes.get_next_ascii_char (ref index, out c)) {-				has_attributes = false;-				return new Attribute.empty ();-			}-			-			if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '/')) {-				break;-			}-		}-		-		name_start = previous_index;--		// read attribute name-		while (true) {-			previous_index = index;-			if (!attributes.get_next_ascii_char (ref index, out c)) {-				error = true;-				warn (@"Unexpected end of attributes in tag $(this.name)");-				has_attributes = false;-				return new Attribute.empty ();-			}-			-			if (c == ' ' || c == '\t' || c == '=' || c == '\n' || c == '\r') {-				break;-			}-		}-		-		attribute_name = attributes.substring (name_start, previous_index - name_start);-		index = name_start + attribute_name.length;-		ns = new XmlString ("", 0);-		ns_separator = attribute_name.index_of (":");-		if (ns_separator != -1) {-			ns = attribute_name.substring (0, ns_separator);-			attribute_name = attribute_name.substring (ns_separator + 1);-		}-		-		// equal sign and space around it-		while (attributes.get_next_ascii_char (ref index, out c)) {-			if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) {-				if (c == '=') {-					break;-				} else {-					has_attributes = false;-					error = true;-					warn (@"Expecting equal sign for attribute $(attribute_name).");-					warn (@"Around: $(attributes.substring (index, 10)).");-					warn (@"Row: $(get_row (((size_t) attributes.data) + index))");-					-					return new Attribute.empty ();-				}-			}-		}-		-		while (attributes.get_next_ascii_char (ref index, out c)) {-			if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) {-				if (c == '"' || c == '\'') {-					break;-				} else {-					has_attributes = false;-					error = true;-					warn (@"Expecting quote for attribute $(attribute_name).");-					return new Attribute.empty ();-				}-			}-		}-		-		quote = c;-		content_start = index;-		-		while (true) {-			if (!attributes.get_next_ascii_char (ref index, out c)) {-				has_attributes = false;-				error = true;-				warn (@"Expecting end quote for attribute $(attribute_name).");-				return new Attribute.empty ();-			}-			-			if (c == quote) {-				break;-			}-		}-		-		content_stop = index - 1;-		content = attributes.substring (content_start, content_stop - content_start);-		-		has_attributes = true;-		-		attribute_index = content_stop + 1;-		return new Attribute (ns, attribute_name, content);-	}--	public class Iterator : GLib.Object {-		public Tag tag;-		public Tag? next_tag = null;-		public int iterator_efcount = 1;-		-		internal Iterator (Tag t) {-			tag = t;-			tag.reparse ();-		}--		public bool next () {-			if (tag.error) { -				return false;-			}-			-			if (tag.has_more_tags ()) {-				next_tag = tag.get_next_tag ();-			} else {-				next_tag = null;-			}-									-			return next_tag != null;-		}--		public new Tag get () {-			if (next_tag == null) {-				XmlParser.warning ("No tag is parsed yet.");-				return new Tag.empty ();-			}-			return (!) next_tag;-		}-	}-	-	internal int get_row (size_t pos) {-		int index = 0;-		unichar c;-		int row = 1;-		size_t e;-		-		e = (size_t) entire_file.data;-		while (entire_file.get_next_ascii_char (ref index, out c)) {-			if (c == '\n') {-				row++;-			}-			-			if (e + index >= pos) {-				break;-			}-		}-		-		return row;-	}-	-	internal void warn (string message) {-		if (log_level == WARNINGS) {-			XmlParser.warning (message);-		}-	}-}--}diff --git a/libbirdxml/Xml.vala b/libbirdxml/Xml.valadeleted file mode 100644index 654228b..0000000--- a/libbirdxml/Xml.vala+++ /dev/null@@ -1,220 +0,0 @@-/*-    Copyright (C) 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.-*/--/** - * Tools originally written for the BirdFont project.- */-namespace B {--/** Log levels */-internal const int NONE = 0;-internal const int WARNINGS = 1;--/** - * XML parser- * - * A tiny XML parser written in Vala.- * - * Example:- * {{{- * - * // Print all tags and attributes in an XML document. - * // Expected output:- * // tag1- * // tag2- * // attribute1- * public static int main (string[] arg) {- * 	Tag root;- * 	XmlParser parser;- * - * 	parser = new XmlParser ("""<tag1><tag2 attribute1=""/></tag1>""");	- * - * 	if (parser.validate ()) {- * 		root = parser.get_root_tag ();- * 		print_tags (root);- * 	}- * }- * - * - * void print_tags (Tag tag) {- * 	print (tag.get_name ());- * 	print ("\n");- * 	print_attributes (tag);- * - * 	foreach (Tag t in tag) {- * 		print_tags (t);- * 	}- * }- * - * void print_attributes (Tag tag) {- * 	Attributes attributes = tag.get_attributes ();- * 	foreach (Attribute attribute in attributes) {- * 		print (attribute.get_name ());- * 		print ("\n");- * 	}- * }- * - * }}}- * - */-public class XmlParser : GLib.Object {-	Tag root;-	XmlData data;-	string input;-	bool error;-	-	/** -	 * Create a new xml parser. -	 * @param data valid xml data-	 */-	public XmlParser (string data) {-		this.input = data;-		this.data = new XmlData (data, data.length);		-		reparse (NONE);-	}-		-	/** -	 * Determine if the document can be parsed.-	 * @return true if the xml document is valid xml.-	 */-	public bool validate () {-		if (this.data.error) {-			error = true;-			return false;-		} -		-		reparse (NONE);--		if (error) {-			return false;-		}-		-		validate_tags (root);-			-		reparse (NONE);-		return !error;-	}-	-	void validate_tags (Tag tag) {-		Attributes attributes = tag.get_attributes ();-		-		foreach (Attribute a in attributes) {-			if (tag.has_failed () || a.name.length == 0) {-				error = true;-				return;-			}-		}-		-		foreach (Tag t in tag) {-			if (tag.has_failed ()) {-				error = true;-				return;-			}-			-			validate_tags (t);-		}		-	}-	-	/** -	 * Obtain the root tag.-	 * @return the root tag. -	 */-	public Tag get_root_tag () {-		reparse (WARNINGS);-		return root;-	}-	-	/** -	 * Reset the parser and start from the beginning of the XML document. -	 */-	internal void reparse (int log_level) {-		int root_index;-		Tag container;-		XmlString content;-		XmlString empty;-		-		error = false;-		empty = new XmlString ("", 0);-		-		root_index = find_root_tag ();-		if (root_index == -1) {-			if (log_level == WARNINGS) {-				XmlParser.warning ("No root tag found.");-			}-			error = true;-			root = new Tag.empty ();-		} else {-			content = data.substring (root_index);-			container = new Tag (empty, empty, content, log_level, data);-			root = container.get_next_tag ();-		}-	}-	-	int find_root_tag () {-		int index = 0;-		int prev_index = 0;-		int modifier = 0;-		unichar c;-		-		while (true) {-			prev_index = index;-			if (!data.get_next_ascii_char (ref index, out c)) {-				break;-			}-			-			if (c == '<') {-				modifier = index;-				data.get_next_ascii_char (ref modifier, out c);-				if (c != '?' && c != '[' && c != '!') {-					return prev_index;-				} -			}-		}-		-		return -1;-	}--	/** Print a warning message. */-	public static void warning (string message) {-		print ("XML error: "); -		print (message);-		print ("\n");-	}--	/** Replace escaped character with plain text characters. -	 * &amp; will be replaced with & etc.-	 */-	public static string decode (string s) {-		string t;-		t = s.replace ("&quot;", "\"");-		t = t.replace ("&apos;", "'");-		t = t.replace ("&lt;", "<");-		t = t.replace ("&gt;", ">");-		t = t.replace ("&amp;", "&");-		return t;-	}--	public static string encode (string s) {-		string t;-		t = s.replace ("\"", "&quot;");-		t = t.replace ("'", "&apos;");-		t = t.replace ("<", "&lt;");-		t = t.replace (">", "&gt;");-		t = t.replace ("&", "&amp;");-		return t;-	}--}--}diff --git a/libbirdxml/XmlData.vala b/libbirdxml/XmlData.valadeleted file mode 100644index 862e800..0000000--- a/libbirdxml/XmlData.vala+++ /dev/null@@ -1,152 +0,0 @@-/*-    Copyright (C) 2015 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.-*/--namespace B {--public class XmlData : XmlString {-	int* start_tags;-	int tags_capacity;-	int tags_size;-	-	internal bool error = false;-	-	public XmlData (char* data, int length) {-		base (data, length);--		start_tags = null;-		tags_capacity = 0;-		tags_size = 0;-		-		index_start_tags ();-	}-	-	~XmlData () {-		if (start_tags != null) {-			delete start_tags;-			start_tags =  null;-		}-	}-	-	public int get_index (XmlString start) {-		int offset = (int) ((size_t) start.data - (size_t) data);-		return offset;-	}-	-	public int find_next_tag_token (int index) {-		int new_index;-				-		if (index >= length) {-			return -1;-		}-		-		for (int i = 0; i < tags_size; i++) {-			new_index = start_tags[i];-			if (new_index >= index) {-				-				if (new_index == 0 && i > 0) { //FIXME:DELETE-					return -1;-				}-				-				return new_index;-			}-		}-		-		return -1;-	}--	void index_start_tags () {-		const char first_bit = 1 << 7;-		int i = 0;-		char* d = data;- 		- 		while (d[i] != '\0') {-			if ((int) (d[i] & first_bit) == 0) {-				if (d[i] == '<') {-					add_tag (i);-				}-			}-			i++;-		}-	}-	-	void add_tag (int index) {-		if (unlikely (tags_size == tags_capacity)) {-			if (!increase_capacity ()) {-				return;-			}-		}-		-		start_tags[tags_size] = index;-		tags_size++;-	}--	bool increase_capacity () {-		int* tags;-		-		tags_capacity += 512;-		tags = (int*) try_malloc (tags_capacity * sizeof (int));-		-		if (tags == null) {-			tags_capacity = 0;-			-			if (start_tags != null) {-				delete start_tags;-				start_tags = null;-				tags_size = 0;-				error = true;-			}-			-			warning ("Can not allocate xml data buffer.");-			return false;-		}-		-		if (tags_size > 0) {-			Posix.memcpy (tags, start_tags, tags_size * sizeof (int));-		}-		-		if (start_tags != null) {-			delete start_tags;-		}-		-		start_tags = tags;-		-		return true;-	}-	-	public void print_all () {-		XmlString s;-		int i = -1;-		string e;-		-		print("All tags:\n");-		-		for (int j = 0; j < tags_size; j++) {-			i = find_next_tag_token (i + 1);-			-			if (i > -1) {-				s = substring (i);-				s = s.substring (0, s.index_of (">"));-				s = s.substring (0, s.index_of (" "));-			} else {-				e = "error";-				s = new XmlString (e, e.length); -			}-			-			int o = start_tags[j];-			print (s.to_string () + " : " + ((string) (data + o)).ndup (4) + @"  $o $j   i: $i\n");-		}-	}-}--}diff --git a/libbirdxml/XmlString.vala b/libbirdxml/XmlString.valadeleted file mode 100644index d5c7724..0000000--- a/libbirdxml/XmlString.vala+++ /dev/null@@ -1,143 +0,0 @@-/*-    Copyright (C) 2014 2015 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.-*/--namespace B {--/** - * Representation of a string in the XmlParser. This class adds reference counting and- * copies a pointer to string instead of the data. It is faster if the string is - * huge.- */-public class XmlString : GLib.Object {	-	public int length;-	public char* data;-	public int refcount = 1;--	internal XmlString (char* data, int length) {-		this.data = data;-		this.length = length;-	}--	internal int index_of (string needle, int offset = 0) {-		int len = length;-		int needle_len = needle.length;-		char* needle_data = (char*) needle;-		char* haystack = data + offset;-		-		if (needle_len == 0 || offset > length) {-			return -1;-		}-		-		for (int i = 0; i < len; i++) {-			if (haystack[i] == '\0') {-				return -1;-			}-			-			for (int j = 0; j <= needle_len && i + j < len; j++) {-				if (j == needle_len) {-					return offset + i;-				}-				-				if (needle_data[j] != haystack[i + j]) {-					break;-				}-			}-		}-								-		return -1;-	}--	internal bool has_prefix (string prefix) {-		unowned string s = (string) data;-		bool p = s.has_prefix (prefix);--		if (!p) {-			return false;-		}-		-		return length > prefix.length;-	}--	internal bool has_suffix (string suffix) {-		int suffix_length = suffix.length;--		if (length < suffix_length) {-			return false;-		}-		-		return Posix.strncmp ((string) (data + length - suffix_length), suffix, suffix_length) == 0;-	}	--	internal bool get_next_char (ref int index, out unichar c) {-		unowned string s;-		unowned string? n = (string) data;-		-		if (index >= length) {-			c = '\0';- 			return false;- 		}- 		-		s = (!) n;- 		-		return s.get_next_char (ref index, out c);- 	}- 	-	internal bool get_next_ascii_char (ref int index, out unichar c) {-		const char first_bit = 1 << 7;-		int i = index;-		char* d = data;--		if (index >= length) {-			c = '\0';- 			return false;- 		}- 		-		if (likely ((int) (d[i] & first_bit) == 0)) {-			c = d[i];-			index++;-			return c != '\0';-		}-		-		while ((int) (d[i] & first_bit) != 0) {-			i++;-		}-		-		index = i;-		return get_next_char (ref index, out c);-	}--	internal XmlString substring (int offset, int len = -1) {-		Posix.assert (offset >= 0);-		Posix.assert (offset < length);-		-		if (len == -1) {-			return new XmlString (data + offset, length - offset);-		}-		-		Posix.assert (len + offset < length); -		return new XmlString (data + offset, len);-	} -	-	public string to_string () {-		unowned string s = (string) data;-		-		if (length == 0) {-			return "".dup ();-		}		-		-		return s.ndup (length);-	}-}--}diff --git a/scripts/build.py b/scripts/build.pyindex 99a291d..089e959 100644--- a/scripts/build.py+++ b/scripts/build.py@@ -47,7 +47,7 @@ def libbirdfont(prefix, cc, cflags, ldflags, valac, valaflags, library, nonNull  		--pkg """ + config.GEE + """ \ 		--pkg gio-2.0 \ 		--pkg cairo \-		--pkg libbirdxml \+		--pkg xmlbird \ 		--pkg libbirdgems \ 		--pkg sqlite3 \ 		""")@@ -68,7 +68,7 @@ def libbirdfont(prefix, cc, cflags, ldflags, valac, valaflags, library, nonNull  			$(pkg-config --cflags gio-2.0) \ 			$(pkg-config --cflags cairo) \ 			$(pkg-config --cflags glib-2.0) \-			-I ./build/libbirdxml \+			$(pkg-config --cflags xmlbird) \ 			-I ./build/libbirdgems""") 		run("mv ./*.o build/libbirdfont/ ") @@ -88,7 +88,8 @@ def libbirdfont(prefix, cc, cflags, ldflags, valac, valaflags, library, nonNull  			$(pkg-config --libs fontconfig) \ 			$(pkg-config --libs cairo) \ 			$(pkg-config --libs glib-2.0) \-			-L./build -L./build/bin -l birdxml -l birdgems\+			$(pkg-config --libs xmlbird) \+			-L./build -L./build/bin -l birdgems\ 			-o """ + library) 		run("mv " + library + " build/bin/") 		@@ -114,64 +115,6 @@ def libbirdfont(prefix, cc, cflags, ldflags, valac, valaflags, library, nonNull  		run("gzip build/birdfont-import.1")  				 -def libbirdxml(prefix, cc, cflags, ldflags, valac, valaflags, library, nonNull = True):-	#libbirdfont-	run("mkdir -p build/libbirdxml")-	run("mkdir -p build/bin")--	experimentalNonNull = ""-	if nonNull:-		experimentalNonNull = "--enable-experimental-non-null"--	run(valac + """\-		-C \-		""" + valaflags + """ \-		--pkg posix \-		--vapidir=./ \-		--basedir build/libbirdxml/ \-		""" + experimentalNonNull + """ \-		--enable-experimental \-		--library libbirdxml \-		-H build/libbirdxml/birdxml.h \-		libbirdxml/*.vala \-		""")-	-	if cc == "":-		print ("Skipping compilation");-	else:-		run(cc + " " + cflags + """ \-			-c build/libbirdxml/*.c \-			-fPIC \-			$(pkg-config --cflags glib-2.0) \-			$(pkg-config --cflags gobject-2.0) \-			""")-			-		run("mv ./*.o build/libbirdxml/ ")--		if library.endswith (".dylib"):-			sonameparam = "" # gcc on mac os does not have the soname parameter-		else:-			sonameparam = "-Wl,-soname," + library-		-		run(cc + " " + ldflags + """ \-			-shared \-			""" + sonameparam + """ \-			build/libbirdxml/*.o \-			$(pkg-config --libs glib-2.0) \-			$(pkg-config --libs gobject-2.0) \-			-o """ + library)-		run("mv " + library + " build/bin/")-		-		if os.path.exists("build/bin/libbirdxml.so"):-			run ("cd build/bin && unlink libbirdxml.so")--		# create link to the versioned library-		if library.find ('.so') > -1:-			run ("""cd build/bin && ln -sf """ + library + " libbirdxml.so")-		elif library.find ('.dylib') > -1:-			run ("""cd build/bin && ln -sf """ + library + " libbirdxml.dylib")- 		- def libbirdgems(prefix, cc, cflags, ldflags, valac, valaflags, library, nonNull = True): 	print ('Compiling libbirdgems') 	run("mkdir -p build/libbirdgems")@@ -275,7 +218,8 @@ def birdfont_export(prefix, cc, cflags, ldflags, valac, valaflags, nonNull = Tru 		$(pkg-config --libs gio-2.0) \ 		$(pkg-config --libs cairo) \ 		$(pkg-config --libs glib-2.0) \-		-L./build -L./build/bin -l birdxml -l birdgems\+		$(pkg-config --libs xmlbird) \+		-L./build -L./build/bin -l birdgems\ 		-o ./build/bin/birdfont-export""")  	run("rm -f build/birdfont.1.gz")@@ -335,7 +279,8 @@ def birdfont_import(prefix, cc, cflags, ldflags, valac, valaflags, nonNull = Tru 		$(pkg-config --libs gio-2.0) \ 		$(pkg-config --libs cairo) \ 		$(pkg-config --libs glib-2.0) \-                -L./build -L./build/bin -l birdxml -l birdgems\+		$(pkg-config --libs xmlbird) \+      -L./build -L./build/bin  -l birdgems\ 		-o ./build/bin/birdfont-import""")  def birdfont_autotrace(prefix, cc, cflags, ldflags, valac, valaflags, nonNull = True):@@ -381,8 +326,9 @@ def birdfont_autotrace(prefix, cc, cflags, ldflags, valac, valaflags, nonNull =  		$(pkg-config --libs gio-2.0) \ 		$(pkg-config --libs cairo) \ 		$(pkg-config --libs glib-2.0) \+		$(pkg-config --libs xmlbird) \ 		$(pkg-config --libs gdk-pixbuf-2.0) \-		-L./build -L./build/bin -l birdxml -l birdgems\+		-L./build -L./build/bin -l birdgems\ 		-o ./build/bin/birdfont-autotrace""")  @@ -435,7 +381,8 @@ def birdfont_gtk(prefix, cc, cflags, ldflags, valac, valaflags, nonNull = True): 		$(pkg-config --libs gdk-pixbuf-2.0) \ 		$(pkg-config --libs webkitgtk-3.0) \ 		$(pkg-config --libs gtk+-2.0) \+		$(pkg-config --libs xmlbird) \ 		$(pkg-config --libs libnotify) \-                -L./build -L./build/bin -l birdxml -l birdgems\+                -L./build -L./build/bin -l birdgems\ 		-o ./build/bin/birdfont""") 

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112