|
|
|
|
#lang fontkit/racket
|
|
|
|
|
(require "clone.rkt" "ttfglyphencoder.rkt" "loca.rkt")
|
|
|
|
|
(provide Subset CFFSubset TTFSubset)
|
|
|
|
|
|
|
|
|
|
#|
|
|
|
|
|
approximates
|
|
|
|
|
https://github.com/devongovett/fontkit/blob/master/src/subset/Subset.js
|
|
|
|
|
|#
|
|
|
|
|
|
|
|
|
|
(define-subclass object% (Subset font)
|
|
|
|
|
(field [glyphs empty] ; list of glyph ids in the subset
|
|
|
|
|
[mapping (mhash)] ; mapping of glyph ids to indexes in `glyphs`
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
(send this includeGlyph 0) ; always include the missing glyph in subset
|
|
|
|
|
|
|
|
|
|
(as-methods
|
|
|
|
|
includeGlyph))
|
|
|
|
|
|
|
|
|
|
(define/contract (includeGlyph this glyph)
|
|
|
|
|
((or/c object? index?) . ->m . index?)
|
|
|
|
|
(let ([glyph (if (object? glyph) (· glyph id) glyph)])
|
|
|
|
|
(hash-ref! (· this mapping) glyph
|
|
|
|
|
(λ ()
|
|
|
|
|
;; put the new glyph at the end of `glyphs`,
|
|
|
|
|
;; and put its index in the mapping
|
|
|
|
|
(push-end-field! glyphs this glyph)
|
|
|
|
|
(sub1 (length (· this glyphs)))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define-subclass Subset (CFFSubset)
|
|
|
|
|
(error 'cff-subset-unimplemented))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#|
|
|
|
|
|
approximates
|
|
|
|
|
https://github.com/mbutterick/fontkit/blob/master/src/subset/TTFSubset.js
|
|
|
|
|
|#
|
|
|
|
|
|
|
|
|
|
(define-subclass Subset (TTFSubset)
|
|
|
|
|
(field [glyphEncoder (make-object TTFGlyphEncoder)])
|
|
|
|
|
(field [glyf #f]
|
|
|
|
|
[offset #f]
|
|
|
|
|
[loca #f]
|
|
|
|
|
[hmtx #f])
|
|
|
|
|
|
|
|
|
|
(as-methods
|
|
|
|
|
_addGlyph
|
|
|
|
|
encode)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
(define-stub-go _addGlyph)
|
|
|
|
|
|
|
|
|
|
;; tables required by PDF spec:
|
|
|
|
|
;; head, hhea, loca, maxp, cvt, prep, glyf, hmtx, fpgm
|
|
|
|
|
;; additional tables required for standalone fonts:
|
|
|
|
|
;; name, cmap, OS/2, post
|
|
|
|
|
|
|
|
|
|
(define/contract (encode this)
|
|
|
|
|
(->m input-port?)
|
|
|
|
|
(set-field! glyf this empty)
|
|
|
|
|
(set-field! offset this 0)
|
|
|
|
|
(set-field! loca this (mhash 'offsets empty))
|
|
|
|
|
(set-field! hmtx this (mhash 'metrics empty 'bearings empty))
|
|
|
|
|
|
|
|
|
|
;; include all the glyphs used in the document
|
|
|
|
|
(for ([gid (in-list (· this glyphs))])
|
|
|
|
|
(send this _addGlyph gid))
|
|
|
|
|
|
|
|
|
|
(define maxp (cloneDeep (send (· this font) _getTable 'maxp)))
|
|
|
|
|
(hash-set! maxp 'numGlyphs (length (· this glyf)))
|
|
|
|
|
|
|
|
|
|
;; populate the new loca table
|
|
|
|
|
(hash-update! (· this loca) 'offsets (λ (vals) (append vals (list (· this offset)))))
|
|
|
|
|
(loca-preEncode (· this loca))
|
|
|
|
|
|
|
|
|
|
(define head (cloneDeep (send (· this font) _getTable 'head)))
|
|
|
|
|
(hash-set! head 'indexToLocFormat (· this loca version))
|
|
|
|
|
|
|
|
|
|
(define hhea (cloneDeep (send (· this font) _getTable 'hhea)))
|
|
|
|
|
(hash-set! hhea 'numberOfMetrics (length (· this hmtx metrics)))
|
|
|
|
|
|
|
|
|
|
;; todo: final encoding of directory, with all tables.
|
|
|
|
|
|
|
|
|
|
(unfinished)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|