From b85aedf7b0f3583c32350d220927cecef1079e7a Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Sat, 9 Mar 2019 01:01:52 -0800 Subject: [PATCH] void operands? --- fontland/fontland/table/cff/cff-dict.rkt | 54 +++++++++++++-------- fontland/fontland/table/cff/cff-index.rkt | 5 +- fontland/fontland/table/cff/cff-operand.rkt | 2 +- fontland/fontland/table/cff/cff-pointer.rkt | 19 +++++--- fontland/fontland/table/cff/cff-top.rkt | 18 +++++-- 5 files changed, 64 insertions(+), 34 deletions(-) diff --git a/fontland/fontland/table/cff/cff-dict.rkt b/fontland/fontland/table/cff/cff-dict.rkt index 9f5720f9..59442553 100644 --- a/fontland/fontland/table/cff/cff-dict.rkt +++ b/fontland/fontland/table/cff/cff-dict.rkt @@ -12,29 +12,33 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFDict.js (class x:base% (super-new) (init-field [(@ops ops)]) + (define (op->key op) + (match (car op) + [(list* 0th 1st _) (bitwise-ior (arithmetic-shift 0th 8) 1st)] + [val val])) (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))]) + (define key (op->key field)) + (values key field))]) (define (decodeOperands type stream ret operands) (match type [(? list?) (for/list ([(op i) (in-indexed operands)]) - (decodeOperands (list-ref type i) stream ret (list op)))] + (decodeOperands (list-ref type i) stream ret (list op)))] [(? xenomorphic?) (decode type stream #:parent ret operands)] [(or 'number 'offset 'sid) (car operands)] ['boolean (if (car operands) #t #f)] [_ operands])) (define (encodeOperands type stream ctx operands) + #R 'in-encode-operands + #R stream (cond [(list? type) (for/list ([(op i) (in-indexed operands)]) - (car (encodeOperands (list-ref type i) stream ctx op)))] - [(xenomorphic? type) (encode type operands stream #:parent ctx)] + (car (encodeOperands (list-ref type i) stream ctx op)))] + [(xenomorphic? type) #R type (send type encode operands #R stream ctx)] [(number? operands) (list operands)] [(boolean? operands) (list (if operands 1 0))] [(list? operands) operands] @@ -55,7 +59,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFDict.js ;; fill in defaults (for ([(key field) (in-hash @fields)]) - (hash-set! ret (second field) (fourth field))) + (hash-set! ret (second field) (fourth field))) (let loop () (when (< (pos stream) end) @@ -82,6 +86,8 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFDict.js (augment [@size size]) (define (@size dict parent [includePointers #true]) + #R 'in-cff-dict-size + (define ctx (mhasheq x:parent-key parent x:val-key dict @@ -90,26 +96,32 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFDict.js (define len 0) - (for* ([(k field) (in-hash @fields)] + (for* ([k (in-list (sort (hash-keys @fields) <))] + [field (in-value (hash-ref @fields k))] [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)))) + #:unless (let ([ res (or (not val) (equal? val (list-ref field 3)))]) + (and res #R 'skipped #R k))) + #R k + #R len + (define operands (encodeOperands (list-ref field 2) #f ctx val)) + #R operands + (set! len (+ len + (for/sum ([op (in-list operands)]) + #R (size CFFOperand op)))) + + (define key (if (list? (list-ref field 0)) + (list-ref field 0) + (list (list-ref field 0)))) + (set! len (+ len #R (length key)))) (when includePointers (set! len (+ len (hash-ref ctx x:pointer-size-key)))) - len) + #R 'final-len + #R len) (augment [@encode encode]) - (define (@encode stream dict parent) + (define (@encode dict stream parent) (error 'cff-dict-encode-undefined)))) (define (CFFDict [ops null]) (make-object CFFDict% ops)) \ No newline at end of file diff --git a/fontland/fontland/table/cff/cff-index.rkt b/fontland/fontland/table/cff/cff-index.rkt index fe130743..8eef4c7a 100644 --- a/fontland/fontland/table/cff/cff-index.rkt +++ b/fontland/fontland/table/cff/cff-index.rkt @@ -46,7 +46,8 @@ 'length (- end start))])) (values (cons val vals) end))])) - (define/augride (size arr parent) + (augride [@size size]) + (define (@size arr parent) (define size 2) (cond [(zero? (length arr)) size] @@ -71,7 +72,7 @@ size])) - (define/augride (encode stream arr parent) + (define/augride (encode arr stream parent) (error 'cff-index-encode-not-implemented)))) (define (CFFIndex [type #f]) diff --git a/fontland/fontland/table/cff/cff-operand.rkt b/fontland/fontland/table/cff/cff-operand.rkt index 0932e320..040778aa 100644 --- a/fontland/fontland/table/cff/cff-operand.rkt +++ b/fontland/fontland/table/cff/cff-operand.rkt @@ -67,7 +67,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFOperand.js [else 5])) (augment [@encode encode]) - (define (@encode stream value) + (define (@encode value stream) ;; if the value needs to be forced to the largest size (32 bit) ;; e.g. for unknown pointers, save the old value and set to 32768 (define val (string->number (format "~a" value))) diff --git a/fontland/fontland/table/cff/cff-pointer.rkt b/fontland/fontland/table/cff/cff-pointer.rkt index 2de234d9..547f3d6c 100644 --- a/fontland/fontland/table/cff/cff-pointer.rkt +++ b/fontland/fontland/table/cff/cff-pointer.rkt @@ -29,24 +29,31 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFPointer.js (define/augment (decode . args) (first operands))))) (super decode stream parent)) - (define/override (encode stream value ctx) + (override [@encode encode]) + (inherit/super encode) + (define (@encode value stream ctx) + #R (get-field offset-type this) + #R (get-field type this) + #R stream (cond - [(not stream) + [#R (not stream) ;; compute the size (so ctx.pointerSize is correct) (set! offset-type (make-object (class x:base% (super-new) (define/augment (size . args) 0)))) (send this size value ctx) - (Ptr 0)] + (list (Ptr 0))] [else + #R value + #R stream (define ptr #false) (set! offset-type (make-object (class x:base% (super-new) - (define/augment (encode stream val) (set! ptr val))))) - (super encode stream value ctx) - (Ptr ptr)])))) + (define/augment (encode val stream) (set! ptr val))))) + (super encode value stream ctx) + (list (Ptr ptr))])))) diff --git a/fontland/fontland/table/cff/cff-top.rkt b/fontland/fontland/table/cff/cff-top.rkt index a0a1a7e6..075a9f9a 100644 --- a/fontland/fontland/table/cff/cff-top.rkt +++ b/fontland/fontland/table/cff/cff-top.rkt @@ -19,6 +19,13 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFTop.js (init-field [(@predefinedOps predefinedOps)] [(@type type) #f]) + (define/override (pre-encode val) + #R 'in-PredefinedOp%-pre-encode + ;; because fontkit depends on overloading 'version key, and we don't + (let ([val (make-hasheq val)]) + (hash-set! val 'x:version (hash-ref val 'version)) + val)) + (augment [@decode decode]) (define (@decode stream parent operands) (define idx (car operands)) @@ -30,10 +37,12 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFTop.js (error 'predefined-op-size-not-finished)) (augment [@encode encode]) - (define (@encode stream value ctx) - #R (get-field pointer-relative-to @type) + (define (@encode value stream ctx) + #R 'encode-pdop + #R value + #R stream (or (index-of @predefinedOps value) - (encode @type value stream #:parent ctx))))) + (send @type encode value stream ctx))))) (define (PredefinedOp predefinedOps type) (make-object PredefinedOp% predefinedOps type)) @@ -71,7 +80,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFTop.js (class x:array% (super-new) (inherit-field [@len len] [@type type]) - (define (:decode stream parent) + (define/override (decode stream parent) (define length (resolve-length @len stream parent)) (for/fold ([res null] [count 0] @@ -179,6 +188,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/cff/CFFTop.js (x:versioned-struct #:pre-encode (λ (val) + #R 'in-cfftop-pre-encode ;; because fontkit depends on overloading 'version key, and we don't (hash-set! val 'x:version (hash-ref val 'version)) val)