soft touch

main
Matthew Butterick 5 years ago
parent 1b081dfe32
commit d71165fd46

@ -26,10 +26,9 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(define (getPath this) (define (getPath this)
(define stream (ttf-font-port (glyph-font this))) (define stream (ttf-font-port (glyph-font this)))
;;;(define pos (pos stream))
(define cff (get-table (glyph-font this) 'CFF_)) (define cff (get-table (glyph-font this) 'CFF_))
(define str (vector-ref (hash-ref (hash-ref cff 'topDict) 'CharStrings) (glyph-id this))) (define str (vector-ref (hash-ref* cff 'topDict 'CharStrings) (glyph-id this)))
(define end (+ (index-item-offset str) (index-item-length str))) (define end (+ (index-item-offset str) (index-item-length str)))
(pos stream (index-item-offset str)) (pos stream (index-item-offset str))
@ -73,15 +72,11 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(define used-subrs (make-hasheq)) (define used-subrs (make-hasheq))
(define open #false) (define open #false)
(define gsubrs (match (hash-ref cff 'globalSubrIndex (vector)) (define gsubrs (hash-ref cff 'globalSubrIndex (vector)))
[(list) (vector)]
[vec vec]))
(define gsubrs-bias (bias this gsubrs)) (define gsubrs-bias (bias this gsubrs))
(define privateDict (or (private-dict-for-glyph cff (glyph-id this)) (make-hasheq))) (define privateDict (or (private-dict-for-glyph cff (glyph-id this)) (make-hasheq)))
(define subrs (match (hash-ref privateDict 'Subrs (vector)) (define subrs (hash-ref privateDict 'Subrs (vector)))
[(list) (vector)]
[vec vec]))
(define subrs-bias (bias this subrs)) (define subrs-bias (bias this subrs))
(define (check-width) (define (check-width)
@ -98,10 +93,10 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(path-moveTo path x y) (path-moveTo path x y)
(set! open #true)) (set! open #true))
(define (parse) (let parse ()
(let/ec return (let/ec return
(let loop () (for ([i (in-naturals)]
(when (< (pos stream) end) #:break (>= (pos stream) end))
(define op (read-byte stream)) (define op (read-byte stream))
(cond (cond
[(< op 32) [(< op 32)
@ -125,24 +120,21 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(loop)))] (loop)))]
[(6 ;; hlineto [(6 ;; hlineto
7) ;; vlineto 7) ;; vlineto
(define phase (= op 6)) (let loop ([phase (= op 6)])
(let loop ()
(when (>= (stack-length stack) 1) (when (>= (stack-length stack) 1)
(if phase (if phase
(set! x (+ x (shift stack))) (set! x (+ x (shift stack)))
(set! y (+ y (shift stack)))) (set! y (+ y (shift stack))))
(path-lineTo path x y) (path-lineTo path x y)
(set! phase (not phase)) (loop (not phase))))]
(loop)))]
[(8) ;; rrcurveto [(8) ;; rrcurveto
(let loop () (let loop ()
(when (> (stack-length stack) 0) (when (positive? (stack-length stack))
(define c1x (+ x (shift stack))) (define c1x (+ x (shift stack)))
(define c1y (+ y (shift stack))) (define c1y (+ y (shift stack)))
(define c2x (+ c1x (shift stack))) (define c2x (+ c1x (shift stack)))
(define c2y (+ c1y (shift stack))) (define c2y (+ c1y (shift stack)))
(path-bezierCurveTo path c1x c1y c2x c2y x y)))] (path-bezierCurveTo path c1x c1y c2x c2y x y)))]
[(10) ;; callsubr [(10) ;; callsubr
(define index (+ (pop stack) subrs-bias)) (define index (+ (pop stack) subrs-bias))
(define subr (vector-ref subrs index)) (define subr (vector-ref subrs index))
@ -156,45 +148,35 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(pos stream p) (pos stream p)
(set! end e))] (set! end e))]
[(11) ;; return [(11) ;; return
(cond (when (< (hash-ref cff 'version) 2)
[(>= (hash-ref cff 'version) 2) (void)] (return))]
[else (return)])]
[(14) ;; endchar [(14) ;; endchar
(cond (when (< (hash-ref cff 'version) 2)
[(>= (hash-ref cff 'version) 2) (void)]
[else
(when (> (stack-length stack) 0) (when (> (stack-length stack) 0)
(check-width)) (check-width))
(when open (when open
(path-closePath path) (path-closePath path)
(set! open #false))])] (set! open #false)))]
[(15) ;; vsindex [(15) ;; vsindex
(when (< (hash-ref cff 'version) 2) (when (< (hash-ref cff 'version) 2)
(error 'vsindex-operator-not-supported))] (error 'vsindex-operator-not-supported))]
[(16) ;; blend [(16) ;; blend
(error 'blend-operator-not-supported)] (error 'blend-operator-not-supported)]
[(19 ;; hintmask [(19 ;; hintmask
20) ;; cntrmask 20) ;; cntrmask
(parse-stems) (parse-stems)
(pos stream (+ (pos stream) (arithmetic-shift (+ nStems 7) -3)))] (pos stream (+ (pos stream) (arithmetic-shift (+ nStems 7) -3)))]
[(21) ;; rmoveto [(21) ;; rmoveto
(when (> (stack-length stack) 2) (when (> (stack-length stack) 2)
(check-width)) (check-width))
(set! x (+ x (shift stack))) (set! x (+ x (shift stack)))
(set! y (+ y (shift stack))) (set! y (+ y (shift stack)))
(moveTo x y)] (moveTo x y)]
[(22) ;; hmoveto [(22) ;; hmoveto
(when (> (stack-length stack) 1) (when (> (stack-length stack) 1)
(check-width)) (check-width))
(set! x (+ x (shift stack))) (set! x (+ x (shift stack)))
(moveTo x y)] (moveTo x y)]
[(24) ;; rcurveline [(24) ;; rcurveline
(let loop () (let loop ()
(when (>= (stack-length stack) 8) (when (>= (stack-length stack) 8)
@ -206,11 +188,9 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(set! y (+ c2y (shift stack))) (set! y (+ c2y (shift stack)))
(path-bezierCurveTo path c1x c1y c2x c2y x y) (path-bezierCurveTo path c1x c1y c2x c2y x y)
(loop))) (loop)))
(set! x (+ x (shift stack))) (set! x (+ x (shift stack)))
(set! y (+ y (shift stack))) (set! y (+ y (shift stack)))
(path-lineTo path x y)] (path-lineTo path x y)]
[(25) ;; rlinecurve [(25) ;; rlinecurve
(let loop () (let loop ()
(when (>= (stack-length stack) 8) (when (>= (stack-length stack) 8)
@ -218,7 +198,6 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(set! y (+ y (shift stack))) (set! y (+ y (shift stack)))
(path-lineTo path x y) (path-lineTo path x y)
(loop))) (loop)))
(define c1x (+ x (shift stack))) (define c1x (+ x (shift stack)))
(define c1y (+ y (shift stack))) (define c1y (+ y (shift stack)))
(define c2x (+ c1x (shift stack))) (define c2x (+ c1x (shift stack)))
@ -226,11 +205,9 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(set! x (+ c2x (shift stack))) (set! x (+ c2x (shift stack)))
(set! y (+ c2y (shift stack))) (set! y (+ c2y (shift stack)))
(path-bezierCurveTo path c1x c1y c2x c2y x y)] (path-bezierCurveTo path c1x c1y c2x c2y x y)]
[(26) ;; vvcurveto [(26) ;; vvcurveto
(when (odd? (stack-length stack)) (when (odd? (stack-length stack))
(set! x (+ x (shift stack)))) (set! x (+ x (shift stack))))
(let loop () (let loop ()
(when (>= (stack-length stack) 4) (when (>= (stack-length stack) 4)
(define c1x x) (define c1x x)
@ -241,11 +218,9 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(set! y (+ c2y (shift stack))) (set! y (+ c2y (shift stack)))
(path-bezierCurveTo path c1x c1y c2x c2y x y) (path-bezierCurveTo path c1x c1y c2x c2y x y)
(loop)))] (loop)))]
[(27) ;; hhcurveto [(27) ;; hhcurveto
(when (odd? (stack-length stack)) (when (odd? (stack-length stack))
(set! y (+ y (shift stack)))) (set! y (+ y (shift stack))))
(let loop () (let loop ()
(when (>= (stack-length stack) 4) (when (>= (stack-length stack) 4)
(define c1x (+ x (shift stack))) (define c1x (+ x (shift stack)))
@ -256,27 +231,23 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(set! y c2y) (set! y c2y)
(path-bezierCurveTo path c1x c1y c2x c2y x y) (path-bezierCurveTo path c1x c1y c2x c2y x y)
(loop)))] (loop)))]
[(28) ;; shortint [(28) ;; shortint
(push stack (decode int16be stream))] (push stack (decode int16be stream))]
[(29) ;; callgsubr [(29) ;; callgsubr
(define index (+ (pop stack) gsubrs-bias)) (define index (+ (pop stack) gsubrs-bias))
(define subr (vector-ref gsubrs index)) (define subr (vector-ref gsubrs index))
(when subr (when subr
(hash-set! used-gsubrs index #true) (hash-set! used-gsubrs index #true)
(define p (pos stream)) (define old-pos (pos stream))
(define e end) (define old-end end)
(pos stream (index-item-offset subr)) (pos stream (index-item-offset subr))
(set! end (+ (index-item-offset subr) (index-item-length subr))) (set! end (+ (index-item-offset subr) (index-item-length subr)))
(parse) (parse)
(pos stream p) (pos stream old-pos)
(set! end e))] (set! end old-end))]
[(30 ;; vhcurveto [(30 ;; vhcurveto
31) ;; hvcurveto 31) ;; hvcurveto
(define phase (= op 31)) (let loop ([phase (= op 31)])
(let loop ()
(when (>= (stack-length stack) 4) (when (>= (stack-length stack) 4)
(cond (cond
[phase [phase
@ -287,7 +258,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(set! y (+ c2y (shift stack))) (set! y (+ c2y (shift stack)))
(set! x (+ c2x (if (= (stack-length stack) 1) (shift stack) 0))) (set! x (+ c2x (if (= (stack-length stack) 1) (shift stack) 0)))
(path-bezierCurveTo path c1x c1y c2x c2y x y) (path-bezierCurveTo path c1x c1y c2x c2y x y)
(set! phase (not phase))] (loop (not phase))]
[else [else
(define c1x x) (define c1x x)
(define c1y (+ y (shift stack))) (define c1y (+ y (shift stack)))
@ -296,9 +267,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(set! x (+ c2x (shift stack))) (set! x (+ c2x (shift stack)))
(set! y (+ c2y (if (= (stack-length stack) 1) (shift stack) 0))) (set! y (+ c2y (if (= (stack-length stack) 1) (shift stack) 0)))
(path-bezierCurveTo path c1x c1y c2x c2y x y) (path-bezierCurveTo path c1x c1y c2x c2y x y)
(set! phase (not phase))]) (loop (not phase))])))]
(loop)))]
[(12) [(12)
(println "warning: check truthiness") (println "warning: check truthiness")
(case= (read-byte stream) (case= (read-byte stream)
@ -306,76 +275,58 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(push stack (if (and (pop stack) (pop stack)) 1 0))] (push stack (if (and (pop stack) (pop stack)) 1 0))]
[(4) ;; or [(4) ;; or
(push stack (if (or (pop stack) (pop stack)) 1 0))] (push stack (if (or (pop stack) (pop stack)) 1 0))]
[(5) ;; not [(5) ;; not
(push stack (if (pop stack) 0 1))] (push stack (if (pop stack) 0 1))]
[(9) ;; abs [(9) ;; abs
(push stack (abs (pop stack)))] (push stack (abs (pop stack)))]
[(10) ;; add [(10) ;; add
(push stack (+ (pop stack) (pop stack)))] (push stack (+ (pop stack) (pop stack)))]
[(11) ;; sub [(11) ;; sub
(push stack (- (pop stack) (pop stack)))] (push stack (- (pop stack) (pop stack)))]
[(12) ;; div [(12) ;; div
(push stack (/ (pop stack) (pop stack) 1.0))] (push stack (/ (pop stack) (pop stack) 1.0))]
[(14) ;; neg [(14) ;; neg
(push stack (- (pop stack)))] (push stack (- (pop stack)))]
[(15) ;; eq [(15) ;; eq
(push stack (if (- (pop stack) (pop stack)) 1 0))] (push stack (if (- (pop stack) (pop stack)) 1 0))]
[(18) ;; drop [(18) ;; drop
(pop stack)] (pop stack)]
[(20) ;; put [(20) ;; put
(define val (pop stack)) (define val (pop stack))
(define idx (pop stack)) (define idx (pop stack))
(set! trans (list-set trans idx val))] (set! trans (list-set trans idx val))]
[(21) ;; get [(21) ;; get
(push stack (or (list-ref trans (pop stack)) 0))] (push stack (or (list-ref trans (pop stack)) 0))]
[(22) ;; ifelse [(22) ;; ifelse
(define s1 (pop stack)) (define s1 (pop stack))
(define s2 (pop stack)) (define s2 (pop stack))
(define v1 (pop stack)) (define v1 (pop stack))
(define v2 (pop stack)) (define v2 (pop stack))
(push stack (if (<= v1 v2) s1 s2))] (push stack (if (<= v1 v2) s1 s2))]
[(23) ;; random [(23) ;; random
(push stack (random))] (push stack (random))]
[(24) ;; mul [(24) ;; mul
(push stack (* (pop stack) (pop stack)))] (push stack (* (pop stack) (pop stack)))]
[(26) ;; sqrt [(26) ;; sqrt
(push stack (sqrt (pop stack)))] (push stack (sqrt (pop stack)))]
[(26) ;; dup [(26) ;; dup
(define a (pop stack)) (define a (pop stack))
(push stack a a)] (push stack a a)]
[(28) ;; exch [(28) ;; exch
(define a (pop stack)) (define a (pop stack))
(define b (pop stack)) (define b (pop stack))
(push stack b a)] (push stack b a)]
[(29) ;; index [(29) ;; index
(define idx (define idx
(min (max 0 (pop stack)) (- (stack-length stack) 1))) (min (max 0 (pop stack)) (- (stack-length stack) 1)))
(push stack (list-ref stack idx))] (push stack (list-ref stack idx))]
[(30) ;; roll [(30) ;; roll
(define n (pop stack)) (define n (pop stack))
(define j (pop stack)) (define j (pop stack))
(cond (cond
[(>= j 0) [(>= j 0)
(let loop ([j j]) (let loop ([j j])
(when (> j 0) (when (positive? j)
(define t (list-ref stack (- n 1))) (define t (list-ref stack (- n 1)))
(for [(i (in-range (- n 2) (sub1 0) -1))] (for [(i (in-range (- n 2) (sub1 0) -1))]
(set! stack (list-set stack (+ i 1) (list-ref stack i)))) (set! stack (list-set stack (+ i 1) (list-ref stack i))))
@ -383,7 +334,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(loop (sub1 j))))] (loop (sub1 j))))]
[else [else
(let loop ([j j]) (let loop ([j j])
(when (< j 0) (when (negative? j)
(define t (list-ref stack 0)) (define t (list-ref stack 0))
(for ([i (in-range (add1 n))]) (for ([i (in-range (add1 n))])
(set! stack (list-set stack i (list-ref stack (+ i 1))))) (set! stack (list-set stack i (list-ref stack (+ i 1)))))
@ -406,19 +357,15 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(set! y c6y) (set! y c6y)
(path-bezierCurveTo path c1x c1y c2x c2y c3x c3y) (path-bezierCurveTo path c1x c1y c2x c2y c3x c3y)
(path-bezierCurveTo path c4x c4y c5x c5y c6x c6y)] (path-bezierCurveTo path c4x c4y c5x c5y c6x c6y)]
[(35) ;; flex [(35) ;; flex
(define pts null) (define pts null)
(for ([i (in-range (add1 5))]) (for ([i (in-range (add1 5))])
(set! x (+ x (shift stack))) (set! x (+ x (shift stack)))
(set! y (+ y (shift stack))) (set! y (+ y (shift stack)))
(push pts x y)) (push pts x y))
(apply path-bezierCurveTo path (take pts 6)) (apply path-bezierCurveTo path (take pts 6))
(apply path-bezierCurveTo path (drop pts 6)) (apply path-bezierCurveTo path (drop pts 6))
(shift stack) ;; fd (shift stack)] ;; fd
]
[(36) ;; hflex1 [(36) ;; hflex1
(define c1x (+ x (shift stack))) (define c1x (+ x (shift stack)))
(define c1y (+ y (shift stack))) (define c1y (+ y (shift stack)))
@ -434,20 +381,16 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
(define c6y c5y) (define c6y c5y)
(set! x c6x) (set! x c6x)
(set! y c6y) (set! y c6y)
(path-bezierCurveTo path c1x c1y c2x c2y c3x c3y) (path-bezierCurveTo path c1x c1y c2x c2y c3x c3y)
(path-bezierCurveTo path c4x c4y c5x c5y c6x c6y)] (path-bezierCurveTo path c4x c4y c5x c5y c6x c6y)]
[(37) ;; flex1 [(37) ;; flex1
(define startx x) (define startx x)
(define starty y) (define starty y)
(define pts null) (define pts null)
(for ([i (in-range 0 (add1 4))]) (for ([i (in-range 0 (add1 4))])
(set! x (+ x (shift stack))) (set! x (+ x (shift stack)))
(set! y (+ y (shift stack))) (set! y (+ y (shift stack)))
(push pts x y)) (push pts x y))
(cond (cond
[(> (abs (- x startx)) (abs (- y starty))) ;; horzontal [(> (abs (- x startx)) (abs (- y starty))) ;; horzontal
(set! x (shift stack)) (set! x (shift stack))
@ -455,25 +398,19 @@ https://github.com/mbutterick/fontkit/blob/master/src/glyph/CFFGlyph.js
[else [else
(set! x startx) (set! x startx)
(set! y (shift stack))]) (set! y (shift stack))])
(push pts x y) (push pts x y)
(apply path-bezierCurveTo path (take pts 6)) (apply path-bezierCurveTo path (take pts 6))
(apply path-bezierCurveTo path (drop pts 6))] (apply path-bezierCurveTo path (drop pts 6))]
[else (error (format "unknown op: 12 ~a" op))])] [else (error (format "unknown op: 12 ~a" op))])]
[else (error (format "unknown op: ~a" op))])] [else (error (format "unknown op: ~a" op))])]
[(< op 247) (push stack (- op 139)) stack]
[(< op 251)
(push stack (+ (* (- op 247) 256) (read-byte stream) 108))]
[(< op 255)
(push stack (- (* (- 251 op) 256) (read-byte stream) 108))]
[else [else
(push stack (/ (decode int32be stream) 65536))]) (push stack (cond
(loop))))) [(< op 247) (- op 139)]
[(< op 251) (+ (* (- op 247) 256) (read-byte stream) 108)]
(parse) [(< op 255) (- (* (- 251 op) 256) (read-byte stream) 108)]
[else (/ (decode int32be stream) 65536)]))]))))
(when open (path-closePath path)) (when open (path-closePath path))
(set-cff-glyph-_usedSubrs! this used-subrs) (set-cff-glyph-_usedSubrs! this used-subrs)
(set-cff-glyph-_usedGsubrs! this used-gsubrs) (set-cff-glyph-_usedGsubrs! this used-gsubrs)
(set-cff-glyph-path! this path) (set-cff-glyph-path! this path)

Loading…
Cancel
Save