main
Matthew Butterick 5 years ago
parent 333c231f09
commit 57404aaaf9

@ -1,56 +1,5 @@
#lang debug racket/base
(require racket/class racket/list xenomorph "cff-top.rkt")
(provide (rename-out (CFFFont CFF_)))
#|
approximates
https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFFont.js
|#
(require "cff/cff-font.rkt")
;; the CFFFont object acts as the decoder for the `CFF ` table.
;; so it should return a hash.
(define CFFFont
(make-object
(class xenobase%
(super-new)
(define/augride (:decode stream parent)
(define cff-font (make-hasheq))
(hash-set! cff-font 'stream stream)
(for ([(k v) (in-hash (decode CFFTop stream))])
(hash-set! cff-font k v))
;; because fontkit depends on overloading 'version key, and we don't
(hash-set! cff-font 'version (hash-ref cff-font 'x:version))
#;(when (and (hash-has-key? cff-font 'version) (< (hash-ref cff-font 'version) 2))
(match (hash-ref cff-font 'topDictIndex)
[(list dict) (hash-set! cff-font 'topDict dict)]
[_ (error 'only-single-font-allowed-in-cff)]))
#;(hash-set! cff-font 'isCIDFont (hash-ref (hash-ref cff-font 'topDict) 'ROS))
cff-font))))
(module+ test
(require rackunit racket/serialize racket/stream "../helper.rkt")
(define dir (deserialize (read (open-input-file fira-otf-directory-path))))
(define cff (hash-ref (hash-ref dir 'tables) 'CFF_))
(define cff-offset (hash-ref cff 'offset))
(check-equal? cff-offset 33472)
(define cff-length (hash-ref cff 'length))
(check-equal? cff-length 164604)
(define ip (open-input-file fira-otf-path))
(define cff-bytes (peek-bytes cff-length cff-offset ip))
(define cff-font (decode CFFFont cff-bytes))
(check-equal? (hash-ref cff-font 'length) 13)
(check-equal? (hash-ref cff-font 'hdrSize) 4)
(check-equal? (hash-ref cff-font 'offSize) 3)
(check-equal? (hash-ref cff-font 'nameIndex) '("FiraSans-Book"))
(check-equal? (hash-ref cff-font 'length) (string-length (car (hash-ref cff-font 'nameIndex))))
cff-font
)
(provide (rename-out (CFFFont CFF_)))

@ -1,28 +0,0 @@
#lang debug racket/base
(require xenomorph sugar/unstable/dict
"cff-index.rkt"
"cff-dict.rkt")
(provide CFFTop)
#|
approximates
https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFTop.js
|#
(define CFFTop
(x:versioned-struct
fixed16be
(dictify
1 (dictify 'hdrSize uint8
'offSize uint8
'nameIndex (CFFIndex (x:string #:length 'length))
;'topDictIndex (CFFIndex CFFTopDict)
;;'stringIndex (CFFIndex (x:string #:length 'length))
;;'globalSubrIndex (CFFIndex)
)
2 (dictify 'hdrSize uint8
'length uint16be
;;'topDict CFF2TopDict
;;'globalSubrIndex (CFFIndex)
))))

@ -0,0 +1,104 @@
#lang racket/base
(provide (all-defined-out))
#|
approximates
https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFCharsets.js
|#
(define ISOAdobeCharset
'(.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))
(define ExpertCharset
'(.notdef space exclamsmall Hungarumlautsmall dollaroldstyle
dollarsuperior ampersandsmall Acutesmall parenleftsuperior
parenrightsuperior twodotenleader onedotenleader comma
hyphen period fraction zerooldstyle oneoldstyle
twooldstyle threeoldstyle fouroldstyle fiveoldstyle
sixoldstyle sevenoldstyle eightoldstyle nineoldstyle
colon semicolon commasuperior threequartersemdash
periodsuperior questionsmall asuperior bsuperior
centsuperior dsuperior esuperior isuperior lsuperior
msuperior nsuperior osuperior rsuperior ssuperior
tsuperior ff fi fl 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 onequarter onehalf threequarters
questiondownsmall oneeighth threeeighths fiveeighths
seveneighths onethird twothirds zerosuperior onesuperior
twosuperior threesuperior 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))
(define ExpertSubsetCharset
'(.notdef space dollaroldstyle dollarsuperior
parenleftsuperior parenrightsuperior twodotenleader
onedotenleader comma hyphen period fraction
zerooldstyle oneoldstyle twooldstyle threeoldstyle
fouroldstyle fiveoldstyle sixoldstyle sevenoldstyle
eightoldstyle nineoldstyle colon semicolon commasuperior
threequartersemdash periodsuperior asuperior bsuperior
centsuperior dsuperior esuperior isuperior lsuperior
msuperior nsuperior osuperior rsuperior ssuperior
tsuperior ff fi fl ffi ffl parenleftinferior
parenrightinferior hyphensuperior colonmonetary onefitted
rupiah centoldstyle figuredash hypheninferior onequarter
onehalf threequarters oneeighth threeeighths fiveeighths
seveneighths onethird twothirds zerosuperior onesuperior
twosuperior threesuperior foursuperior fivesuperior
sixsuperior sevensuperior eightsuperior ninesuperior
zeroinferior oneinferior twoinferior threeinferior
fourinferior fiveinferior sixinferior seveninferior
eightinferior nineinferior centinferior dollarinferior
periodinferior commainferior))

@ -0,0 +1,56 @@
#lang debug racket/base
(require racket/class racket/list xenomorph "cff-top.rkt")
(provide (rename-out (CFFFont CFF_)))
#|
approximates
https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFFont.js
|#
;; the CFFFont object acts as the decoder for the `CFF ` table.
;; so it should return a hash.
(define CFFFont
(make-object
(class xenobase%
(super-new)
(define/augride (:decode stream parent)
(define cff-font (make-hasheq))
(hash-set! cff-font 'stream stream)
(for ([(k v) (in-hash (decode CFFTop stream))])
(hash-set! cff-font k v))
;; because fontkit depends on overloading 'version key, and we don't
(hash-set! cff-font 'version (hash-ref cff-font 'x:version))
#;(when (and (hash-has-key? cff-font 'version) (< (hash-ref cff-font 'version) 2))
(match (hash-ref cff-font 'topDictIndex)
[(list dict) (hash-set! cff-font 'topDict dict)]
[_ (error 'only-single-font-allowed-in-cff)]))
#;(hash-set! cff-font 'isCIDFont (hash-ref (hash-ref cff-font 'topDict) 'ROS))
cff-font))))
(module+ test
(require rackunit racket/serialize racket/stream "../helper.rkt")
(define dir (deserialize (read (open-input-file fira-otf-directory-path))))
(define cff (hash-ref (hash-ref dir 'tables) 'CFF_))
(define cff-offset (hash-ref cff 'offset))
(check-equal? cff-offset 33472)
(define cff-length (hash-ref cff 'length))
(check-equal? cff-length 164604)
(define ip (open-input-file fira-otf-path))
(define cff-bytes (peek-bytes cff-length cff-offset ip))
(define cff-font (decode CFFFont cff-bytes))
(check-equal? (hash-ref cff-font 'length) 13)
(check-equal? (hash-ref cff-font 'hdrSize) 4)
(check-equal? (hash-ref cff-font 'offSize) 3)
(check-equal? (hash-ref cff-font 'nameIndex) '("FiraSans-Book"))
(check-equal? (hash-ref cff-font 'length) (string-length (car (hash-ref cff-font 'nameIndex))))
cff-font
)

@ -0,0 +1,69 @@
#lang debug racket/base
(require xenomorph sugar/unstable/dict
"cff-index.rkt"
"cff-dict.rkt"
"cff-charsets.rkt")
(provide CFFTop)
#|
approximates
https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFTop.js
|#
(define CFFTopDict
(CFFDict
;; key name type(s) default
`(((12 30) ROS (sid sid number) #false)
(0 version sid #false)
(1 Notice sid #false)
((12 0) Copyright sid #false)
(2 FullName sid #false)
(3 FamilyName sid #false)
(4 Weight sid #false)
((12 1) isFixedPitch boolean #false)
((12 2) ItalicAngle number 0)
((12 3) UnderlinePosition number -100)
((12 4) UnderlineThickness number 50)
((12 5) PaintType number 0)
((12 6) CharstringType number 2)
((12 7) FontMatrix array (0.001 0 0 0.001 0 0))
(13 UniqueID number #false)
(5 FontBBox array (0 0 0 0))
((12 8) StrokeWidth number 0)
(14 XUID array #false)
(15 charset ,CFFCharset ,ISOAdobeCharset)
(16 Encoding ,CFFEncoding ,StandardEncoding)
(17 CharStrings ,(CFFPointer CFFIndex) #false)
(18 Private ,(CFFPrivateOp) #false)
((12 20) SyntheticBase number #false)
((12 21) PostScript sid #false)
((12 22) BaseFontName sid #false)
((12 23) BaseFontBlend delta #false)
;; CID font specific
((12 31) CIDFontVersion number 0)
((12 32) CIDFontRevision number 0)
((12 33) CIDFontType number 0)
((12 34) CIDCount number 8720)
((12 35) UIDBase number #false)
((12 37) FDSelect ,(CFFPointer FDSelect) #false)
((12 36) FDArray ,(CFFPointer (CFFIndex FontDict)) #false)
((12 38) FontName sid #false))))
(define CFFTop
(x:versioned-struct
fixed16be
(dictify
1 (dictify 'hdrSize uint8
'offSize uint8
'nameIndex (CFFIndex (x:string #:length 'length))
'topDictIndex (CFFIndex CFFTopDict)
;;'stringIndex (CFFIndex (x:string #:length 'length))
;;'globalSubrIndex (CFFIndex)
)
2 (dictify 'hdrSize uint8
'length uint16be
;;'topDict CFF2TopDict
;;'globalSubrIndex (CFFIndex)
))))
Loading…
Cancel
Save