Clone in a terminal:
Commit e2de178
Johan Mattsson - 2015-03-22T22:16:10+00:00
e2de178e809daf382d73ffabf6149a499bd61e9ejohan.mattsson.m@gmail.com

Write the context for contextual substitutions (ligatures)

Changed files (8)

Diff

diff --git a/libbirdfont/LigatureList.vala b/libbirdfont/LigatureList.valaindex 42b4558..63e9368 100644--- a/libbirdfont/LigatureList.vala+++ b/libbirdfont/LigatureList.vala@@ -29,10 +29,10 @@ public class LigatureList : Table { 		return rows; 	} -	void add_contextual_ligature (string backtrack, string input, string lookahead) {+	void add_contextual_ligature (string ligature, string backtrack, string input, string lookahead) { 		Font font = BirdFont.get_current_font (); 		Ligatures ligatures = font.get_ligatures ();-		ligatures.add_contextual_ligature (backtrack, input, lookahead);+		ligatures.add_contextual_ligature (ligature, backtrack, input, lookahead); 	} 	 	void add_ligature (string subst, string liga) {@@ -52,13 +52,14 @@ public class LigatureList : Table { 			TabContent.hide_text_input (); 		} else if (row.get_index () == NEW_LIGATURE && column == 1) { 			if (BirdFont.has_argument ("--test")) {-				add_contextual_ligature (t_("beginning"), t_("middle"), t_("end"));+				add_contextual_ligature (t_("substitution"), t_("beginning"), t_("middle"), t_("end")); 				TabContent.hide_text_input (); 			} 		} else if (row.has_row_data ()) { 			i = row.get_index (); 			cl = (ContextualLigature) ((!) row.get_row_data ()); 			+			/* // FIXME: DELETE 			if (delete_button) { 				cl.remove_ligature_at (i); 			} else if (column == 0) {@@ -66,6 +67,7 @@ public class LigatureList : Table { 			} else if (column == 2) { 				cl.set_substitution (i); 			}+			*/ 		} else if (row.get_index () < ligatures.count ()) { 			if (ligatures.count () != 0) { 				if (delete_button) {@@ -87,7 +89,10 @@ public class LigatureList : Table { 				if (delete_button) { 					ligatures.remove_contextual_ligatures_at (i); 					TabContent.hide_text_input ();-				} else if (column == 0) {+				}+				+				/* FIXME: DELETE+				 else if (column == 0) { 					ligatures.set_beginning (i); 				} else if (column == 1) { 					ligatures.set_middle (i);@@ -96,6 +101,7 @@ public class LigatureList : Table { 				} else if (column == 3) { 					ligatures.add_substitution_at (i); 				}+				*/ 			} 		} 			@@ -127,20 +133,8 @@ public class LigatureList : Table { 		});  		ligatures.get_contextual_ligatures ((liga) => {-			int j;-			-			row = new Row.columns_4 (liga.backtrack, liga.input, liga.lookahead,-				t_("Add Ligature"), i);+			row = new Row.columns_4 (liga.ligatures, liga.backtrack, liga.input, liga.lookahead, i); 			rows.add (row);-			-			j = 0;-			foreach (Ligature l in liga.ligatures) {-				row = new Row.columns_3 (l.ligature, "",  l.substitution, j);-				row.set_row_data (liga);-				rows.add (row);-				j++;-			}-			 			i++; 		}); 				diff --git a/libbirdfont/Ligatures.vala b/libbirdfont/Ligatures.valaindex 6bbd206..2856623 100644--- a/libbirdfont/Ligatures.vala+++ b/libbirdfont/Ligatures.vala@@ -92,13 +92,7 @@ public class Ligatures : GLib.Object { 		return_if_fail (0 <= i < contextual_ligatures.size); 		contextual_ligatures.remove_at (i); 	}-	-	/** Add ligaure for a chained substitution. */-	public void add_substitution_at (int index) {-		return_if_fail (0 <= index < contextual_ligatures.size);-		contextual_ligatures.get (index).add_ligature ();-	}-	+		 	public void set_beginning (int index) { 		ContextualLigature lig; 		TextListener listener;@@ -185,8 +179,8 @@ public class Ligatures : GLib.Object { 		sort_ligatures (); 	} -	public void add_contextual_ligature (string backtrack, string input, string lookahead) {-		ContextualLigature l = new ContextualLigature (backtrack, input, lookahead);+	public void add_contextual_ligature (string ligature, string backtrack, string input, string lookahead) {+		ContextualLigature l = new ContextualLigature (ligature, backtrack, input, lookahead); 		contextual_ligatures.insert (0, l); 		sort_ligatures (); 	}@@ -222,10 +216,6 @@ public class Ligatures : GLib.Object { 								 			return chars_next - chars_first; 		});-		-		foreach (ContextualLigature c in contextual_ligatures) {-			c.sort ();-		} 	} } diff --git a/libbirdfont/OpenFontFormat/ContextualLigature.vala b/libbirdfont/OpenFontFormat/ContextualLigature.valaindex 6d8952f..7bd2a7b 100644--- a/libbirdfont/OpenFontFormat/ContextualLigature.vala+++ b/libbirdfont/OpenFontFormat/ContextualLigature.vala@@ -15,54 +15,29 @@ namespace BirdFont {  public class ContextualLigature : GLib.Object {-+	 	public string backtrack = ""; 	public string input = ""; 	public string lookahead = "";+	public string ligatures = ""; -	public Gee.ArrayList<Ligature> ligatures;--	public ContextualLigature (string backtrack, string input, string lookahead) {+	/** All arguments are list of glyph names separated by space. */+	public ContextualLigature (string ligatures, string backtrack, string input, string lookahead) { 		this.backtrack = backtrack; 		this.input = input; 		this.lookahead = lookahead;-		-		ligatures = new Gee.ArrayList<Ligature> ();-	}--	public void remove_ligature_at (int i) {-		return_if_fail (0 <= i < ligatures.size);-		ligatures.remove_at (i);-	}--	public void add_ligature () {-		Ligature l = new Ligature (t_("ligature"), t_("glyph sequence"));-		ligatures.add (l);		-	}-	-	public void set_ligature (int i) {-		return_if_fail (0 <= i < ligatures.size);-		ligatures.get (i).set_ligature ();+		this.ligatures = ligatures; 	} -	public void set_substitution (int i) {-		return_if_fail (0 <= i < ligatures.size);-		ligatures.get (i).set_substitution (this);-	}-	-	public void sort () {-		ligatures.sort ((a, b) => {-			Ligature first, next;-			int chars_first, chars_next;-			-			first = (Ligature) a;-			next = (Ligature) b;-			-			chars_first = first.substitution.split (" ").length;-			chars_next = next.substitution.split (" ").length;-							-			return chars_next - chars_first;-		});	+	public Gee.ArrayList<Ligature> get_ligatures () {+		Gee.ArrayList<Ligature> ligature_list = new Gee.ArrayList<Ligature> ();+		string[] ligatures = ligatures.split (" ");+		+		foreach (string ligature_name in ligatures) {+			ligature_list.add (new Ligature (ligature_name)); +		}+		+		return ligature_list; 	} } diff --git a/libbirdfont/OpenFontFormat/ContextualLigatureSet.vala b/libbirdfont/OpenFontFormat/ContextualLigatureSet.valanew file mode 100644index 0000000..ee201bc--- /dev/null+++ b/libbirdfont/OpenFontFormat/ContextualLigatureSet.vala@@ -0,0 +1,38 @@+/*+    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.+*/+using Math;++namespace BirdFont {++public class ContextualLigatureSet : GLib.Object {++	public Gee.ArrayList<ContextualLigature> ligature_context;+	public LigatureSetList ligatures;+	+	public ContextualLigatureSet (GlyfTable glyf_table) {+		ligature_context = new Gee.ArrayList<ContextualLigature> ();	+		add_contextual_ligatures ();+		ligatures = new LigatureSetList.contextual (glyf_table, this);+	}+	+	void add_contextual_ligatures () {+		ContextualLigature ligature ;+		LigatureSet s;+		+		ligature = new ContextualLigature ("ralt", "a", "r", "t t");+		ligature_context.add (ligature);+	}+}++}diff --git a/libbirdfont/OpenFontFormat/GsubTable.vala b/libbirdfont/OpenFontFormat/GsubTable.valaindex fbfba53..aea7bb3 100644--- a/libbirdfont/OpenFontFormat/GsubTable.vala+++ b/libbirdfont/OpenFontFormat/GsubTable.vala@@ -35,7 +35,7 @@ public class GsubTable : OtfTable { 		uint16 length; 		 		LigatureSetList clig;-		LigatureSetList contextual;+		ContextualLigatureSet contextual; 		 		fd.add_ulong (0x00010000); // table version 		fd.add_ushort (10); // offset to script list@@ -66,46 +66,50 @@ public class GsubTable : OtfTable { 		 		fd.add_ushort (0); // feature prameters (null) 		fd.add_ushort (2); // number of lookups-		fd.add_ushort (1); // lookup chained_context+		fd.add_ushort (2); // lookup chained_context (etc.) The chained context tables are listed here but the actual ligature table is only referenced in the context table 		fd.add_ushort (0); // lookup clig_subtable  		clig = new LigatureSetList.clig (glyf_table);-		contextual = new LigatureSetList.context (glyf_table);+		contextual = new ContextualLigatureSet (glyf_table); 		 		clig_subtable = get_ligature_subtable (clig);-		// FIXME: put back contextual ligatures-		//chained_context = get_chaining_contextual_substition_subtable ();-		//chained_ligatures = get_ligature_subtable (contextual);+		chained_ligatures = get_ligature_subtable (contextual.ligatures);+		chained_context = get_chaining_contextual_substition_subtable (contextual); 		 		// lookup table-		fd.add_ushort (1); // number of lookups FIXME: should be 3-		fd.add_ushort (4); // offset to lookup 1 FIXME: should be 8-		//fd.add_ushort (16); // offset to lookup 2-		//fd.add_ushort (24); // offset to lookup 3+		fd.add_ushort (3); // number of lookups+		fd.add_ushort (8); // offset to lookup 1 +		fd.add_ushort (16); // offset to lookup 2+		fd.add_ushort (24); // offset to lookup 3 +		uint16 lookups_end = 3 * 8; 		length = 0; 		fd.add_ushort (4); // lookup type  		fd.add_ushort (0); // lookup flags 		fd.add_ushort (1); // number of subtables-		fd.add_ushort (8 + length); // array of offsets to subtable FIXME: should be 24+		fd.add_ushort (lookups_end + length); // array of offsets to subtable  		length += (uint16) clig_subtable.length_with_padding ();--/*-		fd.add_ushort (6); // lookup type -		fd.add_ushort (0); // lookup flags-		fd.add_ushort (1); // number of subtables-		fd.add_ushort (16 + length); // array of offsets to subtable-		length += (uint16) chained_context.length_with_padding ();+		lookups_end -= 8; 	 		fd.add_ushort (4); // lookup type  		fd.add_ushort (0); // lookup flags 		fd.add_ushort (1); // number of subtables-		fd.add_ushort (8 + length); // array of offsets to subtable+		fd.add_ushort (lookups_end + length); // array of offsets to subtable 		length += (uint16) chained_ligatures.length_with_padding ();-*/		+		lookups_end -= 8;++		fd.add_ushort (6); // lookup type +		fd.add_ushort (0); // lookup flags+		fd.add_ushort (1); // number of subtables+		fd.add_ushort (lookups_end + length); // array of offsets to subtable+		length += (uint16) chained_context.length_with_padding ();+		lookups_end -= 8;+		+		warn_if_fail (lookups_end == 0);+		 		fd.append (clig_subtable);-		// fd.append (chained_context);-		// fd.append (chained_ligatures);+		fd.append (chained_ligatures);+		fd.append (chained_context); 		 		fd.pad (); 		@@ -114,39 +118,39 @@ public class GsubTable : OtfTable {  	FontData get_ligature_subtable (LigatureSetList liga_list) throws GLib.Error { 		FontData set_data;-		Gee.ArrayList<LigatureSet> liga_sets;+		Gee.ArrayList<LigatureSet> ligature_sets; 		uint16 ligature_pos; 		uint16 table_start; 		FontData fd;-		liga_sets = liga_list.liga_sets;-			+		+		ligature_sets = liga_list.ligature_sets; 		fd = new FontData ();  		// ligature substitution subtable 		table_start = (uint16) fd.length_with_padding ();  		fd.add_ushort (1); // format identifier-		fd.add_ushort (6 + (uint16) 2 * liga_sets.size); // offset to coverage-		fd.add_ushort ((uint16) liga_sets.size); // number of ligature set tables+		fd.add_ushort (6 + (uint16) 2 * ligature_sets.size); // offset to coverage+		fd.add_ushort ((uint16) ligature_sets.size); // number of ligature set tables  		// array of offsets to ligature sets 		uint16 size = 0;-		foreach (LigatureSet l in liga_sets) {-			ligature_pos = 10 + (uint16) liga_sets.size * 4 + size;+		foreach (LigatureSet l in ligature_sets) {+			ligature_pos = 10 + (uint16) ligature_sets.size * 4 + size; 			fd.add_ushort (ligature_pos); 			size += (uint16) l.get_set_data ().length_with_padding (); 		}  		// coverage 		fd.add_ushort (1); // format-		fd.add_ushort ((uint16) liga_sets.size);+		fd.add_ushort ((uint16) ligature_sets.size);  		// coverage gid:-		foreach (LigatureSet l in liga_sets) {+		foreach (LigatureSet l in ligature_sets) { 			fd.add_ushort ((uint16) glyf_table.get_gid (l.get_coverage_char ())); 		} 		-		foreach (LigatureSet l in liga_sets) {+		foreach (LigatureSet l in ligature_sets) { 			set_data = l.get_set_data (); 			fd.append (set_data); 		}@@ -155,48 +159,77 @@ public class GsubTable : OtfTable { 	}  	// chaining contextual substitution format3-	FontData get_chaining_contextual_substition_subtable () throws GLib.Error {+	FontData get_chaining_contextual_substition_subtable (ContextualLigatureSet contexts) throws GLib.Error { 		FontData fd = new FontData (); 		+		ContextualLigature context = contexts.ligature_context.get (0); //FIXME:+		+		Gee.ArrayList<string> backtrack = get_names (context.backtrack);+		Gee.ArrayList<string> input = get_names (context.input);+		Gee.ArrayList<string> lookahead = get_names (context.lookahead);+		+		uint16 lookahead_offset, input_offset, backtrack_offset;+		 		fd.add_ushort (3); // format identifier 		-		fd.add_ushort (1); // backtrack glyph count-		// array of offsets to coverage table-		fd.add_ushort (20);+		backtrack_offset = 14 + (uint16) (lookahead.size * 2) + (uint16) (input.size * 2) + (uint16) (backtrack.size * 2);+		fd.add_ushort ((uint16) backtrack.size); // backtrack glyph count+		for (uint16 i = 0; i < input.size; i++) {+			fd.add_ushort (backtrack_offset + 6 * i); // array of offsets to coverage table+		} 		-		fd.add_ushort (1); // input glyph count (middle)-		// array of offsets to coverage table-		fd.add_ushort (20 + 6);+		input_offset = 14 + (uint16) (lookahead.size * 2) + (uint16) (input.size * 2)  + (uint16) (backtrack.size * (2 + 6));+		fd.add_ushort ((uint16) input.size); // input glyph count (middle)+		for (uint16 i = 0; i < input.size; i++) {+			fd.add_ushort (input_offset + 6 * i); // array of offsets to coverage table+		} 		-		fd.add_ushort (1); // lookahead glyph count-		// array of offsets to coverage table-		fd.add_ushort (20 + 2 * 6);--		fd.add_ushort (1); // substitute count, (ligatures)+		lookahead_offset = 14 + (uint16) (lookahead.size * 2) + (uint16) (input.size * (2 + 6)) + (uint16) (backtrack.size * (2 + 6));+		fd.add_ushort ((uint16) lookahead.size); // lookahead glyph count+		for (uint16 i = 0; i < lookahead.size; i++) {+			fd.add_ushort (lookahead_offset + 6 * i); // array of offsets to coverage table+		}+		+		fd.add_ushort (1); // substitute count 		// substitution lookup records 		fd.add_ushort (0); // glyph sequence index-		fd.add_ushort (2); // go to the ligature substitution via lookup table-		+		fd.add_ushort (1); // go to the ligature substitution via lookup table+ 		// backtrack coverage table1-		fd.add_ushort (1); // format-		fd.add_ushort (1); // coverage array length-		-		// gid array-		fd.add_ushort ((uint16) glyf_table.get_gid ("a"));+		if (fd.length_with_padding () != backtrack_offset) {+			warning (@"Wrong backtrack offset: $backtrack_offset != $(fd.length_with_padding ())");+		} 		+		// gid array +		foreach (string glyph_name in backtrack) {+			fd.add_ushort (1); // format+			fd.add_ushort ((uint16) backtrack.size); // coverage array length+			fd.add_ushort ((uint16) glyf_table.get_gid (glyph_name));+		}+				 		// input coverage table1-		fd.add_ushort (1); // format-		fd.add_ushort (1); // coverage array length+		if (fd.length_with_padding () != input_offset) {+			warning (@"Wrong input offset: $input_offset != $(fd.length_with_padding ())");+		} 		-		// gid array-		fd.add_ushort ((uint16) glyf_table.get_gid ("r"));+		// gid array +		foreach (string glyph_name in input) {+			fd.add_ushort (1); // format+			fd.add_ushort ((uint16) input.size); // coverage array length+			fd.add_ushort ((uint16) glyf_table.get_gid (glyph_name));+		}  		// lookahead coverage table1-		fd.add_ushort (1); // format-		fd.add_ushort (1); // coverage array length-		-		// gid array-		fd.add_ushort ((uint16) glyf_table.get_gid ("t"));+		if (fd.length_with_padding () != lookahead_offset) {+			warning (@"Wrong lookahead offset: $lookahead_offset != $(fd.length_with_padding ())");+		}++		// gid array +		foreach (string glyph_name in lookahead) {+			fd.add_ushort (1); // format+			fd.add_ushort ((uint16) lookahead.size); // coverage array length+			fd.add_ushort ((uint16) glyf_table.get_gid (glyph_name));+		} 		 		return fd; 	}@@ -247,6 +280,31 @@ public class GsubTable : OtfTable { 			}  		} 	}++	/** +	 * @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.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.");+				return new Gee.ArrayList<string> ();+			}+			+			names.add (p);+		}+		+		return names;+	} }  }diff --git a/libbirdfont/OpenFontFormat/Ligature.vala b/libbirdfont/OpenFontFormat/Ligature.valaindex af91ccf..308284c 100644--- a/libbirdfont/OpenFontFormat/Ligature.vala+++ b/libbirdfont/OpenFontFormat/Ligature.vala@@ -18,7 +18,7 @@ public class Ligature : GLib.Object { 	public string ligature = ""; 	public string substitution = ""; -	public Ligature (string ligature, string substitution) {+	public Ligature (string ligature, string substitution = "") { 		this.ligature = ligature; 		this.substitution = substitution; 	}@@ -44,9 +44,8 @@ public class Ligature : GLib.Object { 		TabContent.show_text_input (listener); 	} 	-	public void set_substitution (ContextualLigature? clig = null) {+	public void set_substitution () { 		TextListener listener;-		ContextualLigature? cl = clig; 		 		listener = new TextListener (t_("Text"), substitution, t_("Set")); 		@@ -55,10 +54,6 @@ public class Ligature : GLib.Object { 			Ligatures l = f.get_ligatures (); 			substitution = text; 			l.sort_ligatures ();-			-			if (cl != null) {-				((!) cl).sort ();-			} 		}); 		 		listener.signal_submit.connect (() => {diff --git a/libbirdfont/OpenFontFormat/LigatureSet.vala b/libbirdfont/OpenFontFormat/LigatureSet.valaindex 3a24a6e..a836367 100644--- a/libbirdfont/OpenFontFormat/LigatureSet.vala+++ b/libbirdfont/OpenFontFormat/LigatureSet.vala@@ -22,10 +22,10 @@ public class LigatureSet : GLib.Object { 		glyf_table = gt; 	} 	-	public  void add (Ligature lig) {+	public void add (Ligature lig) { 		ligatures.add (lig); 	}-	+ 	public bool starts_with (string s) { 		if (ligatures.size == 0) { 			return false;@@ -78,7 +78,8 @@ public class LigatureSet : GLib.Object { 		 		return fd; 	}-	++	/** Add ligature to fd */ 	void add_ligature (FontData fd, Ligature ligature) throws GLib.Error { 		string[] parts = ligature.substitution.split (" "); 		bool first = true;diff --git a/libbirdfont/OpenFontFormat/LigatureSetList.vala b/libbirdfont/OpenFontFormat/LigatureSetList.valaindex 742218d..ae4d757 100644--- a/libbirdfont/OpenFontFormat/LigatureSetList.vala+++ b/libbirdfont/OpenFontFormat/LigatureSetList.vala@@ -17,77 +17,83 @@ namespace BirdFont {  public class LigatureSetList : GLib.Object { -	public Gee.ArrayList<LigatureSet> liga_sets;+	public Gee.ArrayList<LigatureSet> ligature_sets;++	LigatureSet lig_set;+	LigatureSet last_set;  	public LigatureSetList.clig (GlyfTable glyf_table) {-		liga_sets = new Gee.ArrayList<LigatureSet> ();	-		add_clig_ligatures (glyf_table);-	}-	-	public LigatureSetList.context (GlyfTable glyf_table) {-		liga_sets = new Gee.ArrayList<LigatureSet> ();	-		add_contextual_ligatures (glyf_table);-	}-	-	void add_contextual_ligatures (GlyfTable glyf_table) {-		LigatureSet lig_set;-		+		ligature_sets = new Gee.ArrayList<LigatureSet> ();	 		lig_set = new LigatureSet (glyf_table);-		lig_set.add (new Ligature ("ralt", "r"));+		last_set = new LigatureSet (glyf_table); 		-		liga_sets.add (lig_set);+		add_clig_ligatures (glyf_table); 	}-	-	// create ligature list-	void add_clig_ligatures (GlyfTable glyf_table) {-		Font font;-		Ligatures ligatures;-		LigatureSet lig_set;-		LigatureSet last_set;-				-		font = BirdFont.get_current_font ();-		ligatures = font.get_ligatures ();	 +	public LigatureSetList.contextual (GlyfTable glyf_table, ContextualLigatureSet ligatures) {+		ligature_sets = new Gee.ArrayList<LigatureSet> ();	 		lig_set = new LigatureSet (glyf_table); 		last_set = new LigatureSet (glyf_table);-		ligatures.get_ligatures ((s, lig) => {-			string[] parts = s.split (" ");-			string l = lig; -			if (l.has_prefix ("U+") || l.has_prefix ("u+")) {-				l = (!) Font.to_unichar (l).to_string ();-			}-							-			if (!font.has_glyph (l)) {-				warning (@"Ligature $l does not correspond to a glyph in this font.");-				return;-			}+		add_contextual_ligatures (glyf_table, ligatures);+	}++	void add_clig_ligatures (GlyfTable glyf_table) {+		Font font = BirdFont.get_current_font ();+		Ligatures ligatures = font.get_ligatures ();	+		+		ligatures.get_ligatures ((parts, ligature) => {+			add_ligatures (glyf_table, parts, ligature);+		});	+	}++	void add_contextual_ligatures (GlyfTable glyf_table, ContextualLigatureSet ligatures) {+		foreach (ContextualLigature c in ligatures.ligature_context) {+			add_ligatures (glyf_table, "r", c.ligatures); // FIXME: parts = ""+		}+	}+	+	// FIXME: what if parts equals "" ? Which set does ligatures becomes a part of?+	public void add_ligatures (GlyfTable glyf_table, string characters, string ligatures) +		requires (!is_null (lig_set) && !is_null (last_set)) { 			-			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 (@"Ligature substitution of $p is not possible, the character does have a glyph.");-					return;-				}+		Font font = BirdFont.get_current_font ();+		string[] parts = characters.split (" ");+		string l = ligatures;++		if (l.has_prefix ("U+") || l.has_prefix ("u+")) {+			l = (!) Font.to_unichar (l).to_string ();+		}+						+		if (!font.has_glyph (l)) {+			warning (@"Ligature $l does not correspond to a glyph in this font.");+			return;+		}+		+		foreach (string p in parts) {		+			if (p.has_prefix ("U+") || p.has_prefix ("u+")) {+				p = (!) Font.to_unichar (p).to_string (); 			} 			-			if (parts.length == 0) {-				warning ("No parts.");+			if (!font.has_glyph (p)) {+				warning (@"Ligature substitution of $p is not possible, the character does have a glyph."); 				return; 			}-			-			if (last_set.starts_with (parts[0])) {-				last_set.add (new Ligature (l, s));-			} else {-				lig_set = new LigatureSet (glyf_table);-				lig_set.add (new Ligature (l, s));-				liga_sets.add (lig_set);-				last_set = lig_set;-			}-		});	+		}+		+		if (parts.length == 0) {+			warning ("No parts.");+			return;+		}+		+		if (last_set.starts_with (parts[0])) {+			last_set.add (new Ligature (l, characters));+		} else {+			lig_set = new LigatureSet (glyf_table);+			lig_set.add (new Ligature (l, characters));+			ligature_sets.add (lig_set);+			last_set = lig_set;+		}		 	} } 

Contact

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