The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Generate swsh, salt, smcp and c2sc tables.

These changes was commited to the Birdfont repository Sun, 27 Sep 2015 22:59:38 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
[Sun, 27 Sep 2015 22:59:38 +0000]

Updated Files

libbirdfont/AlternateSets.vala
libbirdfont/ExportTool.vala
libbirdfont/OpenFontFormat/Alternate.vala
libbirdfont/OpenFontFormat/AlternateFeature.vala
libbirdfont/OpenFontFormat/CligFeature.vala
libbirdfont/OpenFontFormat/Feature.vala
libbirdfont/OpenFontFormat/FeatureList.vala
libbirdfont/OpenFontFormat/GsubTable.vala
libbirdfont/OpenFontFormat/Lookup.vala
libbirdfont/OpenFontFormat/Lookups.vala
libbirdfont/OverView.vala
libbirdfont/OverviewTools.vala
--- a/libbirdfont/AlternateSets.vala +++ b/libbirdfont/AlternateSets.vala @@ -40,7 +40,7 @@ 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); } } @@ -50,8 +50,16 @@ 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; } } }
--- a/libbirdfont/ExportTool.vala +++ b/libbirdfont/ExportTool.vala @@ -351,6 +351,14 @@ -ms-font-feature-settings: "smcp"; -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 @@ <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>
--- a/libbirdfont/OpenFontFormat/Alternate.vala +++ b/libbirdfont/OpenFontFormat/Alternate.vala @@ -44,7 +44,16 @@ } } + public Alternate copy () { + Alternate n = new Alternate (character, tag); + + foreach (string s in alternates) { + n.add (s); + } + + return n; + } } }
--- a/libbirdfont/OpenFontFormat/AlternateFeature.vala +++ b/libbirdfont/OpenFontFormat/AlternateFeature.vala @@ -47,13 +47,16 @@ // 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++) { @@ -65,13 +68,22 @@ // 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 @@ -85,18 +97,8 @@ lookups.add_lookup (lookup); return lookups; - } - - int get_number_of_alternates () { - int n = 0; - - foreach (Alternate alternate in alternates) { - n += alternate.alternates.size; - } - - return n; } } }
--- a/libbirdfont/OpenFontFormat/CligFeature.vala +++ b/libbirdfont/OpenFontFormat/CligFeature.vala @@ -59,14 +59,14 @@ 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); }
--- a/libbirdfont/OpenFontFormat/Feature.vala +++ b/libbirdfont/OpenFontFormat/Feature.vala @@ -18,16 +18,14 @@ 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); }
--- a/libbirdfont/OpenFontFormat/FeatureList.vala +++ b/libbirdfont/OpenFontFormat/FeatureList.vala @@ -27,15 +27,28 @@ 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 @@ // 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)); }
--- a/libbirdfont/OpenFontFormat/GsubTable.vala +++ b/libbirdfont/OpenFontFormat/GsubTable.vala @@ -32,19 +32,10 @@ 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 @@ 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 @@ 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,7 +110,21 @@ 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); + } + } + } }
--- a/libbirdfont/OpenFontFormat/Lookup.vala +++ b/libbirdfont/OpenFontFormat/Lookup.vala @@ -19,9 +19,15 @@ 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> ();
--- a/libbirdfont/OpenFontFormat/Lookups.vala +++ b/libbirdfont/OpenFontFormat/Lookups.vala @@ -20,11 +20,6 @@ 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 @@ } /** 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) {
--- a/libbirdfont/OverView.vala +++ b/libbirdfont/OverView.vala @@ -918,6 +918,8 @@ public void delete_selected_glyph () { 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 @@ } } + 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 @@ font.add_glyph_collection (g); } + font.alternates = previous_collection.alternate_sets.copy (); + redo_items.remove_at (redo_items.size - 1); GlyphCanvas.redraw (); } @@ -981,6 +988,8 @@ GlyphCollection? gc; 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 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 void paste () { - GlyphCollection gc = new GlyphCollection ('\0', ""); + GlyphCollection gc; GlyphCollection? c; Glyph glyph; uint32 index; @@ -1422,9 +1433,13 @@ 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 () @@ -1480,6 +1495,7 @@ } undo_item = new OverViewUndoItem (); + undo_item.alternate_sets = f.alternates.copy (); foreach (GlyphCollection g in glyps) { undo_item.glyphs.add (g.copy ()); } @@ -1515,9 +1531,10 @@ } public class OverViewUndoItem { + public AlternateSets alternate_sets = new AlternateSets (); public Gee.ArrayList<GlyphCollection> glyphs = new Gee.ArrayList<GlyphCollection> (); } } }
--- a/libbirdfont/OverviewTools.vala +++ b/libbirdfont/OverviewTools.vala @@ -161,6 +161,9 @@ 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) {