position amiss

main
Matthew Butterick 7 years ago
parent b5855e7ee1
commit 7609fd1126

@ -19,9 +19,9 @@ https://github.com/mbutterick/fontkit/blob/master/src/opentype/GSUBProcessor.js
[(= index -1) #f]
[else (define glyph (· this glyphIterator cur))
(send glyph id
(case (· table version)
[(1) (bitwise-and (+ (· glyph id) (· table deltaGlyphID)) #xffff)]
[(2) (send (· table substitute) get index)]))
(case (· table version)
[(1) (bitwise-and (+ (· glyph id) (· table deltaGlyphID)) #xffff)]
[(2) (send (· table substitute) get index)]))
#t])]
[(2) ;; Multiple Substitution
(report 'multiple-substitution)
@ -64,72 +64,80 @@ https://github.com/mbutterick/fontkit/blob/master/src/opentype/GSUBProcessor.js
(cond
[(= index -1) #f]
[(for*/or ([ligature (in-list (report (send (· table ligatureSets) get (report index 'starting-index))))]
[matched (in-value (send this sequenceMatchIndices 1 (report (· ligature components))))]
#:when (report matched))
(define curGlyph (· this glyphIterator cur))
;; Concatenate all of the characters the new ligature will represent
(define characters
(append (· curGlyph codePoints)
(append* (for/list ([index (in-list matched)])
(report index)
(get-field codePoints (list-ref (· this glyphs) index))))))
(report characters)
;; Create the replacement ligature glyph
(define ligatureGlyph (+GlyphInfo (· this font) (· ligature glyph) characters (· curGlyph features)))
(report (· ligatureGlyph id))
(set-field! shaperInfo ligatureGlyph (· curGlyph shaperInfo))
(set-field! isLigated ligatureGlyph #t)
(set-field! substituted ligatureGlyph #t)
(define isMarkLigature
(and (· curGlyph isMark)
(for/and ([match-idx (in-list matched)])
(· (list-ref (· this glyphs) match-idx) isMark))))
(set-field! ligatureID ligatureGlyph (cond
[isMarkLigature #f]
[else (define id (· this ligatureID))
(increment-field! ligatureID this)
id]))
(define lastLigID (· curGlyph ligatureID))
(define lastNumComps (length (· curGlyph codePoints)))
(define curComps lastNumComps)
(define idx (add1 (· this glyphIterator index)))
;; Set ligatureID and ligatureComponent on glyphs that were skipped in the matched sequence.
;; This allows GPOS to attach marks to the correct ligature components.
(for ([matchIndex (in-list matched)])
;; Don't assign new ligature components for mark ligatures (see above)
(cond
[isMarkLigature (set! idx matchIndex)]
[else (while (< idx matchIndex)
(define ligatureComponent (+ curComps (- lastNumComps) (min (or (get-field ligatureComponent (list-ref (· this glyphs) idx)) 1) lastNumComps)))
(set-field! ligatureID (list-ref (· this glyphs) idx) (· ligatureGlyph ligatureID))
(set-field! ligatureComponent (list-ref (· this glyphs) idx) ligatureComponent)
(increment! idx))])
(define lastLigID (· (list-ref (· this glyphs) idx) ligatureID))
(define lastNumComps (length (· (list-ref (· this glyphs) idx) codePoints)))
(increment! curComps lastNumComps)
(increment! idx)) ;; skip base glyph
[matched (in-value (send this sequenceMatchIndices 1 (report (· ligature components))))]
#:when (report matched))
(define curGlyph (· this glyphIterator cur))
;; Concatenate all of the characters the new ligature will represent
(define characters
(append (· curGlyph codePoints)
(append* (for/list ([index (in-list matched)])
(report index)
(get-field codePoints (list-ref (· this glyphs) index))))))
(report characters)
;; Create the replacement ligature glyph
(define ligatureGlyph (+GlyphInfo (· this font) (· ligature glyph) characters (· curGlyph features)))
(report (· ligatureGlyph id))
(set-field! shaperInfo ligatureGlyph (· curGlyph shaperInfo))
(set-field! isLigated ligatureGlyph #t)
(set-field! substituted ligatureGlyph #t)
(define isMarkLigature
(and (· curGlyph isMark)
(for/and ([match-idx (in-list matched)])
(· (list-ref (· this glyphs) match-idx) isMark))))
(set-field! ligatureID ligatureGlyph (cond
[isMarkLigature #f]
[else (define id (· this ligatureID))
(increment-field! ligatureID this)
id]))
(define lastLigID (· curGlyph ligatureID))
(define lastNumComps (length (· curGlyph codePoints)))
(define curComps lastNumComps)
(define idx (add1 (· this glyphIterator index)))
;; Set ligatureID and ligatureComponent on glyphs that were skipped in the matched sequence.
;; This allows GPOS to attach marks to the correct ligature components.
(for ([matchIndex (in-list matched)])
;; Don't assign new ligature components for mark ligatures (see above)
(cond
[isMarkLigature (set! idx matchIndex)]
[else (while (< idx matchIndex)
(define ligatureComponent (+ curComps (- lastNumComps) (min (or (get-field ligatureComponent (list-ref (· this glyphs) idx)) 1) lastNumComps)))
(set-field! ligatureID (list-ref (· this glyphs) idx) (· ligatureGlyph ligatureID))
(set-field! ligatureComponent (list-ref (· this glyphs) idx) ligatureComponent)
(increment! idx))])
(define lastLigID (· (list-ref (· this glyphs) idx) ligatureID))
(define lastNumComps (length (· (list-ref (· this glyphs) idx) codePoints)))
(increment! curComps lastNumComps)
(increment! idx)) ;; skip base glyph
;; Adjust ligature components for any marks following
(when (and lastLigID (not isMarkLigature))
(for ([i (in-range idx (length (· this glyphs)))]
#:when (= (· (list-ref (· this glyphs) idx) ligatureID) lastLigID))
(define ligatureComponent (+ curComps (- lastNumComps) (min (or (get-field ligatureComponent (list-ref (· this glyphs) i)) 1) lastNumComps)))
(set-field! ligatureComponent (list-ref (· this glyphs) i) ligatureComponent)))
;; Delete the matched glyphs, and replace the current glyph with the ligature glyph
(report* (for/list ([g (· this glyphs)]) (· g id)) (· this glyphIterator index))
(set-field! glyphs this (drop-right (· this glyphs) (length matched)))
(set-field! glyphs this (list-set (· this glyphs) (· this glyphIterator index) ligatureGlyph))
(set-field! glyphs (· this glyphIterator) (· this glyphs))
(report* (for/list ([g (· this glyphs)]) (· g id)) (· this glyphIterator index))
#t)]
;; Adjust ligature components for any marks following
(when (and lastLigID (not isMarkLigature))
(for ([i (in-range idx (length (· this glyphs)))]
#:when (= (· (list-ref (· this glyphs) idx) ligatureID) lastLigID))
(define ligatureComponent (+ curComps (- lastNumComps) (min (or (get-field ligatureComponent (list-ref (· this glyphs) i)) 1) lastNumComps)))
(set-field! ligatureComponent (list-ref (· this glyphs) i) ligatureComponent)))
;; Delete the matched glyphs, and replace the current glyph with the ligature glyph
(report (for/list ([g (· this glyphs)]) (· g id)) 'step-a)
(report matched)
(report (· this glyphIterator index))
(set-field! glyphs this (for*/fold ([gids (· this glyphs)])
([idx (in-list (reverse matched))])
(for/list ([(gid i) (in-indexed gids)]
#:unless (= idx i))
gid)))
(report (for/list ([g (· this glyphs)]) (· g id)) 'step-b)
(set-field! glyphs this (list-set (· this glyphs) (· this glyphIterator index) ligatureGlyph))
(set-field! glyphs (· this glyphIterator) (· this glyphs))
(report (for/list ([g (· this glyphs)]) (· g id)) 'step-c)
(report (· this glyphIterator index))
#t)]
[else #f])]
[(5) ;; Contextual Substitution
(send this applyContext table)]

@ -88,6 +88,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/opentype/ShapingPlan.js
(stage (· this font) glyphs positions)]
[(> (length stage) 0)
#;(report*/file 'shaping-plan:applying-features processor)
(report/file positions)
(report/file (send processor applyFeatures stage glyphs positions))]))))

Binary file not shown.

File diff suppressed because it is too large Load Diff

@ -9,7 +9,7 @@ make = (doc) ->
# Set the font, draw some text
doc.font('the-font')
.fontSize(100)
.text('fi', 100, 100, {width: false})
.text('Wofine', 100, 100, {width: false})
doc.end()

Binary file not shown.

@ -12,7 +12,7 @@
(send* doc
[font "the-font"]
[fontSize 100]
[text "afic" 100 100 (hash 'width #f)]))
[text "Wofine" 100 100 (hash 'width #f)]))
(define-runtime-path this "test16rkt.pdf")

Loading…
Cancel
Save