From 57404aaaf966f886aee501a33c8cbaa5528e5208 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Tue, 5 Mar 2019 08:13:09 -0800 Subject: [PATCH] move --- fontland/fontland/table/CFF_.rkt | 55 +-------- fontland/fontland/table/cff-top.rkt | 28 ----- fontland/fontland/table/cff/cff-charsets.rkt | 104 ++++++++++++++++++ .../fontland/table/{ => cff}/cff-dict.rkt | 0 fontland/fontland/table/cff/cff-font.rkt | 56 ++++++++++ .../fontland/table/{ => cff}/cff-index.rkt | 0 fontland/fontland/table/cff/cff-top.rkt | 69 ++++++++++++ 7 files changed, 231 insertions(+), 81 deletions(-) delete mode 100644 fontland/fontland/table/cff-top.rkt create mode 100644 fontland/fontland/table/cff/cff-charsets.rkt rename fontland/fontland/table/{ => cff}/cff-dict.rkt (100%) create mode 100644 fontland/fontland/table/cff/cff-font.rkt rename fontland/fontland/table/{ => cff}/cff-index.rkt (100%) create mode 100644 fontland/fontland/table/cff/cff-top.rkt diff --git a/fontland/fontland/table/CFF_.rkt b/fontland/fontland/table/CFF_.rkt index 53fee4fc..119ba1d3 100644 --- a/fontland/fontland/table/CFF_.rkt +++ b/fontland/fontland/table/CFF_.rkt @@ -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 - ) \ No newline at end of file +(provide (rename-out (CFFFont CFF_))) diff --git a/fontland/fontland/table/cff-top.rkt b/fontland/fontland/table/cff-top.rkt deleted file mode 100644 index 7b700569..00000000 --- a/fontland/fontland/table/cff-top.rkt +++ /dev/null @@ -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) - )))) \ No newline at end of file diff --git a/fontland/fontland/table/cff/cff-charsets.rkt b/fontland/fontland/table/cff/cff-charsets.rkt new file mode 100644 index 00000000..b54b0e1b --- /dev/null +++ b/fontland/fontland/table/cff/cff-charsets.rkt @@ -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)) \ No newline at end of file diff --git a/fontland/fontland/table/cff-dict.rkt b/fontland/fontland/table/cff/cff-dict.rkt similarity index 100% rename from fontland/fontland/table/cff-dict.rkt rename to fontland/fontland/table/cff/cff-dict.rkt diff --git a/fontland/fontland/table/cff/cff-font.rkt b/fontland/fontland/table/cff/cff-font.rkt new file mode 100644 index 00000000..53fee4fc --- /dev/null +++ b/fontland/fontland/table/cff/cff-font.rkt @@ -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 + ) \ No newline at end of file diff --git a/fontland/fontland/table/cff-index.rkt b/fontland/fontland/table/cff/cff-index.rkt similarity index 100% rename from fontland/fontland/table/cff-index.rkt rename to fontland/fontland/table/cff/cff-index.rkt diff --git a/fontland/fontland/table/cff/cff-top.rkt b/fontland/fontland/table/cff/cff-top.rkt new file mode 100644 index 00000000..faa2e321 --- /dev/null +++ b/fontland/fontland/table/cff/cff-top.rkt @@ -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) + )))) \ No newline at end of file