The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

GsubTable.vala in libbirdfont/OpenFontFormat

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libbirdfont/OpenFontFormat/GsubTable.vala.
Merge branch 'master' of https://github.com/johanmattssonm/birdfont into HEAD
1 /* 2 Copyright (C) 2012, 2013, 2014 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 using Math; 15 16 namespace BirdFont { 17 18 public class GsubTable : OtfTable { 19 20 GlyfTable glyf_table; 21 22 public GsubTable (GlyfTable glyf_table) { 23 this.glyf_table = glyf_table; 24 id = "GSUB"; 25 } 26 27 public override void parse (FontData dis) throws GLib.Error { 28 } 29 30 public void process () throws GLib.Error { 31 FontData fd = new FontData (); 32 FontData clig_subtable; 33 FontData chained_context; 34 FontData chained_ligatures; 35 uint16 length; 36 37 LigatureSetList clig; 38 LigatureSetList contextual; 39 40 fd.add_ulong (0x00010000); // table version 41 fd.add_ushort (10); // offset to script list 42 fd.add_ushort (30); // offset to feature list 43 fd.add_ushort (46); // offset to lookup list 44 45 // script list 46 fd.add_ushort (1); // number of items in script list 47 fd.add_tag ("DFLT"); // default script 48 fd.add_ushort (8); // offset to script table from script list 49 50 // script table 51 fd.add_ushort (4); // offset to default language system 52 fd.add_ushort (0); // number of languages 53 54 // LangSys table 55 fd.add_ushort (0); // reserved 56 fd.add_ushort (0); // required features (0xFFFF is none) 57 fd.add_ushort (1); // number of features 58 fd.add_ushort (0); // feature index 59 60 // feature table 61 fd.add_ushort (1); // number of features 62 63 fd.add_tag ("clig"); // feature tag 64 fd.add_ushort (8); // offset to feature 65 // FIXME: Should it be liga and clig? 66 67 fd.add_ushort (0); // feature prameters (null) 68 fd.add_ushort (2); // number of lookups 69 fd.add_ushort (1); // lookup chained_context 70 fd.add_ushort (0); // lookup clig_subtable 71 72 clig = new LigatureSetList.clig (glyf_table); 73 contextual = new LigatureSetList.context (glyf_table); 74 75 clig_subtable = get_ligature_subtable (clig); 76 // FIXME: put back contextual ligatures 77 //chained_context = get_chaining_contextual_substition_subtable (); 78 //chained_ligatures = get_ligature_subtable (contextual); 79 80 // lookup table 81 fd.add_ushort (1); // number of lookups FIXME: should be 3 82 fd.add_ushort (4); // offset to lookup 1 FIXME: should be 8 83 //fd.add_ushort (16); // offset to lookup 2 84 //fd.add_ushort (24); // offset to lookup 3 85 86 length = 0; 87 fd.add_ushort (4); // lookup type 88 fd.add_ushort (0); // lookup flags 89 fd.add_ushort (1); // number of subtables 90 fd.add_ushort (8 + length); // array of offsets to subtable FIXME: should be 24 91 length += (uint16) clig_subtable.length_with_padding (); 92 93 /* 94 fd.add_ushort (6); // lookup type 95 fd.add_ushort (0); // lookup flags 96 fd.add_ushort (1); // number of subtables 97 fd.add_ushort (16 + length); // array of offsets to subtable 98 length += (uint16) chained_context.length_with_padding (); 99 100 fd.add_ushort (4); // lookup type 101 fd.add_ushort (0); // lookup flags 102 fd.add_ushort (1); // number of subtables 103 fd.add_ushort (8 + length); // array of offsets to subtable 104 length += (uint16) chained_ligatures.length_with_padding (); 105 */ 106 fd.append (clig_subtable); 107 // fd.append (chained_context); 108 // fd.append (chained_ligatures); 109 110 fd.pad (); 111 112 this.font_data = fd; 113 } 114 115 FontData get_ligature_subtable (LigatureSetList liga_list) throws GLib.Error { 116 FontData set_data; 117 Gee.ArrayList<LigatureSet> liga_sets; 118 uint16 ligature_pos; 119 uint16 table_start; 120 FontData fd; 121 liga_sets = liga_list.liga_sets; 122 123 fd = new FontData (); 124 125 // ligature substitution subtable 126 table_start = (uint16) fd.length_with_padding (); 127 128 fd.add_ushort (1); // format identifier 129 fd.add_ushort (6 + (uint16) 2 * liga_sets.size); // offset to coverage 130 fd.add_ushort ((uint16) liga_sets.size); // number of ligature set tables 131 132 // array of offsets to ligature sets 133 uint16 size = 0; 134 foreach (LigatureSet l in liga_sets) { 135 ligature_pos = 10 + (uint16) liga_sets.size * 4 + size; 136 fd.add_ushort (ligature_pos); 137 size += (uint16) l.get_set_data ().length_with_padding (); 138 } 139 140 // coverage 141 fd.add_ushort (1); // format 142 fd.add_ushort ((uint16) liga_sets.size); 143 144 // coverage gid: 145 foreach (LigatureSet l in liga_sets) { 146 fd.add_ushort ((uint16) glyf_table.get_gid (l.get_coverage_char ())); 147 } 148 149 foreach (LigatureSet l in liga_sets) { 150 set_data = l.get_set_data (); 151 fd.append (set_data); 152 } 153 154 return fd; 155 } 156 157 // chaining contextual substitution format3 158 FontData get_chaining_contextual_substition_subtable () throws GLib.Error { 159 FontData fd = new FontData (); 160 161 fd.add_ushort (3); // format identifier 162 163 fd.add_ushort (1); // backtrack glyph count 164 // array of offsets to coverage table 165 fd.add_ushort (20); 166 167 fd.add_ushort (1); // input glyph count (middle) 168 // array of offsets to coverage table 169 fd.add_ushort (20 + 6); 170 171 fd.add_ushort (1); // lookahead glyph count 172 // array of offsets to coverage table 173 fd.add_ushort (20 + 2 * 6); 174 175 fd.add_ushort (1); // substitute count, (ligatures) 176 // substitution lookup records 177 fd.add_ushort (0); // glyph sequence index 178 fd.add_ushort (2); // go to the ligature substitution via lookup table 179 180 // backtrack coverage table1 181 fd.add_ushort (1); // format 182 fd.add_ushort (1); // coverage array length 183 184 // gid array 185 fd.add_ushort ((uint16) glyf_table.get_gid ("a")); 186 187 // input coverage table1 188 fd.add_ushort (1); // format 189 fd.add_ushort (1); // coverage array length 190 191 // gid array 192 fd.add_ushort ((uint16) glyf_table.get_gid ("r")); 193 194 // lookahead coverage table1 195 fd.add_ushort (1); // format 196 fd.add_ushort (1); // coverage array length 197 198 // gid array 199 fd.add_ushort ((uint16) glyf_table.get_gid ("t")); 200 201 return fd; 202 } 203 204 void parse_ligatures (FontData fd, int table_start) { 205 fd.seek (table_start); 206 207 uint16 identifier = fd.read_ushort (); 208 209 if (identifier != 1) { 210 warning (@"Bad identifier expecting 1 found $identifier"); 211 } 212 213 uint16 coverage_offset = fd.read_ushort (); // TODO: read coverage 214 uint16 num_sets = fd.read_ushort (); 215 216 Gee.ArrayList<int> liga_set_offsets = new Gee.ArrayList<int> (); 217 for (int i = 0; i < num_sets; i++) { 218 uint16 liga_set_offset = fd.read_ushort (); 219 liga_set_offsets.add (table_start + liga_set_offset); 220 } 221 222 foreach (int liga_set_pos in liga_set_offsets) { 223 fd.seek (liga_set_pos); 224 parse_ligature_set (fd); 225 } 226 } 227 228 /** Parse ligature set at the current position. */ 229 void parse_ligature_set (FontData fd) { 230 int liga_start = fd.get_read_pos (); 231 uint nliga = fd.read_ushort (); 232 Gee.ArrayList<int> offsets = new Gee.ArrayList<int> (); 233 234 for (uint i = 0; i < nliga; i++) { 235 int off = fd.read_ushort (); 236 offsets.add (off); 237 } 238 239 foreach (int off in offsets) { 240 fd.seek (liga_start); 241 fd.seek_relative (off); 242 uint16 lig = fd.read_ushort (); 243 uint16 nlig_comp = fd.read_ushort (); 244 245 for (int i = 1; i < nlig_comp; i++) { 246 uint16 lig_comp = fd.read_ushort (); 247 } 248 } 249 } 250 } 251 252 } 253