Clone in a terminal:
Commit 41905a8
Johan Mattsson - 2015-03-24T13:41:03+00:00
41905a8f93b53f30702953a964c2458c9c662e21johan.mattsson.m@gmail.com

Process contextual ligatures in kerning and spacing tabs

Changed files (8)

Diff

diff --git a/libbirdfont/BirdFontFile.vala b/libbirdfont/BirdFontFile.valaindex 6e0cd13..c2e04d6 100644--- a/libbirdfont/BirdFontFile.vala+++ b/libbirdfont/BirdFontFile.vala@@ -346,7 +346,7 @@ class BirdFontFile : GLib.Object { 		os.put_string (@"\t<bottom_position>$(round (font.bottom_position))</bottom_position>\n"); 		os.put_string (@"\t<bottom_limit>$(round (font.bottom_limit))</bottom_limit>\n"); 		-		foreach (Line guide in BirdFont.get_current_font ().custom_guides) {+		foreach (Line guide in font.custom_guides) { 			os.put_string (@"\t<custom_guide label=\"$(guide.label)\">$(round (guide.pos))</custom_guide>\n"); 		} 		@@ -1050,7 +1050,7 @@ class BirdFontFile : GLib.Object { 				 				line = new Line (label, position); 				-				BirdFont.get_current_font ().custom_guides.add (line);+				font.custom_guides.add (line); 			} 		}	 	}diff --git a/libbirdfont/Font.vala b/libbirdfont/Font.valaindex eff3e78..82b5fa4 100644--- a/libbirdfont/Font.vala+++ b/libbirdfont/Font.vala@@ -834,6 +834,32 @@ public class Font : GLib.Object { 		read_only = r; 	} +	/** +	 * @param glyphs Name of glyphs or unicode values separated by space.+	 * @return glyph names+	 */+	public Gee.ArrayList<string> get_names (string glyphs) {+		Gee.ArrayList<string> names = new Gee.ArrayList<string> ();+		string[] parts = glyphs.strip ().split (" ");+								+		foreach (string p in parts) {		+			if (p.has_prefix ("U+") || p.has_prefix ("u+")) {+				p = (!) to_unichar (p).to_string ();+			}+			+			if (!has_glyph (p)) {+				warning (@"The character $p does not have a glyph in " + get_file_name ());+				p = ".notdef";+			}+			+			if (p != "") {+				names.add (p);+			}+		}+		+		return names;+	}+ 	public static unichar to_unichar (string unicode) { 		int index = 2; 		int i = 0;diff --git a/libbirdfont/GlyphSequence.vala b/libbirdfont/GlyphSequence.valaindex 5cc032c..d6d9d20 100644--- a/libbirdfont/GlyphSequence.vala+++ b/libbirdfont/GlyphSequence.vala@@ -1,5 +1,5 @@ /*-    Copyright (C) 2013 Johan Mattsson+    Copyright (C) 2013 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 @@ -30,6 +30,21 @@ public class GlyphSequence : GLib.Object { 		return glyph.size; 	} 	+	public void add (Glyph? g) {+		glyph.add (g);+		ranges.add (null);+	}+	+	public void append (GlyphSequence c) {+		foreach (Glyph? g in c.glyph) {+			glyph.add (g);+		}++		foreach (GlyphRange? r in c.ranges) {+			ranges.add (r);+		}+	}+	 	/** Do ligature substitution. 	 * @return a new sequence with ligatures 	 */@@ -57,9 +72,14 @@ public class GlyphSequence : GLib.Object { 		 		ligatures = font.get_ligatures (); 		ligatures.get_single_substitution_ligatures ((substitute, ligature) => {-			ligature_sequence.replace (substitute, ligature.get_current ());+			ligature_sequence.replace (substitute, ligature); 		}); 		+		foreach (ContextualLigature c in  ligatures.contextual_ligatures) {+			ligature_sequence.replace_contextual (c.get_backtrack (),+				c.get_input (), c.get_lookahead (), c.get_ligature_sequence ());	+		}+		 		ligature_sequence.ranges.clear (); 		for (int i = 0; i < ligature_sequence.glyph.size; i++) { 			ligature_sequence.ranges.add (null);@@ -68,18 +88,35 @@ public class GlyphSequence : GLib.Object { 		return ligature_sequence; 	} 	-	void replace (GlyphSequence old, Glyph replacement) {+	void replace (GlyphSequence old, GlyphSequence replacement) { 		int i = 0; 		while (i < glyph.size) { 			if (starts_with (old, i)) { 				substitute (i, old.glyph.size, replacement);-				i = 0;+				i += replacement.length (); 			} else { 				i++; 			} 		} 	}-	++	void replace_contextual (GlyphSequence backtrack, GlyphSequence input, GlyphSequence lookahead, GlyphSequence replacement) {+		bool start, middle, end;+		int i = 0;+		while (i < glyph.size) {+			start = starts_with (backtrack, i);+			middle = starts_with (input, i + backtrack.length ());+			end = starts_with (lookahead, i + backtrack.length () + input.length ());+			+			if (start && middle && end) {+				substitute (i + backtrack.length (), input.length (), replacement);+				i += i + backtrack.length () + input.length ();+			} else {+				i++;+			}+		}+	}+		 	bool starts_with (GlyphSequence old, uint index) { 		Glyph? gl; @@ -100,13 +137,15 @@ public class GlyphSequence : GLib.Object { 		return true; 	} 	-	void substitute (uint index, uint length, Glyph substitute) {+	void substitute (uint index, uint length, GlyphSequence substitute) { 		Gee.ArrayList<Glyph?> new_list = new Gee.ArrayList<Glyph?> (); 		int i = 0; 		 		foreach (Glyph? g in glyph) { 			if (i == index) {-				new_list.add (substitute);+				foreach (Glyph? gn in substitute.glyph) {+					new_list.add (gn);+				} 			}  			if (!(i >= index && i < index + length)) {diff --git a/libbirdfont/Ligatures.vala b/libbirdfont/Ligatures.valaindex 6707836..7508e34 100644--- a/libbirdfont/Ligatures.vala+++ b/libbirdfont/Ligatures.vala@@ -23,7 +23,7 @@ public class Ligatures : GLib.Object { 	public Gee.ArrayList<ContextualLigature> contextual_ligatures = new Gee.ArrayList<ContextualLigature> (); 	 	public delegate void LigatureIterator (string substitution, string ligature);-	public delegate void SingleLigatureIterator (GlyphSequence substitution, GlyphCollection ligature);+	public delegate void SingleLigatureIterator (GlyphSequence substitution, GlyphSequence ligature);  	public delegate void ContextualLigatureIterator (ContextualLigature lig); @@ -48,18 +48,21 @@ public class Ligatures : GLib.Object { 	public void get_single_substitution_ligatures (SingleLigatureIterator iter) { 		get_ligatures ((substitution, ligature) => { 			GlyphCollection? gc;-			GlyphCollection li;+			GlyphSequence lig; 			GlyphSequence gs; 			string[] subst_names = substitution.split (" "); 			-			gc = font.get_glyph_collection_by_name (ligature);-			-			if (gc == null) {-				return;+			lig = new GlyphSequence ();+			foreach (string n in font.get_names (ligature)) {+				gc = font.get_glyph_collection_by_name (n);+				+				if (gc == null) {+					return;+				}+				+				lig.add (((!) gc).get_current ()); 			} 			-			li = (!) gc;-			 			gs = new GlyphSequence (); 			foreach (string s in subst_names) { 				gc = font.get_glyph_collection_by_name (s);@@ -71,7 +74,7 @@ public class Ligatures : GLib.Object { 				gs.glyph.add (((!) gc).get_current ()); 			} 			-			iter (gs, li);+			iter (gs, lig); 		}); 	} 		@@ -206,7 +209,7 @@ public class Ligatures : GLib.Object { 	}  	public void add_contextual_ligature (string ligature, string backtrack, string input, string lookahead) {-		ContextualLigature l = new ContextualLigature (ligature, backtrack, input, lookahead);+		ContextualLigature l = new ContextualLigature (font, ligature, backtrack, input, lookahead); 		contextual_ligatures.insert (0, l); 		sort_ligatures (); 	}diff --git a/libbirdfont/OpenFontFormat/ContextualLigature.vala b/libbirdfont/OpenFontFormat/ContextualLigature.valaindex b260ef5..ed7a791 100644--- a/libbirdfont/OpenFontFormat/ContextualLigature.vala+++ b/libbirdfont/OpenFontFormat/ContextualLigature.vala@@ -21,8 +21,11 @@ public class ContextualLigature : GLib.Object { 	public string lookahead = ""; 	public string ligatures = ""; +	Font font;+ 	/** All arguments are list of glyph names separated by space. */-	public ContextualLigature (string ligatures, string backtrack, string input, string lookahead) {+	public ContextualLigature (Font font, string ligatures, string backtrack, string input, string lookahead) {+		this.font = font; 		this.backtrack = backtrack; 		this.input = input; 		this.lookahead = lookahead;@@ -43,10 +46,11 @@ public class ContextualLigature : GLib.Object { 	public FontData get_font_data (GlyfTable glyf_table, uint16 ligature_lookup_index)  		throws GLib.Error { 		FontData fd = new FontData ();+		Font font = BirdFont.get_current_font (); // FIXME: thread safety? 		-		Gee.ArrayList<string> backtrack = GsubTable.get_names (backtrack);-		Gee.ArrayList<string> input = GsubTable.get_names (input);-		Gee.ArrayList<string> lookahead = GsubTable.get_names (lookahead);+		Gee.ArrayList<string> backtrack = font.get_names (backtrack);+		Gee.ArrayList<string> input = font.get_names (input);+		Gee.ArrayList<string> lookahead = font.get_names (lookahead); 		 		// FIXME: add ligatures 		@@ -115,6 +119,41 @@ public class ContextualLigature : GLib.Object { 		 		return fd; 	}+	+	public GlyphSequence get_backtrack () {+		return get_sequence (backtrack);+	}++	public GlyphSequence get_input () {+		return get_sequence (input);+	}+	+	public GlyphSequence get_lookahead () {+		return get_sequence (lookahead);+	}+	+	public GlyphSequence get_ligature_sequence () {+		return get_sequence (ligatures);+	}+		+	GlyphSequence get_sequence (string context) {+		GlyphCollection? gc;+		GlyphSequence gs;+		+		gs = new GlyphSequence ();+		foreach (string s in font.get_names (context)) {+			gc = font.get_glyph_collection_by_name (s);+			+			if (gc == null) {+				warning (@"No glyph found for $s");+				return new GlyphSequence ();+			}+			+			gs.glyph.add (((!) gc).get_current ());+		}+		+		return gs;+	} }  }diff --git a/libbirdfont/OpenFontFormat/GsubTable.vala b/libbirdfont/OpenFontFormat/GsubTable.valaindex cec53dc..78a9ae9 100644--- a/libbirdfont/OpenFontFormat/GsubTable.vala+++ b/libbirdfont/OpenFontFormat/GsubTable.vala@@ -194,33 +194,6 @@ public class GsubTable : OtfTable { 		 		return fd; 	}-	-	/** -	 * @param glyphs Name of glyphs or unicode values separated by space.-	 * @return glyph names-	 */-	public static Gee.ArrayList<string> get_names (string glyphs) {-		Gee.ArrayList<string> names = new Gee.ArrayList<string> ();-		Font font = BirdFont.get_current_font ();-		string[] parts = glyphs.strip ().split (" ");-								-		foreach (string p in parts) {		-			if (p.has_prefix ("U+") || p.has_prefix ("u+")) {-				p = (!) Font.to_unichar (p).to_string ();-			}-			-			if (!font.has_glyph (p)) {-				warning (@"The character $p does have a glyph.");-				p = ".notdef";-			}-			-			if (p != "") {-				names.add (p);-			}-		}-		-		return names;-	} }  }diff --git a/libbirdfont/Renderer/FontCache.vala b/libbirdfont/Renderer/FontCache.valaindex 0e1b8a5..3c53407 100644--- a/libbirdfont/Renderer/FontCache.vala+++ b/libbirdfont/Renderer/FontCache.vala@@ -38,7 +38,7 @@ public class FontCache { 		bool ok; 		 		if (file_name == "") {-			stderr.printf ("No file name provided.\n");+			stderr.printf ("No file name.\n"); 			return null; 		} 		diff --git a/libbirdfont/Table.vala b/libbirdfont/Table.valaindex 197a1ee..e4240bf 100644--- a/libbirdfont/Table.vala+++ b/libbirdfont/Table.vala@@ -91,7 +91,6 @@ public abstract class Table : FontDisplay { 			Row row, double y, bool color, bool dark) { 		 		Text t;-		double margin; 		double x; 		double o; 		

Contact

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