gpos might work

main
Matthew Butterick 7 years ago
parent 9a028a3822
commit b2077fba21

@ -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
###

@ -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)

@ -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))

@ -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))

@ -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)))

@ -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))
;;#################

@ -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)))

@ -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

Loading…
Cancel
Save