resume in bad stream length of loca

main
Matthew Butterick 7 years ago
parent 4b063efda4
commit 9a433cc96b

@ -15,6 +15,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/tables/directory.js
(define-subclass RStruct (RDirectory)
(define/override (process res stream)
;; in `restructure` `process` method, `res` is aliased as `this`
(define new-tables-val (mhash))
(for ([table (in-list (· res tables))])
(hash-set! new-tables-val (string->symbol (· table tag)) table))
@ -29,7 +30,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/tables/directory.js
'tables (make-object RArray TableEntry 'numTables))))
(define (directory-decode ip [options (mhash)])
(define is (make-object RDecodeStream ip))
(define is (make-object RDecodeStream (port->bytes ip)))
(send Directory decode is))

@ -32,27 +32,29 @@ https://github.com/mbutterick/fontkit/blob/master/src/tables/head.js
(test-module
(require "directory.rkt")
(define ip (open-input-file charter-path))
(define ip (open-input-file charter-italic-path)) ; use italic to make sure style flags are set correctly
(define dir (directory-decode ip))
(define offset (· dir tables head offset))
(define length (· dir tables head length))
(check-equal? offset 236)
(check-equal? length 54)
(define table-bytes #"\0\1\0\0\0\2\0\0@\247\22 _\17<\365\0\t\3\350\0\0\0\0\316\3\301?\0\0\0\0\316\3\304\363\377_\377\24\4\251\3\303\0\0\0\t\0\2\0\0\0\0")
(define table-bytes #"\0\1\0\0\0\2\0\0.\252t<_\17<\365\0\t\3\350\0\0\0\0\316\3\301\261\0\0\0\0\316\3\304\364\377\36\377\24\4\226\3\324\0\2\0\t\0\2\0\0\0\0")
(set-port-position! ip 0)
(check-equal? (peek-bytes length offset ip) table-bytes)
(define table-data (send head decode (make-object RDecodeStream table-bytes)))
(check-equal? (· table-data unitsPerEm) 1000)
(check-equal? (· table-data yMin) -236)
(check-equal? (· table-data yMax) 963)
(check-equal? (· table-data xMax) 1193)
(check-equal? (· table-data xMin) -161)
(check-equal? (· table-data yMax) 980)
(check-equal? (· table-data xMax) 1174)
(check-equal? (· table-data xMin) -226)
(check-equal? (· table-data macStyle) (make-hash '((shadow . #f)
(extended . #f)
(condensed . #f)
(underline . #f)
(outline . #f)
(bold . #f)
(italic . #f))))
(check-equal? (· table-data magicNumber) #x5F0F3CF5))
(italic . #t))))
(check-equal? (· table-data magicNumber) #x5F0F3CF5)
(check-equal? (· table-data indexToLocFormat) 0) ; used in loca table
)

@ -4,7 +4,8 @@
(define index? (λ (x) (and (number? x) (integer? x) (not (negative? x)))))
(define-runtime-path charter-path "../pitfall/test/assets/Charter.ttf")
(define-runtime-path charter-path "../pitfall/test/assets/charter.ttf")
(define-runtime-path charter-italic-path "../pitfall/test/assets/charter-italic.ttf")
(define-macro (test-module . EXPRS)
#`(module+ test

@ -2,20 +2,269 @@
(require restructure)
(provide (all-defined-out))
(define short-style 0)
#|
approximates
https://github.com/mbutterick/fontkit/blob/master/src/tables/loca.js
|#
(define-subclass RVersionedStruct (Rloca))
(define-subclass RVersionedStruct (Rloca)
(define/override (process res stream)
;; in `restructure` `process` method, `res` is aliased as `this`
;;
(when (= short-style (· res version))
;; in a short-style loca table, actual offset values are divided by 2 (to fit into 16 bits)
;; so we re-inflate them.
(hash-update! res 'offsets (λ (offsets) (map (curry * 2) offsets))))))
(define loca (make-object Rloca
(λ (this) (hash-ref (send this _getTable 'head) 'indexToLocFormat))
(λ (parent) (hash-ref (send parent _getTable 'head) 'indexToLocFormat))
(dictify
0 (dictify 'offsets (make-object RArray uint16be))
1 (dictify 'offsets (make-object RArray uint32be))
)))
(test-module
)
(require "directory.rkt")
(define ip (open-input-file charter-path))
(define dir (directory-decode ip))
(define offset (· dir tables loca offset))
(define len (· dir tables loca length))
(check-equal? offset 38692)
(check-equal? len 460)
(set-port-position! ip 0)
(define ds (make-object RDecodeStream (peek-bytes len offset ip)))
(define table-data (send loca decode ds #:version 0))
(check-equal? (length (· table-data offsets)) 230)
(check-equal? (· table-data offsets) '(0
0
0
136
296
500
864
1168
1548
1628
1716
1804
1944
2048
2128
2176
2256
2312
2500
2596
2788
3052
3168
3396
3624
3732
4056
4268
4424
4564
4640
4728
4804
5012
5384
5532
5808
6012
6212
6456
6672
6916
7204
7336
7496
7740
7892
8180
8432
8648
8892
9160
9496
9764
9936
10160
10312
10536
10780
10992
11148
11216
11272
11340
11404
11444
11524
11820
12044
12216
12488
12728
12932
13324
13584
13748
13924
14128
14232
14592
14852
15044
15336
15588
15776
16020
16164
16368
16520
16744
16984
17164
17320
17532
17576
17788
17896
18036
18284
18552
18616
18988
19228
19512
19712
19796
19976
20096
20160
20224
20536
20836
20876
21000
21200
21268
21368
21452
21532
21720
21908
22036
22244
22664
22872
22932
22992
23088
23220
23268
23372
23440
23600
23752
23868
23988
24084
24184
24224
24548
24788
25012
25292
25716
25884
26292
26396
26540
26796
27172
27488
27512
27536
27560
27584
27912
27936
27960
27984
28008
28032
28056
28080
28104
28128
28152
28176
28200
28224
28248
28272
28296
28320
28344
28368
28392
28416
28440
28464
28488
28512
28536
28560
28968
28992
29016
29040
29064
29088
29112
29136
29160
29184
29208
29232
29256
29280
29304
29328
29352
29376
29400
29424
29448
29472
29496
29520
29824
30164
30220
30652
30700
30956
31224
31248
31332
31488
31636
31916
32104
32176
32484
32744
32832
32956
33248
33664
33884
34048
34072)))

@ -73,13 +73,15 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
(hash-set! maxp 'numGlyphs (length (· this glyf))) ; todo
;; todo
(hash-update! (send (· this font) _getTable 'loca) 'offsets (λ (val) (push-end! val (· this offset))))
(report 'boing)
(report (send (· this font) _getTable 'loca) 'offsets)
#;(hash-update! (report (send (· this font) _getTable 'loca)) 'offsets (λ (val) (push-end! val (· this offset))))
;; Tables.loca.preEncode.call(this.loca);
(define head (cloneDeep (send (· this font) _getTable 'head)))
#;(define head (cloneDeep (send (· this font) _getTable 'head)))
;; head.indexToLocFormat = this.loca.version; ; todo
(define hhea (cloneDeep (send (· this font) _getTable 'hhea)))
#;(define hhea (cloneDeep (send (· this font) _getTable 'hhea)))
;; hhea.numberOfMetrics = this.hmtx.metrics.length;
(unfinished)

@ -12,7 +12,8 @@ https://github.com/mbutterick/restructure/blob/master/src/Array.coffee
(define/augment (decode stream [parent #f])
(let ([length (if length
(resolveLength length stream parent)
(send stream length))])
;; implied length: length of stream divided by size of item
(report* (send stream length) (send type size) (floor (/ (send stream length) (send type size)))))])
(caseq lengthType
[(count) (for/list ([i (in-range length)])

@ -1,7 +1,9 @@
#lang restructure/racket
(provide (all-defined-out))
;; approximates https://github.com/mbutterick/restructure/blob/master/src/DecodeStream.coffee
#| approximates
https://github.com/mbutterick/restructure/blob/master/src/DecodeStream.coffee
|#
(define (read-bytes-exact count p)
(define bs (read-bytes count p))
@ -25,12 +27,14 @@
(values (string->symbol (format "~a~a" key endian)) value))))
;; basically just a wrapper for a Racket port
(define-subclass object% (RDecodeStream [buffer-in #""])
(define-subclass object% (RDecodeStream [buffer-in #f])
(field [_port (cond
[(not buffer-in) (open-input-bytes (bytes))]
[(bytes? buffer-in) (open-input-bytes buffer-in)]
[(input-port? buffer-in) buffer-in]
[else (raise-argument-error 'RDecodeStream "bytes or input port" buffer-in)])])
(getter-field [pos (port-position _port)])
(getter-field [length (and (bytes? buffer-in) (bytes-length buffer-in))])
(define/public (read count)
(read-bytes-exact count _port)))

@ -7,12 +7,16 @@ approximates
https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
|#
(define-subclass RBase (RStruct assocs)
(field [key-index (map car assocs)]
(define-subclass RBase (RStruct [assocs (dictify)])
(field [key-index #f]
[fields (mhash)])
(for ([(k v) (in-dict assocs)])
(hash-set! fields k v))
(define/public (make-key-index! [fields assocs])
(set! key-index (map car fields)))
(make-key-index!)
(define/override (decode stream [parent #f] [length 0])
(define res (_setup stream parent length))
(_parseFields stream res fields)
@ -24,7 +28,7 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
(for ([key (in-list key-index)])
(send (hash-ref fields key) encode stream (hash-ref val key))))
(define/private (_setup stream parent length)
(define/public-final (_setup stream parent length)
(define res (mhasheq))
;; define hidden properties
@ -35,13 +39,13 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee
'_length (mhasheq 'value length)))
res)
(define/private (_parseFields stream res field)
(define/public-final (_parseFields stream res fields)
(for ([key (in-list key-index)])
(define hashvalue (hash-ref fields key))
(define dictvalue (dict-ref fields key))
(define val
(if (procedure? hashvalue)
(hashvalue res)
(send hashvalue decode stream res)))
(if (procedure? dictvalue)
(dictvalue res)
(send dictvalue decode stream res)))
(hash-set! res key val)))
)

@ -8,14 +8,22 @@ https://github.com/mbutterick/restructure/blob/master/src/VersionedStruct.coffee
|#
(define-subclass RStruct (RVersionedStruct type [versions (dictify)])
(define/override (decode stream [parent #f] [length 0])
(define/override (decode stream [parent #f] [length 0] #:version [maybe-version #f])
(define res (send this _setup stream parent length))
(define version (cond
[maybe-version]
[(procedure? type) (type parent)]
[(is-a? type RBase) (send type decode stream)]
[else (raise-argument-error 'decode "way of finding version" type)]))
(report version 'yay)
#;(_parseFields stream res fields)
#;(send this process res stream)
res))
(hash-set! res 'version version)
(define fields (dict-ref versions version (λ () (raise-argument-error 'RVersionedStruct:decode "valid version key" version))))
(send this make-key-index! fields)
(cond
[(is-a? fields RVersionedStruct) (send fields decode stream parent)]
[else
(send this _parseFields stream res fields)
(send this process res stream)
res]))
)
Loading…
Cancel
Save