151 lines
4.3 KiB
Plaintext
151 lines
4.3 KiB
Plaintext
// The GlyphSet object
|
|
|
|
import Glyph from './glyph';
|
|
|
|
// Define a property on the glyph that depends on the path being loaded.
|
|
function defineDependentProperty(glyph, externalName, internalName) {
|
|
Object.defineProperty(glyph, externalName, {
|
|
get: function () {
|
|
// Request the path property to make sure the path is loaded.
|
|
glyph.path; // jshint ignore:line
|
|
return glyph[internalName];
|
|
},
|
|
set: function (newValue) {
|
|
glyph[internalName] = newValue;
|
|
},
|
|
enumerable: true,
|
|
configurable: true,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* A GlyphSet represents all glyphs available in the font, but modelled using
|
|
* a deferred glyph loader, for retrieving glyphs only once they are absolutely
|
|
* necessary, to keep the memory footprint down.
|
|
* @exports opentype.GlyphSet
|
|
* @class
|
|
* @param {opentype.Font}
|
|
* @param {Array}
|
|
*/
|
|
function GlyphSet(font, glyphs) {
|
|
this.font = font;
|
|
this.glyphs = {};
|
|
if (Array.isArray(glyphs)) {
|
|
for (let i = 0; i < glyphs.length; i++) {
|
|
const glyph = glyphs[i];
|
|
glyph.path.unitsPerEm = font.unitsPerEm;
|
|
this.glyphs[i] = glyph;
|
|
}
|
|
}
|
|
|
|
this.length = (glyphs && glyphs.length) || 0;
|
|
}
|
|
|
|
/**
|
|
* @param {number} index
|
|
* @return {opentype.Glyph}
|
|
*/
|
|
GlyphSet.prototype.get = function (index) {
|
|
// this.glyphs[index] is 'undefined' when low memory mode is on. glyph is pushed on request only.
|
|
if (this.glyphs[index] === undefined) {
|
|
this.font._push(index);
|
|
if (typeof this.glyphs[index] === 'function') {
|
|
this.glyphs[index] = this.glyphs[index]();
|
|
}
|
|
|
|
let glyph = this.glyphs[index];
|
|
let unicodeObj = this.font._IndexToUnicodeMap[index];
|
|
|
|
if (unicodeObj) {
|
|
for (let j = 0; j < unicodeObj.unicodes.length; j++)
|
|
glyph.addUnicode(unicodeObj.unicodes[j]);
|
|
}
|
|
|
|
this.glyphs[index].advanceWidth =
|
|
this.font._hmtxTableData[index].advanceWidth;
|
|
this.glyphs[index].leftSideBearing =
|
|
this.font._hmtxTableData[index].leftSideBearing;
|
|
} else {
|
|
if (typeof this.glyphs[index] === 'function') {
|
|
this.glyphs[index] = this.glyphs[index]();
|
|
}
|
|
}
|
|
|
|
return this.glyphs[index];
|
|
};
|
|
|
|
/**
|
|
* @param {number} index
|
|
* @param {Object}
|
|
*/
|
|
GlyphSet.prototype.push = function (index, loader) {
|
|
this.glyphs[index] = loader;
|
|
this.length++;
|
|
};
|
|
|
|
/**
|
|
* @alias opentype.glyphLoader
|
|
* @param {opentype.Font} font
|
|
* @param {number} index
|
|
* @return {opentype.Glyph}
|
|
*/
|
|
function glyphLoader(font, index) {
|
|
return new Glyph({ index: index, font: font });
|
|
}
|
|
|
|
/**
|
|
* Generate a stub glyph that can be filled with all metadata *except*
|
|
* the "points" and "path" properties, which must be loaded only once
|
|
* the glyph's path is actually requested for text shaping.
|
|
* @alias opentype.ttfGlyphLoader
|
|
* @param {opentype.Font} font
|
|
* @param {number} index
|
|
* @param {Function} parseGlyph
|
|
* @param {Object} data
|
|
* @param {number} position
|
|
* @param {Function} buildPath
|
|
* @return {opentype.Glyph}
|
|
*/
|
|
function ttfGlyphLoader(font, index, parseGlyph, data, position, buildPath) {
|
|
return function () {
|
|
const glyph = new Glyph({ index: index, font: font });
|
|
|
|
glyph.path = function () {
|
|
parseGlyph(glyph, data, position);
|
|
const path = buildPath(font.glyphs, glyph);
|
|
path.unitsPerEm = font.unitsPerEm;
|
|
return path;
|
|
};
|
|
|
|
defineDependentProperty(glyph, 'xMin', '_xMin');
|
|
defineDependentProperty(glyph, 'xMax', '_xMax');
|
|
defineDependentProperty(glyph, 'yMin', '_yMin');
|
|
defineDependentProperty(glyph, 'yMax', '_yMax');
|
|
|
|
return glyph;
|
|
};
|
|
}
|
|
/**
|
|
* @alias opentype.cffGlyphLoader
|
|
* @param {opentype.Font} font
|
|
* @param {number} index
|
|
* @param {Function} parseCFFCharstring
|
|
* @param {string} charstring
|
|
* @return {opentype.Glyph}
|
|
*/
|
|
function cffGlyphLoader(font, index, parseCFFCharstring, charstring) {
|
|
return function () {
|
|
const glyph = new Glyph({ index: index, font: font });
|
|
|
|
glyph.path = function () {
|
|
const path = parseCFFCharstring(font, glyph, charstring);
|
|
path.unitsPerEm = font.unitsPerEm;
|
|
return path;
|
|
};
|
|
|
|
return glyph;
|
|
};
|
|
}
|
|
|
|
export default { GlyphSet, glyphLoader, ttfGlyphLoader, cffGlyphLoader };
|