Clone in a terminal:
Commit 902267d
Johan Mattsson - 2013-02-16T03:35:09+00:00
902267d515a8ade976079b4229d350f208e578d6johan.mattsson.m@gmail.com

revert "parse ligatures from svg font" since it broke Firefox support This reverts commit a76d9a8e1fd33f29ad36b3d3bf0976499b41d283. Conflicts: libbirdfont/Context.vala libbirdfont/Font.vala libbirdfont/Glyph.vala libbirdfont/SvgFont.vala

Changed files (8)

Diff

diff --git a/libbirdfont/Context.vala b/libbirdfont/Context.valanew file mode 100644index 0000000..3a8051f--- /dev/null+++ b/libbirdfont/Context.vala@@ -0,0 +1,335 @@+/*+    Copyright (C) 2012 Johan Mattsson++    This program is free software: you can redistribute it and/or modify+    it under the terms of the GNU General Public License as published by+    the Free Software Foundation, either version 3 of the License, or+    (at your option) any later version.++    This program 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 General Public License for more details.++    You should have received a copy of the GNU General Public License+    along with this program.  If not, see <http://www.gnu.org/licenses/>.+*/++using Cairo;++namespace BirdFont {++/** Kerning context. */+public class ContextDisplay : FontDisplay {++	List <GlyphSequence> row;+	int active_handle = -1;+	int selected_handle = -1;+	+	double begin_handle_x = 0;+	double begin_handle_y = 0;+	+	double last_handle_x = 0;+/*+<<<<<<< HEAD+	public KerningDisplay () {+		GlyphSequence w = new GlyphSequence ();+		row = new List <GlyphSequence> ();+=======+*/+	public ContextDisplay () {+		GlyphSequence w = new GlyphSequence ();+		row = new List <GlyphSequence> ();+//>>>>>>> parent of a76d9a8... parse ligatures from svg font+		row.append (w);+	}++	public override string get_name () {+		return "Kerning";+	}+	+	public override void draw (Allocation allocation, Context cr) {+		Glyph glyph;+		double x, y, w, kern, alpha;+		double x2;+		int i, wi;+		Glyph? prev;+		Font font = BirdFont.get_current_font ();+		GlyphSequence word_with_ligatures;+		+		i = 0;+		+		// bg color+		cr.save ();+		cr.set_source_rgba (1, 1, 1, 1);+		cr.rectangle (0, 0, allocation.width, allocation.height);+		cr.fill ();+		cr.restore ();+	+		alpha = 1;+		y = 100;+		x = 20;+		w = 0;+		prev = null;+		+		foreach (GlyphSequence word in row) {+			wi = 0;+			word_with_ligatures = word.process_ligatures ();+			foreach (Glyph? g in word_with_ligatures.glyph) {+				if (g == null) {+					continue;+				}+				+				if (prev == null) {+					kern = 0;+				} else {+					kern = font.get_kerning_by_name (((!)prev).get_name (), ((!)g).get_name ());+				}+								+				// draw glyph				+				if (g == null) {+					w = 50;+					alpha = 1;+				} else {+					alpha = 0;+					glyph = (!) g;+					Svg.draw_svg_path (cr, glyph.get_svg_data (), x + kern, y);+					w = glyph.get_width ();+				}++				// handle+				if (active_handle == i) {+					//x2 = x + kern;+					x2 = x + kern / 2.0;+					+					cr.save ();+					cr.set_source_rgba (153/255.0, 153/255.0, 173/255.0, 1);+					cr.move_to (x2 - 5, y + 20);+					cr.line_to (x2 + 0, y + 20 - 5);+					cr.line_to (x2 + 5, y + 20);+					cr.fill ();+					+					cr.set_font_size (10);+					cr.show_text (((!)g).get_name ());+					cr.restore ();+				}	+				+				x += w + kern;+	+				// caption+				if (g == null || ((!)g).is_empty ()) {+					cr.save ();+					cr.set_source_rgba (153/255.0, 153/255.0, 153/255.0, alpha);+					cr.move_to (x - w / 2.0 - 5, y + 20);+					cr.set_font_size (10);+					cr.show_text ("?"); // ?+					cr.restore ();+				}+							+				prev = g;+				+				wi++;+				i++;+			}+			+			if (y > allocation.height && i > 10) {+				row.remove (word);+			}+						+			y += MainWindow.get_current_glyph ().get_height () + 20;+			x = 20;			+		}+	}+	+	private void set_kerning (int handle, double val) {+		string a, b;+		Font font;+		int wi = 0;+		double kern;+		GlyphSequence word_with_ligatures;+		+		font = BirdFont.get_current_font ();++		font.touch ();++		a = "";+		b = "";++		foreach (GlyphSequence word in row) {+			word_with_ligatures = word.process_ligatures ();+			foreach (Glyph? g in word_with_ligatures.glyph) {+				+				if (g == null) {+					continue;+				}+				+				b = ((!) g).get_name ();+				+				if (handle == wi) {+					kern = font.get_kerning_by_name (a, b) + val;+					font.set_kerning_by_name (a, b, kern);+				}+				+				wi++;+				+				a = b;+			}+		}+		+		+	}++	public override void selected_canvas () {+		Glyph g;+		GlyphSequence w;+		unowned List<GlyphSequence>? r;+		StringBuilder s = new StringBuilder ();+		bool append_char = false;+		Font font = BirdFont.get_current_font ();+		+		KeyBindings.singleton.set_require_modifier (true);+		+		g = MainWindow.get_current_glyph ();+		s.append_unichar (g.get_unichar ());++		r = row;+		return_if_fail (r != null);++		if (row.length () == 0) {+			append_char = true;+		}+		+		if (append_char) {+			w = new GlyphSequence ();+			row.append (w);+			w.glyph.prepend (font.get_glyph (s.str));+		}		+	}+	+	public override void key_press (uint keyval) {+		unichar c = (unichar) keyval;+		Glyph? g;+		Font f = BirdFont.get_current_font ();+		string name;+		+		if (KeyBindings.modifier == NONE || KeyBindings.modifier == SHIFT) {+					+			if (keyval == Key.BACK_SPACE && row.length () > 0) {	+				row.first ().data.glyph.remove_link (row.first ().data.glyph.last ());+			}+			+			if (row.length () == 0 || c == Key.ENTER) {+				row.prepend (new GlyphSequence ());+			}+			+			if (!is_modifier_key (c) && c.validate ()) {+				name = f.get_name_for_character (c);+				g = f.get_glyph_by_name (name);+				row.first ().data.glyph.append (g);+			}+		}+		+		MainWindow.get_glyph_canvas ().redraw ();+	}+	+	public override void motion_notify (double ex, double ey) {+		double k, y;+		+		if (selected_handle == -1) {+			set_active_handle (ex, ey);+		} else {+			y = 1;+			+			if (Math.fabs (ey - begin_handle_y) > 20) {+				y = ((Math.fabs (ey - begin_handle_y) / 100) + 1);+			}+			+			k = (ex - last_handle_x) / y; // y-axis is variable precision+			set_kerning (selected_handle, k);+			MainWindow.get_glyph_canvas ().redraw ();+		}+		+		last_handle_x = ex;+	}+	+	public void set_active_handle (double ex, double ey) {+		double y = 100;+		double x = 20;+		double w = 0;+		double d, kern;+		double min = double.MAX;+		int i = 0;+		int row_index = 0;+		int col_index = 0;+		Glyph glyph = new Glyph.no_lines ("");+		Font font = BirdFont.get_current_font ();+		+		Glyph? prev = null;+		string gl_name = "";+		GlyphSequence word_with_ligatures;+		+		foreach (GlyphSequence word in row) {+			col_index = 0;+			+			word_with_ligatures = word.process_ligatures ();+			foreach (Glyph? g in word_with_ligatures.glyph) {+				// draw glyph++				if (g == null) {+					w = 50;	+				} else {+					glyph = (!) g;+					w = glyph.get_width ();+				}+				+				gl_name = glyph.get_name ();+				+				if (prev == null) {+					kern = 0;+				} else {+					kern = font.get_kerning_by_name (((!)prev).get_name (), gl_name);+				}+								+				d = Math.pow (x + kern - ex, 2) + Math.pow (y - ey, 2);+				+				if (d < min) {+					min = d;+					+					if (active_handle != i - row_index) {+						active_handle = i - row_index;+						MainWindow.get_glyph_canvas ().redraw ();+					}++					if (col_index == word.glyph.length () || col_index == 0) {+						active_handle = -1;+					}+				}+				+				prev = g;+				x += w + kern;+				i++;+				col_index++;+			}+			+			row_index++;+			y += MainWindow.get_current_glyph ().get_height () + 20;+			x = 20;+		}+	}+	+	public override void button_release (int button, double ex, double ey) {+		set_active_handle (ex, ey);+		selected_handle = -1;+	}+	+	public override void button_press (uint button, double ex, double ey) {+		set_active_handle (ex, ey);+		selected_handle = active_handle;+		begin_handle_x = ex;+		begin_handle_y = ey;+		last_handle_x = ex;+	}++}++}diff --git a/libbirdfont/Font.vala b/libbirdfont/Font.valaindex 734b284..a67f89c 100644--- a/libbirdfont/Font.vala+++ b/libbirdfont/Font.vala@@ -29,13 +29,13 @@ public enum FontFormat { public class Font : GLib.Object { 	 	/** Table with glyphs sorted by their unicode value. */-	GlyphTable glyph_unicode = new GlyphTable ();+	GlyphTable glyph_cache = new GlyphTable (); 	 	/** Table with glyphs sorted by their name. */ 	GlyphTable glyph_name = new GlyphTable (); -	/** Ligatures */-	GlyphTable ligature = new GlyphTable ();+	/** Last unassigned index */+	int next_unindexed = 0; 	 	public List <string> background_images = new List <string> (); 	public string background_scale = "1";@@ -175,7 +175,7 @@ public class Font : GLib.Object {  	public void print_all () { 		stdout.printf ("Unicode:\n");		-		glyph_unicode.for_each((g) => {+		glyph_cache.for_each((g) => { 			stdout.printf (@"$(g.get_unicode ())\n"); 		}); 		@@ -197,7 +197,7 @@ public class Font : GLib.Object { 		} 				 		ret = new Glyph ("nonmarkingreturn", '\r');-+		ret.set_unassigned (false); 		ret.left_limit = 0; 		ret.right_limit = 0; 		ret.remove_empty_paths ();@@ -215,7 +215,7 @@ public class Font : GLib.Object { 		} 		 		n = new Glyph ("null", '\0');-		+		n.set_unassigned (false); 		n.left_limit = 0; 		n.right_limit = 0; 		n.remove_empty_paths ();@@ -237,7 +237,7 @@ public class Font : GLib.Object { 		} 				 		n = new Glyph ("space", ' ');-+		n.set_unassigned (false); 		n.left_limit = 0; 		n.right_limit = 27; 		n.remove_empty_paths ();@@ -261,6 +261,7 @@ public class Font : GLib.Object { 		p = new Path (); 		i = new Path (); 		+		g.set_unassigned (true); 		g.left_limit = -33; 		g.right_limit = 33; 		@@ -306,10 +307,10 @@ public class Font : GLib.Object { 		} 		 		if (glyph_collection.get_unicode () != "") {-			glyph_unicode.insert (glyph_collection.get_unicode (), glyph_collection);+			glyph_name.insert (glyph_collection.get_name (), glyph_collection);			 		} 		-		glyph_name.insert (glyph_collection.get_name (), glyph_collection);			+		glyph_cache.insert (glyph_collection.get_unicode (), glyph_collection); 	} 	 	public string get_name_for_character (unichar c) {@@ -342,13 +343,19 @@ public class Font : GLib.Object { 	} 	 	public void delete_glyph (GlyphCollection glyph) {-		glyph_unicode.remove (glyph.get_unicode ());+		glyph_cache.remove (glyph.get_unicode ()); 		glyph_name.remove (glyph.get_name ());+/*+<<<<<<< HEAD 	}  	// FIXME: order if ligature substitution is important 	public GlyphCollection? get_ligature (uint indice) { 		return ligature.nth (indice);+=======+*/+		// FIXME: DELETE: glyph_cache.remove (glyph);+//>>>>>>> parent of a76d9a8... parse ligatures from svg font 	} 	 	/** Obtain all versions and alterntes for this glyph. */@@ -372,7 +379,7 @@ public class Font : GLib.Object { 	/** Get glyph collection by unichar code. */ 	public GlyphCollection? get_cached_glyph_collection (string unichar_code) { 		GlyphCollection? gc = null;-		gc = glyph_unicode.get (unichar_code);+		gc = glyph_cache.get (unichar_code); 		return gc; 	} @@ -397,7 +404,11 @@ public class Font : GLib.Object { 		 	public Glyph? get_glyph (string unicode) { 		GlyphCollection? gc = null;-		gc = glyph_unicode.get (unicode);+//<<<<<<< HEAD+//		gc = glyph_unicode.get (unicode);+//=======+		gc = glyph_cache.get (name);+//>>>>>>> parent of a76d9a8... parse ligatures from svg font 		 		if (gc == null) { 			return null;@@ -426,19 +437,6 @@ public class Font : GLib.Object { 		background_images.append (file); 	} -	public string get_name_from_unicode (string unicode) {-		string v = "";-		Glyph? g = get_glyph (unicode);-		-		if (g != null) {-			v = ((!)g).get_name ();-		} else {-			warning (@"no name for \"$unicode\"");-		}-		-		return v;-	}- 	/** Obtain kerning for pair with name a and b. 	 * @param a name of left glyph kerning pair 	 * @param b name of right glyph kerning pair@@ -636,7 +634,7 @@ public class Font : GLib.Object { 				os.put_string ("\n"); 			} 			-			glyph_unicode.for_each ((gc) => {+			glyph_cache.for_each ((gc) => { 				bool selected; 				 				if (is_null (gc)) {@@ -654,7 +652,7 @@ public class Font : GLib.Object { 				} 			}); 		-			glyph_unicode.for_each ((gc) => {+			glyph_cache.for_each ((gc) => { 				Glyph glyph; 				 				try {@@ -682,7 +680,7 @@ public class Font : GLib.Object { 				} 			}); -			glyph_unicode.for_each ((gc) => {+			glyph_cache.for_each ((gc) => { 				GlyphBackgroundImage bg; 				 				try {@@ -828,7 +826,7 @@ public class Font : GLib.Object { 				grid_width.remove_link (grid_width.first ()); 			} -			glyph_unicode.remove_all ();+			glyph_cache.remove_all (); 			glyph_name.remove_all (); 			 			if (path.has_suffix (".svg")) {@@ -955,16 +953,38 @@ public class Font : GLib.Object { 		 		if (gcl != null) { 			warning (@"glyph \"$(g.get_name ())\" does already exist");-			return; 		}-			+		+		if (g.is_unassigned ()) {+			gc = new GlyphCollection (g);+	+/*		+<<<<<<< HEAD 		gc = new GlyphCollection (g); 		add_glyph_collection (gc);  		if (g.is_ligature ()) { 			liga = g.get_ligature_string (); 			ligature.insert (liga, gc);+=======+*/+			if (g.name == "") {+				warning ("refusing to insert glyph without name");+				g.name = @"($(++next_unindexed))";+				return;+			}+			+			add_glyph_collection ((!) gc);+		} else if (gcl == null) {+			gc = new GlyphCollection (g);+			add_glyph_collection ((!) gc);+		} else {+			stderr.printf (@"Glyph collection does already have an entry for $(g.get_name ()) char $((uint64) g.unichar_code).\n");+//>>>>>>> parent of a76d9a8... parse ligatures from svg font 		}+				+		// take xheight from appropriate lower case letter+		// xheight_position = estimate_xheight (); 	}  	public bool parse_otf_file (string path) throws GLib.Error {@@ -985,7 +1005,7 @@ public class Font : GLib.Object { 		font_file = path; 		 		// empty cache and fill it with new glyphs from disk-		glyph_unicode.remove_all ();+		glyph_cache.remove_all (); 		glyph_name.remove_all ();  		while (background_images.length () > 0) {diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex 560ba6b..3098ec9 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -75,6 +75,7 @@ public class Glyph : FontDisplay { 	bool xheight_lines_visible = false; 	bool margin_boundries_visible = false; 	+	bool unassigned = false; 	public unichar unichar_code = 0; 	 	List<Glyph> undo_list = new List<Glyph> ();@@ -83,10 +84,14 @@ public class Glyph : FontDisplay { 	 	string glyph_sequence = ""; 	bool open = true;-	+/*+<<<<<<< HEAD 	bool ligature = false; 	string substitution = ""; 	+=======+>>>>>>> parent of a76d9a8... parse ligatures from svg font+*/ 	public Glyph (string name, unichar unichar_code = 0) { 		this.name = name; 		this.unichar_code = unichar_code;@@ -105,6 +110,8 @@ public class Glyph : FontDisplay {  		path_list.append (new Path ()); 	}+/*+<<<<<<< HEAD 	 	public string get_ligature_string () { 		return substitution;@@ -141,7 +148,9 @@ public class Glyph : FontDisplay { 	public bool is_ligature () { 		return ligature; 	}-+=======+>>>>>>> parent of a76d9a8... parse ligatures from svg font+*/ 	public void select_all_paths () { 		clear_active_paths (); 		@@ -205,6 +214,14 @@ public class Glyph : FontDisplay { 		 		return 0; 	}+		+	public void set_unassigned (bool u) {+		unassigned = u;+	}+	+	public bool is_unassigned () {+		return unassigned;+	}  	public void boundries (out double x1, out double y1, out double x2, out double y2) { 		if (path_list.length () == 0) {@@ -1475,10 +1492,14 @@ public class Glyph : FontDisplay { 		if (background_image != null) { 			g.background_image = ((!) background_image).copy (); 		}-		+	/*	+<<<<<<< HEAD 		g.ligature = ligature; 		g.substitution = substitution; 		+=======+>>>>>>> parent of a76d9a8... parse ligatures from svg font+*/ 		return g; 	} diff --git a/libbirdfont/GlyphSequence.vala b/libbirdfont/GlyphSequence.valaindex cdfbc34..40c48f9 100644--- a/libbirdfont/GlyphSequence.vala+++ b/libbirdfont/GlyphSequence.vala@@ -30,7 +30,7 @@ public class GlyphSequence { 	 */ 	public GlyphSequence process_ligatures () { 		GlyphSequence ligatures = new GlyphSequence ();-		Font font = BirdFont.get_current_font ();+/* // FIXME		Font font = BirdFont.get_current_font (); 		Glyph liga; 		GlyphCollection? gc; 		@@ -51,7 +51,7 @@ public class GlyphSequence { 			ligatures.replace (liga.get_ligature (), liga); 			i++; 		}-		+		*/ 		return ligatures; 	} 	diff --git a/libbirdfont/KerningDisplay.vala b/libbirdfont/KerningDisplay.valadeleted file mode 100644index d24eaf5..0000000--- a/libbirdfont/KerningDisplay.vala+++ /dev/null@@ -1,328 +0,0 @@-/*-    Copyright (C) 2012 Johan Mattsson--    This program is free software: you can redistribute it and/or modify-    it under the terms of the GNU General Public License as published by-    the Free Software Foundation, either version 3 of the License, or-    (at your option) any later version.--    This program 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 General Public License for more details.--    You should have received a copy of the GNU General Public License-    along with this program.  If not, see <http://www.gnu.org/licenses/>.-*/--using Cairo;--namespace BirdFont {--/** Kerning context. */-public class KerningDisplay : FontDisplay {--	List <GlyphSequence> row;-	int active_handle = -1;-	int selected_handle = -1;-	-	double begin_handle_x = 0;-	double begin_handle_y = 0;-	-	double last_handle_x = 0;-	-	public KerningDisplay () {-		GlyphSequence w = new GlyphSequence ();-		row = new List <GlyphSequence> ();-		row.append (w);-	}--	public override string get_name () {-		return "Kerning";-	}-	-	public override void draw (Allocation allocation, Context cr) {-		Glyph glyph;-		double x, y, w, kern, alpha;-		double x2;-		int i, wi;-		Glyph? prev;-		Font font = BirdFont.get_current_font ();-		GlyphSequence word_with_ligatures;-		-		i = 0;-		-		// bg color-		cr.save ();-		cr.set_source_rgba (1, 1, 1, 1);-		cr.rectangle (0, 0, allocation.width, allocation.height);-		cr.fill ();-		cr.restore ();-	-		alpha = 1;-		y = 100;-		x = 20;-		w = 0;-		prev = null;-		-		foreach (GlyphSequence word in row) {-			wi = 0;-			word_with_ligatures = word.process_ligatures ();-			foreach (Glyph? g in word_with_ligatures.glyph) {-				if (g == null) {-					continue;-				}-				-				if (prev == null) {-					kern = 0;-				} else {-					kern = font.get_kerning_by_name (((!)prev).get_name (), ((!)g).get_name ());-				}-								-				// draw glyph				-				if (g == null) {-					w = 50;-					alpha = 1;-				} else {-					alpha = 0;-					glyph = (!) g;-					Svg.draw_svg_path (cr, glyph.get_svg_data (), x + kern, y);-					w = glyph.get_width ();-				}--				// handle-				if (active_handle == i) {-					//x2 = x + kern;-					x2 = x + kern / 2.0;-					-					cr.save ();-					cr.set_source_rgba (153/255.0, 153/255.0, 173/255.0, 1);-					cr.move_to (x2 - 5, y + 20);-					cr.line_to (x2 + 0, y + 20 - 5);-					cr.line_to (x2 + 5, y + 20);-					cr.fill ();-					-					cr.set_font_size (10);-					cr.show_text (((!)g).get_name ());-					cr.restore ();-				}	-				-				x += w + kern;-	-				// caption-				if (g == null || ((!)g).is_empty ()) {-					cr.save ();-					cr.set_source_rgba (153/255.0, 153/255.0, 153/255.0, alpha);-					cr.move_to (x - w / 2.0 - 5, y + 20);-					cr.set_font_size (10);-					cr.show_text ("?"); // ?-					cr.restore ();-				}-							-				prev = g;-				-				wi++;-				i++;-			}-			-			if (y > allocation.height && i > 10) {-				row.remove (word);-			}-						-			y += MainWindow.get_current_glyph ().get_height () + 20;-			x = 20;			-		}-	}-	-	private void set_kerning (int handle, double val) {-		string a, b;-		Font font;-		int wi = 0;-		double kern;-		GlyphSequence word_with_ligatures;-		-		font = BirdFont.get_current_font ();--		font.touch ();--		a = "";-		b = "";--		foreach (GlyphSequence word in row) {-			word_with_ligatures = word.process_ligatures ();-			foreach (Glyph? g in word_with_ligatures.glyph) {-				-				if (g == null) {-					continue;-				}-				-				b = ((!) g).get_name ();-				-				if (handle == wi) {-					kern = font.get_kerning_by_name (a, b) + val;-					font.set_kerning_by_name (a, b, kern);-				}-				-				wi++;-				-				a = b;-			}-		}-		-		-	}--	public override void selected_canvas () {-		Glyph g;-		GlyphSequence w;-		unowned List<GlyphSequence>? r;-		StringBuilder s = new StringBuilder ();-		bool append_char = false;-		Font font = BirdFont.get_current_font ();-		-		KeyBindings.singleton.set_require_modifier (true);-		-		g = MainWindow.get_current_glyph ();-		s.append_unichar (g.get_unichar ());--		r = row;-		return_if_fail (r != null);--		if (row.length () == 0) {-			append_char = true;-		}-		-		if (append_char) {-			w = new GlyphSequence ();-			row.append (w);-			w.glyph.prepend (font.get_glyph (s.str));-		}		-	}-	-	public override void key_press (uint keyval) {-		unichar c = (unichar) keyval;-		Glyph? g;-		Font f = BirdFont.get_current_font ();-		string name;-		-		if (KeyBindings.modifier == NONE || KeyBindings.modifier == SHIFT) {-					-			if (keyval == Key.BACK_SPACE && row.length () > 0) {	-				row.first ().data.glyph.remove_link (row.first ().data.glyph.last ());-			}-			-			if (row.length () == 0 || c == Key.ENTER) {-				row.prepend (new GlyphSequence ());-			}-			-			if (!is_modifier_key (c) && c.validate ()) {-				name = f.get_name_for_character (c);-				g = f.get_glyph_by_name (name);-				row.first ().data.glyph.append (g);-			}-		}-		-		MainWindow.get_glyph_canvas ().redraw ();-	}-	-	public override void motion_notify (double ex, double ey) {-		double k, y;-		-		if (selected_handle == -1) {-			set_active_handle (ex, ey);-		} else {-			y = 1;-			-			if (Math.fabs (ey - begin_handle_y) > 20) {-				y = ((Math.fabs (ey - begin_handle_y) / 100) + 1);-			}-			-			k = (ex - last_handle_x) / y; // y-axis is variable precision-			set_kerning (selected_handle, k);-			MainWindow.get_glyph_canvas ().redraw ();-		}-		-		last_handle_x = ex;-	}-	-	public void set_active_handle (double ex, double ey) {-		double y = 100;-		double x = 20;-		double w = 0;-		double d, kern;-		double min = double.MAX;-		int i = 0;-		int row_index = 0;-		int col_index = 0;-		Glyph glyph = new Glyph.no_lines ("");-		Font font = BirdFont.get_current_font ();-		-		Glyph? prev = null;-		string gl_name = "";-		GlyphSequence word_with_ligatures;-		-		foreach (GlyphSequence word in row) {-			col_index = 0;-			-			word_with_ligatures = word.process_ligatures ();-			foreach (Glyph? g in word_with_ligatures.glyph) {-				// draw glyph--				if (g == null) {-					w = 50;	-				} else {-					glyph = (!) g;-					w = glyph.get_width ();-				}-				-				gl_name = glyph.get_name ();-				-				if (prev == null) {-					kern = 0;-				} else {-					kern = font.get_kerning_by_name (((!)prev).get_name (), gl_name);-				}-								-				d = Math.pow (x + kern - ex, 2) + Math.pow (y - ey, 2);-				-				if (d < min) {-					min = d;-					-					if (active_handle != i - row_index) {-						active_handle = i - row_index;-						MainWindow.get_glyph_canvas ().redraw ();-					}--					if (col_index == word.glyph.length () || col_index == 0) {-						active_handle = -1;-					}-				}-				-				prev = g;-				x += w + kern;-				i++;-				col_index++;-			}-			-			row_index++;-			y += MainWindow.get_current_glyph ().get_height () + 20;-			x = 20;-		}-	}-	-	public override void button_release (int button, double ex, double ey) {-		set_active_handle (ex, ey);-		selected_handle = -1;-	}-	-	public override void button_press (uint button, double ex, double ey) {-		set_active_handle (ex, ey);-		selected_handle = active_handle;-		begin_handle_x = ex;-		begin_handle_y = ey;-		last_handle_x = ex;-	}--}--}diff --git a/libbirdfont/MenuTab.vala b/libbirdfont/MenuTab.valaindex e15f0cc..f144771 100644--- a/libbirdfont/MenuTab.vala+++ b/libbirdfont/MenuTab.vala@@ -408,7 +408,7 @@ c.append (""" 	} 	 	public static void show_kerning_context () {-		MainWindow.get_tab_bar ().add_unique_tab (new KerningDisplay (), 85, false);+		MainWindow.get_tab_bar ().add_unique_tab (new ContextDisplay (), 85, false); 	} 	 	public static void preview () {diff --git a/libbirdfont/OpenFontFormatWriter.vala b/libbirdfont/OpenFontFormatWriter.valaindex 6b5d56a..b279008 100644--- a/libbirdfont/OpenFontFormatWriter.vala+++ b/libbirdfont/OpenFontFormatWriter.vala@@ -759,6 +759,11 @@ class GlyfTable : Table { 		
 		while (gl != glyphs.first ()) {
 			g = (!) gl.data;
+			
+			if (!g.is_unassigned ()) {
+				break;
+			}
+			
 			gl = gl.prev;
 		}
 		
@@ -840,6 +845,10 @@ class GlyfTable : Table { 		
 		glyph.name = name;
 
+		if (character == 0) {
+			glyph.set_unassigned (true);
+		}
+		
 		if (character == 0 && name != "") {
 			stderr.printf (@"Got null character\n");
 			stderr.printf (@"gid: $index\n");
@@ -1551,7 +1560,11 @@ class GlyfTable : Table { 			
 			g.remove_empty_paths ();
 
-			glyphs.append (g);
+			if (!g.is_unassigned ()) {
+				glyphs.append (g);
+			} else {
+				unassigned_glyphs.append (g);
+			}
 		}
 		
 		foreach (Glyph ug in unassigned_glyphs) {
@@ -1796,7 +1809,9 @@ class CmapSubtableWindowsUnicode : CmapSubtable { 		uint32 first_assigned = 1;
 		
 		foreach (Glyph g in glyf_table.glyphs) {
-			glyph_range.add_single (g.unichar_code);
+			if (!g.is_unassigned ()) {
+				glyph_range.add_single (g.unichar_code);
+			}
 		}
 		
 		// glyph_range.print_all ();
diff --git a/libbirdfont/SvgFont.vala b/libbirdfont/SvgFont.valaindex 85c115a..c1a67d9 100644--- a/libbirdfont/SvgFont.vala+++ b/libbirdfont/SvgFont.vala@@ -93,7 +93,6 @@ class SvgFont : GLib.Object { 		StringBuilder sl, sr; 		string attr_name = ""; 		string attr_content;-		string ln, rn; 		 		for (Xml.Attr* prop = node->properties; prop != null; prop = prop->next) { 			attr_name = prop->name;@@ -123,52 +122,22 @@ class SvgFont : GLib.Object { 			} 		} 		-		// , is used as separator-		if (left == ",") {-			left = "&#x2c;";-		}--		if (right == ",") {-			right = "&#x2c;";-		} 		-		// TODO: ranges for u1 & u2 + g1 & g2-		-		// u1 + u2 or g2+		// TODO: ranges and sequences for u1 & u2 + g1 & g2 		foreach (string lk in left.split (",")) {-			l = get_unichar (lk);-			sl = new StringBuilder ();-			sl.append_unichar (l);-			ln = font.get_name_from_unicode (sl.str);-					-			foreach (string rk in right.split (",")) {-				r = get_unichar (rk);-				sr = new StringBuilder ();-				sr.append_unichar (r);-				rn = font.get_name_from_unicode (sr.str);-				font.set_kerning_by_name (ln, rn, -kerning);-			}--			foreach (string rk in right_name.split (",")) {-				font.set_kerning_by_name (ln, rk, -kerning);-			}-		}--		// g1 + u2 or g2-		foreach (string lk in left_name.split (",")) { 			foreach (string rk in right.split (",")) {+				l = get_unichar (lk); 				r = get_unichar (rk);+				+				sl = new StringBuilder ();+				sl.append_unichar (l);+				 				sr = new StringBuilder (); 				sr.append_unichar (r);-				rn = font.get_name_from_unicode (sr.str);-				font.set_kerning_by_name (lk, rn, -kerning);-			}--			foreach (string rk in right_name.split (",")) {-				font.set_kerning_by_name (lk, rk, -kerning);+				+				font.set_kerning (sl.str, sr.str, -kerning);				 			} 		}- 	}  	void parse_font_limits (Xml.Node* node) {@@ -227,18 +196,14 @@ class SvgFont : GLib.Object { 	/** Obtain unichar value from either a character, a hex representation of 	 *  a character or series of characters (f, &#x6d; or ffi). 	 */-	unichar get_unichar (string val) {+	static unichar get_unichar (string val) { 		string v = val; 		unichar unicode_value;-+		 		if (val == "&") { 			return '&'; 		}--		if (val == ",") {-			return ',';-		}-+		 		// TODO: parse ligatures 		if (v.has_prefix ("&")) { 			// parse hex value@@ -247,27 +212,19 @@ class SvgFont : GLib.Object { 			v = v.replace (";", ""); 			unicode_value = Font.to_unichar (v); 		} else {+			// obtain unicode value 			-			// don't assign ligatures to any code point-			if (is_ligature (val)) {+			if (v.char_count () > 1) {+				warning ("font contains ligatures"); 				return '\0'; 			} 			-			// obtain unicode value 			unicode_value = v.get_char (0); 		} 		 		return unicode_value;	 	} 	-	bool is_ligature (string v) {-		if (v.has_prefix ("&")) {-			return false;-		}-		-		return v.char_count () > 1; -	}-	 	void parse_glyph (Xml.Node* node) { 		string attr_name = ""; 		string attr_content;@@ -276,7 +233,6 @@ class SvgFont : GLib.Object { 		string svg = ""; 		Glyph glyph; 		double advance = font_advance;-		string ligature = "";  		for (Xml.Attr* prop = node->properties; prop != null; prop = prop->next) { 			attr_name = prop->name;@@ -288,10 +244,6 @@ class SvgFont : GLib.Object { 				if (glyph_name == "") { 					glyph_name = attr_content; 				}-				-				if (is_ligature (attr_content)) {-					ligature = attr_content;-				} 			} 			 			// svg data@@ -307,16 +259,27 @@ class SvgFont : GLib.Object { 				advance = double.parse (attr_content); 			} 		}-		++/*		+<<<<<<< HEAD 		glyph = new Glyph (glyph_name, unicode_value); 		ImportSvg.parse_svg_data (svg, glyph, true, units);			 		glyph.right_limit = glyph.left_limit + advance * units; 		 		if (ligature != "") { 			glyph.set_ligature_substitution (ligature);+=======+*/+		// FIXME: this code will ignore characters that are mapped several glyphs+		if (unicode_value != '\0') {+			glyph = new Glyph (glyph_name, unicode_value);+			ImportSvg.parse_svg_data (svg, glyph, true, units);			+			glyph.right_limit = glyph.left_limit + advance * units;+			font.add_glyph_callback (glyph);+		} else {+			warning ("ignoring glyph");+//>>>>>>> parent of a76d9a8... parse ligatures from svg font 		}-		-		font.add_glyph_callback (glyph); 	} } 

Contact

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