You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
typesetting/fontland/fontland/table/cff/cff-dict.rkt

81 lines
2.7 KiB
Racket

5 years ago
#lang debug racket/base
5 years ago
(require racket/class racket/match racket/list xenomorph sugar/unstable/dict
"cff-operand.rkt")
5 years ago
(provide CFFDict)
#|
approximates
https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFDict.js
|#
5 years ago
(define CFFDict%
5 years ago
(class x:base%
5 years ago
(super-new)
(init-field [(@ops ops)])
(field [(@fields fields)
(for/hash ([field (in-list @ops)])
(define key (match (car field)
[(list* 0th 1st _) (bitwise-ior (arithmetic-shift 0th 8) 1st)]
[val val]))
(values key field))])
5 years ago
(define (decodeOperands type stream ret operands)
5 years ago
(match type
[(? list?)
(for/list ([(op i) (in-indexed operands)])
(decodeOperands (list-ref type i) stream ret (list op)))]
5 years ago
[(? xenomorphic?) (decode type stream #:parent ret operands)]
5 years ago
[(or 'number 'offset 'sid) (car operands)]
['boolean (if (car operands) #t #f)]
5 years ago
[_ operands]))
5 years ago
(define (encodeOperands type stream ctx operands)
(error 'cff-dict-encodeOperands-undefined))
5 years ago
5 years ago
(define/override (post-decode val)
(dict->mutable-hash val))
5 years ago
(augment [@decode decode])
(define (@decode stream parent)
(define end (+ (pos stream) (hash-ref parent 'length)))
(define ret (make-hash))
(define operands null)
5 years ago
;; define hidden properties
(hash-set! ret x:parent-key parent)
(hash-set! ret x:start-offset-key (pos stream))
5 years ago
;; fill in defaults
(for ([(key field) (in-hash @fields)])
(hash-set! ret (second field) (fourth field)))
(let loop ()
(when (< (pos stream) end)
(define b (read-byte stream))
(cond
[(< b 28)
(when (= b 12)
(set! b (bitwise-ior (arithmetic-shift b 8) (read-byte stream))))
(define field (hash-ref @fields b #false))
(unless field
(error 'cff-dict-decode (format "unknown operator: ~a" b)))
(define val (decodeOperands (third field) stream ret operands))
(unless (void? val)
;; ignoring PropertyDescriptor nonsense
(hash-set! ret (second field) val))
(set! operands null)]
[else
5 years ago
(set! operands (append operands (list (decode CFFOperand stream b))))])
5 years ago
(loop)))
ret)
(define/augment (size dict parent [includePointers #true])
(error 'cff-dict-size-undefined))
(define/augment (encode stream dict parent)
(error 'cff-dict-encode-undefined))))
5 years ago
5 years ago
(define (CFFDict [ops null]) (make-object CFFDict% ops))