Clone in a terminal:
Commit bd66d9b
Johan Mattsson - 2015-09-27T22:59:38+00:00
bd66d9b55d01a161bb623c7739de886981507245johan.mattsson.m@gmail.com

Generate swsh, salt, smcp and c2sc tables. This commit adds support for swashes, stylistic alternatives, small caps and conversion from uppercase to small caps

Changed files (12)

Diff

diff --git a/libbirdfont/AlternateSets.vala b/libbirdfont/AlternateSets.valaindex 519f6d4..b95e968 100644--- a/libbirdfont/AlternateSets.vala+++ b/libbirdfont/AlternateSets.vala@@ -40,7 +40,7 @@ public class AlternateSets : GLib.Object { 		alt = new Gee.ArrayList<Alternate> (); 		 		foreach (Alternate a in alternates) {-			if (a.tag == tag) {+			if (a.tag == tag && a.alternates.size > 0) { 				alt.add (a); 			} 		}@@ -51,6 +51,14 @@ public class AlternateSets : GLib.Object { 	public void add (Alternate alternate) { 		alternates.add (alternate); 	}+	+	public AlternateSets copy () {+		AlternateSets n = new AlternateSets ();+		foreach (Alternate a in alternates) {+			n.alternates.add (a.copy ());+		}+		return n;+	} }  }diff --git a/libbirdfont/ExportTool.vala b/libbirdfont/ExportTool.valaindex 3567183..27262c3 100644--- a/libbirdfont/ExportTool.vala+++ b/libbirdfont/ExportTool.vala@@ -352,6 +352,14 @@ os.put_string ( 			-webkit-font-feature-settings: "smcp"; 			font-feature-settings: "smcp"; 		}++		span.capstosmallcaps {+			font-variant-caps: all-small-caps;+			-moz-font-feature-settings: "c2sc", "smcp";+			-ms-font-feature-settings: "c2sc", "smcp";+			-webkit-font-feature-settings: "c2sc", "smcp";+			font-feature-settings: "c2sc", "smcp";+		} 	</style> """); 	@@ -373,10 +381,11 @@ os.put_string ( <div> 	<h3 class="big"></h3> 	<p class="big">-		OTF features, <span class="swashes">like swashes </span>+		<span class="capstosmallcaps">OTF</span> features, +		<span class="swashes">like swashes </span> 		<span class="alternates">alternates & </span> 		<span class="smallcaps">small caps</span>, can be been added-		to the font.+		to the font.</span> 	</p> </div> diff --git a/libbirdfont/OpenFontFormat/Alternate.vala b/libbirdfont/OpenFontFormat/Alternate.valaindex 5d2fd94..d42d09c 100644--- a/libbirdfont/OpenFontFormat/Alternate.vala+++ b/libbirdfont/OpenFontFormat/Alternate.vala@@ -44,6 +44,15 @@ public class Alternate : GLib.Object { 		} 	} 	+	public Alternate copy () {+		Alternate n = new Alternate (character, tag);++		foreach (string s in alternates) {+			n.add (s);+		}+		+		return n;+	} }  }diff --git a/libbirdfont/OpenFontFormat/AlternateFeature.vala b/libbirdfont/OpenFontFormat/AlternateFeature.valaindex d023195..062a25b 100644--- a/libbirdfont/OpenFontFormat/AlternateFeature.vala+++ b/libbirdfont/OpenFontFormat/AlternateFeature.vala@@ -47,14 +47,17 @@ public class AlternateFeature : GLib.Object { 		// offset to coverage 		int coverage_offset = 6; 		coverage_offset += 2 * alternates.size;-		coverage_offset += 2 + 2 * get_number_of_alternates (); +		+		foreach (Alternate a in alternates) {+			coverage_offset += 2;+			coverage_offset += 2 * a.alternates.size;+		}+		 		fd.add_ushort ((uint16) coverage_offset); 		 		// number of alternate sets 		fd.add_ushort ((uint16) alternates.size);  		-		print (@"alternates.size: $(alternates.size)\n");-		 		int offset = 6 + 2 * alternates.size; 		for (int i = 0; i < alternates.size; i++) { 			// offset to each alternate set@@ -65,14 +68,23 @@ public class AlternateFeature : GLib.Object { 		 		// alternates 		foreach (Alternate alternate in alternates) {-			print (@"alternate.alternates.size: $(alternate.alternates.size)\n"); 			fd.add_ushort ((uint16) alternate.alternates.size); 			+			alternate.alternates.sort ((a, b) => {+				string alt1 = (string) a;+				string alt2 = (string) b;+				return strcmp (alt1, alt2);+			});+			 			foreach (string alt in alternate.alternates) { 				fd.add_ushort ((uint16) glyf_table.get_gid (alt)); 			} 		}		 +		if (fd.length_with_padding () != coverage_offset) {+			warning (@"Bad coverage offset. $(fd.length_with_padding ()) != $coverage_offset");+		}+ 		// coverage   		fd.add_ushort (1); // format 		fd.add_ushort ((uint16) alternates.size); // coverage array length@@ -86,16 +98,6 @@ public class AlternateFeature : GLib.Object { 		 		return lookups; 	}-	-	int get_number_of_alternates () {-		int n = 0;-		-		foreach (Alternate alternate in alternates) {-			n += alternate.alternates.size;-		}-		-		return n;-	} }  }diff --git a/libbirdfont/OpenFontFormat/CligFeature.vala b/libbirdfont/OpenFontFormat/CligFeature.valaindex 0f77c75..488054d 100644--- a/libbirdfont/OpenFontFormat/CligFeature.vala+++ b/libbirdfont/OpenFontFormat/CligFeature.vala@@ -59,14 +59,14 @@ public class CligFeature : GLib.Object { 				lookups.add_lookup(lookup); 			} -			lookup = new Lookup (6, 0, Lookups.CHAINED_CONTEXT);+			lookup = new Lookup (6, 0, "chained"); 			foreach (FontData d in chain_data) { 				lookup.add_subtable (d); 			} 			lookups.add_lookup(lookup);			 		} -		lookup = new Lookup (4, 0, Lookups.LIGATURES);+		lookup = new Lookup (4, 0, "ligatures"); 		lookup.add_subtable (clig_subtable); 		lookups.add_lookup(lookup); 	}diff --git a/libbirdfont/OpenFontFormat/Feature.vala b/libbirdfont/OpenFontFormat/Feature.valaindex a9b7b37..77bea60 100644--- a/libbirdfont/OpenFontFormat/Feature.vala+++ b/libbirdfont/OpenFontFormat/Feature.vala@@ -18,16 +18,14 @@ public class Feature : GLib.Object { 	 	public string tag; 	public Lookups lookups;-	public Gee.ArrayList<int> public_lookups = new Gee.ArrayList<int> ();-	-	public int lookup_offset = 0; // FIXME:DELETE+	public Gee.ArrayList<string> public_lookups = new Gee.ArrayList<string> (); 	 	public Feature (string tag, Lookups lookups) { 		this.tag = tag; 		this.lookups = lookups; 	} 	-	public void add_feature_lookup (int lookup_token) {+	public void add_feature_lookup (string lookup_token) { 		public_lookups.add (lookup_token); 	} 	diff --git a/libbirdfont/OpenFontFormat/FeatureList.vala b/libbirdfont/OpenFontFormat/FeatureList.valaindex d40a523..76f88eb 100644--- a/libbirdfont/OpenFontFormat/FeatureList.vala+++ b/libbirdfont/OpenFontFormat/FeatureList.vala@@ -28,14 +28,27 @@ public class FeatureList : GLib.Object { 	public FontData generate_feature_tags () throws GLib.Error { 		FontData fd = new FontData (); +		features.sort ((fa, fb) => {+			Feature a = (Feature) fa;+			Feature b = (Feature) fb;+			return strcmp (a.tag, b.tag);+		});+ 		fd.add_ushort ((uint16) features.size); // number of features 		 		uint offset = 2 + 6 * features.size; 		foreach (Feature feature in features) {-			fd.add_tag (feature.tag); // feature tag: aalt, clig etc.-			fd.add_ushort ((uint16) offset); // offset to feature+			// feature tag: aalt, clig etc.+			fd.add_tag (feature.tag); +			+			// offset to feature from beginning of this table+			fd.add_ushort ((uint16) offset);  			 			offset += 4 + 2 * feature.get_public_lookups ();+			+			if (feature.get_public_lookups () == 0) {+				warning (@"No lookups for $(feature.tag)");+			} 		}  		foreach (Feature feature in features) {@@ -45,7 +58,7 @@ public class FeatureList : GLib.Object { 			// number of lookups 			fd.add_ushort ((uint16) feature.public_lookups.size);  			-			foreach (int p in feature.public_lookups) {+			foreach (string p in feature.public_lookups) { 				// reference to a lookup table (lookup index) 				fd.add_ushort (feature.lookups.find (p)); 			}diff --git a/libbirdfont/OpenFontFormat/GsubTable.vala b/libbirdfont/OpenFontFormat/GsubTable.valaindex a139b2c..29cbe56 100644--- a/libbirdfont/OpenFontFormat/GsubTable.vala+++ b/libbirdfont/OpenFontFormat/GsubTable.vala@@ -32,19 +32,10 @@ public class GsubTable : OtfTable { 		 		fd = new FontData (); 		CligFeature clig_feature = new CligFeature (glyf_table);-		AlternateFeature salt = new AlternateFeature (glyf_table, "salt");  		Lookups lookups = new Lookups (); 		FeatureList features = new FeatureList (); -		if (salt.has_alternates ()) {			-			Lookups salt_lookup = salt.get_lookups ();-			Feature salt_feature_lookup = new Feature ("salt", lookups);-			salt_feature_lookup.add_feature_lookup ("salt");-			features.add (salt_feature_lookup);	-			lookups.append (salt_lookup);-		}-	 		bool has_clig = clig_feature.contextual.has_ligatures () 			|| clig_feature.has_regular_ligatures (); 			@@ -53,24 +44,30 @@ public class GsubTable : OtfTable { 			Feature clig_feature_lookup = new Feature ("clig", lookups); 			 			if (clig_feature.contextual.has_ligatures ()) {-				clig_feature_lookup.add_feature_lookup (Lookups.CHAINED_CONTEXT);+				clig_feature_lookup.add_feature_lookup ("chained"); 			} 				 			if (clig_feature.has_regular_ligatures ()) {-				clig_feature_lookup.add_feature_lookup (Lookups.LIGATURES);+				clig_feature_lookup.add_feature_lookup ("ligatures"); 			} 			 			features.add (clig_feature_lookup); 			lookups.append (clig_lookups); 		}-+		+		add_alternate_table (features, lookups, "swsh");+		add_alternate_table (features, lookups, "salt");+		add_alternate_table (features, lookups, "c2sc");+		add_alternate_table (features, lookups, "smcp");+	 		FontData feature_tags = features.generate_feature_tags (); -		uint lookup_list_offset = 30 + feature_tags.length_with_padding ();+		uint feature_list_offset = 28 + 2 * features.features.size;+		uint lookup_list_offset = feature_list_offset + feature_tags.length_with_padding (); 		 		fd.add_ulong (0x00010000); // table version 		fd.add_ushort (10); // offset to script list-		fd.add_ushort (30); // offset to feature list+		fd.add_ushort ((uint16) feature_list_offset); // offset to feature list 		fd.add_ushort ((uint16) lookup_list_offset); // offset to lookup list 		 		// script list@@ -86,7 +83,11 @@ public class GsubTable : OtfTable { 		fd.add_ushort (0); // reserved 		fd.add_ushort (0xFFFF); // required features (0xFFFF is none) 		fd.add_ushort ((uint16) features.features.size); // number of features-		fd.add_ushort (0); // feature index++		// FIXME: double check this+		for (int i = 0; i < features.features.size; i++) {+			fd.add_ushort ((uint16) i); // feature index+		}  		// feature lookups with references to the lookup list 		fd.append (feature_tags);@@ -109,6 +110,20 @@ public class GsubTable : OtfTable { 		 		this.font_data = fd; 	}++	/** Add alterate substitutions to lookups and features. */+	public void add_alternate_table (FeatureList features, Lookups lookups, string tag) +	throws GLib.Error {+		AlternateFeature alt = new AlternateFeature (glyf_table, tag);+		if (alt.has_alternates ()) {			+			Lookups alt_lookup = alt.get_lookups ();+			Feature alt_feature_lookup = new Feature (tag, lookups);+			alt_feature_lookup.add_feature_lookup (tag);+			features.add (alt_feature_lookup);	+			lookups.append (alt_lookup);+		}+	}+ }  }diff --git a/libbirdfont/OpenFontFormat/Lookup.vala b/libbirdfont/OpenFontFormat/Lookup.valaindex 978931b..4f85763 100644--- a/libbirdfont/OpenFontFormat/Lookup.vala+++ b/libbirdfont/OpenFontFormat/Lookup.vala@@ -19,9 +19,15 @@ public class Lookup : GLib.Object { 	public uint16 type; 	public uint16 flags; 	public Gee.ArrayList<FontData> subtables;-	public int token;+	public string token; 	-	public Lookup (uint16 type, uint16 flags, int token = Lookups.NONE) {+	// the token is used for obtaining index in lookup list, an empty+	// string ensures that the subtable can't be directly used by+	// a table, chaining context use that feature.+	//+	// Lookups.find is used to obtain index in the lookup list for+	// a token.+	public Lookup (uint16 type, uint16 flags, string token = "") { 		this.type = type; 		this.flags = flags; 		subtables = new Gee.ArrayList<FontData> ();diff --git a/libbirdfont/OpenFontFormat/Lookups.vala b/libbirdfont/OpenFontFormat/Lookups.valaindex 2b6c827..fecd921 100644--- a/libbirdfont/OpenFontFormat/Lookups.vala+++ b/libbirdfont/OpenFontFormat/Lookups.vala@@ -20,11 +20,6 @@ namespace BirdFont {  public class Lookups : GLib.Object { 	public Gee.ArrayList<Lookup> tables = new Gee.ArrayList<Lookup> ();--	public static const int NONE = 0;-	public static const int CHAINED_CONTEXT = 1;-	public static const int LIGATURES = 2;-	public static const int ALTERNATES = 2; 	 	public Lookups () {	 	}@@ -38,7 +33,7 @@ public class Lookups : GLib.Object { 	}  	/** Find the lookup index for a particular lookup. */-	public uint16 find (int token) {+	public uint16 find (string token) { 		uint16 index = 0; 		foreach (Lookup lookup in tables) { 			if (lookup.token == token) {diff --git a/libbirdfont/OverView.vala b/libbirdfont/OverView.valaindex 1c58ea3..77f8bfc 100644--- a/libbirdfont/OverView.vala+++ b/libbirdfont/OverView.vala@@ -919,6 +919,8 @@ public class OverView : FontDisplay { 		Font font = BirdFont.get_current_font (); 		OverViewUndoItem undo_item = new OverViewUndoItem (); 		+		undo_item.alternate_sets = font.alternates.copy ();+		 		foreach (GlyphCollection g in selected_items) { 			undo_item.glyphs.add (g.copy ()); 		}@@ -952,6 +954,9 @@ public class OverView : FontDisplay { 			} 		} 		+		Font f = BirdFont.get_current_font ();+		f.alternates = previous_collection.alternate_sets.copy ();+ 		undo_items.remove_at (undo_items.size - 1); 		GlyphCanvas.redraw (); 	}@@ -973,6 +978,8 @@ public class OverView : FontDisplay { 			font.add_glyph_collection (g); 		} 		+		font.alternates = previous_collection.alternate_sets.copy ();+ 		redo_items.remove_at (redo_items.size - 1); 		GlyphCanvas.redraw (); 	}	@@ -982,6 +989,8 @@ public class OverView : FontDisplay { 		OverViewUndoItem ui = new OverViewUndoItem (); 		Font font = BirdFont.get_current_font (); 		+		ui.alternate_sets = font.alternates.copy ();+		 		foreach (GlyphCollection g in previous_collection.glyphs) { 			gc = font.get_glyph_collection (g.get_name ()); 			@@ -997,6 +1006,8 @@ public class OverView : FontDisplay { 	 	public void store_undo_state (GlyphCollection gc) { 		OverViewUndoItem i = new OverViewUndoItem ();+		Font f = BirdFont.get_current_font ();+		i.alternate_sets = f.alternates.copy (); 		i.glyphs.add (gc); 		store_undo_items (i); 	}@@ -1414,7 +1425,7 @@ public class OverView : FontDisplay { 	} 	 	public void paste () {-		GlyphCollection gc = new GlyphCollection ('\0', "");+		GlyphCollection gc; 		GlyphCollection? c; 		Glyph glyph; 		uint32 index;@@ -1422,10 +1433,14 @@ public class OverView : FontDisplay { 		int skip = 0; 		int s; 		string character_string;-		Gee.ArrayList<GlyphCollection> glyps = new Gee.ArrayList<GlyphCollection> ();-		Font f = BirdFont.get_current_font ();+		Gee.ArrayList<GlyphCollection> glyps;+		Font f; 		OverViewUndoItem undo_item; 		+		f = BirdFont.get_current_font ();+		gc = new GlyphCollection ('\0', "");+		glyps = new Gee.ArrayList<GlyphCollection> ();+		 		copied_glyphs.sort ((a, b) => { 			return (int) ((GlyphCollection) a).get_unicode_character ()  				- (int) ((GlyphCollection) b).get_unicode_character ();@@ -1480,6 +1495,7 @@ public class OverView : FontDisplay { 		}  		undo_item = new OverViewUndoItem ();+		undo_item.alternate_sets = f.alternates.copy (); 		foreach (GlyphCollection g in glyps) { 			undo_item.glyphs.add (g.copy ()); 		}@@ -1515,6 +1531,7 @@ public class OverView : FontDisplay { 	} 	 	public class OverViewUndoItem {+		public AlternateSets alternate_sets = new AlternateSets (); 		public Gee.ArrayList<GlyphCollection> glyphs = new Gee.ArrayList<GlyphCollection> (); 	} }diff --git a/libbirdfont/OverviewTools.vala b/libbirdfont/OverviewTools.valaindex 1d47d54..ab5ef0e 100644--- a/libbirdfont/OverviewTools.vala+++ b/libbirdfont/OverviewTools.vala@@ -162,6 +162,9 @@ public class OverviewTools : ToolCollection  { 		o = get_overview (); 		ui = new OverView.OverViewUndoItem (); 		+		Font f = BirdFont.get_current_font ();+		ui.alternate_sets = f.alternates.copy ();+		 		foreach (GlyphCollection gc in o.selected_items) { 			if (gc.length () > 0) { 				g = gc.get_current ();

Contact

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