The Birdfont Source Code


All Repositories / birdfont.git / commit – RSS feed

GUI for selecting OTF feature tags

These changes was commited to the Birdfont repository Sun, 27 Sep 2015 19:40:30 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
author Johan Mattsson <johan.mattsson.m@gmail.com>
Sun, 27 Sep 2015 19:40:30 +0000 (21:40 +0200)
committer Johan Mattsson <johan.mattsson.m@gmail.com>
Sun, 27 Sep 2015 19:48:47 +0000 (21:48 +0200)
commit d64144422991645142a57f94381bfb9f72eaaadd
tree fca075524367f8bec7a75bebdf8b9b25d0151200
parent c50124cb6534cc967cee3557956d30ed6be2ae36
GUI for selecting OTF feature tags

libbirdfont/AlternateSets.vala [new ]
libbirdfont/BirdFontFile.vala
libbirdfont/ExportTool.vala
libbirdfont/Font.vala
libbirdfont/OpenFontFormat/Alternate.vala
libbirdfont/OpenFontFormat/AlternateFeature.vala
libbirdfont/OpenFontFormat/GsubTable.vala
libbirdfont/OtfFeatureTable.vala [new ]
libbirdfont/OverviewTools.vala
libbirdfont/String.vala [new ]
--- /dev/null +++ b/libbirdfont/AlternateSets.vala @@ -1,1 +1,57 @@ + /* + 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); + } + } + + }
--- a/libbirdfont/BirdFontFile.vala +++ b/libbirdfont/BirdFontFile.vala @@ -191,13 +191,15 @@ } 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 @@ 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") { @@ -840,10 +843,14 @@ 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) {
--- a/libbirdfont/ExportTool.vala +++ b/libbirdfont/ExportTool.vala @@ -371,15 +371,13 @@ </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>
--- a/libbirdfont/Font.vala +++ b/libbirdfont/Font.vala @@ -36,7 +36,7 @@ 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 @@ 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 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 @@ 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 @@ 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); }
--- a/libbirdfont/OpenFontFormat/Alternate.vala +++ b/libbirdfont/OpenFontFormat/Alternate.vala @@ -18,10 +18,12 @@ 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) {
--- a/libbirdfont/OpenFontFormat/AlternateFeature.vala +++ b/libbirdfont/OpenFontFormat/AlternateFeature.vala @@ -16,49 +16,56 @@ 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 @@ // 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 @@ 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; }
--- a/libbirdfont/OpenFontFormat/GsubTable.vala +++ b/libbirdfont/OpenFontFormat/GsubTable.vala @@ -32,17 +32,17 @@ 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 ()
--- /dev/null +++ b/libbirdfont/OtfFeatureTable.vala @@ -1,1 +1,130 @@ + /* + 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); + } + } + + }
--- a/libbirdfont/OverviewTools.vala +++ b/libbirdfont/OverviewTools.vala @@ -31,8 +31,6 @@ public static SpinButton skew; public static SpinButton resize; - - private string alternate_name = ""; public OverviewTools () { Expander font_name = new Expander (); @@ -142,47 +140,18 @@ } 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 libbirdfont/String.vala(new)
--- /dev/null +++ b/libbirdfont/String.vala @@ -1,1 +1,27 @@ + /* + 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; + } + } + + }