embedding achieved

main
Matthew Butterick 8 years ago
parent 37690fc4d6
commit 3847daa32a

@ -11,7 +11,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/tables/hmtx.js
(define HmtxEntry (+Struct
(dictify
'advance uint16be
'bearing uint16be)))
'bearing int16be)))
(define hmtx (+Rhmtx
(dictify

@ -14,6 +14,11 @@ https://github.com/devongovett/fontkit/blob/master/src/subset/Subset.js
(send this includeGlyph 0) ; always include the missing glyph in subset
(define/public (encodeStream)
(define s (+EncodeStream))
(send this encode s)
s)
(as-methods
includeGlyph))
@ -38,6 +43,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
|#
(define-subclass Subset (TTFSubset)
(report 'in-ttf-subset)
(field [glyphEncoder (make-object TTFGlyphEncoder)])
(field [glyf #f]
[offset #f]
@ -48,12 +54,13 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
_addGlyph
encode)
(report 'in-ttf-subset-end)
)
(define/contract (_addGlyph this gid)
(index? . ->m . index?)
(report 'in-ttf-subset-addglyph)
(define glyph (send (· this font) getGlyph gid))
(define glyf (send glyph _decode))
@ -76,11 +83,15 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
;; skip variation shit
(push-end-field! glyf this buffer)
(hash-update! (get-field loca this) 'offsets (λ (os) (append os (list (get-field offset this)))))
(report 'updating-loca)
(hash-update! (get-field loca this) 'offsets (λ (os) (report* os (list (get-field offset this)))
(append os (list (get-field offset this)))))
(report 'updating-hmtx)
(hash-update! (get-field hmtx this) 'metrics (λ (ms) (append ms
(mhash 'advance (· glyph advanceWidth)
'bearing (· (send glyph _getMetrics) leftBearing)))))
(list (mhash 'advance (· glyph advanceWidth)
'bearing (· (send glyph _getMetrics) leftBearing))))))
(increment-field! offset this (bytes-length buffer))
(sub1 (length (· this glyf))))
@ -92,6 +103,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
(define/contract (encode this stream)
(EncodeStream? . ->m . void?)
(report 'in-subset-encode)
(set-field! glyf this empty)
(set-field! offset this 0)
(set-field! loca this (mhash 'offsets empty))
@ -99,13 +111,17 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
;; include all the glyphs used in the document
(for ([gid (in-list (· this glyphs))])
(report gid 'adding-gid)
(send this _addGlyph gid))
(report 'all-glyphs-added)
(report (· this glyphs) 'glyphs-added)
(define maxp (cloneDeep (send (· this font) _getTable 'maxp)))
(hash-set! maxp 'numGlyphs (length (· this glyf)))
;; populate the new loca table
(report 'doing-loca)
(hash-update! (· this loca) 'offsets (λ (vals) (append vals (list (· this offset)))))
(loca-preEncode (· this loca))
@ -116,7 +132,7 @@ https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
(report (· this hmtx metrics))
(hash-set! hhea 'numberOfMetrics (length (· this hmtx metrics)))
;; todo: final encoding of directory, with all tables.
(report 'encoding-directory)
(send Directory encode stream
(mhash 'tables
(mhash

@ -1,6 +1,10 @@
#lang fontkit/racket
(require "glyph.rkt" restructure)
(provide (all-defined-out))
#|
approximates
https://github.com/mbutterick/fontkit/blob/master/src/glyph/TTFGlyph.js
|#
;; The header for both simple and composite glyphs
(define-subclass Struct (RGlyfHeader))
@ -59,8 +63,11 @@
(unfinished))
;; Parses a single glyph coordinate
(define/public (_parseGlyphCoord steam prev short same)
(unfinished))
(define/public (_parseGlyphCoord stream prev short same)
(+ prev (if short
((if (not same) - +) (send uint8 decode stream))
(if same 0 (send int16be decode stream)))))
;; Decodes the glyph data into points for simple glyphs,
;; or components for composite glyphs
@ -76,7 +83,7 @@
[(= glyfPos nextPos) #f]
[else
(define stream (send _font _getTableStream 'glyf))
(increment-field! pos stream glyfPos)
(send stream pos (+ (send stream pos) glyfPos))
(define startPos (· stream pos))
(define glyph (send GlyfHeader decode stream))
@ -91,8 +98,8 @@
glyph]))
(define/public (_decodeSimple glyph stream)
(unless (RGlyfHeader? glyph)
(raise-argument-error 'TTFGlyph-_decodeSimple "RGlyfHeader" glyph))
(unless (hash? glyph)
(raise-argument-error 'TTFGlyph-_decodeSimple "decoded RGlyfHeader" glyph))
(unless (DecodeStream? stream)
(raise-argument-error 'TTFGlyph-_decodeSimple "DecodeStream" stream))
@ -101,46 +108,50 @@
(hash-set! glyph 'points empty)
(define endPtsOfContours (send (+Array uint16be (· glyph numberOfContours)) decode stream))
(report* (· glyph numberOfContours) endPtsOfContours)
(hash-set! glyph 'instructions (send (+Array uint8be uint16be) decode stream))
(define numCoords (add1 (list-ref endPtsOfContours (sub1 (length endPtsOfContours)))))
(report numCoords)
(define flags
(reverse
(for/fold ([flags empty])
([i (in-naturals)]
#:when (< (length flags) numCoords))
(define flag (send stream readUInt8))
#:break (= (length flags) numCoords))
(define flag (send uint8 decode stream))
;; check for repeat flag
(define repeated-flags
(cond
[(not (zero? (bitwise-and flag REPEAT)))
(define count (send stream readUInt8))
(define count (send uint8 decode stream))
(make-list count flag)]
[else empty]))
(append repeated-flags (cons flag flags)))))
(report flags 'my-flags-homey)
(report endPtsOfContours)
(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))
(define point (+Point (zero? (bitwise-and flag ON_CURVE)) (and (index-of endPtsOfContours i) #t) 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)
(define next-px (_parseGlyphCoord stream px (bitwise-and flag X_SHORT_VECTOR) (bitwise-and flag SAME_X)))
(set-field! x (hash-ref glyph-points i) next-px)
next-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)
(define next-py (_parseGlyphCoord stream py (bitwise-and flag Y_SHORT_VECTOR) (bitwise-and flag SAME_Y)))
(set-field! y (hash-ref glyph-points i) next-py)
next-py)
;; skip variations shit
(error 'kabomm)
)
(define/public (_decodeComposite glyph stream [offset 0])

@ -2,7 +2,13 @@
(require "font.rkt" fontkit "reference.rkt")
(provide EmbeddedFont)
#|
approximates
https://github.com/mbutterick/pdfkit/blob/master/lib/font/embedded.coffee
|#
(define-subclass PDFFont (EmbeddedFont document font id)
(report 'embedded-font)
(field [subset (· this font createSubset)]
;; we make `unicode` and `width` fields integer-keyed hashes not lists
;; because they offer better random access and growability
@ -40,6 +46,7 @@ For now, we'll just measure width of the characters.
(define/contract (encode this text [features #f])
((string?) ((or/c list? #f)) . ->*m .
(list/c (listof string?) (listof (is-a?/c GlyphPosition))))
(report 'in-embedded-encode)
(define glyphRun (send (· this font) layout text features))
(define glyphs (· glyphRun glyphs))
(define positions (· glyphRun positions))
@ -69,9 +76,8 @@ For now, we'll just measure width of the characters.
(when isCFF
(hash-set! (· fontFile payload) 'Subtype "CIDFontType0C"))
;; todo
;; (send (send (· this subset) encodeStream) pipe fontFile)
(send fontFile end (send (· this subset) encode)) ;; temp
#;(send (send (· this subset) encodeStream) pipe fontFile)
(send fontFile end (send (send (· this subset) encodeStream) dump))
;; todo
;; (define familyClass (send (· this font) has-table? #"OS/2"))

@ -15,10 +15,10 @@
;; test against non-subsetted font version
(define-runtime-path this "test12rkt.pdf")
(make-doc this #f proc #:pdfkit #f)
(make-doc this #f proc #:test #f #:pdfkit #f)
(define-runtime-path that "test12crkt.pdf")
(make-doc that #t proc #:pdfkit #f)
#;(define-runtime-path that "test12crkt.pdf")
#;(make-doc that #t proc #:pdfkit #f)
#;(module+ test
(define doc (make-object PDFDocument))

@ -80,6 +80,9 @@ https://github.com/mbutterick/restructure/blob/master/src/DecodeStream.coffee
(set-port-position! _port current-position)
bs)
(define/public-final (readUInt8)
(read 1))
(define/public-final (read count)
(unless (index? count)
(raise-argument-error 'DecodeStream:read "positive integer" count))

Loading…
Cancel
Save