main
Matthew Butterick 7 years ago
parent 9ce8f25973
commit 37690fc4d6

@ -12,13 +12,13 @@ https://github.com/mbutterick/fontkit/blob/master/src/TTFFont.js
;; This is the base class for all SFNT-based font formats in fontkit. ;; This is the base class for all SFNT-based font formats in fontkit.
;; It supports TrueType, and PostScript glyphs, and several color glyph formats. ;; It supports TrueType, and PostScript glyphs, and several color glyph formats.
(define-subclass object% (TTFFont stream) (define-subclass object% (TTFFont stream)
(when stream (unless (input-port? stream) (when stream (unless (DecodeStream? stream)
(raise-argument-error 'TTFFont "input port" stream))) (raise-argument-error 'TTFFont "DecodeStream" stream)))
(unless (member (peek-bytes 4 0 stream) (list #"true" #"OTTO" (bytes 0 1 0 0))) (unless (member (peek-bytes 4 0 (get-field _port stream)) (list #"true" #"OTTO" (bytes 0 1 0 0)))
(raise 'probe-fail)) (raise 'probe-fail))
;; skip variationCoords ;; skip variationCoords
(field [_directoryPos (port-position stream)] (field [_directoryPos (send stream pos)]
[_tables (mhash)] ; holds decoded tables (loaded lazily) [_tables (mhash)] ; holds decoded tables (loaded lazily)
[_glyphs (mhash)] [_glyphs (mhash)]
[_layoutEngine #f]) [_layoutEngine #f])
@ -31,16 +31,24 @@ https://github.com/mbutterick/fontkit/blob/master/src/TTFFont.js
(raise-argument-error '_getTable "table that exists in font" table-tag)) (raise-argument-error '_getTable "table that exists in font" table-tag))
(hash-ref! _tables table-tag (_decodeTable table-tag))) ; get table from cache, load if not there (hash-ref! _tables table-tag (_decodeTable table-tag))) ; get table from cache, load if not there
(define/public (_getTableStream tag)
(define table (hash-ref (· this directory tables) tag))
(cond
[table
(send stream pos (· table offset))
stream]
[else #f]))
(define/public (_decodeTable table-tag) (define/public (_decodeTable table-tag)
(define table-decoder (hash-ref table-codecs table-tag (define table-decoder (hash-ref table-codecs table-tag
(λ () (raise-argument-error '_decodeTable "decodable table" table-tag)))) (λ () (raise-argument-error '_decodeTable "decodable table" table-tag))))
(define offset (· (hash-ref (· directory tables) table-tag) offset)) (define offset (· (hash-ref (· directory tables) table-tag) offset))
(define len (· (hash-ref (· directory tables) table-tag) length)) (define len (· (hash-ref (· directory tables) table-tag) length))
(set-port-position! stream 0) (send stream pos 0)
(send table-decoder decode (+DecodeStream (peek-bytes len offset stream)) this length)) (send table-decoder decode (+DecodeStream (peek-bytes len offset (get-field _port stream))) this length))
(define/public (_decodeDirectory) (define/public (_decodeDirectory)
(set! directory (directory-decode stream (mhash '_startOffset 0))) (set! directory (send Directory decode stream (mhash '_startOffset 0)))
directory) directory)
(field [ft-library (FT_Init_FreeType)]) (field [ft-library (FT_Init_FreeType)])
@ -206,7 +214,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/TTFFont.js
;; for now, just use UTF-8 ;; for now, just use UTF-8
(define codepoints (map char->integer (string->list string))) (define codepoints (map char->integer (string->list string)))
(for/list ([cp (in-list codepoints)]) (for/list ([cp (in-list codepoints)])
(send this glyphForCodePoint cp))) (send this glyphForCodePoint cp)))
;; Maps a single unicode code point to a Glyph object. ;; Maps a single unicode code point to a Glyph object.
@ -229,7 +237,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/TTFFont.js
(string? number? . ->m . number?) (string? number? . ->m . number?)
(/ (* size (/ (* size
(for/sum ([c (in-string str)]) (for/sum ([c (in-string str)])
(measure-char-width this c))) (· this unitsPerEm))) (measure-char-width this c))) (· this unitsPerEm)))
;; Register font formats ;; Register font formats
@ -255,11 +263,11 @@ https://github.com/mbutterick/fontkit/blob/master/src/TTFFont.js
;; rather than use a `probe` function, ;; rather than use a `probe` function,
;; just try making a font with each format and see what happens ;; just try making a font with each format and see what happens
[font (in-value (with-handlers ([(curry eq? 'probe-fail) (λ (exn) #f)]) [font (in-value (with-handlers ([(curry eq? 'probe-fail) (λ (exn) #f)])
(make-object format (open-input-bytes buffer))))] (make-object format (+DecodeStream buffer))))]
#:when font) #:when font)
(if postscriptName (if postscriptName
(send font getFont postscriptName) ; used to select from collection files like TTC (send font getFont postscriptName) ; used to select from collection files like TTC
font)) font))
(error 'fontkit:create "unknown font format"))) (error 'fontkit:create "unknown font format")))

@ -52,15 +52,38 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
) )
(define/contract (_addGlyph this gid) (define/contract (_addGlyph this gid)
(index? . ->m . void?) (index? . ->m . index?)
(define glyph (send (· this font) getGlyph gid)) (define glyph (send (· this font) getGlyph gid))
(report glyph)
(define glyf (send glyph _decode)) (define glyf (send glyph _decode))
;; get the offset to the glyph from the loca table ;; get the offset to the glyph from the loca table
(define curOffset (list-ref (hash-ref (send (· this font) _getTable 'loca) 'offsets) gid)) (define loca (send (· this font) _getTable 'loca))
(unfinished)) (define curOffset (list-ref (· loca offsets) gid))
(define nextOffset (list-ref (· loca offsets) (add1 gid)))
(define stream (send (· this font) _getTableStream 'glyf))
(send stream pos (+ (send stream pos) curOffset))
(define buffer (send stream readBuffer (- nextOffset curOffset)))
;; if it is a compound glyph, include its components
(when (and glyf (negative? (· glyf numberOfContours)))
(set! buffer (+Buffer buffer))
(for ([component (in-list (· glyf components))])
(define gid (includeGlyph (· component glyphID)))
(send buffer writUInt16BE gid (send component pos))))
;; skip variation shit
(push-end-field! glyf this buffer)
(hash-update! (get-field loca this) 'offsets (λ (os) (append os (list (get-field offset this)))))
(hash-update! (get-field hmtx this) 'metrics (λ (ms) (append ms
(mhash 'advance (· glyph advanceWidth)
'bearing (· (send glyph _getMetrics) leftBearing)))))
(increment-field! offset this (bytes-length buffer))
(sub1 (length (· this glyf))))
;; tables required by PDF spec: ;; tables required by PDF spec:
;; head, hhea, loca, maxp, cvt, prep, glyf, hmtx, fpgm ;; head, hhea, loca, maxp, cvt, prep, glyf, hmtx, fpgm
@ -76,8 +99,9 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
;; include all the glyphs used in the document ;; include all the glyphs used in the document
(for ([gid (in-list (· this glyphs))]) (for ([gid (in-list (· this glyphs))])
(send this _addGlyph gid)) (send this _addGlyph gid))
(report (· this glyphs) 'glyphs-added)
(define maxp (cloneDeep (send (· this font) _getTable 'maxp))) (define maxp (cloneDeep (send (· this font) _getTable 'maxp)))
(hash-set! maxp 'numGlyphs (length (· this glyf))) (hash-set! maxp 'numGlyphs (length (· this glyf)))
@ -89,6 +113,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
(hash-set! head 'indexToLocFormat (· this loca version)) (hash-set! head 'indexToLocFormat (· this loca version))
(define hhea (cloneDeep (send (· this font) _getTable 'hhea))) (define hhea (cloneDeep (send (· this font) _getTable 'hhea)))
(report (· this hmtx metrics))
(hash-set! hhea 'numberOfMetrics (length (· this hmtx metrics))) (hash-set! hhea 'numberOfMetrics (length (· this hmtx metrics)))
;; todo: final encoding of directory, with all tables. ;; todo: final encoding of directory, with all tables.

@ -69,22 +69,26 @@
(define glyfPos (list-ref offsets id)) (define glyfPos (list-ref offsets id))
(define nextPos (list-ref offsets (add1 id))) (define nextPos (list-ref offsets (add1 id)))
(report* glyfPos nextPos)
;; Nothing to do if there is no data for this glyph ;; Nothing to do if there is no data for this glyph
(unless (= glyfPos nextPos) (cond
(define stream (send _font _getTableStream 'glyf)) [(= glyfPos nextPos) #f]
(increment-field! pos stream glyfPos) [else
(define startPos (· stream pos)) (define stream (send _font _getTableStream 'glyf))
(increment-field! pos stream glyfPos)
(define startPos (· stream pos))
(define glyph (send GlyfHeader decode stream)) (define glyph (send GlyfHeader decode stream))
(let ([contour-count (· glyph numberOfContours)]) (let ([contour-count (· glyph numberOfContours)])
(cond (cond
[(positive? contour-count) [(positive? contour-count)
(_decodeSimple glyph stream)] (_decodeSimple glyph stream)]
[(negative? contour-count) [(negative? contour-count)
(_decodeComposite glyph stream startPos)])) (_decodeComposite glyph stream startPos)]))
glyph)) glyph]))
(define/public (_decodeSimple glyph stream) (define/public (_decodeSimple glyph stream)
(unless (RGlyfHeader? glyph) (unless (RGlyfHeader? glyph)
@ -118,7 +122,26 @@
(append repeated-flags (cons flag flags))))) (append repeated-flags (cons flag flags)))))
(unfinished)) (define glyph-points (mhash))
(for ([(flag i) (in-indexed flags)])
(define point (+Point (zero? (bitwise-and flag ON_CURVE)) (>= (index-of endPtsOfContours i) 0) 0 0))
(hash-set! glyph-points i point))
(for/fold ([px 0])
([(flag i) (in-indexed flags)])
(define px (_parseGlyphCoord stream px (bitwise-and flag X_SHORT_VECTOR) (bitwise-and flag SAME_X)))
(hash-set! (hash-ref glyph-points i) 'x px)
px)
(for/fold ([py 0])
([(flag i) (in-indexed flags)])
(define py (_parseGlyphCoord stream py (bitwise-and flag Y_SHORT_VECTOR) (bitwise-and flag SAME_Y)))
(hash-set! (hash-ref glyph-points i) 'y py)
py)
;; skip variations shit
(error 'kabomm)
)
(define/public (_decodeComposite glyph stream [offset 0]) (define/public (_decodeComposite glyph stream [offset 0])
(unfinished))) (unfinished)))

Loading…
Cancel
Save