next: cff-dict-encodeOperands-undefined

main
Matthew Butterick 6 years ago
parent 6b283bc11a
commit 697f79d125

@ -21,6 +21,6 @@
(struct ttf-glyph glyph () #:transparent)
(struct cff-glyph glyph ([usedGsubrs #:auto] [usedSubrs #:auto])
(struct cff-glyph glyph ([_usedGsubrs #:auto] [_usedSubrs #:auto])
#:transparent
#:auto-value (make-hash))

@ -11,7 +11,10 @@
fontland/ttf-glyph
xenomorph
racket/dict
fontland/table/cff/cff-font)
fontland/table/cff/cff-font
fontland/table/cff/cff-top
racket/class
fontland/table/cff/cff-standard-strings)
(provide subset +subset
ttf-subset +ttf-subset
@ -86,26 +89,110 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/CFFSubset.js
#R gid
(define glyph (get-glyph (subset-font this) gid))
(define path (hash-ref glyph 'path)) ;; this causes the glyph to be parsed
;; apparently path parsing is not necessary?
#;(define path (hash-ref glyph 'path)) ;; this causes the glyph to be parsed
(for ([subr (in-list (hash-ref glyph '_usedGsubrs))])
(for ([subr (in-hash-keys (cff-glyph-_usedGsubrs glyph))])
(hash-set! gsubrs subr #true)))
(set-cff-subset-gsubrs! this (subsetSubrs (hash-ref (cff-subset-cff this) 'globalSubrIndex gsubrs))))
(set-cff-subset-gsubrs! this (subsetSubrs
this
(hash-ref (cff-subset-cff this) 'globalSubrIndex)
gsubrs)))
(define (subsetSubrs this subrs used)
(for/list ([(subr i) (in-indexed subrs)])
(cond
[(list-ref used i)
[(hash-ref used i #false)
(peek-bytes (hash-ref subr 'length)
(hash-ref subr 'offset)
(hash-ref (cff-subset-cff this) 'stream))]
[else (bytes 11)])))
(define (subsetFontdict this topDict)
(error 'subsetFontdict-unimplemented))
(define (createCIDFontdict this topDict)
(define used_subrs (make-hash))
(for ([gid (in-list (subset-glyphs this))])
(define glyph (get-glyph (subset-font this) gid))
;; skip path parsing
(for ([subr (in-hash-keys (cff-glyph-_usedSubrs glyph))])
(hash-set! used_subrs subr #true)))
(define cff-topDict (hash-ref (cff-subset-cff this) 'topDict))
(define privateDict (hash-copy (hash-ref cff-topDict 'Private (make-hash))))
(when (and (hash-has-key? cff-topDict 'Private) (hash-has-key? (hash-ref cff-topDict 'Private) 'Subrs))
(hash-set! privateDict 'Subrs (subsetSubrs this
(hash-ref (hash-ref cff-topDict 'Private) 'Subrs)
used_subrs)))
(hash-set! topDict 'FDArray (list (dictify 'Private privateDict)))
(hash-set! topDict 'FDSelect (dictify 'version 3
'nRanges 1
'ranges (list (dictify 'first 0 'fd 0))
'sentinel (length (cff-subset-charstrings this))))
(hash-ref topDict 'FDSelect))
(define (addString this [string #f])
(cond
[(not string) #false]
[else
(unless (cff-subset-strings this)
(set-cff-subset-strings! this null))
(set-cff-subset-strings! this
(append (cff-subset-strings this) (list string)))
(+ (length standardStrings) (sub1 (length (cff-subset-strings this))))]))
(define (cff-subset-encode this stream)
(subsetCharstrings this)
(error 'cff-subset-encode-unfinished))
(define charset
(dictify 'version (if (> (length (cff-subset-charstrings this)) 255)
2
1)
'ranges (list (dictify 'first 1 'nLeft (- (length (cff-subset-charstrings this)) 2)))))
(define topDict (hash-copy (hash-ref (cff-subset-cff this) 'topDict)))
(hash-set*! topDict
'Private #false
'charset charset
'Encoding #false
'CharStrings (cff-subset-charstrings this))
(for ([key (in-list '(version Notice Copyright FullName
FamilyName Weight PostScript
BaseFontName FontName))])
(hash-update! topDict key
(λ (tdk-val) (addString this (CFFont-string (cff-subset-cff this) tdk-val)))))
(hash-set! topDict 'ROS (list (addString this "Adobe")
(addString this "Identity")
0))
(hash-set! topDict 'CIDCount (length (cff-subset-charstrings this)))
(if (hash-ref (cff-subset-cff this) 'isCIDFont)
(subsetFontdict this topDict)
(createCIDFontdict this topDict))
(define top
(mhasheq 'version 1
'hdrSize (hash-ref (cff-subset-cff this) 'hdrSize)
'offSize 4
'header (hash-ref (cff-subset-cff this) 'header #f)
'nameIndex (list (CFFFont-postscriptName (cff-subset-cff this)))
'topDictIndex (list topDict)
'stringIndex (cff-subset-strings this)
'globalSubrIndex (cff-subset-gsubrs this)))
(encode CFFTop top stream)
(error 'boom))
#;(module+ test
(require "font.rkt" "helper.rkt")

@ -73,9 +73,33 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFDict.js
ret)
(define/augment (size dict parent [includePointers #true])
(error 'cff-dict-size-undefined))
(define ctx
(mhasheq x:parent-key parent
x:val-key dict
x:pointer-size-key 0
x:start-offset-key (hash-ref parent x:start-offset-key 0)))
(define/augment (encode stream dict parent)
(error 'cff-dict-encode-undefined))))
(define len 0)
(for* ([(k field) (in-hash @fields)]
[val (in-value (hash-ref dict (list-ref field 1)))]
#:unless (or (not val) (equal? val (list-ref field 3))))
(define operands (encodeOperands (list-ref field 2) #f ctx val))
(set! len (+ len
(for/sum ([op (in-list operands)])
(size CFFOperand op))))
(define key (if (list? (list-ref field 0))
(list-ref field 0)
(list (list-ref field 0))))
(set! len (+ len (length key))))
(when includePointers
(set! len (+ len (hash-ref ctx x:pointer-size-key))))
len)
(define/augment (encode stream dict parent)
(error 'cff-dict-encode-undefined))))
(define (CFFDict [ops null]) (make-object CFFDict% ops))

@ -1,5 +1,7 @@
#lang debug racket/base
(require racket/class racket/match racket/list xenomorph "cff-top.rkt")
(require racket/class racket/match racket/list xenomorph
"cff-top.rkt"
"cff-standard-strings.rkt")
(provide (all-defined-out))
#|
@ -33,6 +35,20 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFFont.js
(hash-set! cff-font 'isCIDFont (hash-ref (hash-ref cff-font 'topDict) 'ROS))
cff-font)))
(define (CFFont-string this sid)
(let ([sid (or sid 0)])
#R sid
(cond
[(>= (hash-ref this 'version) 2) #false]
[(< sid (length standardStrings)) (list-ref standardStrings sid)]
[else (list-ref (hash-ref this 'stringIndex) (- sid (length standardStrings)))])))
(define (CFFFont-postscriptName this)
(cond
[(< (hash-ref this 'version) 2)
(list-ref (hash-ref this 'nameIndex) 0)]
[else #false]))
(define CFFFont (make-object CFFFont%))
(define (getCharString cff-font glyph-id)

@ -47,7 +47,29 @@
(values (cons val vals) end))]))
(define/augride (size arr parent)
(error 'cff-index-size-not-implemented))
(define size 2)
(cond
[(zero? (length arr)) size]
[else
(define type (or @type (bytes)))
;; find maximum offset to determinine offset type
(define offset 1)
(for ([(item i) (in-indexed arr)])
(set! offset (+ offset (send type size item parent))))
(define offsetType
(cond
[(<= offset #xff) uint8]
[(<= offset #xffff) uint16be]
[(<= offset #xffffff) uint24be]
[(<= offset #xffffffff) uint32be]
[else (error 'CFFIndex-size (format "bad offset: ~a" offset))]))
(set! size (+ size 1 (* (send offsetType size) (add1 (length arr)))))
(set! size (+ size (sub1 offset)))
size]))
(define/augride (encode stream arr parent)
(error 'cff-index-encode-not-implemented))))

@ -0,0 +1,76 @@
#lang racket/base
(provide (all-defined-out))
#|
approximates
https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFStandardStrings.js
|#
(define standardStrings
'(".notdef" "space" "exclam" "quotedbl" "numbersign" "dollar"
"percent" "ampersand" "quoteright" "parenleft" "parenright"
"asterisk" "plus" "comma" "hyphen" "period" "slash" "zero" "one"
"two" "three" "four" "five" "six" "seven" "eight" "nine" "colon"
"semicolon" "less" "equal" "greater" "question" "at" "A" "B" "C"
"D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R"
"S" "T" "U" "V" "W" "X" "Y" "Z" "bracketleft" "backslash"
"bracketright" "asciicircum" "underscore" "quoteleft" "a" "b" "c"
"d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r"
"s" "t" "u" "v" "w" "x" "y" "z" "braceleft" "bar" "braceright"
"asciitilde" "exclamdown" "cent" "sterling" "fraction" "yen"
"florin" "section" "currency" "quotesingle" "quotedblleft"
"guillemotleft" "guilsinglleft" "guilsinglright" "fi" "fl" "endash"
"dagger" "daggerdbl" "periodcentered" "paragraph" "bullet"
"quotesinglbase" "quotedblbase" "quotedblright" "guillemotright"
"ellipsis" "perthousand" "questiondown" "grave" "acute" "circumflex"
"tilde" "macron" "breve" "dotaccent" "dieresis" "ring" "cedilla"
"hungarumlaut" "ogonek" "caron" "emdash" "AE" "ordfeminine" "Lslash"
"Oslash" "OE" "ordmasculine" "ae" "dotlessi" "lslash" "oslash" "oe"
"germandbls" "onesuperior" "logicalnot" "mu" "trademark" "Eth"
"onehalf" "plusminus" "Thorn" "onequarter" "divide" "brokenbar"
"degree" "thorn" "threequarters" "twosuperior" "registered" "minus"
"eth" "multiply" "threesuperior" "copyright" "Aacute" "Acircumflex"
"Adieresis" "Agrave" "Aring" "Atilde" "Ccedilla" "Eacute"
"Ecircumflex" "Edieresis" "Egrave" "Iacute" "Icircumflex" "Idieresis"
"Igrave" "Ntilde" "Oacute" "Ocircumflex" "Odieresis" "Ograve"
"Otilde" "Scaron" "Uacute" "Ucircumflex" "Udieresis" "Ugrave"
"Yacute" "Ydieresis" "Zcaron" "aacute" "acircumflex" "adieresis"
"agrave" "aring" "atilde" "ccedilla" "eacute" "ecircumflex"
"edieresis" "egrave" "iacute" "icircumflex" "idieresis" "igrave"
"ntilde" "oacute" "ocircumflex" "odieresis" "ograve" "otilde"
"scaron" "uacute" "ucircumflex" "udieresis" "ugrave" "yacute"
"ydieresis" "zcaron" "exclamsmall" "Hungarumlautsmall"
"dollaroldstyle" "dollarsuperior" "ampersandsmall" "Acutesmall"
"parenleftsuperior" "parenrightsuperior" "twodotenleader"
"onedotenleader" "zerooldstyle" "oneoldstyle" "twooldstyle"
"threeoldstyle" "fouroldstyle" "fiveoldstyle" "sixoldstyle"
"sevenoldstyle" "eightoldstyle" "nineoldstyle" "commasuperior"
"threequartersemdash" "periodsuperior" "questionsmall" "asuperior"
"bsuperior" "centsuperior" "dsuperior" "esuperior" "isuperior"
"lsuperior" "msuperior" "nsuperior" "osuperior" "rsuperior"
"ssuperior" "tsuperior" "ff" "ffi" "ffl" "parenleftinferior"
"parenrightinferior" "Circumflexsmall" "hyphensuperior" "Gravesmall"
"Asmall" "Bsmall" "Csmall" "Dsmall" "Esmall" "Fsmall" "Gsmall"
"Hsmall" "Ismall" "Jsmall" "Ksmall" "Lsmall" "Msmall" "Nsmall"
"Osmall" "Psmall" "Qsmall" "Rsmall" "Ssmall" "Tsmall" "Usmall"
"Vsmall" "Wsmall" "Xsmall" "Ysmall" "Zsmall" "colonmonetary"
"onefitted" "rupiah" "Tildesmall" "exclamdownsmall" "centoldstyle"
"Lslashsmall" "Scaronsmall" "Zcaronsmall" "Dieresissmall" "Brevesmall"
"Caronsmall" "Dotaccentsmall" "Macronsmall" "figuredash"
"hypheninferior" "Ogoneksmall" "Ringsmall" "Cedillasmall"
"questiondownsmall" "oneeighth" "threeeighths" "fiveeighths"
"seveneighths" "onethird" "twothirds" "zerosuperior" "foursuperior"
"fivesuperior" "sixsuperior" "sevensuperior" "eightsuperior"
"ninesuperior" "zeroinferior" "oneinferior" "twoinferior"
"threeinferior" "fourinferior" "fiveinferior" "sixinferior"
"seveninferior" "eightinferior" "nineinferior" "centinferior"
"dollarinferior" "periodinferior" "commainferior" "Agravesmall"
"Aacutesmall" "Acircumflexsmall" "Atildesmall" "Adieresissmall"
"Aringsmall" "AEsmall" "Ccedillasmall" "Egravesmall" "Eacutesmall"
"Ecircumflexsmall" "Edieresissmall" "Igravesmall" "Iacutesmall"
"Icircumflexsmall" "Idieresissmall" "Ethsmall" "Ntildesmall"
"Ogravesmall" "Oacutesmall" "Ocircumflexsmall" "Otildesmall"
"Odieresissmall" "OEsmall" "Oslashsmall" "Ugravesmall" "Uacutesmall"
"Ucircumflexsmall" "Udieresissmall" "Yacutesmall" "Thornsmall"
"Ydieresissmall" "001.000" "001.001" "001.002" "001.003" "Black"
"Bold" "Book" "Light" "Medium" "Regular" "Roman" "Semibold"))

@ -174,6 +174,11 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFTop.js
(define CFFTop
(x:versioned-struct
#:pre-encode
(λ (val)
;; because fontkit depends on overloading 'version key, and we don't
(hash-set! val 'x:version (hash-ref val 'version))
val)
fixed16be
(dictify
1 (dictify 'hdrSize uint8

Loading…
Cancel
Save