diff --git a/pitfall/fontkit/font.rkt b/pitfall/fontkit/font.rkt index 802aaa88..6a2543b9 100644 --- a/pitfall/fontkit/font.rkt +++ b/pitfall/fontkit/font.rkt @@ -1,5 +1,5 @@ #lang fontkit/racket -(require "freetype-ffi.rkt" ffi/unsafe racket/runtime-path "subset.rkt" "glyph.rkt" "layout-engine.rkt" "bbox.rkt" "glyphrun.rkt" "cmap-processor.rkt" "directory.rkt" restructure/decodestream "tables.rkt") +(require "freetype-ffi.rkt" ffi/unsafe racket/runtime-path "subset.rkt" "glyph.rkt" "layout-engine.rkt" "bbox.rkt" "glyphrun.rkt" "cmap-processor.rkt" "directory.rkt" restructure "tables.rkt") (provide (all-defined-out)) (define-runtime-path charter-path "../pitfall/test/assets/charter.ttf") @@ -280,6 +280,6 @@ https://github.com/mbutterick/fontkit/blob/master/src/TTFFont.js (check-exn exn:fail:contract? (λ () (send f _getTable 'nonexistent-table-tag))) #;(send f _getTable 'maxp) (define subset (make-object TTFSubset f)) - (send subset encode) + (send subset encode (make-object REncodeStream)) ) \ No newline at end of file diff --git a/pitfall/fontkit/fpgm.rkt b/pitfall/fontkit/fpgm.rkt new file mode 100644 index 00000000..e098f7df --- /dev/null +++ b/pitfall/fontkit/fpgm.rkt @@ -0,0 +1,401 @@ +#lang fontkit/racket +(require restructure) +(provide (all-defined-out)) +#| +approximates +https://github.com/mbutterick/fontkit/blob/master/src/tables/fpgm.js +|# + +;; A list of instructions that are executed once when a font is first used. +;; These instructions are known as the font program. The main use of this table +;; is for the definition of functions that are used in many different glyph programs. + + +(define-subclass RStruct (Rfpgm)) + +(define fpgm (make-object Rfpgm + (dictify + 'instructions (make-object RArray uint8)))) + +(test-module + (require "directory.rkt") + (define ip (open-input-file charter-path)) + (define dir (directory-decode ip)) + (define offset (· dir tables fpgm offset)) + (define len (· dir tables fpgm length)) + (check-equal? offset 4140) + (check-equal? len 371) + (set-port-position! ip 0) + (define ds (make-object RDecodeStream (peek-bytes len offset ip))) + (check-equal? (hash-ref (send fpgm decode ds) 'instructions) '(184 + 0 + 0 + 44 + 75 + 184 + 0 + 9 + 80 + 88 + 177 + 1 + 1 + 142 + 89 + 184 + 1 + 255 + 133 + 184 + 0 + 68 + 29 + 185 + 0 + 9 + 0 + 3 + 95 + 94 + 45 + 184 + 0 + 1 + 44 + 32 + 32 + 69 + 105 + 68 + 176 + 1 + 96 + 45 + 184 + 0 + 2 + 44 + 184 + 0 + 1 + 42 + 33 + 45 + 184 + 0 + 3 + 44 + 32 + 70 + 176 + 3 + 37 + 70 + 82 + 88 + 35 + 89 + 32 + 138 + 32 + 138 + 73 + 100 + 138 + 32 + 70 + 32 + 104 + 97 + 100 + 176 + 4 + 37 + 70 + 32 + 104 + 97 + 100 + 82 + 88 + 35 + 101 + 138 + 89 + 47 + 32 + 176 + 0 + 83 + 88 + 105 + 32 + 176 + 0 + 84 + 88 + 33 + 176 + 64 + 89 + 27 + 105 + 32 + 176 + 0 + 84 + 88 + 33 + 176 + 64 + 101 + 89 + 89 + 58 + 45 + 184 + 0 + 4 + 44 + 32 + 70 + 176 + 4 + 37 + 70 + 82 + 88 + 35 + 138 + 89 + 32 + 70 + 32 + 106 + 97 + 100 + 176 + 4 + 37 + 70 + 32 + 106 + 97 + 100 + 82 + 88 + 35 + 138 + 89 + 47 + 253 + 45 + 184 + 0 + 5 + 44 + 75 + 32 + 176 + 3 + 38 + 80 + 88 + 81 + 88 + 176 + 128 + 68 + 27 + 176 + 64 + 68 + 89 + 27 + 33 + 33 + 32 + 69 + 176 + 192 + 80 + 88 + 176 + 192 + 68 + 27 + 33 + 89 + 89 + 45 + 184 + 0 + 6 + 44 + 32 + 32 + 69 + 105 + 68 + 176 + 1 + 96 + 32 + 32 + 69 + 125 + 105 + 24 + 68 + 176 + 1 + 96 + 45 + 184 + 0 + 7 + 44 + 184 + 0 + 6 + 42 + 45 + 184 + 0 + 8 + 44 + 75 + 32 + 176 + 3 + 38 + 83 + 88 + 176 + 64 + 27 + 176 + 0 + 89 + 138 + 138 + 32 + 176 + 3 + 38 + 83 + 88 + 35 + 33 + 176 + 128 + 138 + 138 + 27 + 138 + 35 + 89 + 32 + 176 + 3 + 38 + 83 + 88 + 35 + 33 + 184 + 0 + 192 + 138 + 138 + 27 + 138 + 35 + 89 + 32 + 176 + 3 + 38 + 83 + 88 + 35 + 33 + 184 + 1 + 0 + 138 + 138 + 27 + 138 + 35 + 89 + 32 + 176 + 3 + 38 + 83 + 88 + 35 + 33 + 184 + 1 + 64 + 138 + 138 + 27 + 138 + 35 + 89 + 32 + 184 + 0 + 3 + 38 + 83 + 88 + 176 + 3 + 37 + 69 + 184 + 1 + 128 + 80 + 88 + 35 + 33 + 184 + 1 + 128 + 35 + 33 + 27 + 176 + 3 + 37 + 69 + 35 + 33 + 35 + 33 + 89 + 27 + 33 + 89 + 68 + 45 + 184 + 0 + 9 + 44 + 75 + 83 + 88 + 69 + 68 + 27 + 33 + 33 + 89 + 45))) + diff --git a/pitfall/fontkit/prep.rkt b/pitfall/fontkit/prep.rkt new file mode 100644 index 00000000..578bd190 --- /dev/null +++ b/pitfall/fontkit/prep.rkt @@ -0,0 +1,105 @@ +#lang fontkit/racket +(require restructure) +(provide (all-defined-out)) +#| +approximates +https://github.com/mbutterick/fontkit/blob/master/src/tables/prep.js +|# + +(define-subclass RStruct (Rprep)) + +(define prep (make-object Rprep + (dictify + 'controlValueProgram (make-object RArray uint8)))) + +(test-module + (require "directory.rkt") + (define ip (open-input-file charter-path)) + (define dir (directory-decode ip)) + (define offset (· dir tables prep offset)) + (define len (· dir tables prep length)) + (check-equal? offset 4512) + (check-equal? len 78) + (set-port-position! ip 0) + (define table-bytes #"\270\0\0+\0\272\0\1\0\1\0\2+\1\272\0\2\0\1\0\2+\1\277\0\2\0C\0007\0+\0\37\0\23\0\0\0\b+\0\277\0\1\0\200\0i\0R\0;\0#\0\0\0\b+\0\272\0\3\0\5\0\a+\270\0\0 E}i\30D") + (check-equal? table-bytes (peek-bytes len offset ip)) + (define ds (make-object RDecodeStream (peek-bytes len offset ip))) + (check-equal? (hash-ref (send prep decode ds) 'controlValueProgram) '(184 + 0 + 0 + 43 + 0 + 186 + 0 + 1 + 0 + 1 + 0 + 2 + 43 + 1 + 186 + 0 + 2 + 0 + 1 + 0 + 2 + 43 + 1 + 191 + 0 + 2 + 0 + 67 + 0 + 55 + 0 + 43 + 0 + 31 + 0 + 19 + 0 + 0 + 0 + 8 + 43 + 0 + 191 + 0 + 1 + 0 + 128 + 0 + 105 + 0 + 82 + 0 + 59 + 0 + 35 + 0 + 0 + 0 + 8 + 43 + 0 + 186 + 0 + 3 + 0 + 5 + 0 + 7 + 43 + 184 + 0 + 0 + 32 + 69 + 125 + 105 + 24 + 68))) + diff --git a/pitfall/fontkit/subset.rkt b/pitfall/fontkit/subset.rkt index 2df6b7cd..9d54aad8 100644 --- a/pitfall/fontkit/subset.rkt +++ b/pitfall/fontkit/subset.rkt @@ -1,5 +1,5 @@ #lang fontkit/racket -(require "clone.rkt" "ttfglyphencoder.rkt" "loca.rkt") +(require "clone.rkt" "ttfglyphencoder.rkt" "loca.rkt" "directory.rkt" restructure) (provide Subset CFFSubset TTFSubset) #| @@ -58,8 +58,8 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js ;; additional tables required for standalone fonts: ;; name, cmap, OS/2, post -(define/contract (encode this) - (->m input-port?) +(define/contract (encode this stream) + ((is-a?/c REncodeStream) . ->m . void?) (set-field! glyf this empty) (set-field! offset this 0) (set-field! loca this (mhash 'offsets empty)) @@ -67,7 +67,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js ;; include all the glyphs used in the document (for ([gid (in-list (· this glyphs))]) - (send this _addGlyph gid)) + (send this _addGlyph gid)) (define maxp (cloneDeep (send (· this font) _getTable 'maxp))) (hash-set! maxp 'numGlyphs (length (· this glyf))) @@ -83,6 +83,18 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js (hash-set! hhea 'numberOfMetrics (length (· this hmtx metrics))) ;; todo: final encoding of directory, with all tables. + (send Directory encode stream + (mhash 'tables + (mhash + 'head head + 'hhea hhea + 'loca (· this loca) + 'maxp maxp + ;; todo: cvt + 'prep (send (· this font) _getTable 'prep) + 'glyf (· this glyf) + 'hmtx (· this hmtx) + 'fpgm (send (· this font) _getTable 'fpgm)))) (unfinished) ) diff --git a/pitfall/fontkit/tables.rkt b/pitfall/fontkit/tables.rkt index 86cff693..1c9f4ffa 100644 --- a/pitfall/fontkit/tables.rkt +++ b/pitfall/fontkit/tables.rkt @@ -8,4 +8,4 @@ (r+p . TABLE-ID-STRINGS) (define ID (make-hasheq (map cons (list 'TABLE-ID ...) (list TABLE-ID ...))))))) -(define-table-decoders table-decoders maxp hhea head loca) \ No newline at end of file +(define-table-decoders table-decoders maxp hhea head loca prep fpgm) \ No newline at end of file