Clone in a terminal:
Commit d641444
Johan Mattsson - 2015-09-27T19:48:47+00:00
d64144422991645142a57f94381bfb9f72eaaaddjohan.mattsson.m@gmail.com

GUI for selecting OTF feature tags

Changed files (10)

Diff

diff --git a/libbirdfont/AlternateSets.vala b/libbirdfont/AlternateSets.valanew file mode 100644index 0000000..519f6d4--- /dev/null+++ b/libbirdfont/AlternateSets.vala@@ -0,0 +1,56 @@+/*+    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 BirdFont {++public class AlternateSets : GLib.Object {+	+	public Gee.ArrayList<Alternate> alternates;+	+	public AlternateSets () {+		alternates = new Gee.ArrayList<Alternate> ();+	}+	+	public Gee.ArrayList<string> get_all_tags () {+		Gee.ArrayList<string> tags;+		tags = new Gee.ArrayList<string> ();+		+		foreach (Alternate a in alternates) {+			if (tags.index_of (a.tag) == -1) {+				tags.add (a.tag);+			}+		}+		+		return tags;+	}++	public Gee.ArrayList<Alternate> get_alt (string tag) {	+		Gee.ArrayList<Alternate> alt;+		alt = new Gee.ArrayList<Alternate> ();+		+		foreach (Alternate a in alternates) {+			if (a.tag == tag) {+				alt.add (a);+			}+		}+		+		return alt;+	}+	+	public void add (Alternate alternate) {+		alternates.add (alternate);+	}+}++}diff --git a/libbirdfont/BirdFontFile.vala b/libbirdfont/BirdFontFile.valaindex c20d878..454f71c 100644--- a/libbirdfont/BirdFontFile.vala+++ b/libbirdfont/BirdFontFile.vala@@ -191,13 +191,15 @@ class BirdFontFile : GLib.Object { 	}  	public void write_alternates (DataOutputStream os) throws GLib.Error {-		foreach (Alternate alternate in font.alternates) {+		foreach (Alternate alternate in font.alternates.alternates) { 			string character = @"$(Font.to_hex (alternate.character))";+			string tag = alternate.tag; 			 			foreach (string alt in alternate.alternates) { 				os.put_string (@"<alternate "); 				os.put_string (@"character=\"$character\" ");-				os.put_string (@"alternate=\"$alt\" />\n");+				os.put_string (@"alternate=\"$alt\" ");+				os.put_string (@"tag=\"$(tag)\" />\n"); 			} 		} 	}@@ -832,6 +834,7 @@ class BirdFontFile : GLib.Object { 	public void parse_alternate (Tag tag) { 		unichar character = '\0'; 		string alt = "";+		string alt_tag = ""; 		 		foreach (Attribute attribute in tag.get_attributes ()) { 			if (attribute.get_name () == "character") {@@ -841,9 +844,13 @@ class BirdFontFile : GLib.Object { 			if (attribute.get_name () == "alternate") { 				alt = unserialize (attribute.get_content ()); 			}++			if (attribute.get_name () == "tag") {+				alt_tag = attribute.get_content ();+			} 		} 		-		font.add_alternate (character, alt);+		font.add_alternate (character, alt, alt_tag); 	} 	 	public void parse_format (Tag tag) {diff --git a/libbirdfont/ExportTool.vala b/libbirdfont/ExportTool.valaindex d43a0bd..3567183 100644--- a/libbirdfont/ExportTool.vala+++ b/libbirdfont/ExportTool.vala@@ -371,15 +371,13 @@ os.put_string ( </div>  <div>-	<h3 class="big">Optional Features</h3>+	<h3 class="big"></h3> 	<p class="big">-		<span class="swashes">Like swashes</span>-		<span class="alternates">alternates &</span>-		<span class="smallcaps">small caps</span> can be been added+		OTF 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. 	</p>-	-</p> </div>  <div>diff --git a/libbirdfont/Font.vala b/libbirdfont/Font.valaindex b18c874..6b2d414 100644--- a/libbirdfont/Font.vala+++ b/libbirdfont/Font.vala@@ -36,7 +36,7 @@ public class Font : GLib.Object { 	public GlyphTable ligature; 	 	/** List of alternate glyphs. */-	public Gee.ArrayList<Alternate> alternates;+	public AlternateSets alternates; 	 	public Gee.ArrayList<BackgroundImage> background_images; 	public string background_scale = "1";@@ -179,15 +179,17 @@ public class Font : GLib.Object { 		settings = new FontSettings (); 		kerning_strings = new KerningStrings (); 		-		alternates = new Gee.ArrayList<Alternate> ();+		alternates = new AlternateSets (); 	}  	~Font () { 		font_deleted (); 	} -	public Alternate? get_alternate (unichar character) {-		foreach (Alternate a in alternates) {+	public Alternate? get_alternate (unichar character, string tag) {+		Gee.ArrayList<Alternate> alt = alternates.get_alt (tag);+		+		foreach (Alternate a in alt) { 			if (a.character == character) { 				return a; 			}@@ -197,12 +199,13 @@ public class Font : GLib.Object { 	}  	public void add_new_alternate (GlyphCollection glyph,-		GlyphCollection alternate) {+		GlyphCollection alternate, string tag) {+ 		Alternate  a;-		Alternate? alt = get_alternate (glyph.get_unicode_character ());+		Alternate? alt = get_alternate (glyph.get_unicode_character (), tag); 		 		if (alt == null) {-			a = new Alternate (glyph.get_unicode_character ());+			a = new Alternate (glyph.get_unicode_character (), tag); 			alternates.add (a); 		} else { 			a = (!) alt;@@ -213,12 +216,14 @@ public class Font : GLib.Object { 		glyph_cache.insert (alternate.get_name (), alternate); 	} -	public void add_alternate (unichar character, string alternate) {+	public void add_alternate (unichar character, string alternate, +		string tag) {+			 		Alternate  a;-		Alternate? alt = get_alternate (character);+		Alternate? alt = get_alternate (character, tag); 		 		if (alt == null) {-			a = new Alternate (character);+			a = new Alternate (character, tag); 			alternates.add (a); 		} else { 			a = (!) alt;@@ -586,7 +591,7 @@ public class Font : GLib.Object { 		glyph_name.remove (glyph.get_name ()); 		ligature.remove (glyph.get_current ().get_name ()); 		-		foreach (Alternate a in alternates) {+		foreach (Alternate a in alternates.alternates) { 			a.remove (glyph); 		} 		diff --git a/libbirdfont/OpenFontFormat/Alternate.vala b/libbirdfont/OpenFontFormat/Alternate.valaindex 2da2af4..5d2fd94 100644--- a/libbirdfont/OpenFontFormat/Alternate.vala+++ b/libbirdfont/OpenFontFormat/Alternate.vala@@ -18,10 +18,12 @@ public class Alternate : GLib.Object { 	 	public unichar character; 	public Gee.ArrayList<string> alternates;+	public string tag; 	-	public Alternate (unichar character) {+	public Alternate (unichar character, string tag) { 		this.character = character; 		this.alternates = new Gee.ArrayList<string> ();+		this.tag = tag; 	}  	public void add (string glyph_name) {diff --git a/libbirdfont/OpenFontFormat/AlternateFeature.vala b/libbirdfont/OpenFontFormat/AlternateFeature.valaindex f69f2f4..d023195 100644--- a/libbirdfont/OpenFontFormat/AlternateFeature.vala+++ b/libbirdfont/OpenFontFormat/AlternateFeature.vala@@ -16,49 +16,56 @@ namespace BirdFont {  public class AlternateFeature : GLib.Object { 	GlyfTable glyf_table;+	Gee.ArrayList<Alternate> alternates;+	string tag; 	-	public AlternateFeature (GlyfTable glyf_table) {	+	public AlternateFeature (GlyfTable glyf_table, string tag) {+		Font font = OpenFontFormatWriter.get_current_font ();+		+		this.tag = tag; 		this.glyf_table = glyf_table;+		alternates = font.alternates.get_alt (tag);++		alternates.sort ((a, b) => {+			Alternate alt1 = (Alternate) a;+			Alternate alt2 = (Alternate) b;+			return strcmp ((!) alt1.character.to_string (), (!) alt2.character.to_string ());+		}); 	} 	 	public bool has_alternates () {-		Font font = OpenFontFormatWriter.get_current_font ();-		return font.alternates.size > 0;+		return alternates.size > 0; 	} 	 	public Lookups get_lookups () throws GLib.Error { 		Lookups lookups = new Lookups ();-		Lookup lookup = new Lookup (3, 0, Lookups.ALTERNATES);+		Lookup lookup = new Lookup (3, 0, tag); 		FontData fd = new FontData ();-		Font font = OpenFontFormatWriter.get_current_font ();-		-		font.alternates.sort ((a, b) => {-			Alternate alt1 = (Alternate) a;-			Alternate alt2 = (Alternate) b;-			return strcmp ((!) alt1.character.to_string (), (!) alt2.character.to_string ());-		});-		+ 		fd.add_ushort (1); // format identifier 		 		// offset to coverage 		int coverage_offset = 6;-		coverage_offset += 2 * font.alternates.size;+		coverage_offset += 2 * alternates.size; 		coverage_offset += 2 + 2 * get_number_of_alternates ();  		fd.add_ushort ((uint16) coverage_offset); 		 		// number of alternate sets-		fd.add_ushort ((uint16) font.alternates.size); +		fd.add_ushort ((uint16) alternates.size);  		-		int offset = 6 + 2 * font.alternates.size;-		for (int i = 0; i < font.alternates.size; i++) {+		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 			fd.add_ushort ((uint16) offset); 			offset += 2;-			offset += 2 * font.alternates.get (i).alternates.size;+			offset += 2 * alternates.get (i).alternates.size; 		} 		 		// alternates-		foreach (Alternate alternate in font.alternates) {+		foreach (Alternate alternate in alternates) {+			print (@"alternate.alternates.size: $(alternate.alternates.size)\n"); 			fd.add_ushort ((uint16) alternate.alternates.size); 			 			foreach (string alt in alternate.alternates) {@@ -68,8 +75,8 @@ public class AlternateFeature : GLib.Object {  		// coverage   		fd.add_ushort (1); // format-		fd.add_ushort ((uint16) font.alternates.size); // coverage array length-		foreach (Alternate alternate in font.alternates) {+		fd.add_ushort ((uint16) alternates.size); // coverage array length+		foreach (Alternate alternate in alternates) { 			string glyph_name = (!) alternate.character.to_string (); 			fd.add_ushort ((uint16) glyf_table.get_gid (glyph_name)); 		}@@ -82,9 +89,8 @@ public class AlternateFeature : GLib.Object { 	 	int get_number_of_alternates () { 		int n = 0;-		Font font = OpenFontFormatWriter.get_current_font (); 		-		foreach (Alternate alternate in font.alternates) {+		foreach (Alternate alternate in alternates) { 			n += alternate.alternates.size; 		} 		diff --git a/libbirdfont/OpenFontFormat/GsubTable.vala b/libbirdfont/OpenFontFormat/GsubTable.valaindex c7d2c6a..a139b2c 100644--- a/libbirdfont/OpenFontFormat/GsubTable.vala+++ b/libbirdfont/OpenFontFormat/GsubTable.vala@@ -32,17 +32,17 @@ public class GsubTable : OtfTable { 		 		fd = new FontData (); 		CligFeature clig_feature = new CligFeature (glyf_table);-		AlternateFeature alternate_feature = new AlternateFeature (glyf_table);+		AlternateFeature salt = new AlternateFeature (glyf_table, "salt");  		Lookups lookups = new Lookups (); 		FeatureList features = new FeatureList (); -		if (alternate_feature.has_alternates ()) {			-			Lookups aalt_lookup = alternate_feature.get_lookups ();-			Feature aalt_feature_lookup = new Feature ("salt", lookups);-			aalt_feature_lookup.add_feature_lookup (Lookups.ALTERNATES);-			features.add (aalt_feature_lookup);	-			lookups.append (aalt_lookup);+		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 ()diff --git a/libbirdfont/OtfFeatureTable.vala b/libbirdfont/OtfFeatureTable.valanew file mode 100644index 0000000..a66c82f--- /dev/null+++ b/libbirdfont/OtfFeatureTable.vala@@ -0,0 +1,129 @@+/*+    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 Cairo;++namespace BirdFont {++/** A table for managing feature tags in Open Type tables. */+public class OtfFeatureTable : Table {+	Gee.ArrayList<Row> rows = new Gee.ArrayList<Row> ();+	+	static const int NONE = 0;+	static const int OTF_FEATURE = 1;+	+	GlyphCollection glyph_collection;+	string alternate_name = "";+	TextListener listener;+	+	public OtfFeatureTable (GlyphCollection gc) {+		glyph_collection = gc;+	}++	public override Gee.ArrayList<Row> get_rows () {+		return rows;+	}++	public override void selected_row (Row row, int column, bool delete_button) {+		if (row.get_index () == OTF_FEATURE) {+			String s = (String) row.get_row_data ();+			add_new_alternate (s.data);+		}+	}++	public override void update_rows () {+		Row row;++		rows.clear ();++		row = new Row.headline (t_("OTF Features"));+		rows.add (row);+		+		row = new Row.columns_1 (t_("Glyph") + ": " + glyph_collection.get_name (), NONE, false);+		rows.add (row);+					+		// FIXME: reuse parts of this for fractions etc.+	+		row = new Row.headline (t_("Tag"));+		rows.add (row);+		+		row = new Row.columns_1 (t_("Stylistic Alternate") + " (salt)", OTF_FEATURE, false);+		row.set_row_data (new String ("salt"));+		rows.add (row);++		row = new Row.columns_1 (t_("Small Caps") + " (smcp)", OTF_FEATURE, false);+		row.set_row_data (new String ("smcp"));+		rows.add (row);++		row = new Row.columns_1 (t_("Capitals to Small Caps") + " (c2sc)", OTF_FEATURE, false);+		row.set_row_data (new String ("c2sc"));+		rows.add (row);++		row = new Row.columns_1 (t_("Swashes") + " (swsh)", OTF_FEATURE, false);+		row.set_row_data (new String ("swsh"));+		rows.add (row);+				+		GlyphCanvas.redraw ();+	}++	public override string get_label () {+		return t_("OTF Feature Tags");+	}++	public override string get_name () {+		return "OTF Feature Tags";+	}++	public override void draw (WidgetAllocation allocation, Context cr) {+		base.draw (allocation, cr);+	}	++	public void add_new_alternate (string tag) {+		GlyphCollection gc = glyph_collection;+		+		listener = new TextListener (t_("Glyph name"), "", t_("Add"));+		+		listener.signal_text_input.connect ((text) => {+			alternate_name = text;+		});+		+		listener.signal_submit.connect (() => {+			GlyphCollection alt;+			Font font;+			OverView overview = MainWindow.get_overview ();+			+			font = BirdFont.get_current_font ();+			+			if (alternate_name == "" || gc.is_unassigned ()) {+				MainWindow.tabs.close_display (this);+				return;+			}+			+			if (font.glyph_name.has_key (alternate_name)) {+				MainWindow.show_message (t_("All glyphs must have unique names."));+			} else {+				alt = new GlyphCollection.with_glyph ('\0', alternate_name);+				alt.set_unassigned (true);+				font.add_new_alternate (gc, alt, tag);+				MainWindow.tabs.close_display (this);+				MainWindow.get_overview ().update_item_list ();+				overview.open_glyph_signal (alt);+			}+		});+		+		TabContent.show_text_input (listener);+	}+}++}diff --git a/libbirdfont/OverviewTools.vala b/libbirdfont/OverviewTools.valaindex c58ea20..1d47d54 100644--- a/libbirdfont/OverviewTools.vala+++ b/libbirdfont/OverviewTools.vala@@ -32,8 +32,6 @@ public class OverviewTools : ToolCollection  { 	public static SpinButton skew; 	public static SpinButton resize; 	-	private string alternate_name = "";-	 	public OverviewTools () { 		Expander font_name = new Expander (); 		Expander character_sets = new Expander (t_("Character Sets"));@@ -142,47 +140,18 @@ public class OverviewTools : ToolCollection  { 	} 	 	public void add_new_alternate (Tool tool) {-		TextListener listener; 		OverView o = MainWindow.get_overview (); 		OverViewItem oi = o.selected_item; 		GlyphCollection gc; 		-		if (oi.glyphs == null) {+		tool.set_selected (false);+		+		if (oi.glyphs == null || ((!) oi.glyphs).is_unassigned ()) { 			return; 		} 		-		gc = (!) oi.glyphs;-		-		listener = new TextListener (t_("Alternate"), "", t_("Add"));-		-		listener.signal_text_input.connect ((text) => {-			alternate_name = text;-		});-		-		listener.signal_submit.connect (() => {-			GlyphCollection alt;-			Font font;-			OverView overview = MainWindow.get_overview ();-			-			font = BirdFont.get_current_font ();-			-			if (alternate_name == "" || gc.is_unassigned ()) {-				return;-			}-			-			if (font.glyph_name.has_key (alternate_name)) {-				MainWindow.show_message (t_("All glyphs must have unique names."));-			} else {-				alt = new GlyphCollection.with_glyph ('\0', alternate_name);-				alt.set_unassigned (true);-				font.add_new_alternate (gc, alt);-				MainWindow.get_overview ().update_item_list ();-				overview.open_glyph_signal (alt);-			}-		});-		-		tool.set_selected (false);-		TabContent.show_text_input (listener);+		gc = (!) oi.glyphs;		+		MainWindow.tabs.add_tab (new OtfFeatureTable (gc)); 	} 	 	public void process_transform () {diff --git a/libbirdfont/String.vala b/libbirdfont/String.valanew file mode 100644index 0000000..66e1cf6--- /dev/null+++ b/libbirdfont/String.vala@@ -0,0 +1,26 @@+/*+    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 BirdFont {++/** Boxed string class. */+public class String : GLib.Object {+	public string data;+	+	public String (string data) {+		this.data = data;+	}+}++}

Contact

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