The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Restructure lookups in gsub table

These changes was commited to the Birdfont repository Sat, 26 Sep 2015 19:27: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
[Sat, 26 Sep 2015 19:27:30 +0000]

Updated Files

libbirdfont/OpenFontFormat/AlternateFeature.vala
libbirdfont/OpenFontFormat/CligFeature.vala
libbirdfont/OpenFontFormat/ContextualLigature.vala
libbirdfont/OpenFontFormat/FontData.vala
libbirdfont/OpenFontFormat/GsubTable.vala
libbirdfont/OpenFontFormat/Lookup.vala
libbirdfont/OpenFontFormat/Lookups.vala
libbirdfont/OpenFontFormat/OtfTable.vala
--- /dev/null +++ b/libbirdfont/OpenFontFormat/AlternateFeature.vala @@ -1,1 +1,30 @@ + /* + 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 AlternateFeature : GLib.Object { + FontData font_data = new FontData (); + + public AlternateFeature () { + } + + public FontData get_font_data () { + return font_data; + } + } + + }
--- /dev/null +++ b/libbirdfont/OpenFontFormat/CligFeature.vala @@ -1,1 +1,86 @@ + /* + 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 CligFeature : GLib.Object { + public LigatureCollection clig; + public ContextualLigatureCollection contextual; + Lookups lookups; + GlyfTable glyf_table; + + public CligFeature (GlyfTable glyf_table) throws GLib.Error { + this.glyf_table = glyf_table; + generate_feature (); + } + + public Lookups get_lookups () { + return lookups; + } + + private void generate_feature () throws GLib.Error { + Gee.ArrayList<FontData> chain_data; + FontData clig_subtable; + FontData fd; + Lookup lookup; + + fd = new FontData (); + clig = new LigatureCollection.clig (glyf_table); + contextual = new ContextualLigatureCollection (glyf_table); + + clig_subtable = clig.get_font_data (glyf_table); + clig_subtable.pad (); + + chain_data = get_chaining_contextual_substition_subtable (contextual); + + // lookup table + lookups = new Lookups (); + + if (contextual.has_ligatures ()) { + foreach (LigatureCollection s in contextual.ligatures) { + lookup = new Lookup (4, 0); + lookup.add_subtable (s.get_font_data (glyf_table)); + lookups.add_lookup(lookup); + } + + lookup = new Lookup (6, 0); + foreach (FontData d in chain_data) { + lookup.add_subtable (d); + } + lookups.add_lookup(lookup); + } + + lookup = new Lookup (4, 0); + lookup.add_subtable (clig_subtable); + lookups.add_lookup(lookup); + } + + // chaining contextual substitution format3 + Gee.ArrayList<FontData> get_chaining_contextual_substition_subtable (ContextualLigatureCollection contexts) throws GLib.Error { + Gee.ArrayList<FontData> fd = new Gee.ArrayList<FontData> (); + uint16 ligature_lookup_index = 0; + + foreach (ContextualLigature context in contexts.ligature_context) { + fd.add (context.get_font_data (glyf_table, ligature_lookup_index)); + ligature_lookup_index++; + } + + return fd; + } + } + + } +
--- a/libbirdfont/OpenFontFormat/ContextualLigature.vala +++ b/libbirdfont/OpenFontFormat/ContextualLigature.vala @@ -51,8 +51,6 @@ Gee.ArrayList<string> backtrack = font.get_names (backtrack); Gee.ArrayList<string> input = font.get_names (input); Gee.ArrayList<string> lookahead = font.get_names (lookahead); - - // FIXME: add ligatures uint16 lookahead_offset, input_offset, backtrack_offset;
--- a/libbirdfont/OpenFontFormat/FontData.vala +++ b/libbirdfont/OpenFontFormat/FontData.vala @@ -28,6 +28,8 @@ uint32 capacity; public uint8* table_data = null; + + public uint offset = 0; // for debugging public FontData (uint32 size = 1024) { capacity = size;
--- a/libbirdfont/OpenFontFormat/GsubTable.vala +++ b/libbirdfont/OpenFontFormat/GsubTable.vala @@ -29,28 +29,18 @@ public void process () throws GLib.Error { FontData fd; - FontData clig_subtable; - uint16 length; - - LigatureCollection clig; - ContextualLigatureCollection contextual; - - uint16 feature_lookups; - uint16 lookups_end; - - Gee.ArrayList<FontData> chain_data; fd = new FontData (); - clig = new LigatureCollection.clig (glyf_table); - contextual = new ContextualLigatureCollection (glyf_table); + CligFeature clig_feature = new CligFeature (glyf_table); + AlternateFeature alternate_feature = new AlternateFeature (); 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 (contextual.has_ligatures () ? 46 : 44); // offset to lookup list + fd.add_ushort (clig_feature.contextual.has_ligatures () ? 46 : 44); // offset to lookup list // script list - fd.add_ushort (1); // number of items in script list + fd.add_ushort (1); // number of items in script list fd.add_tag ("DFLT"); // default script fd.add_ushort (8); // offset to script table from script list @@ -71,109 +61,30 @@ fd.add_ushort (8); // offset to feature // FIXME: Should it be liga and clig? - clig = new LigatureCollection.clig (glyf_table); - contextual = new ContextualLigatureCollection (glyf_table); - - feature_lookups = contextual.has_ligatures () ? 2 : 1; + Lookups lookups = new Lookups (); + lookups.append (clig_feature.get_lookups ()); + + // FIXME: refactor clig_feature + uint16 feature_lookups = clig_feature.contextual.has_ligatures () ? 2 : 1; fd.add_ushort (0); // feature prameters (null) fd.add_ushort (feature_lookups); // number of lookups - if (contextual.has_ligatures ()) { - fd.add_ushort (1 + contextual.get_size ()); // 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 + if (clig_feature.contextual.has_ligatures ()) { + fd.add_ushort ((uint16) lookups.tables.size - 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 ((uint16) lookups.tables.size - 1); // lookup clig_subtable } else { fd.add_ushort (0); // lookup clig_subtable } - clig_subtable = clig.get_font_data (glyf_table); - chain_data = get_chaining_contextual_substition_subtable (contextual); - - // lookup table - uint16 lookups; - - if (contextual.has_ligatures ()) { - lookups = 2 + (uint16) contextual.get_size (); - } else { - lookups = 1; - } - - fd.add_ushort (lookups); // number of lookups - - if (contextual.has_ligatures ()) { - uint16 offset_to_lookup; + // lookup list - offset_to_lookup = 6 + 2 * contextual.get_size (); - fd.add_ushort (offset_to_lookup); // offset to lookup 1, regular ligatures - - for (int i = 0; i < contextual.get_size (); i++) { - offset_to_lookup += 8; - // offset to ligature lookups used in chaining substitution - fd.add_ushort (offset_to_lookup); - } - - // offset to lookup for the chain table - offset_to_lookup += 8; - fd.add_ushort (offset_to_lookup); - } else { - fd.add_ushort (4); // offset to lookup 1 - } + fd.append (lookups.genrate_lookup_list ()); - lookups_end = 8; // regular ligatures - - if (contextual.has_ligatures ()) { - lookups_end += 8 * contextual.get_size (); // contextual ligatures - lookups_end += 6; // chaining table - lookups_end += 2 * (uint16) contextual.get_size (); // chaining subtables - } - - length = 0; - fd.add_ushort (4); // 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) clig_subtable.length_with_padding (); - lookups_end -= 8; - - if (contextual.has_ligatures ()) { - - for (int i = 0; i < contextual.ligatures.size; i++) { - fd.add_ushort (4); // lookup type - fd.add_ushort (0); // lookup flags - fd.add_ushort (1); // number of subtables - - LigatureCollection ligature_set = contextual.ligatures.get (i); - fd.add_ushort (lookups_end + length); // array of offsets to subtable - length += (uint16) ligature_set.get_font_data (glyf_table).length_with_padding (); - - lookups_end -= 8; - } - - fd.add_ushort (6); // lookup type - fd.add_ushort (0); // lookup flags - fd.add_ushort (contextual.get_size ()); // number of subtables - - foreach (FontData d in chain_data) { - fd.add_ushort (lookups_end + length); // array of offsets to subtable - length += (uint16) d.length_with_padding (); - } - - lookups_end -= 6 + 2 * chain_data.size; - } - - if (lookups_end != 0) { - warning (@"Wrong offset to end of lookups, $lookups_end bytes left."); - } - - fd.append (clig_subtable); - - if (contextual.has_ligatures ()) { - foreach (LigatureCollection s in contextual.ligatures) { - fd.append (s.get_font_data (glyf_table)); - } - - foreach (FontData d in chain_data) { - fd.append (d); + // subtables + foreach (Lookup lookup in lookups.tables) { + foreach (FontData subtable in lookup.subtables) { + fd.append (subtable); } } @@ -181,20 +92,8 @@ this.font_data = fd; } + } - // chaining contextual substitution format3 - Gee.ArrayList<FontData> get_chaining_contextual_substition_subtable (ContextualLigatureCollection contexts) throws GLib.Error { - Gee.ArrayList<FontData> fd = new Gee.ArrayList<FontData> (); - uint16 ligature_lookup_index = 1; - - foreach (ContextualLigature context in contexts.ligature_context) { - fd.add (context.get_font_data (glyf_table, ligature_lookup_index)); - ligature_lookup_index++; - } - - return fd; - } } - }
--- /dev/null +++ b/libbirdfont/OpenFontFormat/Lookup.vala @@ -1,1 +1,82 @@ + /* + 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. + */ + + /** Representation of one lookup in gsub and gpos tables. */ + public class Lookup : GLib.Object { + public uint16 type; + public uint16 flags; + public Gee.ArrayList<FontData> subtables; + + public Lookup (uint16 type, uint16 flags) { + this.type = type; + this.flags = flags; + subtables = new Gee.ArrayList<FontData> (); + } + + public void add_subtable (FontData subtable) { + subtables.add (subtable); + } + + public uint get_lookup_entry_size () throws GLib.Error { + return 6 + 2 * subtables.size; + } + + public uint get_subtable_size () throws GLib.Error { + uint size = 0; + uint s; + + foreach (FontData subtable in subtables) { + s = subtable.length_with_padding (); + + if (s == 0) { + warning ("Zero size in subtable."); + } + + size += s; + } + + warn_if_fail (size != 0); + + return size; + } + + public FontData get_lookup_entry (uint lookup_offset) + throws GLib.Error { + FontData fd = new FontData (); + + return_val_if_fail (subtables.size > 0, fd); + + fd.add_ushort (type); // lookup type + fd.add_ushort (flags); // lookup flags + fd.add_ushort ((uint16) subtables.size); // number of subtables + + // array of offsets to subtable + uint s; + foreach (FontData subtable in subtables) { + uint offset = lookup_offset; + fd.add_ushort ((uint16) offset); + subtable.offset = offset; + s = subtable.length_with_padding (); + + if (s == 0) { + warning ("Zero size in subtable."); + } + + lookup_offset += s; + } + + return fd; + } + }
--- /dev/null +++ b/libbirdfont/OpenFontFormat/Lookups.vala @@ -1,1 +1,77 @@ + /* + 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 { + + // Contextual substitutions uses this table for chained substitutions, + // the order is not arbitrary. + + public class Lookups : GLib.Object { + public Gee.ArrayList<Lookup> tables = new Gee.ArrayList<Lookup> (); + + public Lookups () { + } + + /** Subtables added in the proirity order for the substitution or + * spacing transformation. The first table will have highest + * priority. + */ + public void add_lookup (Lookup lookup) { + tables.add (lookup); + } + + public void append (Lookups lookups) { + foreach (Lookup lookup in lookups.tables) { + tables.add (lookup); + } + } + + public FontData genrate_lookup_list () throws GLib.Error { + FontData fd = new FontData (); + uint lookup_offset; + uint tables_size; + uint entry_size; + uint total_entries_size; + FontData entry; + + fd.add_ushort ((uint16) tables.size); // number of lookups + lookup_offset = 2 + 2 * tables.size; + total_entries_size = 0; + + foreach (Lookup lookup in tables) { + fd.add_ushort ((uint16) lookup_offset); + entry_size = lookup.get_lookup_entry_size (); + return_val_if_fail (lookup.subtables.size != 0, fd); + return_val_if_fail (entry_size == 6 + 2 * lookup.subtables.size, fd); + lookup_offset += entry_size; + total_entries_size += entry_size; + } + + tables_size = 0; + uint offset = total_entries_size; + + foreach (Lookup lookup in tables) { + entry = lookup.get_lookup_entry (offset); + offset -= lookup.get_lookup_entry_size (); + offset += lookup.get_subtable_size (); + fd.append (entry); + } + + return fd; + } + } + + }
--- a/libbirdfont/OpenFontFormat/OtfTable.vala +++ b/libbirdfont/OpenFontFormat/OtfTable.vala @@ -1,4 +1,3 @@ - /* Copyright (C) 2012, 2013 Johan Mattsson