History

more logic for reading tables with rather peculiar dependencies

Sigrid Solveig Haflínudóttir committed 2 years ago

Commit f152a7f1 parent 0ce46015 files · +1188 −526Browse files

Unified · Split

5 files
  1. gen.rkt +97 −50
  2. otf.c +818 −349
  3. otf.h +171 −84
  4. otf.rkt +101 −42
  5. test.c +1 −1
gen.rkt+97−50
@@ -4,6 +4,7 @@ · 3 unmodified lines
44 (require (for-syntax racket/format))
55 (require (for-syntax syntax/parse))
66 (require (for-syntax racket/contract))
7+(require (for-syntax racket/string))
78
89 (require racket/contract)
910 (require racket/generic)
@@ -26,6 +27,10 @@ · 16 unmodified lines
2627 (-> string? boolean?)
2728 (string-prefix? s "typedef"))
2829
30+(define/contract (extra-context-ref? ref)
31+ (-> symbol? boolean?)
32+ (string-prefix? (symbol->string ref) "o->"))
33+
2934 (define/contract (format f)
3035 (-> procedure? string?)
3136 (define-values (a b) (partition c-typedef? (flatten (map f cmplxs))))
@@ -55,10 +60,12 @@ · 23 unmodified lines
5560 (if (= (length lst) 1) (list* stmt lst) (list (string-append stmt "{") lst "}")))
5661
5762 (define (wrap-cond-c cond lst)
63+ (define (fmt-ref ref)
64+ (if (extra-context-ref? ref) ref (~a "v->" ref)))
5865 (match cond
5966 [#f lst]
6067 [(list op ref n ...)
61− (block (~a "if(" (string-join (map (λ (n) (~a "v->" ref " " op " " n)) n) " || ") ")")
68+ (block (~a "if(" (string-join (map (λ (n) (~a (fmt-ref ref) " " op " " n)) n) " || ") ")")
6269 (indent lst))]))
6370
6471 (define (invert-c op)
@@ -98,11 +105,12 @@ · 33 unmodified lines
98105 [#f
99106 (if (or declared (not (field-unused? f)))
100107 (if index
101− (~a (if declared (~a (name (field-type f)) " ") "")
102− ref
103− " = "
104− ((type-parse (field-type f)) b index)
105− ";")
108+ (list (~a (if declared (~a (name (field-type f)) " ") "")
109+ ref
110+ " = "
111+ ((type-parse (field-type f)) b index)
112+ ";")
113+ (if (field-context? f) (~a "o->" (field-name f) " = " ref ";") empty))
106114 (list
107115 (if declared
108116 (~a (name (field-type f)) " " ref ";")
@@ -186,6 +194,9 @@ · 77 unmodified lines
186194 (define v (assoc 'cond (field-attrs f)))
187195 (and v (rest v)))
188196
197+(define (field-context? f)
198+ (field-attr f '->o))
199+
189200 (define/contract (field-count f)
190201 (-> field? (or/c false/c number? string?))
191202 (define (fmt-expr e)
@@ -193,7 +204,8 @@ · 1 unmodified line
193204 [(number? e) e]
194205 [(list? e)
195206 (match e
196− [(list op x y) (~a (fmt-expr x) op (fmt-expr y))])]
207+ [(list op x y) (~a "(" (fmt-expr x) op (fmt-expr y) ")")])]
208+ [(and (symbol? e) (extra-context-ref? e)) (~a e)]
197209 [(symbol? e) (~a "v->" e)]))
198210 (define e (field-attr f 'count))
199211 (and e (fmt-expr e)))
@@ -243,7 +255,7 @@ · 43 unmodified lines
243255 (~a (if is-ptr "\t" "")
244256 "print_"
245257 (cmplx-name t)
246− "(f, indent+indentΔ, "
258+ "(f, indent+indentΔ, o, "
247259 (if is-ptr "" "&")
248260 "v->"
249261 (field-name f)
@@ -254,23 +266,25 @@ · 4 unmodified lines
254266 (define (filter-extra extra key)
255267 (flatten (filter-map (λ (e) (and (eq? (car e) key) (cdr e))) extra)))
256268
257−(define-struct cmplx (name fields tag extra)
269+(define-struct cmplx (name fields tag extra after)
258270 #:transparent
259271 #:methods gen:code
260272 [(define/generic super-gen-h gen-h)
261273 (define/generic super-gen-c gen-c)
262274 (define (gen-h c)
263− (flatten
264− (append
265− (list (~a "typedef struct " (cmplx-name c) " " (cmplx-name c) ";")
266− (~a "")
267− (~a "struct " (cmplx-name c) " {"))
268− (indent (map super-gen-h (cmplx-fields c)))
269− (indent (filter-extra (cmplx-extra c) 'field))
270− (list (~a "};")
271− (~a "")
272− (~a "int read_" (cmplx-name c) "(Otf *o, " (cmplx-name c) " *v);")
273− (~a "void print_" (cmplx-name c) "(Biobuf *f, int indent, " (cmplx-name c) " *v);")))))
275+ (flatten (append (list (~a "typedef struct " (cmplx-name c) " " (cmplx-name c) ";")
276+ (~a "")
277+ (~a "struct " (cmplx-name c) " {"))
278+ (indent (map super-gen-h (cmplx-fields c)))
279+ (indent (filter-extra (cmplx-extra c) 'field))
280+ (list (~a "};")
281+ (~a "")
282+ (~a "int read_" (cmplx-name c) "(Otf *o, " (cmplx-name c) " *v);")
283+ (~a "void print_"
284+ (cmplx-name c)
285+ "(Biobuf *f, int indent, Otf *o, "
286+ (cmplx-name c)
287+ " *v);")))))
274288 (define (gen-c c b index)
275289 (define (no-vla? f)
276290 (define cnt (field-count f))
@@ -323,25 +337,27 @@ · 46 unmodified lines
323337 (parse-group fields)))])
324338 lst))))
325339 (flatten
326− (append (list (~a "")
327− (~a "int")
328− (~a "read_" (cmplx-name c) "(Otf *o, " (cmplx-name c) " *v)")
329− (~a "{")
330− (~a "\tu8int *b;"))
331− (indent (map gen-group-c (group-fields (cmplx-fields c))))
332− (indent (filter-extra (cmplx-extra c) 'read))
333− (list (~a "\treturn 0;")
334− (~a "err:")
335− (~a "\twerrstr(\"%s: %r\", \"" (cmplx-name c) "\");")
336− (~a "\treturn -1;")
337− (~a "}"))
338− (list (~a "")
339− (~a "void")
340− (~a "print_" (cmplx-name c) "(Biobuf *f, int indent, " (cmplx-name c) " *v)")
341− (~a "{")
342− (indent (map field-print-c (cmplx-fields c)))
343− (indent (filter-extra (cmplx-extra c) 'print))
344− (~a "}")))))
340+ (append
341+ (list (~a "")
342+ (~a "int")
343+ (~a "read_" (cmplx-name c) "(Otf *o, " (cmplx-name c) " *v)")
344+ (~a "{")
345+ (~a "\tu8int *b;"))
346+ (indent (map gen-group-c (group-fields (cmplx-fields c))))
347+ (indent (filter-extra (cmplx-extra c) 'read))
348+ (list (~a "\treturn 0;")
349+ (~a "err:")
350+ (~a "\twerrstr(\"%s: %r\", \"" (cmplx-name c) "\");")
351+ (~a "\treturn -1;")
352+ (~a "}"))
353+ (list (~a "")
354+ (~a "void")
355+ (~a "print_" (cmplx-name c) "(Biobuf *f, int indent, Otf *o, " (cmplx-name c) " *v)")
356+ (~a "{")
357+ (indent (map field-print-c (cmplx-fields c)))
358+ (indent (filter-extra (cmplx-extra c) 'print))
359+ (~a "\tUSED(o);")
360+ (~a "}")))))
345361 (define (c-type c)
346362 (cmplx-name c))])
347363
@@ -371,13 +387,22 @@ · 23 unmodified lines
371387
372388 (define-syntax (mkcmplx stx)
373389 (syntax-parse stx
374− [(_ typ:id fields:expr ...+ (~optional (~seq #:tag tag)) (~optional (~seq #:extra extra:expr)))
390+ [(_ typ:id
391+ fields:expr ...+
392+ (~optional (~seq #:tag tag))
393+ (~optional (~seq #:extra extra:expr))
394+ (~optional (~seq #:after after)))
375395 #:declare tag (expr/c #'tag/c #:name "table tag")
376396 (begin
377397 (set! typenames (cons (syntax-e #`typ) typenames))
378398 #'(begin
379399 (define tag- (~? (~@ tag.c) #f))
380− (define typ (make-cmplx `typ (mkfields [~@ fields] ...) tag- (~? (~@ extra) empty)))
400+ (define typ
401+ (make-cmplx `typ
402+ (mkfields [~@ fields] ...)
403+ tag-
404+ (~? (~@ extra) empty)
405+ (~? (~@ after) empty)))
381406 (set! cmplxs (append cmplxs (list typ)))
382407 (when tag-
383408 (set! tagged (append tagged (list typ))))))]))
@@ -395,6 +420,11 @@ · 11 unmodified lines
395420 (pattern op:id
396421 #:when (member (syntax-e #'op) '(+ - / *))))
397422
423+ (define-syntax-class oref
424+ #:description "extra context field reference"
425+ (pattern oref:id
426+ #:when (string-prefix? (symbol->string (syntax-e #'oref)) "o->")))
427+
398428 (define-syntax-class ref
399429 #:description "field reference"
400430 (pattern ref:id
@@ -402,26 +432,32 @@ · 1 unmodified line
402432 #:with type (cadr (assoc (syntax-e #'ref) fields))))
403433
404434 (syntax-parse stx
405− [(_ _ ({~literal at} ref:ref))
435+ [(_ type name {~literal ->o}) #''(->o #t)]
436+ [(_ _ _ ({~literal at} ref:ref))
406437 #:fail-when (not (type-offset? (syntax-e #'ref.type))) "can't be used as an offset"
407438 #''(at ref)]
408− [(_ type {~literal hex})
439+ [(_ type _ {~literal hex})
409440 #:fail-when (not (type-number? (syntax-e #'type))) "not a number type"
410441 #''(verb "%#ux")]
411− [(_ type (p:compop vs:number ...+))
442+ [(_ type _ (p:compop vs:number ...+))
412443 #:fail-when (not (type-comparable? (syntax-e #'type))) "type can't be used in a comparison"
413444 #''(test p vs ...)]
414− [(_ _ (p:compop ref:ref vs:number ...+))
445+ [(_ _ _ (p:compop oref:oref vs:number ...+))
446+ #''(cond
447+ p
448+ oref
449+ vs ...)]
450+ [(_ _ _ (p:compop ref:ref vs:number ...+))
415451 #''(cond
416452 p
417453 ref
418454 vs ...)]
419− [(_ _ {~literal unused}) #''(unused #t)]
420− [(_ _ (ref:ref))
455+ [(_ _ _ {~literal unused}) #''(unused #t)]
456+ [(_ _ _ (ref:ref))
421457 #:fail-when (not (type-index? (syntax-e #'ref.type))) "can't be used as index to an array"
422458 #''(count ref)]
423− [(_ _ (n:number)) #''(count n)]
424− [(_ _ (p:arithop e:expr ...+)) #''(count (p e ...))])) ; FIXME - check fields and ops/numbers
459+ [(_ _ _ (n:number)) #''(count n)]
460+ [(_ _ _ (p:arithop e:expr ...+)) #''(count (p e ...))])) ; FIXME - check fields and ops/numbers
425461
426462 (define-syntax (mkfield stx)
427463 (define-syntax-class name
@@ -440,7 +476,7 @@ · 12 unmodified lines
440476 (set! fields (cons (syntax->datum #'(name type)) fields))
441477 #'(field type
442478 `name
443− (list (mkattr type [~@ attrs]) ...)))]))
479+ (list (mkattr type `name [~@ attrs]) ...)))]))
444480
445481 (define-syntax (mkfields stx)
446482 (syntax-parse stx
@@ -485,6 +521,11 @@ void otfclose(Otf *o); · 38 unmodified lines
485521 EOF
486522 )))
487523
524+(define (extra-context-fields c)
525+ (if (cmplx? c)
526+ (filter-map (λ (f) (and (field-context? f) (indent (gen-h f)))) (cmplx-fields c))
527+ empty))
528+
488529 (out "otf.c"
489530 (λ ()
490531 (printf #<<EOF
@@ -502,6 +543,12 @@ struct Otf { · 11 unmodified lines
502543 u8int *buf;
503544 int bufsz;
504545 int off;
546+ /* extra fields to simplify parsing */
547+
548+EOF
549+ )
550+ (printf (format extra-context-fields))
551+ (printf #<<EOF
505552 };
506553
507554 struct Range {
otf.c+818−349
@@ -12,6 +12,12 @@ struct Otf { · 11 unmodified lines
1212 u8int *buf;
1313 int bufsz;
1414 int off;
15+ /* extra fields to simplify parsing */
16+ s16int indexToLocFormat;
17+ u16int numberOfHMetrics;
18+ u16int numGlyphs;
19+ u16int firstGlyphIndex;
20+ u16int lastGlyphIndex;
1521 };
1622
1723 struct Range {
@@ -179,12 +185,13 @@ err: · 161 unmodified lines
179185 }
180186
181187 void
182−print_SubHeader(Biobuf *f, int indent, SubHeader *v)
188+print_SubHeader(Biobuf *f, int indent, Otf *o, SubHeader *v)
183189 {
184190 Bprint(f, "%*s%s: %ud\n", indent, "", "firstCode", v->firstCode);
185191 Bprint(f, "%*s%s: %ud\n", indent, "", "entryCode", v->entryCode);
186192 Bprint(f, "%*s%s: %d\n", indent, "", "idDelta", v->idDelta);
187193 Bprint(f, "%*s%s: %ud\n", indent, "", "idRangeOffset", v->idRangeOffset);
194+ USED(o);
188195 }
189196
190197 int
@@ -203,11 +210,12 @@ err: · 12 unmodified lines
203210 }
204211
205212 void
206−print_MapGroup(Biobuf *f, int indent, MapGroup *v)
213+print_MapGroup(Biobuf *f, int indent, Otf *o, MapGroup *v)
207214 {
208215 Bprint(f, "%*s%s: %ud\n", indent, "", "startCharCode", v->startCharCode);
209216 Bprint(f, "%*s%s: %ud\n", indent, "", "endCharCode", v->endCharCode);
210217 Bprint(f, "%*s%s: %ud\n", indent, "", "startGlyphID", v->startGlyphID);
218+ USED(o);
211219 }
212220
213221 int
@@ -227,12 +235,13 @@ err: · 13 unmodified lines
227235 }
228236
229237 void
230−print_SubtableCmap0(Biobuf *f, int indent, SubtableCmap0 *v)
238+print_SubtableCmap0(Biobuf *f, int indent, Otf *o, SubtableCmap0 *v)
231239 {
232240 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
233241 Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
234242 for(int i = 0; i < 256; i++)
235243 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
244+ USED(o);
236245 }
237246
238247 int
@@ -252,12 +261,13 @@ err: · 13 unmodified lines
252261 }
253262
254263 void
255−print_SubtableCmap2(Biobuf *f, int indent, SubtableCmap2 *v)
264+print_SubtableCmap2(Biobuf *f, int indent, Otf *o, SubtableCmap2 *v)
256265 {
257266 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
258267 Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
259268 for(int i = 0; i < 256; i++)
260269 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "subHeaderKeys", i, v->subHeaderKeys[i]);
270+ USED(o);
261271 }
262272
263273 int
@@ -272,28 +282,28 @@ read_SubtableCmap4(Otf *o, SubtableCmap4 *v) · 8 unmodified lines
272282 v->searchRange = b[6]<<8 | b[7];
273283 v->entrySelector = b[8]<<8 | b[9];
274284 v->rangeShift = b[10]<<8 | b[11];
275− if((b = otfreadn(o, v->segCountX2/2*2)) == nil)
285+ if((b = otfreadn(o, (v->segCountX2/2)*2)) == nil)
276286 goto err;
277− v->endCode = malloc(v->segCountX2/2*sizeof(*v->endCode));
278− for(int i = 0; i < v->segCountX2/2; i++)
287+ v->endCode = malloc((v->segCountX2/2)*sizeof(*v->endCode));
288+ for(int i = 0; i < (v->segCountX2/2); i++)
279289 v->endCode[i] = b[0+i*2]<<8 | b[1+i*2];
280290 if((b = otfreadn(o, 2)) == nil)
281291 goto err;
282292 USED(b);
283− if((b = otfreadn(o, v->segCountX2/2*2)) == nil)
293+ if((b = otfreadn(o, (v->segCountX2/2)*2)) == nil)
284294 goto err;
285− v->startCode = malloc(v->segCountX2/2*sizeof(*v->startCode));
286− for(int i = 0; i < v->segCountX2/2; i++)
295+ v->startCode = malloc((v->segCountX2/2)*sizeof(*v->startCode));
296+ for(int i = 0; i < (v->segCountX2/2); i++)
287297 v->startCode[i] = b[0+i*2]<<8 | b[1+i*2];
288− if((b = otfreadn(o, v->segCountX2/2*2)) == nil)
298+ if((b = otfreadn(o, (v->segCountX2/2)*2)) == nil)
289299 goto err;
290− v->idDelta = malloc(v->segCountX2/2*sizeof(*v->idDelta));
291− for(int i = 0; i < v->segCountX2/2; i++)
300+ v->idDelta = malloc((v->segCountX2/2)*sizeof(*v->idDelta));
301+ for(int i = 0; i < (v->segCountX2/2); i++)
292302 v->idDelta[i] = b[0+i*2]<<8 | b[1+i*2];
293− if((b = otfreadn(o, v->segCountX2/2*2)) == nil)
303+ if((b = otfreadn(o, (v->segCountX2/2)*2)) == nil)
294304 goto err;
295− v->idRangeOffset = malloc(v->segCountX2/2*sizeof(*v->idRangeOffset));
296− for(int i = 0; i < v->segCountX2/2; i++)
305+ v->idRangeOffset = malloc((v->segCountX2/2)*sizeof(*v->idRangeOffset));
306+ for(int i = 0; i < (v->segCountX2/2); i++)
297307 v->idRangeOffset[i] = b[0+i*2]<<8 | b[1+i*2];
298308 return 0;
299309 err:
@@ -302,7 +312,7 @@ err: · 2 unmodified lines
302312 }
303313
304314 void
305−print_SubtableCmap4(Biobuf *f, int indent, SubtableCmap4 *v)
315+print_SubtableCmap4(Biobuf *f, int indent, Otf *o, SubtableCmap4 *v)
306316 {
307317 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
308318 Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
@@ -310,14 +320,15 @@ print_SubtableCmap4(Biobuf *f, int indent, SubtableCmap4 *v) · 1 unmodified line
310320 Bprint(f, "%*s%s: %ud\n", indent, "", "searchRange", v->searchRange);
311321 Bprint(f, "%*s%s: %ud\n", indent, "", "entrySelector", v->entrySelector);
312322 Bprint(f, "%*s%s: %ud\n", indent, "", "rangeShift", v->rangeShift);
313− for(int i = 0; i < v->segCountX2/2; i++)
323+ for(int i = 0; i < (v->segCountX2/2); i++)
314324 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "endCode", i, v->endCode[i]);
315− for(int i = 0; i < v->segCountX2/2; i++)
325+ for(int i = 0; i < (v->segCountX2/2); i++)
316326 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "startCode", i, v->startCode[i]);
317− for(int i = 0; i < v->segCountX2/2; i++)
327+ for(int i = 0; i < (v->segCountX2/2); i++)
318328 Bprint(f, "%*s%s[%d]: %d\n", indent, "", "idDelta", i, v->idDelta[i]);
319− for(int i = 0; i < v->segCountX2/2; i++)
329+ for(int i = 0; i < (v->segCountX2/2); i++)
320330 Bprint(f, "%*s%s[%d]: %d\n", indent, "", "idRangeOffset", i, v->idRangeOffset[i]);
331+ USED(o);
321332 }
322333
323334 int
@@ -342,7 +353,7 @@ err: · 18 unmodified lines
342353 }
343354
344355 void
345−print_SubtableCmap6(Biobuf *f, int indent, SubtableCmap6 *v)
356+print_SubtableCmap6(Biobuf *f, int indent, Otf *o, SubtableCmap6 *v)
346357 {
347358 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
348359 Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
@@ -350,6 +361,7 @@ print_SubtableCmap6(Biobuf *f, int indent, SubtableCmap6 *v) · 1 unmodified line
350361 Bprint(f, "%*s%s: %ud\n", indent, "", "entryCount", v->entryCount);
351362 for(int i = 0; i < v->entryCount; i++)
352363 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
364+ USED(o);
353365 }
354366
355367 int
@@ -374,7 +386,7 @@ err: · 18 unmodified lines
374386 }
375387
376388 void
377−print_SubtableCmap8(Biobuf *f, int indent, SubtableCmap8 *v)
389+print_SubtableCmap8(Biobuf *f, int indent, Otf *o, SubtableCmap8 *v)
378390 {
379391 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
380392 Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
@@ -383,8 +395,9 @@ print_SubtableCmap8(Biobuf *f, int indent, SubtableCmap8 *v) · 2 unmodified lines
383395 Bprint(f, "%*s%s: %ud\n", indent, "", "numGroups", v->numGroups);
384396 for(int i = 0; i < v->numGroups; i++){
385397 Bprint(f, "%*s%s[%d]:\n", indent, "", "groups", i);
386− print_MapGroup(f, indent+indentΔ, &v->groups[i]);
398+ print_MapGroup(f, indent+indentΔ, o, &v->groups[i]);
387399 }
400+ USED(o);
388401 }
389402
390403 int
@@ -405,13 +418,14 @@ err: · 14 unmodified lines
405418 }
406419
407420 void
408−print_SubtableCmap10(Biobuf *f, int indent, SubtableCmap10 *v)
421+print_SubtableCmap10(Biobuf *f, int indent, Otf *o, SubtableCmap10 *v)
409422 {
410423 Bprint(f, "%*s%s: %ud\n", indent, "", "reserved", v->reserved);
411424 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
412425 Bprint(f, "%*s%s: %ud\n", indent, "", "language", v->language);
413426 Bprint(f, "%*s%s: %ud\n", indent, "", "startCharCode", v->startCharCode);
414427 Bprint(f, "%*s%s: %ud\n", indent, "", "numChars", v->numChars);
428+ USED(o);
415429 }
416430
417431 int
@@ -435,7 +449,7 @@ err: · 17 unmodified lines
435449 }
436450
437451 void
438−print_SubtableCmap12or13(Biobuf *f, int indent, SubtableCmap12or13 *v)
452+print_SubtableCmap12or13(Biobuf *f, int indent, Otf *o, SubtableCmap12or13 *v)
439453 {
440454 Bprint(f, "%*s%s: %ud\n", indent, "", "reserved", v->reserved);
441455 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
@@ -443,8 +457,9 @@ print_SubtableCmap12or13(Biobuf *f, int indent, SubtableCmap12or13 *v) · 1 unmodified line
443457 Bprint(f, "%*s%s: %ud\n", indent, "", "numGroups", v->numGroups);
444458 for(int i = 0; i < v->numGroups; i++){
445459 Bprint(f, "%*s%s[%d]:\n", indent, "", "groups", i);
446− print_MapGroup(f, indent+indentΔ, &v->groups[i]);
460+ print_MapGroup(f, indent+indentΔ, o, &v->groups[i]);
447461 }
462+ USED(o);
448463 }
449464
450465 int
@@ -462,10 +477,11 @@ err: · 11 unmodified lines
462477 }
463478
464479 void
465−print_UnicodeRange(Biobuf *f, int indent, UnicodeRange *v)
480+print_UnicodeRange(Biobuf *f, int indent, Otf *o, UnicodeRange *v)
466481 {
467482 Bprint(f, "%*s%s: %ud\n", indent, "", "startUnicodeValue", v->startUnicodeValue);
468483 Bprint(f, "%*s%s: %ud\n", indent, "", "additionalCount", v->additionalCount);
484+ USED(o);
469485 }
470486
471487 int
@@ -486,13 +502,14 @@ err: · 14 unmodified lines
486502 }
487503
488504 void
489−print_DefaultUVS(Biobuf *f, int indent, DefaultUVS *v)
505+print_DefaultUVS(Biobuf *f, int indent, Otf *o, DefaultUVS *v)
490506 {
491507 Bprint(f, "%*s%s: %ud\n", indent, "", "numUnicodeValueRanges", v->numUnicodeValueRanges);
492508 for(int i = 0; i < v->numUnicodeValueRanges; i++){
493509 Bprint(f, "%*s%s[%d]:\n", indent, "", "ranges", i);
494− print_UnicodeRange(f, indent+indentΔ, &v->ranges[i]);
510+ print_UnicodeRange(f, indent+indentΔ, o, &v->ranges[i]);
495511 }
512+ USED(o);
496513 }
497514
498515 int
@@ -510,10 +527,11 @@ err: · 11 unmodified lines
510527 }
511528
512529 void
513−print_UVSMapping(Biobuf *f, int indent, UVSMapping *v)
530+print_UVSMapping(Biobuf *f, int indent, Otf *o, UVSMapping *v)
514531 {
515532 Bprint(f, "%*s%s: %ud\n", indent, "", "unicodeValue", v->unicodeValue);
516533 Bprint(f, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
534+ USED(o);
517535 }
518536
519537 int
@@ -534,13 +552,14 @@ err: · 14 unmodified lines
534552 }
535553
536554 void
537−print_NonDefaultUVS(Biobuf *f, int indent, NonDefaultUVS *v)
555+print_NonDefaultUVS(Biobuf *f, int indent, Otf *o, NonDefaultUVS *v)
538556 {
539557 Bprint(f, "%*s%s: %ud\n", indent, "", "numUVSMappings", v->numUVSMappings);
540558 for(int i = 0; i < v->numUVSMappings; i++){
541559 Bprint(f, "%*s%s[%d]:\n", indent, "", "uvsMappings", i);
542− print_UVSMapping(f, indent+indentΔ, &v->uvsMappings[i]);
560+ print_UVSMapping(f, indent+indentΔ, o, &v->uvsMappings[i]);
543561 }
562+ USED(o);
544563 }
545564
546565 int
@@ -581,17 +600,18 @@ err: · 34 unmodified lines
581600 }
582601
583602 void
584−print_VariationSelector(Biobuf *f, int indent, VariationSelector *v)
603+print_VariationSelector(Biobuf *f, int indent, Otf *o, VariationSelector *v)
585604 {
586605 Bprint(f, "%*s%s: %ud\n", indent, "", "varSelector", v->varSelector);
587606 Bprint(f, "%*s%s: %ud\n", indent, "", "defaultUVSOffset", v->defaultUVSOffset);
588607 Bprint(f, "%*s%s: %ud\n", indent, "", "nonDefaultUVSOffset", v->nonDefaultUVSOffset);
589608 Bprint(f, "%*s%s:\n", indent, "", "defaultUVS");
590609 if(v->defaultUVS != nil)
591− print_DefaultUVS(f, indent+indentΔ, v->defaultUVS);
610+ print_DefaultUVS(f, indent+indentΔ, o, v->defaultUVS);
592611 Bprint(f, "%*s%s:\n", indent, "", "nonDefaultUVS");
593612 if(v->nonDefaultUVS != nil)
594− print_NonDefaultUVS(f, indent+indentΔ, v->nonDefaultUVS);
613+ print_NonDefaultUVS(f, indent+indentΔ, o, v->nonDefaultUVS);
614+ USED(o);
595615 }
596616
597617 int
@@ -613,14 +633,15 @@ err: · 15 unmodified lines
613633 }
614634
615635 void
616−print_SubtableCmap14(Biobuf *f, int indent, SubtableCmap14 *v)
636+print_SubtableCmap14(Biobuf *f, int indent, Otf *o, SubtableCmap14 *v)
617637 {
618638 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
619639 Bprint(f, "%*s%s: %ud\n", indent, "", "numVarSelectorRecords", v->numVarSelectorRecords);
620640 for(int i = 0; i < v->numVarSelectorRecords; i++){
621641 Bprint(f, "%*s%s[%d]:\n", indent, "", "varSelector", i);
622− print_VariationSelector(f, indent+indentΔ, &v->varSelector[i]);
642+ print_VariationSelector(f, indent+indentΔ, o, &v->varSelector[i]);
623643 }
644+ USED(o);
624645 }
625646
626647 int
@@ -689,41 +710,42 @@ err: · 62 unmodified lines
689710 }
690711
691712 void
692−print_SubtableCmap(Biobuf *f, int indent, SubtableCmap *v)
713+print_SubtableCmap(Biobuf *f, int indent, Otf *o, SubtableCmap *v)
693714 {
694715 Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
695716 if(v->format == 0){
696717 Bprint(f, "%*s%s:\n", indent, "", "sub0");
697− print_SubtableCmap0(f, indent+indentΔ, &v->sub0);
718+ print_SubtableCmap0(f, indent+indentΔ, o, &v->sub0);
698719 }
699720 if(v->format == 2){
700721 Bprint(f, "%*s%s:\n", indent, "", "sub2");
701− print_SubtableCmap2(f, indent+indentΔ, &v->sub2);
722+ print_SubtableCmap2(f, indent+indentΔ, o, &v->sub2);
702723 }
703724 if(v->format == 4){
704725 Bprint(f, "%*s%s:\n", indent, "", "sub4");
705− print_SubtableCmap4(f, indent+indentΔ, &v->sub4);
726+ print_SubtableCmap4(f, indent+indentΔ, o, &v->sub4);
706727 }
707728 if(v->format == 6){
708729 Bprint(f, "%*s%s:\n", indent, "", "sub6");
709− print_SubtableCmap6(f, indent+indentΔ, &v->sub6);
730+ print_SubtableCmap6(f, indent+indentΔ, o, &v->sub6);
710731 }
711732 if(v->format == 8){
712733 Bprint(f, "%*s%s:\n", indent, "", "sub8");
713− print_SubtableCmap8(f, indent+indentΔ, &v->sub8);
734+ print_SubtableCmap8(f, indent+indentΔ, o, &v->sub8);
714735 }
715736 if(v->format == 10){
716737 Bprint(f, "%*s%s:\n", indent, "", "sub10");
717− print_SubtableCmap10(f, indent+indentΔ, &v->sub10);
738+ print_SubtableCmap10(f, indent+indentΔ, o, &v->sub10);
718739 }
719740 if(v->format == 12 || v->format == 13){
720741 Bprint(f, "%*s%s:\n", indent, "", "sub12or13");
721− print_SubtableCmap12or13(f, indent+indentΔ, &v->sub12or13);
742+ print_SubtableCmap12or13(f, indent+indentΔ, o, &v->sub12or13);
722743 }
723744 if(v->format == 14){
724745 Bprint(f, "%*s%s:\n", indent, "", "sub14");
725− print_SubtableCmap14(f, indent+indentΔ, &v->sub14);
746+ print_SubtableCmap14(f, indent+indentΔ, o, &v->sub14);
726747 }
748+ USED(o);
727749 }
728750
729751 int
@@ -757,14 +779,15 @@ err: · 27 unmodified lines
757779 }
758780
759781 void
760−print_EncodingRecord(Biobuf *f, int indent, EncodingRecord *v)
782+print_EncodingRecord(Biobuf *f, int indent, Otf *o, EncodingRecord *v)
761783 {
762784 Bprint(f, "%*s%s: %ud\n", indent, "", "platformID", v->platformID);
763785 Bprint(f, "%*s%s: %ud\n", indent, "", "encodingID", v->encodingID);
764786 Bprint(f, "%*s%s: %ud\n", indent, "", "subtableOffset", v->subtableOffset);
765787 Bprint(f, "%*s%s:\n", indent, "", "subtable");
766788 if(v->subtable != nil)
767− print_SubtableCmap(f, indent+indentΔ, v->subtable);
789+ print_SubtableCmap(f, indent+indentΔ, o, v->subtable);
790+ USED(o);
768791 }
769792
770793 int
@@ -790,13 +813,14 @@ err: · 19 unmodified lines
790813 }
791814
792815 void
793−print_TableCmap(Biobuf *f, int indent, TableCmap *v)
816+print_TableCmap(Biobuf *f, int indent, Otf *o, TableCmap *v)
794817 {
795818 Bprint(f, "%*s%s: %ud\n", indent, "", "numTables", v->numTables);
796819 for(int i = 0; i < v->numTables; i++){
797820 Bprint(f, "%*s%s[%d]:\n", indent, "", "encodingRecords", i);
798− print_EncodingRecord(f, indent+indentΔ, &v->encodingRecords[i]);
821+ print_EncodingRecord(f, indent+indentΔ, o, &v->encodingRecords[i]);
799822 }
823+ USED(o);
800824 }
801825
802826 int
@@ -840,6 +864,7 @@ read_TableHead(Otf *o, TableHead *v) · 37 unmodified lines
840864 goto err;
841865 }
842866 v->indexToLocFormat = b[50]<<8 | b[51];
867+ o->indexToLocFormat = v->indexToLocFormat;
843868 if(v->indexToLocFormat > 1){
844869 werrstr("%s: invalid value: %d (0x%ux)", "indexToLocFormat", v->indexToLocFormat, v->indexToLocFormat);
845870 goto err;
@@ -856,7 +881,7 @@ err: · 10 unmodified lines
856881 }
857882
858883 void
859−print_TableHead(Biobuf *f, int indent, TableHead *v)
884+print_TableHead(Biobuf *f, int indent, Otf *o, TableHead *v)
860885 {
861886 Bprint(f, "%*s%s: %ud\n", indent, "", "flags", v->flags);
862887 Bprint(f, "%*s%s: %ud\n", indent, "", "unitsPerEm", v->unitsPerEm);
@@ -869,6 +894,7 @@ print_TableHead(Biobuf *f, int indent, TableHead *v) · 6 unmodified lines
869894 Bprint(f, "%*s%s: %ud\n", indent, "", "macStyle", v->macStyle);
870895 Bprint(f, "%*s%s: %ud\n", indent, "", "lowestRecPPEM", v->lowestRecPPEM);
871896 Bprint(f, "%*s%s: %d\n", indent, "", "indexToLocFormat", v->indexToLocFormat);
897+ USED(o);
872898 }
873899
874900 int
@@ -903,6 +929,7 @@ read_TableHhea(Otf *o, TableHhea *v) · 28 unmodified lines
903929 goto err;
904930 }
905931 v->numberOfHMetrics = b[34]<<8 | b[35];
932+ o->numberOfHMetrics = v->numberOfHMetrics;
906933 return 0;
907934 err:
908935 werrstr("%s: %r", "TableHhea");
@@ -910,7 +937,7 @@ err: · 1 unmodified line
910937 }
911938
912939 void
913−print_TableHhea(Biobuf *f, int indent, TableHhea *v)
940+print_TableHhea(Biobuf *f, int indent, Otf *o, TableHhea *v)
914941 {
915942 Bprint(f, "%*s%s: %ud\n", indent, "", "majorVersion", v->majorVersion);
916943 Bprint(f, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
@@ -926,6 +953,7 @@ print_TableHhea(Biobuf *f, int indent, TableHhea *v) · 9 unmodified lines
926953 Bprint(f, "%*s%s: %d\n", indent, "", "caretOffset", v->caretOffset);
927954 Bprint(f, "%*s%s: %d\n", indent, "", "metricDataFormat", v->metricDataFormat);
928955 Bprint(f, "%*s%s: %ud\n", indent, "", "numberOfHMetrics", v->numberOfHMetrics);
956+ USED(o);
929957 }
930958
931959 int
@@ -943,10 +971,11 @@ err: · 11 unmodified lines
943971 }
944972
945973 void
946−print_LongHorMetric(Biobuf *f, int indent, LongHorMetric *v)
974+print_LongHorMetric(Biobuf *f, int indent, Otf *o, LongHorMetric *v)
947975 {
948976 Bprint(f, "%*s%s: %ud\n", indent, "", "advanceWidth", v->advanceWidth);
949977 Bprint(f, "%*s%s: %d\n", indent, "", "lsb", v->lsb);
978+ USED(o);
950979 }
951980
952981 int
@@ -961,6 +990,7 @@ read_TableMaxp(Otf *o, TableMaxp *v) · 8 unmodified lines
961990 goto err;
962991 }
963992 v->numGlyphs = b[4]<<8 | b[5];
993+ o->numGlyphs = v->numGlyphs;
964994 return 0;
965995 err:
966996 werrstr("%s: %r", "TableMaxp");
@@ -968,9 +998,41 @@ err: · 1 unmodified line
968998 }
969999
9701000 void
971−print_TableMaxp(Biobuf *f, int indent, TableMaxp *v)
1001+print_TableMaxp(Biobuf *f, int indent, Otf *o, TableMaxp *v)
9721002 {
9731003 Bprint(f, "%*s%s: %ud\n", indent, "", "numGlyphs", v->numGlyphs);
1004+ USED(o);
1005+}
1006+
1007+int
1008+read_TableHmtx(Otf *o, TableHmtx *v)
1009+{
1010+ u8int *b;
1011+ if(otfarray(o, &v->hMetrics, read_LongHorMetric, sizeof(LongHorMetric), (o->numberOfHMetrics+0)) < 0){
1012+ werrstr("%s: %r", "hMetrics");
1013+ goto err;
1014+ }
1015+ if((b = otfreadn(o, (o->numGlyphs-o->numberOfHMetrics)*2)) == nil)
1016+ goto err;
1017+ v->leftSideBearings = malloc((o->numGlyphs-o->numberOfHMetrics)*sizeof(*v->leftSideBearings));
1018+ for(int i = 0; i < (o->numGlyphs-o->numberOfHMetrics); i++)
1019+ v->leftSideBearings[i] = b[0+i*2]<<8 | b[1+i*2];
1020+ return 0;
1021+err:
1022+ werrstr("%s: %r", "TableHmtx");
1023+ return -1;
1024+}
1025+
1026+void
1027+print_TableHmtx(Biobuf *f, int indent, Otf *o, TableHmtx *v)
1028+{
1029+ for(int i = 0; i < (o->numberOfHMetrics+0); i++){
1030+ Bprint(f, "%*s%s[%d]:\n", indent, "", "hMetrics", i);
1031+ print_LongHorMetric(f, indent+indentΔ, o, &v->hMetrics[i]);
1032+ }
1033+ for(int i = 0; i < (o->numGlyphs-o->numberOfHMetrics); i++)
1034+ Bprint(f, "%*s%s[%d]: %d\n", indent, "", "leftSideBearings", i, v->leftSideBearings[i]);
1035+ USED(o);
9741036 }
9751037
9761038 int
@@ -995,12 +1057,13 @@ err: · 18 unmodified lines
9951057 }
9961058
9971059 void
998−print_TablePost(Biobuf *f, int indent, TablePost *v)
1060+print_TablePost(Biobuf *f, int indent, Otf *o, TablePost *v)
9991061 {
10001062 Bprint(f, "%*s%s: %g\n", indent, "", "italicAngle", v->italicAngle);
10011063 Bprint(f, "%*s%s: %d\n", indent, "", "underlinePosition", v->underlinePosition);
10021064 Bprint(f, "%*s%s: %d\n", indent, "", "underlineThickness", v->underlineThickness);
10031065 Bprint(f, "%*s%s: %ud\n", indent, "", "isFixedPitch", v->isFixedPitch);
1066+ USED(o);
10041067 }
10051068
10061069 int
@@ -1022,7 +1085,7 @@ err: · 15 unmodified lines
10221085 }
10231086
10241087 void
1025−print_NameRecord(Biobuf *f, int indent, NameRecord *v)
1088+print_NameRecord(Biobuf *f, int indent, Otf *o, NameRecord *v)
10261089 {
10271090 Bprint(f, "%*s%s: %ud\n", indent, "", "platformID", v->platformID);
10281091 Bprint(f, "%*s%s: %ud\n", indent, "", "encodingID", v->encodingID);
@@ -1030,6 +1093,7 @@ print_NameRecord(Biobuf *f, int indent, NameRecord *v) · 1 unmodified line
10301093 Bprint(f, "%*s%s: %ud\n", indent, "", "nameID", v->nameID);
10311094 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
10321095 Bprint(f, "%*s%s: %ud\n", indent, "", "stringOffset", v->stringOffset);
1096+ USED(o);
10331097 }
10341098
10351099 int
@@ -1047,10 +1111,11 @@ err: · 11 unmodified lines
10471111 }
10481112
10491113 void
1050−print_LangTagRecord(Biobuf *f, int indent, LangTagRecord *v)
1114+print_LangTagRecord(Biobuf *f, int indent, Otf *o, LangTagRecord *v)
10511115 {
10521116 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
10531117 Bprint(f, "%*s%s: %ud\n", indent, "", "langTagOffset", v->langTagOffset);
1118+ USED(o);
10541119 }
10551120
10561121 int
@@ -1088,23 +1153,24 @@ err: · 31 unmodified lines
10881153 }
10891154
10901155 void
1091−print_TableName(Biobuf *f, int indent, TableName *v)
1156+print_TableName(Biobuf *f, int indent, Otf *o, TableName *v)
10921157 {
10931158 Bprint(f, "%*s%s: %ud\n", indent, "", "version", v->version);
10941159 Bprint(f, "%*s%s: %ud\n", indent, "", "count", v->count);
10951160 Bprint(f, "%*s%s: %ud\n", indent, "", "storageOffset", v->storageOffset);
10961161 for(int i = 0; i < v->count; i++){
10971162 Bprint(f, "%*s%s[%d]:\n", indent, "", "nameRecord", i);
1098− print_NameRecord(f, indent+indentΔ, &v->nameRecord[i]);
1163+ print_NameRecord(f, indent+indentΔ, o, &v->nameRecord[i]);
10991164 }
11001165 if(v->version >= 1)
11011166 Bprint(f, "%*s%s: %ud\n", indent, "", "langTagCount", v->langTagCount);
11021167 if(v->version >= 1){
11031168 for(int i = 0; i < v->langTagCount; i++){
11041169 Bprint(f, "%*s%s[%d]:\n", indent, "", "langTagRecord", i);
1105− print_LangTagRecord(f, indent+indentΔ, &v->langTagRecord[i]);
1170+ print_LangTagRecord(f, indent+indentΔ, o, &v->langTagRecord[i]);
11061171 }
11071172 }
1173+ USED(o);
11081174 }
11091175
11101176 int
@@ -1128,7 +1194,7 @@ err: · 17 unmodified lines
11281194 }
11291195
11301196 void
1131−print_BigGlyphMetrics(Biobuf *f, int indent, BigGlyphMetrics *v)
1197+print_BigGlyphMetrics(Biobuf *f, int indent, Otf *o, BigGlyphMetrics *v)
11321198 {
11331199 Bprint(f, "%*s%s: %ud\n", indent, "", "height", v->height);
11341200 Bprint(f, "%*s%s: %ud\n", indent, "", "width", v->width);
@@ -1138,6 +1204,7 @@ print_BigGlyphMetrics(Biobuf *f, int indent, BigGlyphMetrics *v) · 3 unmodified lines
11381204 Bprint(f, "%*s%s: %d\n", indent, "", "vertBearingX", v->vertBearingX);
11391205 Bprint(f, "%*s%s: %d\n", indent, "", "vertBearingY", v->vertBearingY);
11401206 Bprint(f, "%*s%s: %ud\n", indent, "", "vertAdvance", v->vertAdvance);
1207+ USED(o);
11411208 }
11421209
11431210 int
@@ -1158,13 +1225,14 @@ err: · 14 unmodified lines
11581225 }
11591226
11601227 void
1161−print_SmallGlyphMetrics(Biobuf *f, int indent, SmallGlyphMetrics *v)
1228+print_SmallGlyphMetrics(Biobuf *f, int indent, Otf *o, SmallGlyphMetrics *v)
11621229 {
11631230 Bprint(f, "%*s%s: %ud\n", indent, "", "height", v->height);
11641231 Bprint(f, "%*s%s: %ud\n", indent, "", "width", v->width);
11651232 Bprint(f, "%*s%s: %d\n", indent, "", "bearingX", v->bearingX);
11661233 Bprint(f, "%*s%s: %d\n", indent, "", "bearingY", v->bearingY);
11671234 Bprint(f, "%*s%s: %ud\n", indent, "", "advance", v->advance);
1235+ USED(o);
11681236 }
11691237
11701238 int
@@ -1190,7 +1258,7 @@ err: · 19 unmodified lines
11901258 }
11911259
11921260 void
1193−print_SbitLineMetrics(Biobuf *f, int indent, SbitLineMetrics *v)
1261+print_SbitLineMetrics(Biobuf *f, int indent, Otf *o, SbitLineMetrics *v)
11941262 {
11951263 Bprint(f, "%*s%s: %d\n", indent, "", "ascender", v->ascender);
11961264 Bprint(f, "%*s%s: %d\n", indent, "", "descender", v->descender);
@@ -1202,15 +1270,18 @@ print_SbitLineMetrics(Biobuf *f, int indent, SbitLineMetrics *v) · 5 unmodified lines
12021270 Bprint(f, "%*s%s: %d\n", indent, "", "minAdvanceSB", v->minAdvanceSB);
12031271 Bprint(f, "%*s%s: %d\n", indent, "", "maxBeforeBL", v->maxBeforeBL);
12041272 Bprint(f, "%*s%s: %d\n", indent, "", "minAfterBL", v->minAfterBL);
1273+ USED(o);
12051274 }
12061275
12071276 int
12081277 read_IndexSubtable1(Otf *o, IndexSubtable1 *v)
12091278 {
12101279 u8int *b;
1211− if((b = otfreadn(o, 4)) == nil)
1280+ if((b = otfreadn(o, ((o->lastGlyphIndex-o->firstGlyphIndex)+2)*4)) == nil)
12121281 goto err;
1213− v->sbitOffsets = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
1282+ v->sbitOffsets = malloc(((o->lastGlyphIndex-o->firstGlyphIndex)+2)*sizeof(*v->sbitOffsets));
1283+ for(int i = 0; i < ((o->lastGlyphIndex-o->firstGlyphIndex)+2); i++)
1284+ v->sbitOffsets[i] = b[0+i*4]<<24 | b[1+i*4]<<16 | b[2+i*4]<<8 | b[3+i*4];
12141285 return 0;
12151286 err:
12161287 werrstr("%s: %r", "IndexSubtable1");
@@ -1218,9 +1289,11 @@ err: · 1 unmodified line
12181289 }
12191290
12201291 void
1221−print_IndexSubtable1(Biobuf *f, int indent, IndexSubtable1 *v)
1292+print_IndexSubtable1(Biobuf *f, int indent, Otf *o, IndexSubtable1 *v)
12221293 {
1223− Bprint(f, "%*s%s: %ud\n", indent, "", "sbitOffsets", v->sbitOffsets);
1294+ for(int i = 0; i < ((o->lastGlyphIndex-o->firstGlyphIndex)+2); i++)
1295+ Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "sbitOffsets", i, v->sbitOffsets[i]);
1296+ USED(o);
12241297 }
12251298
12261299 int
@@ -1241,20 +1314,23 @@ err: · 14 unmodified lines
12411314 }
12421315
12431316 void
1244−print_IndexSubtable2(Biobuf *f, int indent, IndexSubtable2 *v)
1317+print_IndexSubtable2(Biobuf *f, int indent, Otf *o, IndexSubtable2 *v)
12451318 {
12461319 Bprint(f, "%*s%s: %ud\n", indent, "", "imageSize", v->imageSize);
12471320 Bprint(f, "%*s%s:\n", indent, "", "bigMetrics");
1248− print_BigGlyphMetrics(f, indent+indentΔ, &v->bigMetrics);
1321+ print_BigGlyphMetrics(f, indent+indentΔ, o, &v->bigMetrics);
1322+ USED(o);
12491323 }
12501324
12511325 int
12521326 read_IndexSubtable3(Otf *o, IndexSubtable3 *v)
12531327 {
12541328 u8int *b;
1255− if((b = otfreadn(o, 2)) == nil)
1329+ if((b = otfreadn(o, ((o->lastGlyphIndex-o->firstGlyphIndex)+2)*2)) == nil)
12561330 goto err;
1257− v->sbitOffsets = b[0]<<8 | b[1];
1331+ v->sbitOffsets = malloc(((o->lastGlyphIndex-o->firstGlyphIndex)+2)*sizeof(*v->sbitOffsets));
1332+ for(int i = 0; i < ((o->lastGlyphIndex-o->firstGlyphIndex)+2); i++)
1333+ v->sbitOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
12581334 return 0;
12591335 err:
12601336 werrstr("%s: %r", "IndexSubtable3");
@@ -1262,9 +1338,11 @@ err: · 1 unmodified line
12621338 }
12631339
12641340 void
1265−print_IndexSubtable3(Biobuf *f, int indent, IndexSubtable3 *v)
1341+print_IndexSubtable3(Biobuf *f, int indent, Otf *o, IndexSubtable3 *v)
12661342 {
1267− Bprint(f, "%*s%s: %ud\n", indent, "", "sbitOffsets", v->sbitOffsets);
1343+ for(int i = 0; i < ((o->lastGlyphIndex-o->firstGlyphIndex)+2); i++)
1344+ Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "sbitOffsets", i, v->sbitOffsets[i]);
1345+ USED(o);
12681346 }
12691347
12701348 int
@@ -1282,10 +1360,11 @@ err: · 11 unmodified lines
12821360 }
12831361
12841362 void
1285−print_GlyphIdOffsetPair(Biobuf *f, int indent, GlyphIdOffsetPair *v)
1363+print_GlyphIdOffsetPair(Biobuf *f, int indent, Otf *o, GlyphIdOffsetPair *v)
12861364 {
12871365 Bprint(f, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
12881366 Bprint(f, "%*s%s: %ud\n", indent, "", "sbitOffset", v->sbitOffset);
1367+ USED(o);
12891368 }
12901369
12911370 int
@@ -1295,7 +1374,7 @@ read_IndexSubtable4(Otf *o, IndexSubtable4 *v) · 3 unmodified lines
12951374 if((b = otfreadn(o, 4)) == nil)
12961375 goto err;
12971376 v->numGlyphs = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
1298− if(otfarray(o, &v->glyphArray, read_GlyphIdOffsetPair, sizeof(GlyphIdOffsetPair), v->numGlyphs+1) < 0){
1377+ if(otfarray(o, &v->glyphArray, read_GlyphIdOffsetPair, sizeof(GlyphIdOffsetPair), (v->numGlyphs+1)) < 0){
12991378 werrstr("%s: %r", "glyphArray");
13001379 goto err;
13011380 }
@@ -1306,13 +1385,14 @@ err: · 4 unmodified lines
13061385 }
13071386
13081387 void
1309−print_IndexSubtable4(Biobuf *f, int indent, IndexSubtable4 *v)
1388+print_IndexSubtable4(Biobuf *f, int indent, Otf *o, IndexSubtable4 *v)
13101389 {
13111390 Bprint(f, "%*s%s: %ud\n", indent, "", "numGlyphs", v->numGlyphs);
1312− for(int i = 0; i < v->numGlyphs+1; i++){
1391+ for(int i = 0; i < (v->numGlyphs+1); i++){
13131392 Bprint(f, "%*s%s[%d]:\n", indent, "", "glyphArray", i);
1314− print_GlyphIdOffsetPair(f, indent+indentΔ, &v->glyphArray[i]);
1393+ print_GlyphIdOffsetPair(f, indent+indentΔ, o, &v->glyphArray[i]);
13151394 }
1395+ USED(o);
13161396 }
13171397
13181398 int
@@ -1341,14 +1421,15 @@ err: · 22 unmodified lines
13411421 }
13421422
13431423 void
1344−print_IndexSubtable5(Biobuf *f, int indent, IndexSubtable5 *v)
1424+print_IndexSubtable5(Biobuf *f, int indent, Otf *o, IndexSubtable5 *v)
13451425 {
13461426 Bprint(f, "%*s%s: %ud\n", indent, "", "imageSize", v->imageSize);
13471427 Bprint(f, "%*s%s:\n", indent, "", "bigMetrics");
1348− print_BigGlyphMetrics(f, indent+indentΔ, &v->bigMetrics);
1428+ print_BigGlyphMetrics(f, indent+indentΔ, o, &v->bigMetrics);
13491429 Bprint(f, "%*s%s: %ud\n", indent, "", "numGlyphs", v->numGlyphs);
13501430 for(int i = 0; i < v->numGlyphs; i++)
13511431 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphIdArray", i, v->glyphIdArray[i]);
1432+ USED(o);
13521433 }
13531434
13541435 int
@@ -1401,31 +1482,32 @@ err: · 46 unmodified lines
14011482 }
14021483
14031484 void
1404−print_IndexSubtable(Biobuf *f, int indent, IndexSubtable *v)
1485+print_IndexSubtable(Biobuf *f, int indent, Otf *o, IndexSubtable *v)
14051486 {
14061487 Bprint(f, "%*s%s: %ud\n", indent, "", "indexFormat", v->indexFormat);
14071488 Bprint(f, "%*s%s: %ud\n", indent, "", "imageFormat", v->imageFormat);
14081489 Bprint(f, "%*s%s: %ud\n", indent, "", "imageDataOffset", v->imageDataOffset);
14091490 if(v->indexFormat == 1){
14101491 Bprint(f, "%*s%s:\n", indent, "", "sub1");
1411− print_IndexSubtable1(f, indent+indentΔ, &v->sub1);
1492+ print_IndexSubtable1(f, indent+indentΔ, o, &v->sub1);
14121493 }
14131494 if(v->indexFormat == 2){
14141495 Bprint(f, "%*s%s:\n", indent, "", "sub2");
1415− print_IndexSubtable2(f, indent+indentΔ, &v->sub2);
1496+ print_IndexSubtable2(f, indent+indentΔ, o, &v->sub2);
14161497 }
14171498 if(v->indexFormat == 3){
14181499 Bprint(f, "%*s%s:\n", indent, "", "sub3");
1419− print_IndexSubtable3(f, indent+indentΔ, &v->sub3);
1500+ print_IndexSubtable3(f, indent+indentΔ, o, &v->sub3);
14201501 }
14211502 if(v->indexFormat == 4){
14221503 Bprint(f, "%*s%s:\n", indent, "", "sub4");
1423− print_IndexSubtable4(f, indent+indentΔ, &v->sub4);
1504+ print_IndexSubtable4(f, indent+indentΔ, o, &v->sub4);
14241505 }
14251506 if(v->indexFormat == 5){
14261507 Bprint(f, "%*s%s:\n", indent, "", "sub5");
1427− print_IndexSubtable5(f, indent+indentΔ, &v->sub5);
1508+ print_IndexSubtable5(f, indent+indentΔ, o, &v->sub5);
14281509 }
1510+ USED(o);
14291511 }
14301512
14311513 int
@@ -1435,7 +1517,9 @@ read_IndexSubtableRecord(Otf *o, IndexSubtableRecord *v) · 3 unmodified lines
14351517 if((b = otfreadn(o, 8)) == nil)
14361518 goto err;
14371519 v->firstGlyphIndex = b[0]<<8 | b[1];
1520+ o->firstGlyphIndex = v->firstGlyphIndex;
14381521 v->lastGlyphIndex = b[2]<<8 | b[3];
1522+ o->lastGlyphIndex = v->lastGlyphIndex;
14391523 v->indexSubtableOffset = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
14401524 if(v->indexSubtableOffset != 0){
14411525 if(otfpushrange(o, v->indexSubtableOffset, -1) < 0)
@@ -1455,14 +1539,15 @@ err: · 13 unmodified lines
14551539 }
14561540
14571541 void
1458−print_IndexSubtableRecord(Biobuf *f, int indent, IndexSubtableRecord *v)
1542+print_IndexSubtableRecord(Biobuf *f, int indent, Otf *o, IndexSubtableRecord *v)
14591543 {
14601544 Bprint(f, "%*s%s: %ud\n", indent, "", "firstGlyphIndex", v->firstGlyphIndex);
14611545 Bprint(f, "%*s%s: %ud\n", indent, "", "lastGlyphIndex", v->lastGlyphIndex);
14621546 Bprint(f, "%*s%s: %ud\n", indent, "", "indexSubtableOffset", v->indexSubtableOffset);
14631547 Bprint(f, "%*s%s:\n", indent, "", "indexSubtable");
14641548 if(v->indexSubtable != nil)
1465− print_IndexSubtable(f, indent+indentΔ, v->indexSubtable);
1549+ print_IndexSubtable(f, indent+indentΔ, o, v->indexSubtable);
1550+ USED(o);
14661551 }
14671552
14681553 int
@@ -1507,15 +1592,15 @@ err: · 38 unmodified lines
15071592 }
15081593
15091594 void
1510−print_BitmapSize(Biobuf *f, int indent, BitmapSize *v)
1595+print_BitmapSize(Biobuf *f, int indent, Otf *o, BitmapSize *v)
15111596 {
15121597 Bprint(f, "%*s%s: %ud\n", indent, "", "indexSubtableListOffset", v->indexSubtableListOffset);
15131598 Bprint(f, "%*s%s: %ud\n", indent, "", "indexSubtableListSize", v->indexSubtableListSize);
15141599 Bprint(f, "%*s%s: %ud\n", indent, "", "numberOfIndexSubtables", v->numberOfIndexSubtables);
15151600 Bprint(f, "%*s%s:\n", indent, "", "hori");
1516− print_SbitLineMetrics(f, indent+indentΔ, &v->hori);
1601+ print_SbitLineMetrics(f, indent+indentΔ, o, &v->hori);
15171602 Bprint(f, "%*s%s:\n", indent, "", "vert");
1518− print_SbitLineMetrics(f, indent+indentΔ, &v->vert);
1603+ print_SbitLineMetrics(f, indent+indentΔ, o, &v->vert);
15191604 Bprint(f, "%*s%s: %ud\n", indent, "", "startGlyphIndex", v->startGlyphIndex);
15201605 Bprint(f, "%*s%s: %ud\n", indent, "", "endGlyphIndex", v->endGlyphIndex);
15211606 Bprint(f, "%*s%s: %ud\n", indent, "", "ppemX", v->ppemX);
@@ -1524,8 +1609,9 @@ print_BitmapSize(Biobuf *f, int indent, BitmapSize *v) · 2 unmodified lines
15241609 Bprint(f, "%*s%s: %d\n", indent, "", "flags", v->flags);
15251610 for(int i = 0; i < v->numberOfIndexSubtables; i++){
15261611 Bprint(f, "%*s%s[%d]:\n", indent, "", "indexSubtableList", i);
1527− print_IndexSubtableRecord(f, indent+indentΔ, &v->indexSubtableList[i]);
1612+ print_IndexSubtableRecord(f, indent+indentΔ, o, &v->indexSubtableList[i]);
15281613 }
1614+ USED(o);
15291615 }
15301616
15311617 int
@@ -1551,9 +1637,10 @@ err: · 19 unmodified lines
15511637 }
15521638
15531639 void
1554−print_TableEBDT(Biobuf *f, int indent, TableEBDT *v)
1640+print_TableEBDT(Biobuf *f, int indent, Otf *o, TableEBDT *v)
15551641 {
15561642 Bprint(f, "%*s%s: %ud\n", indent, "", "majorVersion", v->majorVersion);
1643+ USED(o);
15571644 }
15581645
15591646 int
@@ -1584,13 +1671,14 @@ err: · 24 unmodified lines
15841671 }
15851672
15861673 void
1587−print_TableEBLC(Biobuf *f, int indent, TableEBLC *v)
1674+print_TableEBLC(Biobuf *f, int indent, Otf *o, TableEBLC *v)
15881675 {
15891676 Bprint(f, "%*s%s: %ud\n", indent, "", "numSizes", v->numSizes);
15901677 for(int i = 0; i < v->numSizes; i++){
15911678 Bprint(f, "%*s%s[%d]:\n", indent, "", "bitmapSizes", i);
1592− print_BitmapSize(f, indent+indentΔ, &v->bitmapSizes[i]);
1679+ print_BitmapSize(f, indent+indentΔ, o, &v->bitmapSizes[i]);
15931680 }
1681+ USED(o);
15941682 }
15951683
15961684 int
@@ -1613,12 +1701,13 @@ err: · 16 unmodified lines
16131701 }
16141702
16151703 void
1616−print_AttachList(Biobuf *f, int indent, AttachList *v)
1704+print_AttachList(Biobuf *f, int indent, Otf *o, AttachList *v)
16171705 {
16181706 Bprint(f, "%*s%s: %ud\n", indent, "", "coverageOffset", v->coverageOffset);
16191707 Bprint(f, "%*s%s: %ud\n", indent, "", "glyphCount", v->glyphCount);
16201708 for(int i = 0; i < v->glyphCount; i++)
16211709 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "attachPointOffsets", i, v->attachPointOffsets[i]);
1710+ USED(o);
16221711 }
16231712
16241713 int
@@ -1640,11 +1729,12 @@ err: · 15 unmodified lines
16401729 }
16411730
16421731 void
1643−print_AttachPoint(Biobuf *f, int indent, AttachPoint *v)
1732+print_AttachPoint(Biobuf *f, int indent, Otf *o, AttachPoint *v)
16441733 {
16451734 Bprint(f, "%*s%s: %ud\n", indent, "", "pointCount", v->pointCount);
16461735 for(int i = 0; i < v->pointCount; i++)
16471736 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "pointIndices", i, v->pointIndices[i]);
1737+ USED(o);
16481738 }
16491739
16501740 int
@@ -1667,12 +1757,13 @@ err: · 16 unmodified lines
16671757 }
16681758
16691759 void
1670−print_LigCaretList(Biobuf *f, int indent, LigCaretList *v)
1760+print_LigCaretList(Biobuf *f, int indent, Otf *o, LigCaretList *v)
16711761 {
16721762 Bprint(f, "%*s%s: %ud\n", indent, "", "coverageOffset", v->coverageOffset);
16731763 Bprint(f, "%*s%s: %ud\n", indent, "", "ligGlyphCount", v->ligGlyphCount);
16741764 for(int i = 0; i < v->ligGlyphCount; i++)
16751765 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "ligGlyphOffsets", i, v->ligGlyphOffsets[i]);
1766+ USED(o);
16761767 }
16771768
16781769 int
@@ -1694,11 +1785,12 @@ err: · 15 unmodified lines
16941785 }
16951786
16961787 void
1697−print_LigGlyph(Biobuf *f, int indent, LigGlyph *v)
1788+print_LigGlyph(Biobuf *f, int indent, Otf *o, LigGlyph *v)
16981789 {
16991790 Bprint(f, "%*s%s: %ud\n", indent, "", "caretCount", v->caretCount);
17001791 for(int i = 0; i < v->caretCount; i++)
17011792 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "caretValueOffsets", i, v->caretValueOffsets[i]);
1793+ USED(o);
17021794 }
17031795
17041796 int
@@ -1734,7 +1826,7 @@ err: · 29 unmodified lines
17341826 }
17351827
17361828 void
1737−print_CaretValue(Biobuf *f, int indent, CaretValue *v)
1829+print_CaretValue(Biobuf *f, int indent, Otf *o, CaretValue *v)
17381830 {
17391831 Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
17401832 if(v->format == 1 || v->format == 3)
@@ -1743,6 +1835,7 @@ print_CaretValue(Biobuf *f, int indent, CaretValue *v) · 2 unmodified lines
17431835 Bprint(f, "%*s%s: %ud\n", indent, "", "caretValuePointIndex", v->caretValuePointIndex);
17441836 if(v->format == 3)
17451837 Bprint(f, "%*s%s: %ud\n", indent, "", "deviceOffset", v->deviceOffset);
1838+ USED(o);
17461839 }
17471840
17481841 int
@@ -1766,7 +1859,7 @@ err: · 17 unmodified lines
17661859 }
17671860
17681861 void
1769−print_ValueRecord(Biobuf *f, int indent, ValueRecord *v)
1862+print_ValueRecord(Biobuf *f, int indent, Otf *o, ValueRecord *v)
17701863 {
17711864 Bprint(f, "%*s%s: %d\n", indent, "", "xPlacement", v->xPlacement);
17721865 Bprint(f, "%*s%s: %d\n", indent, "", "yPlacement", v->yPlacement);
@@ -1776,6 +1869,7 @@ print_ValueRecord(Biobuf *f, int indent, ValueRecord *v) · 3 unmodified lines
17761869 Bprint(f, "%*s%s: %ud\n", indent, "", "yPlaDeviceOffset", v->yPlaDeviceOffset);
17771870 Bprint(f, "%*s%s: %ud\n", indent, "", "xAdvDeviceOffset", v->xAdvDeviceOffset);
17781871 Bprint(f, "%*s%s: %ud\n", indent, "", "yAdvDeviceOffset", v->yAdvDeviceOffset);
1872+ USED(o);
17791873 }
17801874
17811875 int
@@ -1815,23 +1909,24 @@ err: · 33 unmodified lines
18151909 }
18161910
18171911 void
1818−print_SinglePos(Biobuf *f, int indent, SinglePos *v)
1912+print_SinglePos(Biobuf *f, int indent, Otf *o, SinglePos *v)
18191913 {
18201914 Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
18211915 Bprint(f, "%*s%s: %ud\n", indent, "", "coverageOffset", v->coverageOffset);
18221916 Bprint(f, "%*s%s: %ud\n", indent, "", "valueFormat", v->valueFormat);
18231917 if(v->format == 1){
18241918 Bprint(f, "%*s%s:\n", indent, "", "valueRecord");
1825− print_ValueRecord(f, indent+indentΔ, &v->valueRecord);
1919+ print_ValueRecord(f, indent+indentΔ, o, &v->valueRecord);
18261920 }
18271921 if(v->format == 2)
18281922 Bprint(f, "%*s%s: %ud\n", indent, "", "valueCount", v->valueCount);
18291923 if(v->format == 2){
18301924 for(int i = 0; i < v->valueCount; i++){
18311925 Bprint(f, "%*s%s[%d]:\n", indent, "", "valueRecords", i);
1832− print_ValueRecord(f, indent+indentΔ, &v->valueRecords[i]);
1926+ print_ValueRecord(f, indent+indentΔ, o, &v->valueRecords[i]);
18331927 }
18341928 }
1929+ USED(o);
18351930 }
18361931
18371932 int
@@ -1871,7 +1966,7 @@ err: · 33 unmodified lines
18711966 }
18721967
18731968 void
1874−print_TableGDEF(Biobuf *f, int indent, TableGDEF *v)
1969+print_TableGDEF(Biobuf *f, int indent, Otf *o, TableGDEF *v)
18751970 {
18761971 Bprint(f, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
18771972 Bprint(f, "%*s%s: %ud\n", indent, "", "glyphClassDefOffset", v->glyphClassDefOffset);
@@ -1882,6 +1977,7 @@ print_TableGDEF(Biobuf *f, int indent, TableGDEF *v) · 4 unmodified lines
18821977 Bprint(f, "%*s%s: %ud\n", indent, "", "markGlyphSetsDefOffset", v->markGlyphSetsDefOffset);
18831978 if(v->minorVersion >= 3)
18841979 Bprint(f, "%*s%s: %ud\n", indent, "", "itemVarStoreOffset", v->itemVarStoreOffset);
1980+ USED(o);
18851981 }
18861982
18871983 int
@@ -1904,12 +2000,13 @@ err: · 16 unmodified lines
19042000 }
19052001
19062002 void
1907−print_LangSys(Biobuf *f, int indent, LangSys *v)
2003+print_LangSys(Biobuf *f, int indent, Otf *o, LangSys *v)
19082004 {
19092005 Bprint(f, "%*s%s: %ud\n", indent, "", "requiredFeatureIndex", v->requiredFeatureIndex);
19102006 Bprint(f, "%*s%s: %ud\n", indent, "", "featureIndexCount", v->featureIndexCount);
19112007 for(int i = 0; i < v->featureIndexCount; i++)
19122008 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "featureIndices", i, v->featureIndices[i]);
2009+ USED(o);
19132010 }
19142011
19152012 int
@@ -1938,13 +2035,14 @@ err: · 22 unmodified lines
19382035 }
19392036
19402037 void
1941−print_LangSysRecord(Biobuf *f, int indent, LangSysRecord *v)
2038+print_LangSysRecord(Biobuf *f, int indent, Otf *o, LangSysRecord *v)
19422039 {
19432040 Bprint(f, "%*s%s: %t\n", indent, "", "langSysTag", v->langSysTag);
19442041 Bprint(f, "%*s%s: %ud\n", indent, "", "langSysOffset", v->langSysOffset);
19452042 Bprint(f, "%*s%s:\n", indent, "", "langSys");
19462043 if(v->langSys != nil)
1947− print_LangSys(f, indent+indentΔ, v->langSys);
2044+ print_LangSys(f, indent+indentΔ, o, v->langSys);
2045+ USED(o);
19482046 }
19492047
19502048 int
@@ -1977,17 +2075,18 @@ err: · 26 unmodified lines
19772075 }
19782076
19792077 void
1980−print_Script(Biobuf *f, int indent, Script *v)
2078+print_Script(Biobuf *f, int indent, Otf *o, Script *v)
19812079 {
19822080 Bprint(f, "%*s%s: %ud\n", indent, "", "defaultLangSysOffset", v->defaultLangSysOffset);
19832081 Bprint(f, "%*s%s: %ud\n", indent, "", "langSysCount", v->langSysCount);
19842082 for(int i = 0; i < v->langSysCount; i++){
19852083 Bprint(f, "%*s%s[%d]:\n", indent, "", "langSysRecords", i);
1986− print_LangSysRecord(f, indent+indentΔ, &v->langSysRecords[i]);
2084+ print_LangSysRecord(f, indent+indentΔ, o, &v->langSysRecords[i]);
19872085 }
19882086 Bprint(f, "%*s%s:\n", indent, "", "defaultLangSys");
19892087 if(v->defaultLangSys != nil)
1990− print_LangSys(f, indent+indentΔ, v->defaultLangSys);
2088+ print_LangSys(f, indent+indentΔ, o, v->defaultLangSys);
2089+ USED(o);
19912090 }
19922091
19932092 int
@@ -2016,13 +2115,14 @@ err: · 22 unmodified lines
20162115 }
20172116
20182117 void
2019−print_ScriptRecord(Biobuf *f, int indent, ScriptRecord *v)
2118+print_ScriptRecord(Biobuf *f, int indent, Otf *o, ScriptRecord *v)
20202119 {
20212120 Bprint(f, "%*s%s: %t\n", indent, "", "scriptTag", v->scriptTag);
20222121 Bprint(f, "%*s%s: %ud\n", indent, "", "scriptOffset", v->scriptOffset);
20232122 Bprint(f, "%*s%s:\n", indent, "", "script");
20242123 if(v->script != nil)
2025− print_Script(f, indent+indentΔ, v->script);
2124+ print_Script(f, indent+indentΔ, o, v->script);
2125+ USED(o);
20262126 }
20272127
20282128 int
@@ -2043,13 +2143,14 @@ err: · 14 unmodified lines
20432143 }
20442144
20452145 void
2046−print_ScriptList(Biobuf *f, int indent, ScriptList *v)
2146+print_ScriptList(Biobuf *f, int indent, Otf *o, ScriptList *v)
20472147 {
20482148 Bprint(f, "%*s%s: %ud\n", indent, "", "scriptCount", v->scriptCount);
20492149 for(int i = 0; i < v->scriptCount; i++){
20502150 Bprint(f, "%*s%s[%d]:\n", indent, "", "scriptRecords", i);
2051− print_ScriptRecord(f, indent+indentΔ, &v->scriptRecords[i]);
2151+ print_ScriptRecord(f, indent+indentΔ, o, &v->scriptRecords[i]);
20522152 }
2153+ USED(o);
20532154 }
20542155
20552156 int
@@ -2072,12 +2173,13 @@ err: · 16 unmodified lines
20722173 }
20732174
20742175 void
2075−print_Feature(Biobuf *f, int indent, Feature *v)
2176+print_Feature(Biobuf *f, int indent, Otf *o, Feature *v)
20762177 {
20772178 Bprint(f, "%*s%s: %ud\n", indent, "", "featureParamsOffset", v->featureParamsOffset);
20782179 Bprint(f, "%*s%s: %ud\n", indent, "", "lookupIndexCount", v->lookupIndexCount);
20792180 for(int i = 0; i < v->lookupIndexCount; i++)
20802181 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "lookupListIndices", i, v->lookupListIndices[i]);
2182+ USED(o);
20812183 }
20822184
20832185 int
@@ -2106,13 +2208,14 @@ err: · 22 unmodified lines
21062208 }
21072209
21082210 void
2109−print_FeatureRecord(Biobuf *f, int indent, FeatureRecord *v)
2211+print_FeatureRecord(Biobuf *f, int indent, Otf *o, FeatureRecord *v)
21102212 {
21112213 Bprint(f, "%*s%s: %t\n", indent, "", "featureTag", v->featureTag);
21122214 Bprint(f, "%*s%s: %ud\n", indent, "", "featureOffset", v->featureOffset);
21132215 Bprint(f, "%*s%s:\n", indent, "", "feature");
21142216 if(v->feature != nil)
2115− print_Feature(f, indent+indentΔ, v->feature);
2217+ print_Feature(f, indent+indentΔ, o, v->feature);
2218+ USED(o);
21162219 }
21172220
21182221 int
@@ -2133,13 +2236,14 @@ err: · 14 unmodified lines
21332236 }
21342237
21352238 void
2136−print_FeatureList(Biobuf *f, int indent, FeatureList *v)
2239+print_FeatureList(Biobuf *f, int indent, Otf *o, FeatureList *v)
21372240 {
21382241 Bprint(f, "%*s%s: %ud\n", indent, "", "featureCount", v->featureCount);
21392242 for(int i = 0; i < v->featureCount; i++){
21402243 Bprint(f, "%*s%s[%d]:\n", indent, "", "featureRecords", i);
2141− print_FeatureRecord(f, indent+indentΔ, &v->featureRecords[i]);
2244+ print_FeatureRecord(f, indent+indentΔ, o, &v->featureRecords[i]);
21422245 }
2246+ USED(o);
21432247 }
21442248
21452249 int
@@ -2166,7 +2270,7 @@ err: · 20 unmodified lines
21662270 }
21672271
21682272 void
2169−print_Lookup(Biobuf *f, int indent, Lookup *v)
2273+print_Lookup(Biobuf *f, int indent, Otf *o, Lookup *v)
21702274 {
21712275 Bprint(f, "%*s%s: %ud\n", indent, "", "lookupType", v->lookupType);
21722276 Bprint(f, "%*s%s: %ud\n", indent, "", "lookupFlag", v->lookupFlag);
@@ -2174,6 +2278,7 @@ print_Lookup(Biobuf *f, int indent, Lookup *v) · 1 unmodified line
21742278 for(int i = 0; i < v->subTableCount; i++)
21752279 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "subtableOffsets", i, v->subtableOffsets[i]);
21762280 Bprint(f, "%*s%s: %ud\n", indent, "", "markFilteringSet", v->markFilteringSet);
2281+ USED(o);
21772282 }
21782283
21792284 int
@@ -2195,11 +2300,12 @@ err: · 15 unmodified lines
21952300 }
21962301
21972302 void
2198−print_LookupList(Biobuf *f, int indent, LookupList *v)
2303+print_LookupList(Biobuf *f, int indent, Otf *o, LookupList *v)
21992304 {
22002305 Bprint(f, "%*s%s: %ud\n", indent, "", "lookupCount", v->lookupCount);
22012306 for(int i = 0; i < v->lookupCount; i++)
22022307 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "lookupOffsets", i, v->lookupOffsets[i]);
2308+ USED(o);
22032309 }
22042310
22052311 int
@@ -2266,7 +2372,7 @@ err: · 60 unmodified lines
22662372 }
22672373
22682374 void
2269−print_TableGPOS(Biobuf *f, int indent, TableGPOS *v)
2375+print_TableGPOS(Biobuf *f, int indent, Otf *o, TableGPOS *v)
22702376 {
22712377 Bprint(f, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
22722378 Bprint(f, "%*s%s: %ud\n", indent, "", "scriptListOffset", v->scriptListOffset);
@@ -2276,13 +2382,14 @@ print_TableGPOS(Biobuf *f, int indent, TableGPOS *v) · 3 unmodified lines
22762382 Bprint(f, "%*s%s: %ud\n", indent, "", "featureVariationsOffset", v->featureVariationsOffset);
22772383 Bprint(f, "%*s%s:\n", indent, "", "scriptList");
22782384 if(v->scriptList != nil)
2279− print_ScriptList(f, indent+indentΔ, v->scriptList);
2385+ print_ScriptList(f, indent+indentΔ, o, v->scriptList);
22802386 Bprint(f, "%*s%s:\n", indent, "", "featureList");
22812387 if(v->featureList != nil)
2282− print_FeatureList(f, indent+indentΔ, v->featureList);
2388+ print_FeatureList(f, indent+indentΔ, o, v->featureList);
22832389 Bprint(f, "%*s%s:\n", indent, "", "lookupList");
22842390 if(v->lookupList != nil)
2285− print_LookupList(f, indent+indentΔ, v->lookupList);
2391+ print_LookupList(f, indent+indentΔ, o, v->lookupList);
2392+ USED(o);
22862393 }
22872394
22882395 int
@@ -2338,7 +2445,7 @@ err: · 49 unmodified lines
23382445 }
23392446
23402447 void
2341−print_TableGSUB(Biobuf *f, int indent, TableGSUB *v)
2448+print_TableGSUB(Biobuf *f, int indent, Otf *o, TableGSUB *v)
23422449 {
23432450 Bprint(f, "%*s%s: %ud\n", indent, "", "minorVersion", v->minorVersion);
23442451 Bprint(f, "%*s%s: %ud\n", indent, "", "scriptListOffset", v->scriptListOffset);
@@ -2348,10 +2455,11 @@ print_TableGSUB(Biobuf *f, int indent, TableGSUB *v) · 3 unmodified lines
23482455 Bprint(f, "%*s%s: %ud\n", indent, "", "featureVariationsOffset", v->featureVariationsOffset);
23492456 Bprint(f, "%*s%s:\n", indent, "", "scriptList");
23502457 if(v->scriptList != nil)
2351− print_ScriptList(f, indent+indentΔ, v->scriptList);
2458+ print_ScriptList(f, indent+indentΔ, o, v->scriptList);
23522459 Bprint(f, "%*s%s:\n", indent, "", "featureList");
23532460 if(v->featureList != nil)
2354− print_FeatureList(f, indent+indentΔ, v->featureList);
2461+ print_FeatureList(f, indent+indentΔ, o, v->featureList);
2462+ USED(o);
23552463 }
23562464
23572465 int
@@ -2369,10 +2477,11 @@ err: · 11 unmodified lines
23692477 }
23702478
23712479 void
2372−print_MathValueRecord(Biobuf *f, int indent, MathValueRecord *v)
2480+print_MathValueRecord(Biobuf *f, int indent, Otf *o, MathValueRecord *v)
23732481 {
23742482 Bprint(f, "%*s%s: %d\n", indent, "", "value", v->value);
23752483 Bprint(f, "%*s%s: %ud\n", indent, "", "deviceOffset", v->deviceOffset);
2484+ USED(o);
23762485 }
23772486
23782487 int
@@ -2599,115 +2708,116 @@ err: · 220 unmodified lines
25992708 }
26002709
26012710 void
2602−print_MathConstants(Biobuf *f, int indent, MathConstants *v)
2711+print_MathConstants(Biobuf *f, int indent, Otf *o, MathConstants *v)
26032712 {
26042713 Bprint(f, "%*s%s: %d\n", indent, "", "scriptPercentScaleDown", v->scriptPercentScaleDown);
26052714 Bprint(f, "%*s%s: %d\n", indent, "", "scriptScriptPercentScaleDown", v->scriptScriptPercentScaleDown);
26062715 Bprint(f, "%*s%s: %ud\n", indent, "", "delimitedSubFormulaMinHeight", v->delimitedSubFormulaMinHeight);
26072716 Bprint(f, "%*s%s: %ud\n", indent, "", "displayOperatorMinHeight", v->displayOperatorMinHeight);
26082717 Bprint(f, "%*s%s:\n", indent, "", "mathLeading");
2609− print_MathValueRecord(f, indent+indentΔ, &v->mathLeading);
2718+ print_MathValueRecord(f, indent+indentΔ, o, &v->mathLeading);
26102719 Bprint(f, "%*s%s:\n", indent, "", "axisHeight");
2611− print_MathValueRecord(f, indent+indentΔ, &v->axisHeight);
2720+ print_MathValueRecord(f, indent+indentΔ, o, &v->axisHeight);
26122721 Bprint(f, "%*s%s:\n", indent, "", "accentBaseHeight");
2613− print_MathValueRecord(f, indent+indentΔ, &v->accentBaseHeight);
2722+ print_MathValueRecord(f, indent+indentΔ, o, &v->accentBaseHeight);
26142723 Bprint(f, "%*s%s:\n", indent, "", "flattenedAccentBaseHeight");
2615− print_MathValueRecord(f, indent+indentΔ, &v->flattenedAccentBaseHeight);
2724+ print_MathValueRecord(f, indent+indentΔ, o, &v->flattenedAccentBaseHeight);
26162725 Bprint(f, "%*s%s:\n", indent, "", "subscriptShiftDown");
2617− print_MathValueRecord(f, indent+indentΔ, &v->subscriptShiftDown);
2726+ print_MathValueRecord(f, indent+indentΔ, o, &v->subscriptShiftDown);
26182727 Bprint(f, "%*s%s:\n", indent, "", "subscriptTopMax");
2619− print_MathValueRecord(f, indent+indentΔ, &v->subscriptTopMax);
2728+ print_MathValueRecord(f, indent+indentΔ, o, &v->subscriptTopMax);
26202729 Bprint(f, "%*s%s:\n", indent, "", "subscriptBaselineDropMin");
2621− print_MathValueRecord(f, indent+indentΔ, &v->subscriptBaselineDropMin);
2730+ print_MathValueRecord(f, indent+indentΔ, o, &v->subscriptBaselineDropMin);
26222731 Bprint(f, "%*s%s:\n", indent, "", "superscriptShiftUp");
2623− print_MathValueRecord(f, indent+indentΔ, &v->superscriptShiftUp);
2732+ print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptShiftUp);
26242733 Bprint(f, "%*s%s:\n", indent, "", "superscriptShiftUpCramped");
2625− print_MathValueRecord(f, indent+indentΔ, &v->superscriptShiftUpCramped);
2734+ print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptShiftUpCramped);
26262735 Bprint(f, "%*s%s:\n", indent, "", "superscriptBottomMin");
2627− print_MathValueRecord(f, indent+indentΔ, &v->superscriptBottomMin);
2736+ print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptBottomMin);
26282737 Bprint(f, "%*s%s:\n", indent, "", "superscriptBaselineDropMax");
2629− print_MathValueRecord(f, indent+indentΔ, &v->superscriptBaselineDropMax);
2738+ print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptBaselineDropMax);
26302739 Bprint(f, "%*s%s:\n", indent, "", "subSuperscriptGapMin");
2631− print_MathValueRecord(f, indent+indentΔ, &v->subSuperscriptGapMin);
2740+ print_MathValueRecord(f, indent+indentΔ, o, &v->subSuperscriptGapMin);
26322741 Bprint(f, "%*s%s:\n", indent, "", "superscriptBottomMaxWithSubscript");
2633− print_MathValueRecord(f, indent+indentΔ, &v->superscriptBottomMaxWithSubscript);
2742+ print_MathValueRecord(f, indent+indentΔ, o, &v->superscriptBottomMaxWithSubscript);
26342743 Bprint(f, "%*s%s:\n", indent, "", "spaceAfterScript");
2635− print_MathValueRecord(f, indent+indentΔ, &v->spaceAfterScript);
2744+ print_MathValueRecord(f, indent+indentΔ, o, &v->spaceAfterScript);
26362745 Bprint(f, "%*s%s:\n", indent, "", "upperLimitGapMin");
2637− print_MathValueRecord(f, indent+indentΔ, &v->upperLimitGapMin);
2746+ print_MathValueRecord(f, indent+indentΔ, o, &v->upperLimitGapMin);
26382747 Bprint(f, "%*s%s:\n", indent, "", "upperLimitBaselineRiseMin");
2639− print_MathValueRecord(f, indent+indentΔ, &v->upperLimitBaselineRiseMin);
2748+ print_MathValueRecord(f, indent+indentΔ, o, &v->upperLimitBaselineRiseMin);
26402749 Bprint(f, "%*s%s:\n", indent, "", "lowerLimitGapMin");
2641− print_MathValueRecord(f, indent+indentΔ, &v->lowerLimitGapMin);
2750+ print_MathValueRecord(f, indent+indentΔ, o, &v->lowerLimitGapMin);
26422751 Bprint(f, "%*s%s:\n", indent, "", "lowerLimitBaselineDropMin");
2643− print_MathValueRecord(f, indent+indentΔ, &v->lowerLimitBaselineDropMin);
2752+ print_MathValueRecord(f, indent+indentΔ, o, &v->lowerLimitBaselineDropMin);
26442753 Bprint(f, "%*s%s:\n", indent, "", "stackTopShiftUp");
2645− print_MathValueRecord(f, indent+indentΔ, &v->stackTopShiftUp);
2754+ print_MathValueRecord(f, indent+indentΔ, o, &v->stackTopShiftUp);
26462755 Bprint(f, "%*s%s:\n", indent, "", "stackTopDisplayStyleShiftUp");
2647− print_MathValueRecord(f, indent+indentΔ, &v->stackTopDisplayStyleShiftUp);
2756+ print_MathValueRecord(f, indent+indentΔ, o, &v->stackTopDisplayStyleShiftUp);
26482757 Bprint(f, "%*s%s:\n", indent, "", "stackBottomShiftDown");
2649− print_MathValueRecord(f, indent+indentΔ, &v->stackBottomShiftDown);
2758+ print_MathValueRecord(f, indent+indentΔ, o, &v->stackBottomShiftDown);
26502759 Bprint(f, "%*s%s:\n", indent, "", "stackBottomDisplayStyleShiftDown");
2651− print_MathValueRecord(f, indent+indentΔ, &v->stackBottomDisplayStyleShiftDown);
2760+ print_MathValueRecord(f, indent+indentΔ, o, &v->stackBottomDisplayStyleShiftDown);
26522761 Bprint(f, "%*s%s:\n", indent, "", "stackGapMin");
2653− print_MathValueRecord(f, indent+indentΔ, &v->stackGapMin);
2762+ print_MathValueRecord(f, indent+indentΔ, o, &v->stackGapMin);
26542763 Bprint(f, "%*s%s:\n", indent, "", "stackDisplayStyleGapMin");
2655− print_MathValueRecord(f, indent+indentΔ, &v->stackDisplayStyleGapMin);
2764+ print_MathValueRecord(f, indent+indentΔ, o, &v->stackDisplayStyleGapMin);
26562765 Bprint(f, "%*s%s:\n", indent, "", "stretchStackTopShiftUp");
2657− print_MathValueRecord(f, indent+indentΔ, &v->stretchStackTopShiftUp);
2766+ print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackTopShiftUp);
26582767 Bprint(f, "%*s%s:\n", indent, "", "stretchStackBottomShiftDown");
2659− print_MathValueRecord(f, indent+indentΔ, &v->stretchStackBottomShiftDown);
2768+ print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackBottomShiftDown);
26602769 Bprint(f, "%*s%s:\n", indent, "", "stretchStackGapAboveMin");
2661− print_MathValueRecord(f, indent+indentΔ, &v->stretchStackGapAboveMin);
2770+ print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackGapAboveMin);
26622771 Bprint(f, "%*s%s:\n", indent, "", "stretchStackGapBelowMin");
2663− print_MathValueRecord(f, indent+indentΔ, &v->stretchStackGapBelowMin);
2772+ print_MathValueRecord(f, indent+indentΔ, o, &v->stretchStackGapBelowMin);
26642773 Bprint(f, "%*s%s:\n", indent, "", "fractionNumeratorShiftUp");
2665− print_MathValueRecord(f, indent+indentΔ, &v->fractionNumeratorShiftUp);
2774+ print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumeratorShiftUp);
26662775 Bprint(f, "%*s%s:\n", indent, "", "fractionNumeratorDisplayStyleShiftUp");
2667− print_MathValueRecord(f, indent+indentΔ, &v->fractionNumeratorDisplayStyleShiftUp);
2776+ print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumeratorDisplayStyleShiftUp);
26682777 Bprint(f, "%*s%s:\n", indent, "", "fractionDenominatorShiftDown");
2669− print_MathValueRecord(f, indent+indentΔ, &v->fractionDenominatorShiftDown);
2778+ print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenominatorShiftDown);
26702779 Bprint(f, "%*s%s:\n", indent, "", "fractionDenominatorDisplayStyleShiftDown");
2671− print_MathValueRecord(f, indent+indentΔ, &v->fractionDenominatorDisplayStyleShiftDown);
2780+ print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenominatorDisplayStyleShiftDown);
26722781 Bprint(f, "%*s%s:\n", indent, "", "fractionNumeratorGapMin");
2673− print_MathValueRecord(f, indent+indentΔ, &v->fractionNumeratorGapMin);
2782+ print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumeratorGapMin);
26742783 Bprint(f, "%*s%s:\n", indent, "", "fractionNumDisplayStyleGapMin");
2675− print_MathValueRecord(f, indent+indentΔ, &v->fractionNumDisplayStyleGapMin);
2784+ print_MathValueRecord(f, indent+indentΔ, o, &v->fractionNumDisplayStyleGapMin);
26762785 Bprint(f, "%*s%s:\n", indent, "", "fractionRuleThickness");
2677− print_MathValueRecord(f, indent+indentΔ, &v->fractionRuleThickness);
2786+ print_MathValueRecord(f, indent+indentΔ, o, &v->fractionRuleThickness);
26782787 Bprint(f, "%*s%s:\n", indent, "", "fractionDenominatorGapMin");
2679− print_MathValueRecord(f, indent+indentΔ, &v->fractionDenominatorGapMin);
2788+ print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenominatorGapMin);
26802789 Bprint(f, "%*s%s:\n", indent, "", "fractionDenomDisplayStyleGapMin");
2681− print_MathValueRecord(f, indent+indentΔ, &v->fractionDenomDisplayStyleGapMin);
2790+ print_MathValueRecord(f, indent+indentΔ, o, &v->fractionDenomDisplayStyleGapMin);
26822791 Bprint(f, "%*s%s:\n", indent, "", "skewedFractionHorizontalGap");
2683− print_MathValueRecord(f, indent+indentΔ, &v->skewedFractionHorizontalGap);
2792+ print_MathValueRecord(f, indent+indentΔ, o, &v->skewedFractionHorizontalGap);
26842793 Bprint(f, "%*s%s:\n", indent, "", "skewedFractionVerticalGap");
2685− print_MathValueRecord(f, indent+indentΔ, &v->skewedFractionVerticalGap);
2794+ print_MathValueRecord(f, indent+indentΔ, o, &v->skewedFractionVerticalGap);
26862795 Bprint(f, "%*s%s:\n", indent, "", "overbarVerticalGap");
2687− print_MathValueRecord(f, indent+indentΔ, &v->overbarVerticalGap);
2796+ print_MathValueRecord(f, indent+indentΔ, o, &v->overbarVerticalGap);
26882797 Bprint(f, "%*s%s:\n", indent, "", "overbarRuleThickness");
2689− print_MathValueRecord(f, indent+indentΔ, &v->overbarRuleThickness);
2798+ print_MathValueRecord(f, indent+indentΔ, o, &v->overbarRuleThickness);
26902799 Bprint(f, "%*s%s:\n", indent, "", "overbarExtraAscender");
2691− print_MathValueRecord(f, indent+indentΔ, &v->overbarExtraAscender);
2800+ print_MathValueRecord(f, indent+indentΔ, o, &v->overbarExtraAscender);
26922801 Bprint(f, "%*s%s:\n", indent, "", "underbarVerticalGap");
2693− print_MathValueRecord(f, indent+indentΔ, &v->underbarVerticalGap);
2802+ print_MathValueRecord(f, indent+indentΔ, o, &v->underbarVerticalGap);
26942803 Bprint(f, "%*s%s:\n", indent, "", "underbarRuleThickness");
2695− print_MathValueRecord(f, indent+indentΔ, &v->underbarRuleThickness);
2804+ print_MathValueRecord(f, indent+indentΔ, o, &v->underbarRuleThickness);
26962805 Bprint(f, "%*s%s:\n", indent, "", "underbarExtraDescender");
2697− print_MathValueRecord(f, indent+indentΔ, &v->underbarExtraDescender);
2806+ print_MathValueRecord(f, indent+indentΔ, o, &v->underbarExtraDescender);
26982807 Bprint(f, "%*s%s:\n", indent, "", "radicalVerticalGap");
2699− print_MathValueRecord(f, indent+indentΔ, &v->radicalVerticalGap);
2808+ print_MathValueRecord(f, indent+indentΔ, o, &v->radicalVerticalGap);
27002809 Bprint(f, "%*s%s:\n", indent, "", "radicalDisplayStyleVerticalGap");
2701− print_MathValueRecord(f, indent+indentΔ, &v->radicalDisplayStyleVerticalGap);
2810+ print_MathValueRecord(f, indent+indentΔ, o, &v->radicalDisplayStyleVerticalGap);
27022811 Bprint(f, "%*s%s:\n", indent, "", "radicalRuleThickness");
2703− print_MathValueRecord(f, indent+indentΔ, &v->radicalRuleThickness);
2812+ print_MathValueRecord(f, indent+indentΔ, o, &v->radicalRuleThickness);
27042813 Bprint(f, "%*s%s:\n", indent, "", "radicalExtraAscender");
2705− print_MathValueRecord(f, indent+indentΔ, &v->radicalExtraAscender);
2814+ print_MathValueRecord(f, indent+indentΔ, o, &v->radicalExtraAscender);
27062815 Bprint(f, "%*s%s:\n", indent, "", "radicalKernBeforeDegree");
2707− print_MathValueRecord(f, indent+indentΔ, &v->radicalKernBeforeDegree);
2816+ print_MathValueRecord(f, indent+indentΔ, o, &v->radicalKernBeforeDegree);
27082817 Bprint(f, "%*s%s:\n", indent, "", "radicalKernAfterDegree");
2709− print_MathValueRecord(f, indent+indentΔ, &v->radicalKernAfterDegree);
2818+ print_MathValueRecord(f, indent+indentΔ, o, &v->radicalKernAfterDegree);
27102819 Bprint(f, "%*s%s: %d\n", indent, "", "radicalDegreeBottomRaisePercent", v->radicalDegreeBottomRaisePercent);
2820+ USED(o);
27112821 }
27122822
27132823 int
@@ -2729,14 +2839,15 @@ err: · 15 unmodified lines
27292839 }
27302840
27312841 void
2732−print_MathItalicsCorrectionInfo(Biobuf *f, int indent, MathItalicsCorrectionInfo *v)
2842+print_MathItalicsCorrectionInfo(Biobuf *f, int indent, Otf *o, MathItalicsCorrectionInfo *v)
27332843 {
27342844 Bprint(f, "%*s%s: %ud\n", indent, "", "italicsCorrectionCoverageOffset", v->italicsCorrectionCoverageOffset);
27352845 Bprint(f, "%*s%s: %ud\n", indent, "", "italicsCorrectionCount", v->italicsCorrectionCount);
27362846 for(int i = 0; i < v->italicsCorrectionCount; i++){
27372847 Bprint(f, "%*s%s[%d]:\n", indent, "", "italicsCorrection", i);
2738− print_MathValueRecord(f, indent+indentΔ, &v->italicsCorrection[i]);
2848+ print_MathValueRecord(f, indent+indentΔ, o, &v->italicsCorrection[i]);
27392849 }
2850+ USED(o);
27402851 }
27412852
27422853 int
@@ -2758,14 +2869,15 @@ err: · 15 unmodified lines
27582869 }
27592870
27602871 void
2761−print_MathTopAccentAttachment(Biobuf *f, int indent, MathTopAccentAttachment *v)
2872+print_MathTopAccentAttachment(Biobuf *f, int indent, Otf *o, MathTopAccentAttachment *v)
27622873 {
27632874 Bprint(f, "%*s%s: %ud\n", indent, "", "topAccentCoverageOffset", v->topAccentCoverageOffset);
27642875 Bprint(f, "%*s%s: %ud\n", indent, "", "topAccentAttachmentCount", v->topAccentAttachmentCount);
27652876 for(int i = 0; i < v->topAccentAttachmentCount; i++){
27662877 Bprint(f, "%*s%s[%d]:\n", indent, "", "topAccentAttachment", i);
2767− print_MathValueRecord(f, indent+indentΔ, &v->topAccentAttachment[i]);
2878+ print_MathValueRecord(f, indent+indentΔ, o, &v->topAccentAttachment[i]);
27682879 }
2880+ USED(o);
27692881 }
27702882
27712883 int
@@ -2785,12 +2897,13 @@ err: · 13 unmodified lines
27852897 }
27862898
27872899 void
2788−print_MathKernInfoRecord(Biobuf *f, int indent, MathKernInfoRecord *v)
2900+print_MathKernInfoRecord(Biobuf *f, int indent, Otf *o, MathKernInfoRecord *v)
27892901 {
27902902 Bprint(f, "%*s%s: %ud\n", indent, "", "topRightMathKernOffset", v->topRightMathKernOffset);
27912903 Bprint(f, "%*s%s: %ud\n", indent, "", "topLeftMathKernOffset", v->topLeftMathKernOffset);
27922904 Bprint(f, "%*s%s: %ud\n", indent, "", "bottomRightMathKernOffset", v->bottomRightMathKernOffset);
27932905 Bprint(f, "%*s%s: %ud\n", indent, "", "bottomLeftMathKernOffset", v->bottomLeftMathKernOffset);
2906+ USED(o);
27942907 }
27952908
27962909 int
@@ -2812,14 +2925,15 @@ err: · 15 unmodified lines
28122925 }
28132926
28142927 void
2815−print_MathKernInfo(Biobuf *f, int indent, MathKernInfo *v)
2928+print_MathKernInfo(Biobuf *f, int indent, Otf *o, MathKernInfo *v)
28162929 {
28172930 Bprint(f, "%*s%s: %ud\n", indent, "", "mathKernCoverageOffset", v->mathKernCoverageOffset);
28182931 Bprint(f, "%*s%s: %ud\n", indent, "", "mathKernCount", v->mathKernCount);
28192932 for(int i = 0; i < v->mathKernCount; i++){
28202933 Bprint(f, "%*s%s[%d]:\n", indent, "", "mathKernInfoRecords", i);
2821− print_MathKernInfoRecord(f, indent+indentΔ, &v->mathKernInfoRecords[i]);
2934+ print_MathKernInfoRecord(f, indent+indentΔ, o, &v->mathKernInfoRecords[i]);
28222935 }
2936+ USED(o);
28232937 }
28242938
28252939 int
@@ -2844,17 +2958,18 @@ err: · 18 unmodified lines
28442958 }
28452959
28462960 void
2847−print_MathKern(Biobuf *f, int indent, MathKern *v)
2961+print_MathKern(Biobuf *f, int indent, Otf *o, MathKern *v)
28482962 {
28492963 Bprint(f, "%*s%s: %ud\n", indent, "", "heightCount", v->heightCount);
28502964 for(int i = 0; i < v->heightCount; i++){
28512965 Bprint(f, "%*s%s[%d]:\n", indent, "", "correctionHeight", i);
2852− print_MathValueRecord(f, indent+indentΔ, &v->correctionHeight[i]);
2966+ print_MathValueRecord(f, indent+indentΔ, o, &v->correctionHeight[i]);
28532967 }
28542968 for(int i = 0; i < v->heightCount; i++){
28552969 Bprint(f, "%*s%s[%d]:\n", indent, "", "kernValues", i);
2856− print_MathValueRecord(f, indent+indentΔ, &v->kernValues[i]);
2970+ print_MathValueRecord(f, indent+indentΔ, o, &v->kernValues[i]);
28572971 }
2972+ USED(o);
28582973 }
28592974
28602975 int
@@ -2876,11 +2991,12 @@ err: · 15 unmodified lines
28762991 }
28772992
28782993 void
2879−print_Coverage1(Biobuf *f, int indent, Coverage1 *v)
2994+print_Coverage1(Biobuf *f, int indent, Otf *o, Coverage1 *v)
28802995 {
28812996 Bprint(f, "%*s%s: %ud\n", indent, "", "glyphCount", v->glyphCount);
28822997 for(int i = 0; i < v->glyphCount; i++)
28832998 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "glyphArray", i, v->glyphArray[i]);
2999+ USED(o);
28843000 }
28853001
28863002 int
@@ -2899,11 +3015,12 @@ err: · 12 unmodified lines
28993015 }
29003016
29013017 void
2902−print_RangeRecord(Biobuf *f, int indent, RangeRecord *v)
3018+print_RangeRecord(Biobuf *f, int indent, Otf *o, RangeRecord *v)
29033019 {
29043020 Bprint(f, "%*s%s: %ud\n", indent, "", "startGlyphID", v->startGlyphID);
29053021 Bprint(f, "%*s%s: %ud\n", indent, "", "endGlyphID", v->endGlyphID);
29063022 Bprint(f, "%*s%s: %ud\n", indent, "", "startCoverageIndex", v->startCoverageIndex);
3023+ USED(o);
29073024 }
29083025
29093026 int
@@ -2924,13 +3041,14 @@ err: · 14 unmodified lines
29243041 }
29253042
29263043 void
2927−print_Coverage2(Biobuf *f, int indent, Coverage2 *v)
3044+print_Coverage2(Biobuf *f, int indent, Otf *o, Coverage2 *v)
29283045 {
29293046 Bprint(f, "%*s%s: %ud\n", indent, "", "rangeCount", v->rangeCount);
29303047 for(int i = 0; i < v->rangeCount; i++){
29313048 Bprint(f, "%*s%s[%d]:\n", indent, "", "rangeRecords", i);
2932− print_RangeRecord(f, indent+indentΔ, &v->rangeRecords[i]);
3049+ print_RangeRecord(f, indent+indentΔ, o, &v->rangeRecords[i]);
29333050 }
3051+ USED(o);
29343052 }
29353053
29363054 int
@@ -2963,17 +3081,18 @@ err: · 26 unmodified lines
29633081 }
29643082
29653083 void
2966−print_Coverage(Biobuf *f, int indent, Coverage *v)
3084+print_Coverage(Biobuf *f, int indent, Otf *o, Coverage *v)
29673085 {
29683086 Bprint(f, "%*s%s: %ud\n", indent, "", "format", v->format);
29693087 if(v->format == 1){
29703088 Bprint(f, "%*s%s:\n", indent, "", "cov1");
2971− print_Coverage1(f, indent+indentΔ, &v->cov1);
3089+ print_Coverage1(f, indent+indentΔ, o, &v->cov1);
29723090 }
29733091 if(v->format == 2){
29743092 Bprint(f, "%*s%s:\n", indent, "", "cov2");
2975− print_Coverage2(f, indent+indentΔ, &v->cov2);
3093+ print_Coverage2(f, indent+indentΔ, o, &v->cov2);
29763094 }
3095+ USED(o);
29773096 }
29783097
29793098 int
@@ -3026,7 +3145,7 @@ err: · 46 unmodified lines
30263145 }
30273146
30283147 void
3029−print_MathVariants(Biobuf *f, int indent, MathVariants *v)
3148+print_MathVariants(Biobuf *f, int indent, Otf *o, MathVariants *v)
30303149 {
30313150 Bprint(f, "%*s%s: %ud\n", indent, "", "minConnectorOverlap", v->minConnectorOverlap);
30323151 Bprint(f, "%*s%s: %ud\n", indent, "", "vertGlyphCoverageOffset", v->vertGlyphCoverageOffset);
@@ -3039,10 +3158,11 @@ print_MathVariants(Biobuf *f, int indent, MathVariants *v) · 6 unmodified lines
30393158 Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "horizGlyphConstructionOffsets", i, v->horizGlyphConstructionOffsets[i]);
30403159 Bprint(f, "%*s%s:\n", indent, "", "vertGlyphCoverage");
30413160 if(v->vertGlyphCoverage != nil)
3042− print_Coverage(f, indent+indentΔ, v->vertGlyphCoverage);
3161+ print_Coverage(f, indent+indentΔ, o, v->vertGlyphCoverage);
30433162 Bprint(f, "%*s%s:\n", indent, "", "horizGlyphCoverage");
30443163 if(v->horizGlyphCoverage != nil)
3045− print_Coverage(f, indent+indentΔ, v->horizGlyphCoverage);
3164+ print_Coverage(f, indent+indentΔ, o, v->horizGlyphCoverage);
3165+ USED(o);
30463166 }
30473167
30483168 int
@@ -3106,7 +3226,7 @@ err: · 57 unmodified lines
31063226 }
31073227
31083228 void
3109−print_MathGlyphInfo(Biobuf *f, int indent, MathGlyphInfo *v)
3229+print_MathGlyphInfo(Biobuf *f, int indent, Otf *o, MathGlyphInfo *v)
31103230 {
31113231 Bprint(f, "%*s%s: %ud\n", indent, "", "mathItalicsCorrectionInfoOffset", v->mathItalicsCorrectionInfoOffset);
31123232 Bprint(f, "%*s%s: %ud\n", indent, "", "mathTopAccentAttachmentOffset", v->mathTopAccentAttachmentOffset);
@@ -3114,16 +3234,17 @@ print_MathGlyphInfo(Biobuf *f, int indent, MathGlyphInfo *v) · 1 unmodified line
31143234 Bprint(f, "%*s%s: %ud\n", indent, "", "mathKernInfoOffset", v->mathKernInfoOffset);
31153235 Bprint(f, "%*s%s:\n", indent, "", "mathItalicsCorrectionInfo");
31163236 if(v->mathItalicsCorrectionInfo != nil)
3117− print_MathItalicsCorrectionInfo(f, indent+indentΔ, v->mathItalicsCorrectionInfo);
3237+ print_MathItalicsCorrectionInfo(f, indent+indentΔ, o, v->mathItalicsCorrectionInfo);
31183238 Bprint(f, "%*s%s:\n", indent, "", "mathTopAccentAttachment");
31193239 if(v->mathTopAccentAttachment != nil)
3120− print_MathTopAccentAttachment(f, indent+indentΔ, v->mathTopAccentAttachment);
3240+ print_MathTopAccentAttachment(f, indent+indentΔ, o, v->mathTopAccentAttachment);
31213241 Bprint(f, "%*s%s:\n", indent, "", "mathKernInfo");
31223242 if(v->mathKernInfo != nil)
3123− print_MathKernInfo(f, indent+indentΔ, v->mathKernInfo);
3243+ print_MathKernInfo(f, indent+indentΔ, o, v->mathKernInfo);
31243244 Bprint(f, "%*s%s:\n", indent, "", "extendedShapeCoverage");
31253245 if(v->extendedShapeCoverage != nil)
3126− print_Coverage(f, indent+indentΔ, v->extendedShapeCoverage);
3246+ print_Coverage(f, indent+indentΔ, o, v->extendedShapeCoverage);
3247+ USED(o);
31273248 }
31283249
31293250 int
@@ -3141,10 +3262,11 @@ err: · 11 unmodified lines
31413262 }
31423263
31433264 void
3144−print_MathGlyphVariantRecord(Biobuf *f, int indent, MathGlyphVariantRecord *v)
3265+print_MathGlyphVariantRecord(Biobuf *f, int indent, Otf *o, MathGlyphVariantRecord *v)
31453266 {
31463267 Bprint(f, "%*s%s: %ud\n", indent, "", "variantGlyph", v->variantGlyph);
31473268 Bprint(f, "%*s%s: %ud\n", indent, "", "advanceMeasurement", v->advanceMeasurement);
3269+ USED(o);
31483270 }
31493271
31503272 int
@@ -3165,13 +3287,14 @@ err: · 14 unmodified lines
31653287 }
31663288
31673289 void
3168−print_GlyphPart(Biobuf *f, int indent, GlyphPart *v)
3290+print_GlyphPart(Biobuf *f, int indent, Otf *o, GlyphPart *v)
31693291 {
31703292 Bprint(f, "%*s%s: %ud\n", indent, "", "glyphID", v->glyphID);
31713293 Bprint(f, "%*s%s: %ud\n", indent, "", "startConnectorLength", v->startConnectorLength);
31723294 Bprint(f, "%*s%s: %ud\n", indent, "", "endConnectorLength", v->endConnectorLength);
31733295 Bprint(f, "%*s%s: %ud\n", indent, "", "fullAdvance", v->fullAdvance);
31743296 Bprint(f, "%*s%s: %ud\n", indent, "", "partFlags", v->partFlags);
3297+ USED(o);
31753298 }
31763299
31773300 int
@@ -3196,15 +3319,16 @@ err: · 18 unmodified lines
31963319 }
31973320
31983321 void
3199−print_GlyphAssembly(Biobuf *f, int indent, GlyphAssembly *v)
3322+print_GlyphAssembly(Biobuf *f, int indent, Otf *o, GlyphAssembly *v)
32003323 {
32013324 Bprint(f, "%*s%s:\n", indent, "", "italicsCorrection");
3202− print_MathValueRecord(f, indent+indentΔ, &v->italicsCorrection);
3325+ print_MathValueRecord(f, indent+indentΔ, o, &v->italicsCorrection);
32033326 Bprint(f, "%*s%s: %ud\n", indent, "", "partCount", v->partCount);
32043327 for(int i = 0; i < v->partCount; i++){
32053328 Bprint(f, "%*s%s[%d]:\n", indent, "", "partRecords", i);
3206− print_GlyphPart(f, indent+indentΔ, &v->partRecords[i]);
3329+ print_GlyphPart(f, indent+indentΔ, o, &v->partRecords[i]);
32073330 }
3331+ USED(o);
32083332 }
32093333
32103334 int
@@ -3237,17 +3361,18 @@ err: · 26 unmodified lines
32373361 }
32383362
32393363 void
3240−print_MathGlyphConstruction(Biobuf *f, int indent, MathGlyphConstruction *v)
3364+print_MathGlyphConstruction(Biobuf *f, int indent, Otf *o, MathGlyphConstruction *v)
32413365 {
32423366 Bprint(f, "%*s%s: %ud\n", indent, "", "glyphAssemblyOffset", v->glyphAssemblyOffset);
32433367 Bprint(f, "%*s%s: %ud\n", indent, "", "variantCount", v->variantCount);
32443368 for(int i = 0; i < v->variantCount; i++){
32453369 Bprint(f, "%*s%s[%d]:\n", indent, "", "mathGlyphVariantRecords", i);
3246− print_MathGlyphVariantRecord(f, indent+indentΔ, &v->mathGlyphVariantRecords[i]);
3370+ print_MathGlyphVariantRecord(f, indent+indentΔ, o, &v->mathGlyphVariantRecords[i]);
32473371 }
32483372 Bprint(f, "%*s%s:\n", indent, "", "glyphAssembly");
32493373 if(v->glyphAssembly != nil)
3250− print_GlyphAssembly(f, indent+indentΔ, v->glyphAssembly);
3374+ print_GlyphAssembly(f, indent+indentΔ, o, v->glyphAssembly);
3375+ USED(o);
32513376 }
32523377
32533378 int
@@ -3309,20 +3434,271 @@ err: · 55 unmodified lines
33093434 }
33103435
33113436 void
3312−print_TableMATH(Biobuf *f, int indent, TableMATH *v)
3437+print_TableMATH(Biobuf *f, int indent, Otf *o, TableMATH *v)
33133438 {
33143439 Bprint(f, "%*s%s: %ud\n", indent, "", "mathConstantsOffset", v->mathConstantsOffset);
33153440 Bprint(f, "%*s%s: %ud\n", indent, "", "mathGlyphInfoOffset", v->mathGlyphInfoOffset);
33163441 Bprint(f, "%*s%s: %ud\n", indent, "", "mathVariantsOffset", v->mathVariantsOffset);
33173442 Bprint(f, "%*s%s:\n", indent, "", "mathConstants");
33183443 if(v->mathConstants != nil)
3319− print_MathConstants(f, indent+indentΔ, v->mathConstants);
3444+ print_MathConstants(f, indent+indentΔ, o, v->mathConstants);
33203445 Bprint(f, "%*s%s:\n", indent, "", "mathGlyphInfo");
33213446 if(v->mathGlyphInfo != nil)
3322− print_MathGlyphInfo(f, indent+indentΔ, v->mathGlyphInfo);
3447+ print_MathGlyphInfo(f, indent+indentΔ, o, v->mathGlyphInfo);
33233448 Bprint(f, "%*s%s:\n", indent, "", "mathVariants");
33243449 if(v->mathVariants != nil)
3325− print_MathVariants(f, indent+indentΔ, v->mathVariants);
3450+ print_MathVariants(f, indent+indentΔ, o, v->mathVariants);
3451+ USED(o);
3452+}
3453+
3454+int
3455+read_KernPair(Otf *o, KernPair *v)
3456+{
3457+ u8int *b;
3458+ if((b = otfreadn(o, 6)) == nil)
3459+ goto err;
3460+ v->left = b[0]<<8 | b[1];
3461+ v->right = b[2]<<8 | b[3];
3462+ v->value = b[4]<<8 | b[5];
3463+ return 0;
3464+err:
3465+ werrstr("%s: %r", "KernPair");
3466+ return -1;
3467+}
3468+
3469+void
3470+print_KernPair(Biobuf *f, int indent, Otf *o, KernPair *v)
3471+{
3472+ Bprint(f, "%*s%s: %ud\n", indent, "", "left", v->left);
3473+ Bprint(f, "%*s%s: %ud\n", indent, "", "right", v->right);
3474+ Bprint(f, "%*s%s: %d\n", indent, "", "value", v->value);
3475+ USED(o);
3476+}
3477+
3478+int
3479+read_KernSubtable0(Otf *o, KernSubtable0 *v)
3480+{
3481+ u8int *b;
3482+ if((b = otfreadn(o, 8)) == nil)
3483+ goto err;
3484+ v->nPairs = b[0]<<8 | b[1];
3485+ v->searchRange = b[2]<<8 | b[3];
3486+ v->entrySelector = b[4]<<8 | b[5];
3487+ v->rangeShift = b[6]<<8 | b[7];
3488+ if(otfarray(o, &v->kernPairs, read_KernPair, sizeof(KernPair), v->nPairs) < 0){
3489+ werrstr("%s: %r", "kernPairs");
3490+ goto err;
3491+ }
3492+ return 0;
3493+err:
3494+ werrstr("%s: %r", "KernSubtable0");
3495+ return -1;
3496+}
3497+
3498+void
3499+print_KernSubtable0(Biobuf *f, int indent, Otf *o, KernSubtable0 *v)
3500+{
3501+ Bprint(f, "%*s%s: %ud\n", indent, "", "nPairs", v->nPairs);
3502+ Bprint(f, "%*s%s: %ud\n", indent, "", "searchRange", v->searchRange);
3503+ Bprint(f, "%*s%s: %ud\n", indent, "", "entrySelector", v->entrySelector);
3504+ Bprint(f, "%*s%s: %ud\n", indent, "", "rangeShift", v->rangeShift);
3505+ for(int i = 0; i < v->nPairs; i++){
3506+ Bprint(f, "%*s%s[%d]:\n", indent, "", "kernPairs", i);
3507+ print_KernPair(f, indent+indentΔ, o, &v->kernPairs[i]);
3508+ }
3509+ USED(o);
3510+}
3511+
3512+int
3513+read_KernClass(Otf *o, KernClass *v)
3514+{
3515+ u8int *b;
3516+ if((b = otfreadn(o, 4)) == nil)
3517+ goto err;
3518+ v->firstGlyph = b[0]<<8 | b[1];
3519+ v->nGlyphs = b[2]<<8 | b[3];
3520+ if((b = otfreadn(o, v->nGlyphs*2)) == nil)
3521+ goto err;
3522+ v->values = malloc(v->nGlyphs*sizeof(*v->values));
3523+ for(int i = 0; i < v->nGlyphs; i++)
3524+ v->values[i] = b[0+i*2]<<8 | b[1+i*2];
3525+ return 0;
3526+err:
3527+ werrstr("%s: %r", "KernClass");
3528+ return -1;
3529+}
3530+
3531+void
3532+print_KernClass(Biobuf *f, int indent, Otf *o, KernClass *v)
3533+{
3534+ Bprint(f, "%*s%s: %ud\n", indent, "", "firstGlyph", v->firstGlyph);
3535+ Bprint(f, "%*s%s: %ud\n", indent, "", "nGlyphs", v->nGlyphs);
3536+ for(int i = 0; i < v->nGlyphs; i++)
3537+ Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "values", i, v->values[i]);
3538+ USED(o);
3539+}
3540+
3541+int
3542+read_KernSubtable2(Otf *o, KernSubtable2 *v)
3543+{
3544+ u8int *b;
3545+ if((b = otfreadn(o, 8)) == nil)
3546+ goto err;
3547+ v->rowWidth = b[0]<<8 | b[1];
3548+ v->leftClassOffset = b[2]<<8 | b[3];
3549+ v->rightClassOffset = b[4]<<8 | b[5];
3550+ v->kerningArrayOffset = b[6]<<8 | b[7];
3551+ if(v->leftClassOffset != 0){
3552+ if(otfpushrange(o, v->leftClassOffset, -1) < 0)
3553+ goto err;
3554+ v->leftClass = calloc(1, sizeof(*v->leftClass));
3555+ if(read_KernClass(o, v->leftClass) < 0){
3556+ werrstr("%s: %r", "leftClass");
3557+ goto err;
3558+ }
3559+ if(otfpoprange(o) < 0)
3560+ goto err;
3561+ }
3562+ if(v->rightClassOffset != 0){
3563+ if(otfpushrange(o, v->rightClassOffset, -1) < 0)
3564+ goto err;
3565+ v->rightClass = calloc(1, sizeof(*v->rightClass));
3566+ if(read_KernClass(o, v->rightClass) < 0){
3567+ werrstr("%s: %r", "rightClass");
3568+ goto err;
3569+ }
3570+ if(otfpoprange(o) < 0)
3571+ goto err;
3572+ }
3573+ if((b = otfreadn(o, (v->rowWidth/2)*2)) == nil)
3574+ goto err;
3575+ v->kerningArray = malloc((v->rowWidth/2)*sizeof(*v->kerningArray));
3576+ for(int i = 0; i < (v->rowWidth/2); i++)
3577+ v->kerningArray[i] = b[0+i*2]<<8 | b[1+i*2];
3578+ return 0;
3579+err:
3580+ werrstr("%s: %r", "KernSubtable2");
3581+ return -1;
3582+}
3583+
3584+void
3585+print_KernSubtable2(Biobuf *f, int indent, Otf *o, KernSubtable2 *v)
3586+{
3587+ Bprint(f, "%*s%s: %ud\n", indent, "", "rowWidth", v->rowWidth);
3588+ Bprint(f, "%*s%s: %ud\n", indent, "", "leftClassOffset", v->leftClassOffset);
3589+ Bprint(f, "%*s%s: %ud\n", indent, "", "rightClassOffset", v->rightClassOffset);
3590+ Bprint(f, "%*s%s: %ud\n", indent, "", "kerningArrayOffset", v->kerningArrayOffset);
3591+ Bprint(f, "%*s%s:\n", indent, "", "leftClass");
3592+ if(v->leftClass != nil)
3593+ print_KernClass(f, indent+indentΔ, o, v->leftClass);
3594+ Bprint(f, "%*s%s:\n", indent, "", "rightClass");
3595+ if(v->rightClass != nil)
3596+ print_KernClass(f, indent+indentΔ, o, v->rightClass);
3597+ for(int i = 0; i < (v->rowWidth/2); i++)
3598+ Bprint(f, "%*s%s[%d]: %d\n", indent, "", "kerningArray", i, v->kerningArray[i]);
3599+ USED(o);
3600+}
3601+
3602+int
3603+read_KernSubtable(Otf *o, KernSubtable *v)
3604+{
3605+ u8int *b;
3606+ if((b = otfreadn(o, 6)) == nil)
3607+ goto err;
3608+ u16int version = b[0]<<8 | b[1];
3609+ if(version != 0){
3610+ werrstr("%s: invalid value: %d (0x%ux)", "version", version, version);
3611+ goto err;
3612+ }
3613+ v->length = b[2]<<8 | b[3];
3614+ if(v->length < 6){
3615+ werrstr("%s: invalid value: %d (0x%ux)", "length", v->length, v->length);
3616+ goto err;
3617+ }
3618+ v->coverage = b[4]<<8 | b[5];
3619+ return 0;
3620+err:
3621+ werrstr("%s: %r", "KernSubtable");
3622+ return -1;
3623+}
3624+
3625+void
3626+print_KernSubtable(Biobuf *f, int indent, Otf *o, KernSubtable *v)
3627+{
3628+ Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
3629+ Bprint(f, "%*s%s: %ud\n", indent, "", "coverage", v->coverage);
3630+ USED(o);
3631+}
3632+
3633+int
3634+read_TableKern(Otf *o, TableKern *v)
3635+{
3636+ u8int *b;
3637+ if((b = otfreadn(o, 4)) == nil)
3638+ goto err;
3639+ u16int version = b[0]<<8 | b[1];
3640+ if(version != 0){
3641+ werrstr("%s: invalid value: %d (0x%ux)", "version", version, version);
3642+ goto err;
3643+ }
3644+ v->nTables = b[2]<<8 | b[3];
3645+ if(otfarray(o, &v->subtables, read_KernSubtable, sizeof(KernSubtable), v->nTables) < 0){
3646+ werrstr("%s: %r", "subtables");
3647+ goto err;
3648+ }
3649+ return 0;
3650+err:
3651+ werrstr("%s: %r", "TableKern");
3652+ return -1;
3653+}
3654+
3655+void
3656+print_TableKern(Biobuf *f, int indent, Otf *o, TableKern *v)
3657+{
3658+ Bprint(f, "%*s%s: %ud\n", indent, "", "nTables", v->nTables);
3659+ for(int i = 0; i < v->nTables; i++){
3660+ Bprint(f, "%*s%s[%d]:\n", indent, "", "subtables", i);
3661+ print_KernSubtable(f, indent+indentΔ, o, &v->subtables[i]);
3662+ }
3663+ USED(o);
3664+}
3665+
3666+int
3667+read_TableLoca(Otf *o, TableLoca *v)
3668+{
3669+ u8int *b;
3670+ if(o->indexToLocFormat == 0){
3671+ if((b = otfreadn(o, (o->numGlyphs+1)*2)) == nil)
3672+ goto err;
3673+ v->shortOffsets = malloc((o->numGlyphs+1)*sizeof(*v->shortOffsets));
3674+ for(int i = 0; i < (o->numGlyphs+1); i++)
3675+ v->shortOffsets[i] = b[0+i*2]<<8 | b[1+i*2];
3676+ }
3677+ if(o->indexToLocFormat == 1){
3678+ if((b = otfreadn(o, (o->numGlyphs+1)*4)) == nil)
3679+ goto err;
3680+ v->longOffsets = malloc((o->numGlyphs+1)*sizeof(*v->longOffsets));
3681+ for(int i = 0; i < (o->numGlyphs+1); i++)
3682+ v->longOffsets[i] = b[0+i*4]<<24 | b[1+i*4]<<16 | b[2+i*4]<<8 | b[3+i*4];
3683+ }
3684+ return 0;
3685+err:
3686+ werrstr("%s: %r", "TableLoca");
3687+ return -1;
3688+}
3689+
3690+void
3691+print_TableLoca(Biobuf *f, int indent, Otf *o, TableLoca *v)
3692+{
3693+ if(o->indexToLocFormat == 0){
3694+ for(int i = 0; i < (o->numGlyphs+1); i++)
3695+ Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "shortOffsets", i, v->shortOffsets[i]);
3696+ }
3697+ if(o->indexToLocFormat == 1){
3698+ for(int i = 0; i < (o->numGlyphs+1); i++)
3699+ Bprint(f, "%*s%s[%d]: %ud\n", indent, "", "longOffsets", i, v->longOffsets[i]);
3700+ }
3701+ USED(o);
33263702 }
33273703
33283704 int
@@ -3394,7 +3770,7 @@ err: · 65 unmodified lines
33943770 }
33953771
33963772 void
3397−print_TableOS∕2(Biobuf *f, int indent, TableOS∕2 *v)
3773+print_TableOS∕2(Biobuf *f, int indent, Otf *o, TableOS∕2 *v)
33983774 {
33993775 Bprint(f, "%*s%s: %ud\n", indent, "", "version", v->version);
34003776 Bprint(f, "%*s%s: %d\n", indent, "", "xAvgCharWidth", v->xAvgCharWidth);
@@ -3445,6 +3821,7 @@ print_TableOS∕2(Biobuf *f, int indent, TableOS∕2 *v) · 44 unmodified lines
34453821 Bprint(f, "%*s%s: %ud\n", indent, "", "usLowerOpticalPointSize", v->usLowerOpticalPointSize);
34463822 if(v->version >= 5)
34473823 Bprint(f, "%*s%s: %ud\n", indent, "", "usUpperOpticalPointSize", v->usUpperOpticalPointSize);
3824+ USED(o);
34483825 }
34493826
34503827 int
@@ -3463,13 +3840,14 @@ err: · 12 unmodified lines
34633840 }
34643841
34653842 void
3466−print_TableRecord(Biobuf *f, int indent, TableRecord *v)
3843+print_TableRecord(Biobuf *f, int indent, Otf *o, TableRecord *v)
34673844 {
34683845 Bprint(f, "%*s%s: %t\n", indent, "", "tableTag", v->tableTag);
34693846 Bprint(f, "%*s%s: %ud\n", indent, "", "offset", v->offset);
34703847 Bprint(f, "%*s%s: %ud\n", indent, "", "length", v->length);
34713848 if(v->print != nil && v->parsed != nil)
3472− v->print(f, indent+indentΔ, v->parsed);
3849+ v->print(f, indent+indentΔ, o, v->parsed);
3850+ USED(o);
34733851 }
34743852
34753853 int
@@ -3491,134 +3869,224 @@ read_TableDirectory(Otf *o, TableDirectory *v) · 15 unmodified lines
34913869 werrstr("%s: %r", "tableRecords");
34923870 goto err;
34933871 }
3494− for(int i = 0; i < v->numTables; i++){
3495− TableRecord *rec = &v->tableRecords[i];
3496− if(rec->length == 0)
3497− continue;
3498− if(otfpushrange(o, rec->offset, rec->length) < 0)
3499− goto err;
3500− switch(rec->tableTag){
3501− case (u32int)('c'<<24|'m'<<16|'a'<<8|'p'):
3502− v->cmap = calloc(1, sizeof(TableCmap));
3503− if(read_TableCmap(o, v->cmap) < 0){
3504− free(v->cmap);
3505− goto err;
3506− }
3507− rec->parsed = v->cmap;
3508− rec->print = (void*)print_TableCmap;
3509− break;
3510− case (u32int)('h'<<24|'e'<<16|'a'<<8|'d'):
3511− v->head = calloc(1, sizeof(TableHead));
3512− if(read_TableHead(o, v->head) < 0){
3513− free(v->head);
3514− goto err;
3515− }
3516− rec->parsed = v->head;
3517− rec->print = (void*)print_TableHead;
3518− break;
3519− case (u32int)('h'<<24|'h'<<16|'e'<<8|'a'):
3520− v->hhea = calloc(1, sizeof(TableHhea));
3521− if(read_TableHhea(o, v->hhea) < 0){
3522− free(v->hhea);
3872+ int retry = 0;
3873+ do{
3874+ for(int i = 0; i < v->numTables; i++){
3875+ TableRecord *rec = &v->tableRecords[i];
3876+ if(rec->length == 0)
3877+ continue;
3878+ if(otfpushrange(o, rec->offset, rec->length) < 0)
35233879 goto err;
3880+ switch(rec->tableTag){
3881+ case (u32int)('c'<<24|'m'<<16|'a'<<8|'p'):
3882+ if(v->cmap != nil)
3883+ break;
3884+ v->cmap = calloc(1, sizeof(TableCmap));
3885+ if(read_TableCmap(o, v->cmap) < 0){
3886+ free(v->cmap);
3887+ goto err;
3888+ }
3889+ rec->parsed = v->cmap;
3890+ rec->print = (void*)print_TableCmap;
3891+ break;
3892+ case (u32int)('h'<<24|'e'<<16|'a'<<8|'d'):
3893+ if(v->head != nil)
3894+ break;
3895+ v->head = calloc(1, sizeof(TableHead));
3896+ if(read_TableHead(o, v->head) < 0){
3897+ free(v->head);
3898+ goto err;
3899+ }
3900+ rec->parsed = v->head;
3901+ rec->print = (void*)print_TableHead;
3902+ break;
3903+ case (u32int)('h'<<24|'h'<<16|'e'<<8|'a'):
3904+ if(v->hhea != nil)
3905+ break;
3906+ v->hhea = calloc(1, sizeof(TableHhea));
3907+ if(read_TableHhea(o, v->hhea) < 0){
3908+ free(v->hhea);
3909+ goto err;
3910+ }
3911+ rec->parsed = v->hhea;
3912+ rec->print = (void*)print_TableHhea;
3913+ break;
3914+ case (u32int)('m'<<24|'a'<<16|'x'<<8|'p'):
3915+ if(v->maxp != nil)
3916+ break;
3917+ v->maxp = calloc(1, sizeof(TableMaxp));
3918+ if(read_TableMaxp(o, v->maxp) < 0){
3919+ free(v->maxp);
3920+ goto err;
3921+ }
3922+ rec->parsed = v->maxp;
3923+ rec->print = (void*)print_TableMaxp;
3924+ break;
3925+ case (u32int)('h'<<24|'m'<<16|'t'<<8|'x'):
3926+ {
3927+ static int retried = 0;
3928+ if(v->hhea == nil || v->maxp == nil){
3929+ if(retried){
3930+ werrstr("%s: deps missing", "TableHmtx");
3931+ goto err;
3932+ }
3933+ retried = 1;
3934+ retry++;
3935+ break;
3936+ }
3937+ if(retried)
3938+ retry--;
3939+ }
3940+ if(v->hmtx != nil)
3941+ break;
3942+ v->hmtx = calloc(1, sizeof(TableHmtx));
3943+ if(read_TableHmtx(o, v->hmtx) < 0){
3944+ free(v->hmtx);
3945+ goto err;
3946+ }
3947+ rec->parsed = v->hmtx;
3948+ rec->print = (void*)print_TableHmtx;
3949+ break;
3950+ case (u32int)('p'<<24|'o'<<16|'s'<<8|'t'):
3951+ if(v->post != nil)
3952+ break;
3953+ v->post = calloc(1, sizeof(TablePost));
3954+ if(read_TablePost(o, v->post) < 0){
3955+ free(v->post);
3956+ goto err;
3957+ }
3958+ rec->parsed = v->post;
3959+ rec->print = (void*)print_TablePost;
3960+ break;
3961+ case (u32int)('n'<<24|'a'<<16|'m'<<8|'e'):
3962+ if(v->name != nil)
3963+ break;
3964+ v->name = calloc(1, sizeof(TableName));
3965+ if(read_TableName(o, v->name) < 0){
3966+ free(v->name);
3967+ goto err;
3968+ }
3969+ rec->parsed = v->name;
3970+ rec->print = (void*)print_TableName;
3971+ break;
3972+ case (u32int)('E'<<24|'B'<<16|'D'<<8|'T'):
3973+ if(v->ebdt != nil)
3974+ break;
3975+ v->ebdt = calloc(1, sizeof(TableEBDT));
3976+ if(read_TableEBDT(o, v->ebdt) < 0){
3977+ free(v->ebdt);
3978+ goto err;
3979+ }
3980+ rec->parsed = v->ebdt;
3981+ rec->print = (void*)print_TableEBDT;
3982+ break;
3983+ case (u32int)('E'<<24|'B'<<16|'L'<<8|'C'):
3984+ if(v->eblc != nil)
3985+ break;
3986+ v->eblc = calloc(1, sizeof(TableEBLC));
3987+ if(read_TableEBLC(o, v->eblc) < 0){
3988+ free(v->eblc);
3989+ goto err;
3990+ }
3991+ rec->parsed = v->eblc;
3992+ rec->print = (void*)print_TableEBLC;
3993+ break;
3994+ case (u32int)('G'<<24|'D'<<16|'E'<<8|'F'):
3995+ if(v->gdef != nil)
3996+ break;
3997+ v->gdef = calloc(1, sizeof(TableGDEF));
3998+ if(read_TableGDEF(o, v->gdef) < 0){
3999+ free(v->gdef);
4000+ goto err;
4001+ }
4002+ rec->parsed = v->gdef;
4003+ rec->print = (void*)print_TableGDEF;
4004+ break;
4005+ case (u32int)('G'<<24|'P'<<16|'O'<<8|'S'):
4006+ if(v->gpos != nil)
4007+ break;
4008+ v->gpos = calloc(1, sizeof(TableGPOS));
4009+ if(read_TableGPOS(o, v->gpos) < 0){
4010+ free(v->gpos);
4011+ goto err;
4012+ }
4013+ rec->parsed = v->gpos;
4014+ rec->print = (void*)print_TableGPOS;
4015+ break;
4016+ case (u32int)('G'<<24|'S'<<16|'U'<<8|'B'):
4017+ if(v->gsub != nil)
4018+ break;
4019+ v->gsub = calloc(1, sizeof(TableGSUB));
4020+ if(read_TableGSUB(o, v->gsub) < 0){
4021+ free(v->gsub);
4022+ goto err;
4023+ }
4024+ rec->parsed = v->gsub;
4025+ rec->print = (void*)print_TableGSUB;
4026+ break;
4027+ case (u32int)('M'<<24|'A'<<16|'T'<<8|'H'):
4028+ if(v->math != nil)
4029+ break;
4030+ v->math = calloc(1, sizeof(TableMATH));
4031+ if(read_TableMATH(o, v->math) < 0){
4032+ free(v->math);
4033+ goto err;
4034+ }
4035+ rec->parsed = v->math;
4036+ rec->print = (void*)print_TableMATH;
4037+ break;
4038+ case (u32int)('k'<<24|'e'<<16|'r'<<8|'n'):
4039+ if(v->kern != nil)
4040+ break;
4041+ v->kern = calloc(1, sizeof(TableKern));
4042+ if(read_TableKern(o, v->kern) < 0){
4043+ free(v->kern);
4044+ goto err;
4045+ }
4046+ rec->parsed = v->kern;
4047+ rec->print = (void*)print_TableKern;
4048+ break;
4049+ case (u32int)('l'<<24|'o'<<16|'c'<<8|'a'):
4050+ {
4051+ static int retried = 0;
4052+ if(v->head == nil){
4053+ if(retried){
4054+ werrstr("%s: deps missing", "TableLoca");
4055+ goto err;
4056+ }
4057+ retried = 1;
4058+ retry++;
4059+ break;
4060+ }
4061+ if(retried)
4062+ retry--;
4063+ }
4064+ if(v->loca != nil)
4065+ break;
4066+ v->loca = calloc(1, sizeof(TableLoca));
4067+ if(read_TableLoca(o, v->loca) < 0){
4068+ free(v->loca);
4069+ goto err;
4070+ }
4071+ rec->parsed = v->loca;
4072+ rec->print = (void*)print_TableLoca;
4073+ break;
4074+ case (u32int)('O'<<24|'S'<<16|'/'<<8|'2'):
4075+ if(v->os∕2 != nil)
4076+ break;
4077+ v->os∕2 = calloc(1, sizeof(TableOS∕2));
4078+ if(read_TableOS∕2(o, v->os∕2) < 0){
4079+ free(v->os∕2);
4080+ goto err;
4081+ }
4082+ rec->parsed = v->os∕2;
4083+ rec->print = (void*)print_TableOS∕2;
4084+ break;
35244085 }
3525− rec->parsed = v->hhea;
3526− rec->print = (void*)print_TableHhea;
3527− break;
3528− case (u32int)('m'<<24|'a'<<16|'x'<<8|'p'):
3529− v->maxp = calloc(1, sizeof(TableMaxp));
3530− if(read_TableMaxp(o, v->maxp) < 0){
3531− free(v->maxp);
4086+ if(otfpoprange(o) < 0)
35324087 goto err;
3533− }
3534− rec->parsed = v->maxp;
3535− rec->print = (void*)print_TableMaxp;
3536− break;
3537− case (u32int)('p'<<24|'o'<<16|'s'<<8|'t'):
3538− v->post = calloc(1, sizeof(TablePost));
3539− if(read_TablePost(o, v->post) < 0){
3540− free(v->post);
3541− goto err;
3542− }
3543− rec->parsed = v->post;
3544− rec->print = (void*)print_TablePost;
3545− break;
3546− case (u32int)('n'<<24|'a'<<16|'m'<<8|'e'):
3547− v->name = calloc(1, sizeof(TableName));
3548− if(read_TableName(o, v->name) < 0){
3549− free(v->name);
3550− goto err;
3551− }
3552− rec->parsed = v->name;
3553− rec->print = (void*)print_TableName;
3554− break;
3555− case (u32int)('E'<<24|'B'<<16|'D'<<8|'T'):
3556− v->ebdt = calloc(1, sizeof(TableEBDT));
3557− if(read_TableEBDT(o, v->ebdt) < 0){
3558− free(v->ebdt);
3559− goto err;
3560− }
3561− rec->parsed = v->ebdt;
3562− rec->print = (void*)print_TableEBDT;
3563− break;
3564− case (u32int)('E'<<24|'B'<<16|'L'<<8|'C'):
3565− v->eblc = calloc(1, sizeof(TableEBLC));
3566− if(read_TableEBLC(o, v->eblc) < 0){
3567− free(v->eblc);
3568− goto err;
3569− }
3570− rec->parsed = v->eblc;
3571− rec->print = (void*)print_TableEBLC;
3572− break;
3573− case (u32int)('G'<<24|'D'<<16|'E'<<8|'F'):
3574− v->gdef = calloc(1, sizeof(TableGDEF));
3575− if(read_TableGDEF(o, v->gdef) < 0){
3576− free(v->gdef);
3577− goto err;
3578− }
3579− rec->parsed = v->gdef;
3580− rec->print = (void*)print_TableGDEF;
3581− break;
3582− case (u32int)('G'<<24|'P'<<16|'O'<<8|'S'):
3583− v->gpos = calloc(1, sizeof(TableGPOS));
3584− if(read_TableGPOS(o, v->gpos) < 0){
3585− free(v->gpos);
3586− goto err;
3587− }
3588− rec->parsed = v->gpos;
3589− rec->print = (void*)print_TableGPOS;
3590− break;
3591− case (u32int)('G'<<24|'S'<<16|'U'<<8|'B'):
3592− v->gsub = calloc(1, sizeof(TableGSUB));
3593− if(read_TableGSUB(o, v->gsub) < 0){
3594− free(v->gsub);
3595− goto err;
3596− }
3597− rec->parsed = v->gsub;
3598− rec->print = (void*)print_TableGSUB;
3599− break;
3600− case (u32int)('M'<<24|'A'<<16|'T'<<8|'H'):
3601− v->math = calloc(1, sizeof(TableMATH));
3602− if(read_TableMATH(o, v->math) < 0){
3603− free(v->math);
3604− goto err;
3605− }
3606− rec->parsed = v->math;
3607− rec->print = (void*)print_TableMATH;
3608− break;
3609− case (u32int)('O'<<24|'S'<<16|'/'<<8|'2'):
3610− v->os∕2 = calloc(1, sizeof(TableOS∕2));
3611− if(read_TableOS∕2(o, v->os∕2) < 0){
3612− free(v->os∕2);
3613− goto err;
3614− }
3615− rec->parsed = v->os∕2;
3616− rec->print = (void*)print_TableOS∕2;
3617− break;
36184088 }
3619− if(otfpoprange(o) < 0)
3620− goto err;
3621− }
4089+ }while(retry > 0);
36224090 return 0;
36234091 err:
36244092 werrstr("%s: %r", "TableDirectory");
@@ -3626,7 +4094,7 @@ err: · 1 unmodified line
36264094 }
36274095
36284096 void
3629−print_TableDirectory(Biobuf *f, int indent, TableDirectory *v)
4097+print_TableDirectory(Biobuf *f, int indent, Otf *o, TableDirectory *v)
36304098 {
36314099 Bprint(f, "%*s%s: %#ux\n", indent, "", "sfntVersion", v->sfntVersion);
36324100 Bprint(f, "%*s%s: %ud\n", indent, "", "numTables", v->numTables);
@@ -3635,8 +4103,9 @@ print_TableDirectory(Biobuf *f, int indent, TableDirectory *v) · 2 unmodified lines
36354103 Bprint(f, "%*s%s: %ud\n", indent, "", "rangeShift", v->rangeShift);
36364104 for(int i = 0; i < v->numTables; i++){
36374105 Bprint(f, "%*s%s[%d]:\n", indent, "", "tableRecords", i);
3638− print_TableRecord(f, indent+indentΔ, &v->tableRecords[i]);
4106+ print_TableRecord(f, indent+indentΔ, o, &v->tableRecords[i]);
36394107 }
4108+ USED(o);
36404109 }
36414110
36424111 int indentΔ = 2;
otf.h+171−84
@@ -23,6 +23,7 @@ typedef struct TableHead TableHead; · 22 unmodified lines
2323 typedef struct TableHhea TableHhea;
2424 typedef struct LongHorMetric LongHorMetric;
2525 typedef struct TableMaxp TableMaxp;
26+typedef struct TableHmtx TableHmtx;
2627 typedef struct TablePost TablePost;
2728 typedef struct NameRecord NameRecord;
2829 typedef struct LangTagRecord LangTagRecord;
@@ -79,6 +80,13 @@ typedef struct GlyphPart GlyphPart; · 50 unmodified lines
7980 typedef struct GlyphAssembly GlyphAssembly;
8081 typedef struct MathGlyphConstruction MathGlyphConstruction;
8182 typedef struct TableMATH TableMATH;
83+typedef struct KernPair KernPair;
84+typedef struct KernSubtable0 KernSubtable0;
85+typedef struct KernClass KernClass;
86+typedef struct KernSubtable2 KernSubtable2;
87+typedef struct KernSubtable KernSubtable;
88+typedef struct TableKern TableKern;
89+typedef struct TableLoca TableLoca;
8290 typedef struct TableOS∕2 TableOS∕2;
8391 typedef struct TableRecord TableRecord;
8492 typedef struct TableDirectory TableDirectory;
@@ -91,7 +99,7 @@ struct SubHeader { · 6 unmodified lines
9199 };
92100
93101 int read_SubHeader(Otf *o, SubHeader *v);
94−void print_SubHeader(Biobuf *f, int indent, SubHeader *v);
102+void print_SubHeader(Biobuf *f, int indent, Otf *o, SubHeader *v);
95103
96104 struct MapGroup {
97105 u32int startCharCode;
@@ -100,7 +108,7 @@ struct MapGroup { · 2 unmodified lines
100108 };
101109
102110 int read_MapGroup(Otf *o, MapGroup *v);
103−void print_MapGroup(Biobuf *f, int indent, MapGroup *v);
111+void print_MapGroup(Biobuf *f, int indent, Otf *o, MapGroup *v);
104112
105113 struct SubtableCmap0 {
106114 u16int length;
@@ -109,7 +117,7 @@ struct SubtableCmap0 { · 2 unmodified lines
109117 };
110118
111119 int read_SubtableCmap0(Otf *o, SubtableCmap0 *v);
112−void print_SubtableCmap0(Biobuf *f, int indent, SubtableCmap0 *v);
120+void print_SubtableCmap0(Biobuf *f, int indent, Otf *o, SubtableCmap0 *v);
113121
114122 struct SubtableCmap2 {
115123 u16int length;
@@ -118,7 +126,7 @@ struct SubtableCmap2 { · 2 unmodified lines
118126 };
119127
120128 int read_SubtableCmap2(Otf *o, SubtableCmap2 *v);
121−void print_SubtableCmap2(Biobuf *f, int indent, SubtableCmap2 *v);
129+void print_SubtableCmap2(Biobuf *f, int indent, Otf *o, SubtableCmap2 *v);
122130
123131 struct SubtableCmap4 {
124132 u16int length;
@@ -135,7 +143,7 @@ struct SubtableCmap4 { · 10 unmodified lines
135143 };
136144
137145 int read_SubtableCmap4(Otf *o, SubtableCmap4 *v);
138−void print_SubtableCmap4(Biobuf *f, int indent, SubtableCmap4 *v);
146+void print_SubtableCmap4(Biobuf *f, int indent, Otf *o, SubtableCmap4 *v);
139147
140148 struct SubtableCmap6 {
141149 u16int length;
@@ -146,7 +154,7 @@ struct SubtableCmap6 { · 4 unmodified lines
146154 };
147155
148156 int read_SubtableCmap6(Otf *o, SubtableCmap6 *v);
149−void print_SubtableCmap6(Biobuf *f, int indent, SubtableCmap6 *v);
157+void print_SubtableCmap6(Biobuf *f, int indent, Otf *o, SubtableCmap6 *v);
150158
151159 struct SubtableCmap8 {
152160 u16int length;
@@ -157,7 +165,7 @@ struct SubtableCmap8 { · 4 unmodified lines
157165 };
158166
159167 int read_SubtableCmap8(Otf *o, SubtableCmap8 *v);
160−void print_SubtableCmap8(Biobuf *f, int indent, SubtableCmap8 *v);
168+void print_SubtableCmap8(Biobuf *f, int indent, Otf *o, SubtableCmap8 *v);
161169
162170 struct SubtableCmap10 {
163171 u16int reserved;
@@ -168,7 +176,7 @@ struct SubtableCmap10 { · 4 unmodified lines
168176 };
169177
170178 int read_SubtableCmap10(Otf *o, SubtableCmap10 *v);
171−void print_SubtableCmap10(Biobuf *f, int indent, SubtableCmap10 *v);
179+void print_SubtableCmap10(Biobuf *f, int indent, Otf *o, SubtableCmap10 *v);
172180
173181 struct SubtableCmap12or13 {
174182 u16int reserved;
@@ -179,7 +187,7 @@ struct SubtableCmap12or13 { · 4 unmodified lines
179187 };
180188
181189 int read_SubtableCmap12or13(Otf *o, SubtableCmap12or13 *v);
182−void print_SubtableCmap12or13(Biobuf *f, int indent, SubtableCmap12or13 *v);
190+void print_SubtableCmap12or13(Biobuf *f, int indent, Otf *o, SubtableCmap12or13 *v);
183191
184192 struct UnicodeRange {
185193 u32int startUnicodeValue;
@@ -187,7 +195,7 @@ struct UnicodeRange { · 1 unmodified line
187195 };
188196
189197 int read_UnicodeRange(Otf *o, UnicodeRange *v);
190−void print_UnicodeRange(Biobuf *f, int indent, UnicodeRange *v);
198+void print_UnicodeRange(Biobuf *f, int indent, Otf *o, UnicodeRange *v);
191199
192200 struct DefaultUVS {
193201 u32int numUnicodeValueRanges;
@@ -195,7 +203,7 @@ struct DefaultUVS { · 1 unmodified line
195203 };
196204
197205 int read_DefaultUVS(Otf *o, DefaultUVS *v);
198−void print_DefaultUVS(Biobuf *f, int indent, DefaultUVS *v);
206+void print_DefaultUVS(Biobuf *f, int indent, Otf *o, DefaultUVS *v);
199207
200208 struct UVSMapping {
201209 u32int unicodeValue;
@@ -203,7 +211,7 @@ struct UVSMapping { · 1 unmodified line
203211 };
204212
205213 int read_UVSMapping(Otf *o, UVSMapping *v);
206−void print_UVSMapping(Biobuf *f, int indent, UVSMapping *v);
214+void print_UVSMapping(Biobuf *f, int indent, Otf *o, UVSMapping *v);
207215
208216 struct NonDefaultUVS {
209217 u32int numUVSMappings;
@@ -211,7 +219,7 @@ struct NonDefaultUVS { · 1 unmodified line
211219 };
212220
213221 int read_NonDefaultUVS(Otf *o, NonDefaultUVS *v);
214−void print_NonDefaultUVS(Biobuf *f, int indent, NonDefaultUVS *v);
222+void print_NonDefaultUVS(Biobuf *f, int indent, Otf *o, NonDefaultUVS *v);
215223
216224 struct VariationSelector {
217225 u32int varSelector;
@@ -222,7 +230,7 @@ struct VariationSelector { · 4 unmodified lines
222230 };
223231
224232 int read_VariationSelector(Otf *o, VariationSelector *v);
225−void print_VariationSelector(Biobuf *f, int indent, VariationSelector *v);
233+void print_VariationSelector(Biobuf *f, int indent, Otf *o, VariationSelector *v);
226234
227235 struct SubtableCmap14 {
228236 u32int length;
@@ -231,7 +239,7 @@ struct SubtableCmap14 { · 2 unmodified lines
231239 };
232240
233241 int read_SubtableCmap14(Otf *o, SubtableCmap14 *v);
234−void print_SubtableCmap14(Biobuf *f, int indent, SubtableCmap14 *v);
242+void print_SubtableCmap14(Biobuf *f, int indent, Otf *o, SubtableCmap14 *v);
235243
236244 struct SubtableCmap {
237245 u16int format;
@@ -246,7 +254,7 @@ struct SubtableCmap { · 8 unmodified lines
246254 };
247255
248256 int read_SubtableCmap(Otf *o, SubtableCmap *v);
249−void print_SubtableCmap(Biobuf *f, int indent, SubtableCmap *v);
257+void print_SubtableCmap(Biobuf *f, int indent, Otf *o, SubtableCmap *v);
250258
251259 struct EncodingRecord {
252260 u16int platformID;
@@ -256,7 +264,7 @@ struct EncodingRecord { · 3 unmodified lines
256264 };
257265
258266 int read_EncodingRecord(Otf *o, EncodingRecord *v);
259−void print_EncodingRecord(Biobuf *f, int indent, EncodingRecord *v);
267+void print_EncodingRecord(Biobuf *f, int indent, Otf *o, EncodingRecord *v);
260268
261269 struct TableCmap {
262270 // u16int version;
@@ -265,7 +273,7 @@ struct TableCmap { · 2 unmodified lines
265273 };
266274
267275 int read_TableCmap(Otf *o, TableCmap *v);
268−void print_TableCmap(Biobuf *f, int indent, TableCmap *v);
276+void print_TableCmap(Biobuf *f, int indent, Otf *o, TableCmap *v);
269277
270278 struct TableHead {
271279 // u16int majorVersion;
@@ -289,7 +297,7 @@ struct TableHead { · 17 unmodified lines
289297 };
290298
291299 int read_TableHead(Otf *o, TableHead *v);
292−void print_TableHead(Biobuf *f, int indent, TableHead *v);
300+void print_TableHead(Biobuf *f, int indent, Otf *o, TableHead *v);
293301
294302 struct TableHhea {
295303 u16int majorVersion;
@@ -310,7 +318,7 @@ struct TableHhea { · 14 unmodified lines
310318 };
311319
312320 int read_TableHhea(Otf *o, TableHhea *v);
313−void print_TableHhea(Biobuf *f, int indent, TableHhea *v);
321+void print_TableHhea(Biobuf *f, int indent, Otf *o, TableHhea *v);
314322
315323 struct LongHorMetric {
316324 u16int advanceWidth;
@@ -318,7 +326,7 @@ struct LongHorMetric { · 1 unmodified line
318326 };
319327
320328 int read_LongHorMetric(Otf *o, LongHorMetric *v);
321−void print_LongHorMetric(Biobuf *f, int indent, LongHorMetric *v);
329+void print_LongHorMetric(Biobuf *f, int indent, Otf *o, LongHorMetric *v);
322330
323331 struct TableMaxp {
324332 // u32int version;
@@ -326,7 +334,15 @@ struct TableMaxp { · 1 unmodified line
326334 };
327335
328336 int read_TableMaxp(Otf *o, TableMaxp *v);
329−void print_TableMaxp(Biobuf *f, int indent, TableMaxp *v);
337+void print_TableMaxp(Biobuf *f, int indent, Otf *o, TableMaxp *v);
338+
339+struct TableHmtx {
340+ LongHorMetric *hMetrics;
341+ s16int *leftSideBearings;
342+};
343+
344+int read_TableHmtx(Otf *o, TableHmtx *v);
345+void print_TableHmtx(Biobuf *f, int indent, Otf *o, TableHmtx *v);
330346
331347 struct TablePost {
332348 // u32int version;
@@ -337,7 +353,7 @@ struct TablePost { · 4 unmodified lines
337353 };
338354
339355 int read_TablePost(Otf *o, TablePost *v);
340−void print_TablePost(Biobuf *f, int indent, TablePost *v);
356+void print_TablePost(Biobuf *f, int indent, Otf *o, TablePost *v);
341357
342358 struct NameRecord {
343359 u16int platformID;
@@ -349,7 +365,7 @@ struct NameRecord { · 5 unmodified lines
349365 };
350366
351367 int read_NameRecord(Otf *o, NameRecord *v);
352−void print_NameRecord(Biobuf *f, int indent, NameRecord *v);
368+void print_NameRecord(Biobuf *f, int indent, Otf *o, NameRecord *v);
353369
354370 struct LangTagRecord {
355371 u16int length;
@@ -357,7 +373,7 @@ struct LangTagRecord { · 1 unmodified line
357373 };
358374
359375 int read_LangTagRecord(Otf *o, LangTagRecord *v);
360−void print_LangTagRecord(Biobuf *f, int indent, LangTagRecord *v);
376+void print_LangTagRecord(Biobuf *f, int indent, Otf *o, LangTagRecord *v);
361377
362378 struct TableName {
363379 u16int version;
@@ -369,7 +385,7 @@ struct TableName { · 5 unmodified lines
369385 };
370386
371387 int read_TableName(Otf *o, TableName *v);
372−void print_TableName(Biobuf *f, int indent, TableName *v);
388+void print_TableName(Biobuf *f, int indent, Otf *o, TableName *v);
373389
374390 struct BigGlyphMetrics {
375391 u8int height;
@@ -383,7 +399,7 @@ struct BigGlyphMetrics { · 7 unmodified lines
383399 };
384400
385401 int read_BigGlyphMetrics(Otf *o, BigGlyphMetrics *v);
386−void print_BigGlyphMetrics(Biobuf *f, int indent, BigGlyphMetrics *v);
402+void print_BigGlyphMetrics(Biobuf *f, int indent, Otf *o, BigGlyphMetrics *v);
387403
388404 struct SmallGlyphMetrics {
389405 u8int height;
@@ -394,7 +410,7 @@ struct SmallGlyphMetrics { · 4 unmodified lines
394410 };
395411
396412 int read_SmallGlyphMetrics(Otf *o, SmallGlyphMetrics *v);
397−void print_SmallGlyphMetrics(Biobuf *f, int indent, SmallGlyphMetrics *v);
413+void print_SmallGlyphMetrics(Biobuf *f, int indent, Otf *o, SmallGlyphMetrics *v);
398414
399415 struct SbitLineMetrics {
400416 s8int ascender;
@@ -411,14 +427,14 @@ struct SbitLineMetrics { · 10 unmodified lines
411427 };
412428
413429 int read_SbitLineMetrics(Otf *o, SbitLineMetrics *v);
414−void print_SbitLineMetrics(Biobuf *f, int indent, SbitLineMetrics *v);
430+void print_SbitLineMetrics(Biobuf *f, int indent, Otf *o, SbitLineMetrics *v);
415431
416432 struct IndexSubtable1 {
417− u32int sbitOffsets;
433+ u32int *sbitOffsets;
418434 };
419435
420436 int read_IndexSubtable1(Otf *o, IndexSubtable1 *v);
421−void print_IndexSubtable1(Biobuf *f, int indent, IndexSubtable1 *v);
437+void print_IndexSubtable1(Biobuf *f, int indent, Otf *o, IndexSubtable1 *v);
422438
423439 struct IndexSubtable2 {
424440 u32int imageSize;
@@ -426,14 +442,14 @@ struct IndexSubtable2 { · 1 unmodified line
426442 };
427443
428444 int read_IndexSubtable2(Otf *o, IndexSubtable2 *v);
429−void print_IndexSubtable2(Biobuf *f, int indent, IndexSubtable2 *v);
445+void print_IndexSubtable2(Biobuf *f, int indent, Otf *o, IndexSubtable2 *v);
430446
431447 struct IndexSubtable3 {
432− u16int sbitOffsets;
448+ u16int *sbitOffsets;
433449 };
434450
435451 int read_IndexSubtable3(Otf *o, IndexSubtable3 *v);
436−void print_IndexSubtable3(Biobuf *f, int indent, IndexSubtable3 *v);
452+void print_IndexSubtable3(Biobuf *f, int indent, Otf *o, IndexSubtable3 *v);
437453
438454 struct GlyphIdOffsetPair {
439455 u16int glyphID;
@@ -441,7 +457,7 @@ struct GlyphIdOffsetPair { · 1 unmodified line
441457 };
442458
443459 int read_GlyphIdOffsetPair(Otf *o, GlyphIdOffsetPair *v);
444−void print_GlyphIdOffsetPair(Biobuf *f, int indent, GlyphIdOffsetPair *v);
460+void print_GlyphIdOffsetPair(Biobuf *f, int indent, Otf *o, GlyphIdOffsetPair *v);
445461
446462 struct IndexSubtable4 {
447463 u32int numGlyphs;
@@ -449,7 +465,7 @@ struct IndexSubtable4 { · 1 unmodified line
449465 };
450466
451467 int read_IndexSubtable4(Otf *o, IndexSubtable4 *v);
452−void print_IndexSubtable4(Biobuf *f, int indent, IndexSubtable4 *v);
468+void print_IndexSubtable4(Biobuf *f, int indent, Otf *o, IndexSubtable4 *v);
453469
454470 struct IndexSubtable5 {
455471 u32int imageSize;
@@ -459,7 +475,7 @@ struct IndexSubtable5 { · 3 unmodified lines
459475 };
460476
461477 int read_IndexSubtable5(Otf *o, IndexSubtable5 *v);
462−void print_IndexSubtable5(Biobuf *f, int indent, IndexSubtable5 *v);
478+void print_IndexSubtable5(Biobuf *f, int indent, Otf *o, IndexSubtable5 *v);
463479
464480 struct IndexSubtable {
465481 u16int indexFormat;
@@ -473,7 +489,7 @@ struct IndexSubtable { · 7 unmodified lines
473489 };
474490
475491 int read_IndexSubtable(Otf *o, IndexSubtable *v);
476−void print_IndexSubtable(Biobuf *f, int indent, IndexSubtable *v);
492+void print_IndexSubtable(Biobuf *f, int indent, Otf *o, IndexSubtable *v);
477493
478494 struct IndexSubtableRecord {
479495 u16int firstGlyphIndex;
@@ -483,7 +499,7 @@ struct IndexSubtableRecord { · 3 unmodified lines
483499 };
484500
485501 int read_IndexSubtableRecord(Otf *o, IndexSubtableRecord *v);
486−void print_IndexSubtableRecord(Biobuf *f, int indent, IndexSubtableRecord *v);
502+void print_IndexSubtableRecord(Biobuf *f, int indent, Otf *o, IndexSubtableRecord *v);
487503
488504 struct BitmapSize {
489505 u32int indexSubtableListOffset;
@@ -502,7 +518,7 @@ struct BitmapSize { · 12 unmodified lines
502518 };
503519
504520 int read_BitmapSize(Otf *o, BitmapSize *v);
505−void print_BitmapSize(Biobuf *f, int indent, BitmapSize *v);
521+void print_BitmapSize(Biobuf *f, int indent, Otf *o, BitmapSize *v);
506522
507523 struct TableEBDT {
508524 u16int majorVersion;
@@ -510,7 +526,7 @@ struct TableEBDT { · 1 unmodified line
510526 };
511527
512528 int read_TableEBDT(Otf *o, TableEBDT *v);
513−void print_TableEBDT(Biobuf *f, int indent, TableEBDT *v);
529+void print_TableEBDT(Biobuf *f, int indent, Otf *o, TableEBDT *v);
514530
515531 struct TableEBLC {
516532 // u16int majorVersion;
@@ -520,7 +536,7 @@ struct TableEBLC { · 3 unmodified lines
520536 };
521537
522538 int read_TableEBLC(Otf *o, TableEBLC *v);
523−void print_TableEBLC(Biobuf *f, int indent, TableEBLC *v);
539+void print_TableEBLC(Biobuf *f, int indent, Otf *o, TableEBLC *v);
524540
525541 struct AttachList {
526542 u16int coverageOffset;
@@ -529,7 +545,7 @@ struct AttachList { · 2 unmodified lines
529545 };
530546
531547 int read_AttachList(Otf *o, AttachList *v);
532−void print_AttachList(Biobuf *f, int indent, AttachList *v);
548+void print_AttachList(Biobuf *f, int indent, Otf *o, AttachList *v);
533549
534550 struct AttachPoint {
535551 u16int pointCount;
@@ -537,7 +553,7 @@ struct AttachPoint { · 1 unmodified line
537553 };
538554
539555 int read_AttachPoint(Otf *o, AttachPoint *v);
540−void print_AttachPoint(Biobuf *f, int indent, AttachPoint *v);
556+void print_AttachPoint(Biobuf *f, int indent, Otf *o, AttachPoint *v);
541557
542558 struct LigCaretList {
543559 u16int coverageOffset;
@@ -546,7 +562,7 @@ struct LigCaretList { · 2 unmodified lines
546562 };
547563
548564 int read_LigCaretList(Otf *o, LigCaretList *v);
549−void print_LigCaretList(Biobuf *f, int indent, LigCaretList *v);
565+void print_LigCaretList(Biobuf *f, int indent, Otf *o, LigCaretList *v);
550566
551567 struct LigGlyph {
552568 u16int caretCount;
@@ -554,7 +570,7 @@ struct LigGlyph { · 1 unmodified line
554570 };
555571
556572 int read_LigGlyph(Otf *o, LigGlyph *v);
557−void print_LigGlyph(Biobuf *f, int indent, LigGlyph *v);
573+void print_LigGlyph(Biobuf *f, int indent, Otf *o, LigGlyph *v);
558574
559575 struct CaretValue {
560576 u16int format;
@@ -564,7 +580,7 @@ struct CaretValue { · 3 unmodified lines
564580 };
565581
566582 int read_CaretValue(Otf *o, CaretValue *v);
567−void print_CaretValue(Biobuf *f, int indent, CaretValue *v);
583+void print_CaretValue(Biobuf *f, int indent, Otf *o, CaretValue *v);
568584
569585 struct ValueRecord {
570586 s16int xPlacement;
@@ -578,7 +594,7 @@ struct ValueRecord { · 7 unmodified lines
578594 };
579595
580596 int read_ValueRecord(Otf *o, ValueRecord *v);
581−void print_ValueRecord(Biobuf *f, int indent, ValueRecord *v);
597+void print_ValueRecord(Biobuf *f, int indent, Otf *o, ValueRecord *v);
582598
583599 struct SinglePos {
584600 u16int format;
@@ -590,7 +606,7 @@ struct SinglePos { · 5 unmodified lines
590606 };
591607
592608 int read_SinglePos(Otf *o, SinglePos *v);
593−void print_SinglePos(Biobuf *f, int indent, SinglePos *v);
609+void print_SinglePos(Biobuf *f, int indent, Otf *o, SinglePos *v);
594610
595611 struct TableGDEF {
596612 // u16int majorVersion;
@@ -604,7 +620,7 @@ struct TableGDEF { · 7 unmodified lines
604620 };
605621
606622 int read_TableGDEF(Otf *o, TableGDEF *v);
607−void print_TableGDEF(Biobuf *f, int indent, TableGDEF *v);
623+void print_TableGDEF(Biobuf *f, int indent, Otf *o, TableGDEF *v);
608624
609625 struct LangSys {
610626 // u16int lookupOrderOffset;
@@ -614,7 +630,7 @@ struct LangSys { · 3 unmodified lines
614630 };
615631
616632 int read_LangSys(Otf *o, LangSys *v);
617−void print_LangSys(Biobuf *f, int indent, LangSys *v);
633+void print_LangSys(Biobuf *f, int indent, Otf *o, LangSys *v);
618634
619635 struct LangSysRecord {
620636 u32int langSysTag;
@@ -623,7 +639,7 @@ struct LangSysRecord { · 2 unmodified lines
623639 };
624640
625641 int read_LangSysRecord(Otf *o, LangSysRecord *v);
626−void print_LangSysRecord(Biobuf *f, int indent, LangSysRecord *v);
642+void print_LangSysRecord(Biobuf *f, int indent, Otf *o, LangSysRecord *v);
627643
628644 struct Script {
629645 u16int defaultLangSysOffset;
@@ -633,7 +649,7 @@ struct Script { · 3 unmodified lines
633649 };
634650
635651 int read_Script(Otf *o, Script *v);
636−void print_Script(Biobuf *f, int indent, Script *v);
652+void print_Script(Biobuf *f, int indent, Otf *o, Script *v);
637653
638654 struct ScriptRecord {
639655 u32int scriptTag;
@@ -642,7 +658,7 @@ struct ScriptRecord { · 2 unmodified lines
642658 };
643659
644660 int read_ScriptRecord(Otf *o, ScriptRecord *v);
645−void print_ScriptRecord(Biobuf *f, int indent, ScriptRecord *v);
661+void print_ScriptRecord(Biobuf *f, int indent, Otf *o, ScriptRecord *v);
646662
647663 struct ScriptList {
648664 u16int scriptCount;
@@ -650,7 +666,7 @@ struct ScriptList { · 1 unmodified line
650666 };
651667
652668 int read_ScriptList(Otf *o, ScriptList *v);
653−void print_ScriptList(Biobuf *f, int indent, ScriptList *v);
669+void print_ScriptList(Biobuf *f, int indent, Otf *o, ScriptList *v);
654670
655671 struct Feature {
656672 u16int featureParamsOffset;
@@ -659,7 +675,7 @@ struct Feature { · 2 unmodified lines
659675 };
660676
661677 int read_Feature(Otf *o, Feature *v);
662−void print_Feature(Biobuf *f, int indent, Feature *v);
678+void print_Feature(Biobuf *f, int indent, Otf *o, Feature *v);
663679
664680 struct FeatureRecord {
665681 u32int featureTag;
@@ -668,7 +684,7 @@ struct FeatureRecord { · 2 unmodified lines
668684 };
669685
670686 int read_FeatureRecord(Otf *o, FeatureRecord *v);
671−void print_FeatureRecord(Biobuf *f, int indent, FeatureRecord *v);
687+void print_FeatureRecord(Biobuf *f, int indent, Otf *o, FeatureRecord *v);
672688
673689 struct FeatureList {
674690 u16int featureCount;
@@ -676,7 +692,7 @@ struct FeatureList { · 1 unmodified line
676692 };
677693
678694 int read_FeatureList(Otf *o, FeatureList *v);
679−void print_FeatureList(Biobuf *f, int indent, FeatureList *v);
695+void print_FeatureList(Biobuf *f, int indent, Otf *o, FeatureList *v);
680696
681697 struct Lookup {
682698 u16int lookupType;
@@ -687,7 +703,7 @@ struct Lookup { · 4 unmodified lines
687703 };
688704
689705 int read_Lookup(Otf *o, Lookup *v);
690−void print_Lookup(Biobuf *f, int indent, Lookup *v);
706+void print_Lookup(Biobuf *f, int indent, Otf *o, Lookup *v);
691707
692708 struct LookupList {
693709 u16int lookupCount;
@@ -695,7 +711,7 @@ struct LookupList { · 1 unmodified line
695711 };
696712
697713 int read_LookupList(Otf *o, LookupList *v);
698−void print_LookupList(Biobuf *f, int indent, LookupList *v);
714+void print_LookupList(Biobuf *f, int indent, Otf *o, LookupList *v);
699715
700716 struct TableGPOS {
701717 // u16int majorVersion;
@@ -710,7 +726,7 @@ struct TableGPOS { · 8 unmodified lines
710726 };
711727
712728 int read_TableGPOS(Otf *o, TableGPOS *v);
713−void print_TableGPOS(Biobuf *f, int indent, TableGPOS *v);
729+void print_TableGPOS(Biobuf *f, int indent, Otf *o, TableGPOS *v);
714730
715731 struct TableGSUB {
716732 // u16int majorVersion;
@@ -724,7 +740,7 @@ struct TableGSUB { · 7 unmodified lines
724740 };
725741
726742 int read_TableGSUB(Otf *o, TableGSUB *v);
727−void print_TableGSUB(Biobuf *f, int indent, TableGSUB *v);
743+void print_TableGSUB(Biobuf *f, int indent, Otf *o, TableGSUB *v);
728744
729745 struct MathValueRecord {
730746 s16int value;
@@ -732,7 +748,7 @@ struct MathValueRecord { · 1 unmodified line
732748 };
733749
734750 int read_MathValueRecord(Otf *o, MathValueRecord *v);
735−void print_MathValueRecord(Biobuf *f, int indent, MathValueRecord *v);
751+void print_MathValueRecord(Biobuf *f, int indent, Otf *o, MathValueRecord *v);
736752
737753 struct MathConstants {
738754 s16int scriptPercentScaleDown;
@@ -794,7 +810,7 @@ struct MathConstants { · 55 unmodified lines
794810 };
795811
796812 int read_MathConstants(Otf *o, MathConstants *v);
797−void print_MathConstants(Biobuf *f, int indent, MathConstants *v);
813+void print_MathConstants(Biobuf *f, int indent, Otf *o, MathConstants *v);
798814
799815 struct MathItalicsCorrectionInfo {
800816 u16int italicsCorrectionCoverageOffset;
@@ -803,7 +819,7 @@ struct MathItalicsCorrectionInfo { · 2 unmodified lines
803819 };
804820
805821 int read_MathItalicsCorrectionInfo(Otf *o, MathItalicsCorrectionInfo *v);
806−void print_MathItalicsCorrectionInfo(Biobuf *f, int indent, MathItalicsCorrectionInfo *v);
822+void print_MathItalicsCorrectionInfo(Biobuf *f, int indent, Otf *o, MathItalicsCorrectionInfo *v);
807823
808824 struct MathTopAccentAttachment {
809825 u16int topAccentCoverageOffset;
@@ -812,7 +828,7 @@ struct MathTopAccentAttachment { · 2 unmodified lines
812828 };
813829
814830 int read_MathTopAccentAttachment(Otf *o, MathTopAccentAttachment *v);
815−void print_MathTopAccentAttachment(Biobuf *f, int indent, MathTopAccentAttachment *v);
831+void print_MathTopAccentAttachment(Biobuf *f, int indent, Otf *o, MathTopAccentAttachment *v);
816832
817833 struct MathKernInfoRecord {
818834 u16int topRightMathKernOffset;
@@ -822,7 +838,7 @@ struct MathKernInfoRecord { · 3 unmodified lines
822838 };
823839
824840 int read_MathKernInfoRecord(Otf *o, MathKernInfoRecord *v);
825−void print_MathKernInfoRecord(Biobuf *f, int indent, MathKernInfoRecord *v);
841+void print_MathKernInfoRecord(Biobuf *f, int indent, Otf *o, MathKernInfoRecord *v);
826842
827843 struct MathKernInfo {
828844 u16int mathKernCoverageOffset;
@@ -831,7 +847,7 @@ struct MathKernInfo { · 2 unmodified lines
831847 };
832848
833849 int read_MathKernInfo(Otf *o, MathKernInfo *v);
834−void print_MathKernInfo(Biobuf *f, int indent, MathKernInfo *v);
850+void print_MathKernInfo(Biobuf *f, int indent, Otf *o, MathKernInfo *v);
835851
836852 struct MathKern {
837853 u16int heightCount;
@@ -840,7 +856,7 @@ struct MathKern { · 2 unmodified lines
840856 };
841857
842858 int read_MathKern(Otf *o, MathKern *v);
843−void print_MathKern(Biobuf *f, int indent, MathKern *v);
859+void print_MathKern(Biobuf *f, int indent, Otf *o, MathKern *v);
844860
845861 struct Coverage1 {
846862 u16int glyphCount;
@@ -848,7 +864,7 @@ struct Coverage1 { · 1 unmodified line
848864 };
849865
850866 int read_Coverage1(Otf *o, Coverage1 *v);
851−void print_Coverage1(Biobuf *f, int indent, Coverage1 *v);
867+void print_Coverage1(Biobuf *f, int indent, Otf *o, Coverage1 *v);
852868
853869 struct RangeRecord {
854870 u16int startGlyphID;
@@ -857,7 +873,7 @@ struct RangeRecord { · 2 unmodified lines
857873 };
858874
859875 int read_RangeRecord(Otf *o, RangeRecord *v);
860−void print_RangeRecord(Biobuf *f, int indent, RangeRecord *v);
876+void print_RangeRecord(Biobuf *f, int indent, Otf *o, RangeRecord *v);
861877
862878 struct Coverage2 {
863879 u16int rangeCount;
@@ -865,7 +881,7 @@ struct Coverage2 { · 1 unmodified line
865881 };
866882
867883 int read_Coverage2(Otf *o, Coverage2 *v);
868−void print_Coverage2(Biobuf *f, int indent, Coverage2 *v);
884+void print_Coverage2(Biobuf *f, int indent, Otf *o, Coverage2 *v);
869885
870886 struct Coverage {
871887 u16int format;
@@ -874,7 +890,7 @@ struct Coverage { · 2 unmodified lines
874890 };
875891
876892 int read_Coverage(Otf *o, Coverage *v);
877−void print_Coverage(Biobuf *f, int indent, Coverage *v);
893+void print_Coverage(Biobuf *f, int indent, Otf *o, Coverage *v);
878894
879895 struct MathVariants {
880896 u16int minConnectorOverlap;
@@ -889,7 +905,7 @@ struct MathVariants { · 8 unmodified lines
889905 };
890906
891907 int read_MathVariants(Otf *o, MathVariants *v);
892−void print_MathVariants(Biobuf *f, int indent, MathVariants *v);
908+void print_MathVariants(Biobuf *f, int indent, Otf *o, MathVariants *v);
893909
894910 struct MathGlyphInfo {
895911 u16int mathItalicsCorrectionInfoOffset;
@@ -903,7 +919,7 @@ struct MathGlyphInfo { · 7 unmodified lines
903919 };
904920
905921 int read_MathGlyphInfo(Otf *o, MathGlyphInfo *v);
906−void print_MathGlyphInfo(Biobuf *f, int indent, MathGlyphInfo *v);
922+void print_MathGlyphInfo(Biobuf *f, int indent, Otf *o, MathGlyphInfo *v);
907923
908924 struct MathGlyphVariantRecord {
909925 u16int variantGlyph;
@@ -911,7 +927,7 @@ struct MathGlyphVariantRecord { · 1 unmodified line
911927 };
912928
913929 int read_MathGlyphVariantRecord(Otf *o, MathGlyphVariantRecord *v);
914−void print_MathGlyphVariantRecord(Biobuf *f, int indent, MathGlyphVariantRecord *v);
930+void print_MathGlyphVariantRecord(Biobuf *f, int indent, Otf *o, MathGlyphVariantRecord *v);
915931
916932 struct GlyphPart {
917933 u16int glyphID;
@@ -922,7 +938,7 @@ struct GlyphPart { · 4 unmodified lines
922938 };
923939
924940 int read_GlyphPart(Otf *o, GlyphPart *v);
925−void print_GlyphPart(Biobuf *f, int indent, GlyphPart *v);
941+void print_GlyphPart(Biobuf *f, int indent, Otf *o, GlyphPart *v);
926942
927943 struct GlyphAssembly {
928944 MathValueRecord italicsCorrection;
@@ -931,7 +947,7 @@ struct GlyphAssembly { · 2 unmodified lines
931947 };
932948
933949 int read_GlyphAssembly(Otf *o, GlyphAssembly *v);
934−void print_GlyphAssembly(Biobuf *f, int indent, GlyphAssembly *v);
950+void print_GlyphAssembly(Biobuf *f, int indent, Otf *o, GlyphAssembly *v);
935951
936952 struct MathGlyphConstruction {
937953 u16int glyphAssemblyOffset;
@@ -941,7 +957,7 @@ struct MathGlyphConstruction { · 3 unmodified lines
941957 };
942958
943959 int read_MathGlyphConstruction(Otf *o, MathGlyphConstruction *v);
944−void print_MathGlyphConstruction(Biobuf *f, int indent, MathGlyphConstruction *v);
960+void print_MathGlyphConstruction(Biobuf *f, int indent, Otf *o, MathGlyphConstruction *v);
945961
946962 struct TableMATH {
947963 // u16int majorVersion;
@@ -955,7 +971,75 @@ struct TableMATH { · 7 unmodified lines
955971 };
956972
957973 int read_TableMATH(Otf *o, TableMATH *v);
958−void print_TableMATH(Biobuf *f, int indent, TableMATH *v);
974+void print_TableMATH(Biobuf *f, int indent, Otf *o, TableMATH *v);
975+
976+struct KernPair {
977+ u16int left;
978+ u16int right;
979+ s16int value;
980+};
981+
982+int read_KernPair(Otf *o, KernPair *v);
983+void print_KernPair(Biobuf *f, int indent, Otf *o, KernPair *v);
984+
985+struct KernSubtable0 {
986+ u16int nPairs;
987+ u16int searchRange;
988+ u16int entrySelector;
989+ u16int rangeShift;
990+ KernPair *kernPairs;
991+};
992+
993+int read_KernSubtable0(Otf *o, KernSubtable0 *v);
994+void print_KernSubtable0(Biobuf *f, int indent, Otf *o, KernSubtable0 *v);
995+
996+struct KernClass {
997+ u16int firstGlyph;
998+ u16int nGlyphs;
999+ u16int *values;
1000+};
1001+
1002+int read_KernClass(Otf *o, KernClass *v);
1003+void print_KernClass(Biobuf *f, int indent, Otf *o, KernClass *v);
1004+
1005+struct KernSubtable2 {
1006+ u16int rowWidth;
1007+ u16int leftClassOffset;
1008+ u16int rightClassOffset;
1009+ u16int kerningArrayOffset;
1010+ KernClass *leftClass;
1011+ KernClass *rightClass;
1012+ s16int *kerningArray;
1013+};
1014+
1015+int read_KernSubtable2(Otf *o, KernSubtable2 *v);
1016+void print_KernSubtable2(Biobuf *f, int indent, Otf *o, KernSubtable2 *v);
1017+
1018+struct KernSubtable {
1019+ // u16int version;
1020+ u16int length;
1021+ u16int coverage;
1022+};
1023+
1024+int read_KernSubtable(Otf *o, KernSubtable *v);
1025+void print_KernSubtable(Biobuf *f, int indent, Otf *o, KernSubtable *v);
1026+
1027+struct TableKern {
1028+ // u16int version;
1029+ u16int nTables;
1030+ KernSubtable *subtables;
1031+};
1032+
1033+int read_TableKern(Otf *o, TableKern *v);
1034+void print_TableKern(Biobuf *f, int indent, Otf *o, TableKern *v);
1035+
1036+struct TableLoca {
1037+ u16int *shortOffsets;
1038+ u32int *longOffsets;
1039+};
1040+
1041+int read_TableLoca(Otf *o, TableLoca *v);
1042+void print_TableLoca(Biobuf *f, int indent, Otf *o, TableLoca *v);
9591043
9601044 struct TableOS∕2 {
9611045 u16int version;
@@ -1000,7 +1084,7 @@ struct TableOS∕2 { · 38 unmodified lines
10001084 };
10011085
10021086 int read_TableOS∕2(Otf *o, TableOS∕2 *v);
1003−void print_TableOS∕2(Biobuf *f, int indent, TableOS∕2 *v);
1087+void print_TableOS∕2(Biobuf *f, int indent, Otf *o, TableOS∕2 *v);
10041088
10051089 struct TableRecord {
10061090 u32int tableTag;
@@ -1008,11 +1092,11 @@ struct TableRecord { · 1 unmodified line
10081092 u32int offset;
10091093 u32int length;
10101094 void *parsed;
1011− void (*print)(Biobuf *f, int indent, void *parsed);
1095+ void (*print)(Biobuf *f, int indent, Otf *o, void *parsed);
10121096 };
10131097
10141098 int read_TableRecord(Otf *o, TableRecord *v);
1015−void print_TableRecord(Biobuf *f, int indent, TableRecord *v);
1099+void print_TableRecord(Biobuf *f, int indent, Otf *o, TableRecord *v);
10161100
10171101 struct TableDirectory {
10181102 u32int sfntVersion;
@@ -1025,6 +1109,7 @@ struct TableDirectory { · 6 unmodified lines
10251109 TableHead *head;
10261110 TableHhea *hhea;
10271111 TableMaxp *maxp;
1112+ TableHmtx *hmtx;
10281113 TablePost *post;
10291114 TableName *name;
10301115 TableEBDT *ebdt;
@@ -1033,11 +1118,13 @@ struct TableDirectory { · 2 unmodified lines
10331118 TableGPOS *gpos;
10341119 TableGSUB *gsub;
10351120 TableMATH *math;
1121+ TableKern *kern;
1122+ TableLoca *loca;
10361123 TableOS∕2 *os∕2;
10371124 };
10381125
10391126 int read_TableDirectory(Otf *o, TableDirectory *v);
1040−void print_TableDirectory(Biobuf *f, int indent, TableDirectory *v);
1127+void print_TableDirectory(Biobuf *f, int indent, Otf *o, TableDirectory *v);
10411128
10421129 extern int indentΔ;
10431130
otf.rkt+101−42
@@ -159,7 +159,7 @@ · 158 unmodified lines
159159 {uint16 macStyle}
160160 {uint16 lowestRecPPEM}
161161 {int16 fontDirectionHint unused (>= -2) (<= 2)}
162− {int16 indexToLocFormat (<= 1)}
162+ {int16 indexToLocFormat ->o (<= 1)}
163163 {int16 glyphDataFormat unused (== 0)}
164164 #:tag "head")
165165
@@ -178,24 +178,23 @@ · 12 unmodified lines
178178 {int16 caretOffset}
179179 {int16 reserved [4] unused}
180180 {int16 metricDataFormat (== 0)}
181− {uint16 numberOfHMetrics}
181+ {uint16 numberOfHMetrics ->o}
182182 #:tag "hhea")
183183
184184 (mkcmplx LongHorMetric {UFWORD advanceWidth} {FWORD lsb})
185185
186−#|
187−FIXME what. WHAT.
188−(mkcmplx TableHmtx
189− {LongHorMetric hMetrics[TableHhea numberOfHMetrics]}
190− {FWORD leftSideBearings[- (TableMaxp numGlyphs) (TableHhea numberOfHMetrics)]})
191−|#
192−
193186 (mkcmplx TableMaxp
194187 {Version16Dot16 version (== #x05000 #x10000) unused}
195− {uint16 numGlyphs}
188+ {uint16 numGlyphs ->o}
196189 ; a bunch of fields ignored here
197190 #:tag "maxp")
198191
192+(mkcmplx TableHmtx
193+ {LongHorMetric hMetrics [+ o->numberOfHMetrics 0]}
194+ {FWORD leftSideBearings [- o->numGlyphs o->numberOfHMetrics]}
195+ #:tag "hmtx"
196+ #:after (list TableHhea TableMaxp))
197+
199198 (mkcmplx TablePost
200199 {Version16Dot16 version (== #x10000 #x20000 #x25000 #x30000) unused}
201200 {Fixed italicAngle}
@@ -254,12 +253,11 @@ FIXME what. WHAT. · 52 unmodified lines
254253 {int8 minAfterBL}
255254 {int8 pad [2] unused})
256255
257−(mkcmplx IndexSubtable1 {Offset32 sbitOffsets} #;[+ (- lastGlyphIndex firstGlyphIndex) 2])
256+(mkcmplx IndexSubtable1 {Offset32 sbitOffsets [+ (- o->lastGlyphIndex o->firstGlyphIndex) 2]})
258257
259258 (mkcmplx IndexSubtable2 {uint32 imageSize} {BigGlyphMetrics bigMetrics})
260259
261−; FIXME
262−(mkcmplx IndexSubtable3 {Offset16 sbitOffsets} #;[+ (- lastGlyphIndex firstGlyphIndex) 2])
260+(mkcmplx IndexSubtable3 {Offset16 sbitOffsets [+ (- o->lastGlyphIndex o->firstGlyphIndex) 2]})
263261
264262 (mkcmplx GlyphIdOffsetPair {uint16 glyphID} {Offset16 sbitOffset})
265263
@@ -282,8 +280,8 @@ FIXME what. WHAT. · 16 unmodified lines
282280 {IndexSubtable5 sub5 (== indexFormat 5)})
283281
284282 (mkcmplx IndexSubtableRecord
285− {uint16 firstGlyphIndex}
286− {uint16 lastGlyphIndex}
283+ {uint16 firstGlyphIndex ->o}
284+ {uint16 lastGlyphIndex ->o}
287285 {Offset32 indexSubtableOffset}
288286 {IndexSubtable indexSubtable (at indexSubtableOffset)})
289287
@@ -569,6 +567,43 @@ FIXME what. WHAT. · 279 unmodified lines
569567 {MathVariants mathVariants (at mathVariantsOffset)}
570568 #:tag "MATH")
571569
570+(mkcmplx KernPair {uint16 left} {uint16 right} {FWORD value})
571+
572+(mkcmplx KernSubtable0
573+ {uint16 nPairs}
574+ {uint16 searchRange}
575+ {uint16 entrySelector}
576+ {uint16 rangeShift}
577+ {KernPair kernPairs [nPairs]})
578+
579+(mkcmplx KernClass {uint16 firstGlyph} {uint16 nGlyphs} {uint16 values [nGlyphs]})
580+
581+(mkcmplx KernSubtable2
582+ {uint16 rowWidth}
583+ {Offset16 leftClassOffset}
584+ {Offset16 rightClassOffset}
585+ {Offset16 kerningArrayOffset}
586+ {KernClass leftClass (at leftClassOffset)}
587+ {KernClass rightClass (at rightClassOffset)}
588+ {FWORD kerningArray [/ rowWidth 2]})
589+
590+(mkcmplx KernSubtable
591+ {uint16 version (== 0) unused}
592+ {uint16 length (>= 6)} ; including this header
593+ {uint16 coverage}) ; FIXME the rest depends on the coverage bits (8-15 = 0 or 2)
594+
595+(mkcmplx TableKern
596+ {uint16 version (== 0) unused}
597+ {uint16 nTables}
598+ {KernSubtable subtables [nTables]}
599+ #:tag "kern")
600+
601+(mkcmplx TableLoca
602+ {Offset16 shortOffsets [+ o->numGlyphs 1] (== o->indexToLocFormat 0)}
603+ {Offset32 longOffsets [+ o->numGlyphs 1] (== o->indexToLocFormat 1)}
604+ #:tag "loca"
605+ #:after (list TableHead))
606+
572607 (mkcmplx TableOS∕2
573608 {uint16 version (<= 5)}
574609 {FWORD xAvgCharWidth}
@@ -616,12 +651,13 @@ FIXME what. WHAT. · 41 unmodified lines
616651 {uint32 checksum unused hex}
617652 {Offset32 offset}
618653 {uint32 length}
619− #:extra (list (cons 'field
620− (list (~a "void *parsed;")
621− (~a "void (*print)(Biobuf *f, int indent, void *parsed);")))
622− (cons 'print
623− (list (~a "if(v->print != nil && v->parsed != nil)")
624− (~a "\tv->print(f, indent+indentΔ, v->parsed);")))))
654+ #:extra
655+ (list (cons 'field
656+ (list (~a "void *parsed;")
657+ (~a "void (*print)(Biobuf *f, int indent, Otf *o, void *parsed);")))
658+ (cons 'print
659+ (list (~a "if(v->print != nil && v->parsed != nil)")
660+ (~a " v->print(f, indent+indentΔ, o, v->parsed);")))))
625661
626662 (define (c-friendly-name t)
627663 (string-replace (string-trim (string-downcase t)) "/" "∕"))
@@ -634,29 +670,52 @@ FIXME what. WHAT. · 6 unmodified lines
634670 (define (ft t i)
635671 (~a "'" (string-ref t i) "'" (if (< i 3) (~a "<<" (* 8 (- 3 i))) "")))
636672 (define case-tag (~a "(u32int)(" (string-join (map (λ (i) (ft tag i)) (range 4)) "|") ")"))
637− (list (~a "\tcase " case-tag ":")
638− (~a "\t\tv->" (ptr c) " = calloc(1, sizeof(" (cmplx-name c) "));")
639− (~a "\t\tif(read_" (cmplx-name c) "(o, v->" (ptr c) ") < 0){")
640− (~a "\t\t\tfree(v->" (ptr c) ");")
641− (~a "\t\t\tgoto err;")
642− (~a "\t\t}")
643− (~a "\t\trec->parsed = v->" (ptr c) ";")
644− (~a "\t\trec->print = (void*)print_" (cmplx-name c) ";")
645− (~a "\t\tbreak;")))
673+ (define after (cmplx-after c))
674+ (define if-ready (string-join (map (λ (ac) (~a "v->" (ptr ac) " == nil")) after) " || "))
675+ (list (~a "case " case-tag ":")
676+ (indent (if (empty? after)
677+ empty
678+ (list (~a "{")
679+ (~a " static int retried = 0;")
680+ (~a " if(" if-ready "){")
681+ (~a " if(retried){")
682+ (~a " werrstr(\"%s: deps missing\", \"" (cmplx-name c) "\");")
683+ (~a " goto err;")
684+ (~a " }")
685+ (~a " retried = 1;")
686+ (~a " retry++;")
687+ (~a " break;")
688+ (~a " }")
689+ (~a " if(retried)")
690+ (~a " retry--;")
691+ (~a "}"))))
692+ (~a " if(v->" (ptr c) " != nil)") ; don't reparse the same table
693+ (~a " break;")
694+ (~a " v->" (ptr c) " = calloc(1, sizeof(" (cmplx-name c) "));")
695+ (~a " if(read_" (cmplx-name c) "(o, v->" (ptr c) ") < 0){")
696+ (~a " free(v->" (ptr c) ");")
697+ (~a " goto err;")
698+ (~a " }")
699+ (~a " rec->parsed = v->" (ptr c) ";")
700+ (~a " rec->print = (void*)print_" (cmplx-name c) ";")
701+ (~a " break;")))
646702 (list (cons 'field (map (λ (c) (~a (cmplx-name c) " *" (ptr c) ";")) tagged))
647703 (cons 'read
648− (list (~a "for(int i = 0; i < v->numTables; i++){")
649− (~a "\tTableRecord *rec = &v->tableRecords[i];")
650− (~a "\tif(rec->length == 0)") ; skip all empty tables
651− (~a "\t\tcontinue;")
652− (~a "\tif(otfpushrange(o, rec->offset, rec->length) < 0)")
653− (~a "\t\tgoto err;")
654− (~a "\tswitch(rec->tableTag){")
655− (map case-statement tagged)
656− (~a "\t}")
657− (~a "\tif(otfpoprange(o) < 0)")
658− (~a "\t\tgoto err;")
659− (~a "}")))))
704+ (list (~a "int retry = 0;")
705+ (~a "do{")
706+ (~a " for(int i = 0; i < v->numTables; i++){")
707+ (~a " TableRecord *rec = &v->tableRecords[i];")
708+ (~a " if(rec->length == 0)") ; skip all empty tables
709+ (~a " continue;")
710+ (~a " if(otfpushrange(o, rec->offset, rec->length) < 0)")
711+ (~a " goto err;")
712+ (~a " switch(rec->tableTag){")
713+ (indent (indent (map case-statement tagged)))
714+ (~a " }")
715+ (~a " if(otfpoprange(o) < 0)")
716+ (~a " goto err;")
717+ (~a " }")
718+ (~a "}while(retry > 0);")))))
660719
661720 (mkcmplx TableDirectory
662721 {uint32 sfntVersion (== #x00010000 #x4f54544f) hex}
test.c+1−1
@@ -20,7 +20,7 @@ main(int argc, char **argv) · 19 unmodified lines
2020 }else if(read_TableDirectory(o, &td) != 0){
2121 fprint(2, "%s: %r\n", argv[i]);
2222 } else {
23− print_TableDirectory(out, indentΔ, &td);
23+ print_TableDirectory(out, indentΔ, o, &td);
2424 }
2525 otfclose(o);
2626 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t