Commit 2430dc5
Fix OTF lookups
Changed files (5)
modifiedlibbirdfont/OpenFontFormat/FeatureList.valamodifiedlibbirdfont/OpenFontFormat/FontData.valamodifiedlibbirdfont/OpenFontFormat/GsubTable.valamodifiedlibbirdfont/OpenFontFormat/Lookup.valamodifiedlibbirdfont/OpenFontFormat/Lookups.vala
Diff
@@ -37,7 +37,7 @@ public class FeatureList : GLib.Object { fd.add_ushort ((uint16) features.size); // number of features uint offset = 2 + 6 * features.size;- foreach (Feature feature in features) {+ foreach (Feature feature in features) { // feature tag: aalt, clig etc. fd.add_tag (feature.tag); @@ -46,7 +46,11 @@ public class FontData : Object { public int get_read_pos () { return (int) rp; }- ++ public int get_write_pos () {+ return (int) wp;+ }+ public void write_at (uint pos, uint8 new_data) throws GLib.Error requires (pos <= capacity) { @@ -96,15 +96,9 @@ public class GsubTable : OtfTable { warning (@"Bad offset to lookup list: $(lookup_list_offset) != $(fd.length_with_padding ())"); } - // lookup list- fd.append (lookups.generate_lookup_list ()); -- // subtable data- foreach (Lookup lookup in lookups.tables) {- foreach (FontData subtable in lookup.subtables) {- fd.append (subtable);- }- }+ // lookup list and the table data+ FontData lookup_list = lookups.generate_lookup_list ();+ fd.append (lookup_list); fd.pad (); @@ -21,6 +21,9 @@ public class Lookup : GLib.Object { public Gee.ArrayList<FontData> subtables; public string token; + public uint subtable_offset = 0;+ public uint entry_offset = 0;+ // 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.@@ -32,6 +35,7 @@ public class Lookup : GLib.Object { this.flags = flags; subtables = new Gee.ArrayList<FontData> (); this.token = token;+ subtable_offset = 0; } public void add_subtable (FontData subtable) {@@ -39,11 +43,7 @@ public class Lookup : GLib.Object { } public uint get_lookup_entry_size () throws GLib.Error {- if (subtables.size == 0) {- warning ("No subtables.");- }- - return 6 + 2 * subtables.size;+ return get_lookup_entry (0).length_with_padding (); } public uint get_subtable_size () throws GLib.Error {@@ -65,7 +65,7 @@ public class Lookup : GLib.Object { return size; } - public FontData get_lookup_entry (uint lookup_offset) + public FontData get_lookup_entry (uint offset) throws GLib.Error { FontData fd = new FontData (); @@ -77,17 +77,16 @@ public class Lookup : GLib.Object { // array of offsets to subtable uint s;- foreach (FontData subtable in subtables) {- uint offset = lookup_offset;+ + foreach (FontData subtable in subtables) { fd.add_ushort ((uint16) offset); - subtable.offset = offset; s = subtable.length_with_padding (); if (s == 0) { warning ("Zero size in subtable."); } - lookup_offset += s;+ offset += 2 + s; } return fd;@@ -55,34 +55,39 @@ public class Lookups : GLib.Object { public FontData generate_lookup_list () throws GLib.Error { FontData fd = new FontData ();- uint lookup_offset;- uint tables_size;- uint entry_size;- uint total_entries_size; FontData entry; + uint lookup_offset; 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;+ lookup_offset += lookup.get_lookup_entry_size (); } - tables_size = 0;- uint offset = total_entries_size;-+ // add empty lookups and step back when tables are written foreach (Lookup lookup in tables) {- entry = lookup.get_lookup_entry (offset);- offset -= lookup.get_lookup_entry_size ();- offset += lookup.get_subtable_size ();+ entry = lookup.get_lookup_entry (0);+ lookup.entry_offset = fd.length_with_padding (); fd.append (entry); }++ if (lookup_offset != fd.length_with_padding ()) {+ warning ("Wrong lookup offset."); + warning (@"$lookup_offset != $(fd.length_with_padding ())");+ }++ foreach (Lookup lookup in tables) {+ uint offset_pos = lookup.entry_offset + 6;+ fd.seek (offset_pos);+ fd.add_ushort ((uint16) (fd.length_with_padding () - (lookup.entry_offset)));+ fd.seek_end ();+ + foreach (FontData subtable in lookup.subtables) {+ fd.append (subtable);+ }+ } return fd; }