pdfkit
Version:
A PDF generation library for Node.js
152 lines (137 loc) • 4.62 kB
JavaScript
(function() {
var CmapTable, Subset, utils;
var __hasProp = Object.prototype.hasOwnProperty, __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; };
CmapTable = require('./tables/cmap');
utils = require('./utils');
Subset = (function() {
function Subset(font) {
this.font = font;
this.subset = {};
this.unicodes = {};
this.next = 33;
}
Subset.prototype.use = function(character) {
var i, _ref;
if (typeof character === 'string') {
for (i = 0, _ref = character.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
this.use(character.charCodeAt(i));
}
return;
}
if (!this.unicodes[character]) {
this.subset[this.next] = character;
return this.unicodes[character] = this.next++;
}
};
Subset.prototype.encodeText = function(text) {
var char, i, string, _ref;
string = '';
for (i = 0, _ref = text.length; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
char = this.unicodes[text.charCodeAt(i)];
string += String.fromCharCode(char);
}
return string;
};
Subset.prototype.cmap = function() {
var mapping, roman, unicode, unicodeCmap, _ref;
unicodeCmap = this.font.cmap.tables[0].codeMap;
mapping = {};
_ref = this.subset;
for (roman in _ref) {
unicode = _ref[roman];
mapping[roman] = unicodeCmap[unicode];
}
return mapping;
};
Subset.prototype.glyphIDs = function() {
var ret, roman, unicode, unicodeCmap, val, _ref;
unicodeCmap = this.font.cmap.tables[0].codeMap;
ret = [0];
_ref = this.subset;
for (roman in _ref) {
unicode = _ref[roman];
val = unicodeCmap[unicode];
if ((val != null) && __indexOf.call(ret, val) < 0) ret.push(val);
}
return ret.sort();
};
Subset.prototype.glyphsFor = function(glyphIDs) {
var additionalIDs, glyph, glyphs, id, _i, _len, _ref;
glyphs = {};
for (_i = 0, _len = glyphIDs.length; _i < _len; _i++) {
id = glyphIDs[_i];
glyphs[id] = this.font.glyf.glyphFor(id);
}
additionalIDs = [];
for (id in glyphs) {
glyph = glyphs[id];
if (glyph != null ? glyph.compound : void 0) {
additionalIDs.push.apply(additionalIDs, glyph.glyphIDs);
}
}
if (additionalIDs.length > 0) {
_ref = this.glyphsFor(additionalIDs);
for (id in _ref) {
glyph = _ref[id];
glyphs[id] = glyph;
}
}
return glyphs;
};
Subset.prototype.encode = function() {
var cmap, code, glyf, glyphs, id, ids, loca, name, new2old, newIDs, nextGlyphID, old2new, oldID, oldIDs, tables, _ref, _ref2;
cmap = CmapTable.encode(this.cmap(), 'unicode');
glyphs = this.glyphsFor(this.glyphIDs());
old2new = {
0: 0
};
_ref = cmap.charMap;
for (code in _ref) {
ids = _ref[code];
old2new[ids.old] = ids["new"];
}
nextGlyphID = cmap.maxGlyphID;
for (oldID in glyphs) {
if (!(oldID in old2new)) old2new[oldID] = nextGlyphID++;
}
new2old = utils.invert(old2new);
newIDs = Object.keys(new2old).sort(function(a, b) {
return a - b;
});
oldIDs = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = newIDs.length; _i < _len; _i++) {
id = newIDs[_i];
_results.push(new2old[id]);
}
return _results;
})();
glyf = this.font.glyf.encode(glyphs, oldIDs, old2new);
loca = this.font.loca.encode(glyf.offsets);
name = this.font.name.encode();
this.postscriptName = name.postscriptName;
this.cmap = {};
_ref2 = cmap.charMap;
for (code in _ref2) {
ids = _ref2[code];
this.cmap[code] = ids.old;
}
tables = {
cmap: cmap.table,
glyf: glyf.table,
loca: loca.table,
hmtx: this.font.hmtx.encode(oldIDs),
hhea: this.font.hhea.encode(oldIDs),
maxp: this.font.maxp.encode(oldIDs),
post: this.font.post.encode(oldIDs),
name: name.table,
head: this.font.head.encode(loca)
};
if (this.font.os2.exists) tables['OS/2'] = this.font.os2.raw();
return this.font.directory.encode(tables);
};
return Subset;
})();
module.exports = Subset;
}).call(this);