#lang racket/base (require xenomorph) (provide (all-defined-out)) #| approximates https://github.com/mbutterick/fontkit/blob/master/src/tables/hmtx.js |# (define hmtx-entry (x:struct 'advance uint16be 'bearing int16be)) (define hmtx (x:struct 'metrics (x:lazy-array #:type hmtx-entry #:length (λ (arr) (hash-ref (hash-ref (hash-ref arr 'parent) 'hhea) 'numberOfMetrics))) 'bearings (x:lazy-array #:type int16be #:length (λ (arr) (- (hash-ref (hash-ref (hash-ref arr 'parent) 'maxp) 'numGlyphs) (hash-ref (hash-ref (hash-ref arr 'parent) 'hhea) 'numberOfMetrics)))))) (module+ test (require rackunit racket/serialize racket/stream racket/class "../helper.rkt") ;; same as hmtx but doesn't require resolution of function to get length (define hmtx-test (x:struct 'metrics (x:lazy-array hmtx-entry (λ (t) 229)) 'bearing (x:lazy-array int16be (λ (t) 0)))) (define ip (open-input-file charter-path)) (define dir (deserialize (read (open-input-file charter-directory-path)))) (define hmtx-offset (hash-ref (hash-ref (hash-ref dir 'tables) 'hmtx) 'offset)) (define hmtx-length (hash-ref (hash-ref (hash-ref dir 'tables) 'hmtx) 'length)) (check-equal? hmtx-offset 456) (check-equal? hmtx-length 916) (define hmtx-bytes (peek-bytes hmtx-length hmtx-offset ip)) (define hmtx-data (decode hmtx-test hmtx-bytes)) (check-equal? (send hmtx-test x:size) (* 229 (send hmtx-entry x:size))) (define H-gid 41) (define OE-gid 142) (check-equal? (stream-ref (hash-ref hmtx-data 'metrics) H-gid) (make-hasheq '((bearing . 33) (advance . 738)))) (check-equal? (stream-ref (hash-ref hmtx-data 'metrics) OE-gid) (make-hasheq '((bearing . 43) (advance . 993)))))