The Birdfont Source Code


All Repositories / birdfont.git / commit – 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
author Johan Mattsson <johan.mattsson.m@gmail.com>
Sat, 26 Sep 2015 19:27:30 +0000 (21:27 +0200)
committer Johan Mattsson <johan.mattsson.m@gmail.com>
Sat, 26 Sep 2015 19:28:33 +0000 (21:28 +0200)
commit 23055787570f005b9729ae1c34df30235a17edfa
tree f59d92f08ba48551ab44fa4e0727095023b57c00
parent 08ce1c3a19143277131a219a876ead89ec7cd691
Restructure lookups in gsub table
This commit does also change the order of subtables in the gsub table.
1. Chained substitutions
2. Context for chained substitutions
3. Regular ligatures

libbirdfont/OpenFontFormat/AlternateFeature.vala [new ]
libbirdfont/OpenFontFormat/CligFeature.vala [new ]
libbirdfont/OpenFontFormat/ContextualLigature.vala
libbirdfont/OpenFontFormat/FontData.vala
libbirdfont/OpenFontFormat/GsubTable.vala
libbirdfont/OpenFontFormat/Lookup.vala [new ]
libbirdfont/OpenFontFormat/Lookups.vala [new ]
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