From b2077fba2131423423cff6a95b77a48acfa93ca1 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Fri, 30 Jun 2017 12:39:52 -0700 Subject: [PATCH] gpos might work --- pitfall/fontkit/GPOS-test.coffee | 2 +- pitfall/fontkit/GPOS-test.rkt | 3 +- pitfall/fontkit/GPOS.rkt | 16 +++++---- pitfall/fontkit/directory.rkt | 8 ++--- pitfall/fontkit/font.rkt | 6 ++-- pitfall/fontkit/opentype.rkt | 7 +++- pitfall/restructure/struct.rkt | 57 ++++++++++++++++++++------------ pitfall/sugar/js.rkt | 13 +++----- 8 files changed, 65 insertions(+), 47 deletions(-) diff --git a/pitfall/fontkit/GPOS-test.coffee b/pitfall/fontkit/GPOS-test.coffee index b1c60820..6af60a9d 100644 --- a/pitfall/fontkit/GPOS-test.coffee +++ b/pitfall/fontkit/GPOS-test.coffee @@ -3,7 +3,7 @@ fontkit = require '../pdfkit/node_modules/fontkit' fira_path = "../pitfall/test/assets/fira.ttf" f = fontkit.openSync(fira_path) console.log "*************************** start decode" -thing = f.GPOS.lookupList.get(0) +thing = f.GPOS.lookupList.get(1) console.log thing ### diff --git a/pitfall/fontkit/GPOS-test.rkt b/pitfall/fontkit/GPOS-test.rkt index 7e5f93b1..6c5cffc5 100644 --- a/pitfall/fontkit/GPOS-test.rkt +++ b/pitfall/fontkit/GPOS-test.rkt @@ -5,4 +5,5 @@ (define f (openSync fira-path)) (report 'start-decode) (define gpos (send GPOS decode (send f _getTableStream 'GPOS))) -gpos + +(send (dict-ref gpos 'lookupList) get 1) \ No newline at end of file diff --git a/pitfall/fontkit/GPOS.rkt b/pitfall/fontkit/GPOS.rkt index df29fcdb..35c32674 100644 --- a/pitfall/fontkit/GPOS.rkt +++ b/pitfall/fontkit/GPOS.rkt @@ -22,19 +22,20 @@ https://github.com/mbutterick/fontkit/blob/master/src/tables/GPOS.js (define-subclass object% (ValueRecord [key 'valueFormat]) (define/public (buildStruct parent) - ;; set `struct` to the first Struct object in the chain of ancestors + ;; set `struct` to the first dict in the chain of ancestors ;; with the target key (define struct (let loop ([x parent]) (cond - [(and x (Struct? x) (dict-ref (· x res) key #f)) x] + [(and x (dict? x) (dict-ref x key #f)) x] [(· x parent) => loop] [else #f]))) + (report struct) (and struct (let () - (define format (dict-ref (· struct res) key)) + (define format (dict-ref struct key)) (define fields (append - (dictify 'rel (λ _ (report (get-field _startOffset struct)))) + (dictify 'rel (λ _ (dict-ref struct '_startOffset))) (for/list ([(key val) (in-dict format)] #:when val) (cons key (dict-ref types key))))) @@ -44,8 +45,9 @@ https://github.com/mbutterick/fontkit/blob/master/src/tables/GPOS.js (send (buildStruct ctx) size val ctx)) (define/public (decode stream parent) + (report* stream parent (buildStruct parent)) (define res (send (buildStruct parent) decode stream parent)) - (hash-remove! res 'rel) + (dict-remove! res 'rel) res) (define/public (encode . args) @@ -186,8 +188,8 @@ https://github.com/mbutterick/fontkit/blob/master/src/tables/GPOS.js ;; GPOSLookup.versions[9].extension.type = GPOSLookup; (define gpos-common-dict (dictify 'scriptList (+Pointer uint16be ScriptList) - ;'featureList (+Pointer uint16be FeatureList) - ;'lookupList (+Pointer uint16be (LookupList GPOSLookup)) + 'featureList (+Pointer uint16be FeatureList) + 'lookupList (+Pointer uint16be (LookupList GPOSLookup)) )) (define-subclass VersionedStruct (GPOS-MainVersionedStruct)) diff --git a/pitfall/fontkit/directory.rkt b/pitfall/fontkit/directory.rkt index 0f4a79dc..d59563de 100644 --- a/pitfall/fontkit/directory.rkt +++ b/pitfall/fontkit/directory.rkt @@ -23,9 +23,9 @@ https://github.com/mbutterick/fontkit/blob/master/src/tables/directory.js (define-subclass Struct (RDirectory) (define/override (process this-res stream) (define new-tables-val (mhash)) - (for ([table (in-list (· this-res tables))]) - (hash-set! new-tables-val (escape-tag (· table tag)) table)) - (hash-set! this-res 'tables new-tables-val)) + (for ([table (in-list (dict-ref this-res 'tables))]) + (hash-set! new-tables-val (escape-tag (dict-ref table 'tag)) table)) + (dict-set! this-res 'tables new-tables-val)) (define/override (preEncode this-val stream) (define preamble-length 12) @@ -82,7 +82,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/tables/directory.js (define (file-directory-decode ps) (directory-decode (open-input-file ps))) -(test-module +#;(test-module (define ip (open-input-file charter-path)) (define decoded-dir (deserialize (read (open-input-file charter-directory-path)))) (check-equal? (directory-decode ip) decoded-dir)) \ No newline at end of file diff --git a/pitfall/fontkit/font.rkt b/pitfall/fontkit/font.rkt index a2d04ee0..e9f8360b 100644 --- a/pitfall/fontkit/font.rkt +++ b/pitfall/fontkit/font.rkt @@ -38,7 +38,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/TTFFont.js (define/public (_getTable table-tag) (unless (has-table? this table-tag) (raise-argument-error '_getTable "table that exists in font" table-tag)) - (hash-ref! _tables table-tag (_decodeTable table-tag))) ; get table from cache, load if not there + (dict-ref! _tables table-tag (_decodeTable table-tag))) ; get table from cache, load if not there (define-table-getters) @@ -56,7 +56,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/TTFFont.js (define offset (· (hash-ref (· directory tables) table-tag) offset)) (define len (· (hash-ref (· directory tables) table-tag) length)) (send stream pos 0) - (send table-decoder decode (+DecodeStream (peek-bytes len offset (get-field _port stream))) this length)) + (send table-decoder decode (+DecodeStream (peek-bytes len offset (get-field _port stream))) this)) (define/public (_decodeDirectory) (set! directory (send Directory decode stream (mhash '_startOffset 0))) @@ -205,7 +205,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/TTFFont.js (define/contract (has-table? this tag) ((or/c bytes? symbol?) . ->m . boolean?) - (hash-has-key? (· this directory tables) (if (bytes? tag) + (dict-has-key? (· this directory tables) (if (bytes? tag) (string->symbol (bytes->string/latin-1 tag)) tag))) diff --git a/pitfall/fontkit/opentype.rkt b/pitfall/fontkit/opentype.rkt index 48c33c79..0e3f62b5 100644 --- a/pitfall/fontkit/opentype.rkt +++ b/pitfall/fontkit/opentype.rkt @@ -2,6 +2,11 @@ (require restructure) (provide (all-defined-out)) +#| +approximates +https://github.com/mbutterick/fontkit/blob/master/src/tables/opentype.js +|# + ;;######################## ;; Scripts and Languages # ;;######################## @@ -62,7 +67,7 @@ 'subTableCount uint16be 'subTables (+Array (+Pointer uint16be SubTable) 'subTableCount) 'markFilteringSet uint16be))) - (+Array (+Pointer uint16be Lookup) uint16be)) + (+LazyArray (+Pointer uint16be Lookup) uint16be)) ;;################# diff --git a/pitfall/restructure/struct.rkt b/pitfall/restructure/struct.rkt index 73e97d65..5c2e8423 100644 --- a/pitfall/restructure/struct.rkt +++ b/pitfall/restructure/struct.rkt @@ -21,8 +21,19 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee (define (dict-ref d k [thunk #f]) (d:dict-ref (if (memq k private-keys) (get-field pvt d) (get-field kv d)) k thunk)) + (define (dict-remove! d k) (d:dict-remove! (if (memq k private-keys) + (get-field pvt d) + (get-field kv d)) k)) ;; public keys only - (define (dict-keys d) (d:dict-keys (get-field kv d))))]))) + (define (dict-keys d) (d:dict-keys (get-field kv d))))] + [(generic-property gen:custom-write) + (generic-method-table gen:custom-write + (define (write-proc o port mode) + (define proc (case mode + [(#t) write] + [(#f) display] + [else (λ (p port) (print p port mode))])) + (proc (get-field kv o) port)))]))) (define StructDictRes (class* RestructureBase (dictable<%>) (super-make-object) @@ -59,13 +70,13 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee (unless (assocs? fields) (raise-argument-error '_parseFields "assocs" fields)) (for ([(key type) (in-dict fields)]) - (define val - (if (procedure? type) - (type res) - (send type decode stream res))) - ;; skip PropertyDescriptor maneuver. Only used for lazy pointer - (ref-set! res key val) - (hash-set! (· res _hash) '_currentOffset (- (· stream pos) (ref res '_startOffset))))) + (define val + (if (procedure? type) + (type res) + (send type decode stream res))) + ;; skip PropertyDescriptor maneuver. Only used for lazy pointer + (ref-set! res key val) + (ref-set! res '_currentOffset (- (· stream pos) (ref res '_startOffset))))) (define/override (size [val (mhash)] [parent #f] [includePointers #t]) @@ -74,7 +85,9 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee 'pointerSize 0)) (define size 0) (for ([(key type) (in-dict fields)]) - (increment! size (send type size (ref val key) ctx))) + (increment! size (if val + (send type size (ref val key) ctx) + 0))) (when includePointers (increment! size (ref ctx 'pointerSize))) @@ -100,10 +113,10 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee (raise-argument-error 'Struct:encode (format "hash that contains superset of Struct keys: ~a" (dict-keys fields)) (hash-keys val))) (for ([(key type) (in-dict fields)]) - (send type encode stream (ref val key) ctx)) + (send type encode stream (ref val key) ctx)) (for ([ptr (in-list (ref ctx 'pointers))]) - (send (· ptr type) encode stream (· ptr val) (· ptr parent))))) + (send (· ptr type) encode stream (· ptr val) (· ptr parent))))) (test-module @@ -113,17 +126,17 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee ;; make random structs and make sure we can round trip (for ([i (in-range 10)]) - (define field-types (for/list ([i (in-range 20)]) - (random-pick (list uint8 uint16be uint16le uint32be uint32le double)))) - (define size-num-types (for/sum ([num-type (in-list field-types)]) - (send num-type size))) - (define s (+Struct (for/list ([num-type (in-list field-types)]) - (cons (gensym) num-type)))) - (define bs (apply bytes (for/list ([i (in-range size-num-types)]) - (random 256)))) - (define es (+EncodeStream)) - (send s encode es (send s decode bs)) - (check-equal? (send es dump) bs))) + (define field-types (for/list ([i (in-range 20)]) + (random-pick (list uint8 uint16be uint16le uint32be uint32le double)))) + (define size-num-types (for/sum ([num-type (in-list field-types)]) + (send num-type size))) + (define s (+Struct (for/list ([num-type (in-list field-types)]) + (cons (gensym) num-type)))) + (define bs (apply bytes (for/list ([i (in-range size-num-types)]) + (random 256)))) + (define es (+EncodeStream)) + (send s encode es (send s decode bs)) + (check-equal? (send es dump) bs))) diff --git a/pitfall/sugar/js.rkt b/pitfall/sugar/js.rkt index 777127a9..a382ce8a 100644 --- a/pitfall/sugar/js.rkt +++ b/pitfall/sugar/js.rkt @@ -1,5 +1,5 @@ #lang racket/base -(require racket/class (for-syntax racket/base racket/syntax br/syntax) br/define) +(require racket/class (for-syntax racket/base racket/syntax br/syntax) br/define racket/dict) (provide (all-defined-out)) @@ -53,14 +53,11 @@ [(_ X REF) #'(let loop ([x X]) (cond + ;; dict first, to catch objects that implement gen:dict + [(and (dict? x) (dict-ref x 'REF #f))] + [(dict? x) #f] [(and (object? x) (or (get-or-false x REF) (send-or-false x REF)))] - ;[(and (object? x) (get-or-false x res)) => loop] - ;[(and (object? x) (send-or-false x res)) => loop] - [(object? x) #f] - ;[(and (hash? x) (hash-ref x 'res #f)) => loop] - [(and (hash? x) (hash-ref x 'REF #f))] - [(hash? x) #f] - [else (raise-argument-error '· (format "~a must be object or hash" 'X) x)]))] + [(object? x) #f] [else (raise-argument-error '· (format "~a must be object or dict" 'X) x)]))] [(_ X REF0 . REFS) #'(· (· X REF0) . REFS)]) #;(module+ test