
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import cloneDeep from 'clone';
import Subset from './Subset';
import Directory from '../tables/directory';
import Tables from '../tables';
import TTFGlyphEncoder from '../glyph/TTFGlyphEncoder';
export default class TTFSubset extends Subset {
constructor(font) {
super(font);
this.glyphEncoder = new TTFGlyphEncoder;
}
_addGlyph(gid) {
let glyph = this.font.getGlyph(gid);
let glyf = glyph._decode();
// get the offset to the glyph from the loca table
let curOffset = this.font.loca.offsets[gid];
let nextOffset = this.font.loca.offsets[gid + 1];
let stream = this.font._getTableStream('glyf');
stream.pos += curOffset;
let buffer = stream.readBuffer(nextOffset - curOffset);
// if it is a compound glyph, include its components
if (glyf && glyf.numberOfContours < 0) {
buffer = Buffer.from(buffer);
for (let component of glyf.components) {
gid = this.includeGlyph(component.glyphID);
buffer.writeUInt16BE(gid, component.pos);
}
} else if (glyf && this.font._variationProcessor) {
// If this is a TrueType variation glyph, re-encode the path
buffer = this.glyphEncoder.encodeSimple(glyph.path, glyf.instructions);
}
this.glyf.push(buffer);
this.loca.offsets.push(this.offset);
this.hmtx.metrics.push({
advance: glyph.advanceWidth,
bearing: glyph._getMetrics().leftBearing
});
this.offset += buffer.length;
return this.glyf.length - 1;
}
encode(stream) {
// 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
this.glyf = [];
this.offset = 0;
this.loca = {
offsets: [],
version: this.font.loca.version
};
this.hmtx = {
metrics: [],
bearings: []
};
// include all the glyphs
// not using a for loop because we need to support adding more
// glyphs to the array as we go, and CoffeeScript caches the length.
let i = 0;
while (i < this.glyphs.length) {
this._addGlyph(this.glyphs[i++]);
}
let maxp = cloneDeep(this.font.maxp);
maxp.numGlyphs = this.glyf.length;
this.loca.offsets.push(this.offset);
let head = cloneDeep(this.font.head);
head.indexToLocFormat = this.loca.version;
let hhea = cloneDeep(this.font.hhea);
hhea.numberOfMetrics = this.hmtx.metrics.length;
// map = []
// for index in [0...256]
// if index < @numGlyphs
// map[index] = index
// else
// map[index] = 0
//
// cmapTable =
// version: 0
// length: 262
// language: 0
// codeMap: map
//
// cmap =
// version: 0
// numSubtables: 1
// tables: [
// platformID: 1
// encodingID: 0
// table: cmapTable
// ]
// TODO: subset prep, cvt, fpgm?
Directory.encode(stream, {
tables: {
head,
hhea,
loca: this.loca,
maxp,
'cvt ': this.font['cvt '],
prep: this.font.prep,
glyf: this.glyf,
hmtx: this.hmtx,
fpgm: this.font.fpgm
// name: clone @font.name
// 'OS/2': clone @font['OS/2']
// post: clone @font.post
// cmap: cmap
}
});
}
}