Re-factor the charsCache on Font-instances

Currently `charsCache` is initialized *lazily*, which considering that it just contains a simple `Object` doesn't seem entirely necessary. This first of all forces us to do repeated exists-checks in the `Font.charsToGlyphs` method, and secondly the similar/related `glyphCache` is already initialized eagerly.

Furthermore, this patch also does a bit of clean-up in the `Font.charsToGlyphs` method since this code is quite old.
This commit is contained in:
Jonas Jenwald 2021-05-26 13:07:00 +02:00
parent 3da9f077be
commit 8b1d01816b

View File

@ -802,7 +802,8 @@ class Font {
this.missingFile = false; this.missingFile = false;
this.cssFontInfo = properties.cssFontInfo; this.cssFontInfo = properties.cssFontInfo;
this.glyphCache = Object.create(null); this._charsCache = Object.create(null);
this._glyphCache = Object.create(null);
this.isSerifFont = !!(properties.flags & FontFlags.Serif); this.isSerifFont = !!(properties.flags & FontFlags.Serif);
this.isSymbolicFont = !!(properties.flags & FontFlags.Symbolic); this.isSymbolicFont = !!(properties.flags & FontFlags.Symbolic);
@ -2946,7 +2947,7 @@ class Font {
} }
} }
let glyph = this.glyphCache[charcode]; let glyph = this._glyphCache[charcode];
if ( if (
!glyph || !glyph ||
!glyph.matchesForCache( !glyph.matchesForCache(
@ -2970,57 +2971,46 @@ class Font {
isSpace, isSpace,
isInFont isInFont
); );
this.glyphCache[charcode] = glyph; this._glyphCache[charcode] = glyph;
} }
return glyph; return glyph;
} }
charsToGlyphs(chars) { charsToGlyphs(chars) {
let charsCache = this.charsCache; // If we translated this string before, just grab it from the cache.
let glyphs, glyph, charcode; let glyphs = this._charsCache[chars];
if (glyphs) {
// if we translated this string before, just grab it from the cache return glyphs;
if (charsCache) {
glyphs = charsCache[chars];
if (glyphs) {
return glyphs;
}
} }
// lazily create the translation cache
if (!charsCache) {
charsCache = this.charsCache = Object.create(null);
}
glyphs = []; glyphs = [];
const charsCacheKey = chars;
let i = 0,
ii;
if (this.cMap) { if (this.cMap) {
// composite fonts have multi-byte strings convert the string from // Composite fonts have multi-byte strings, convert the string from
// single-byte to multi-byte // single-byte to multi-byte.
const c = Object.create(null); const c = Object.create(null),
while (i < chars.length) { ii = chars.length;
let i = 0;
while (i < ii) {
this.cMap.readCharCode(chars, i, c); this.cMap.readCharCode(chars, i, c);
charcode = c.charcode; const { charcode, length } = c;
const length = c.length;
i += length; i += length;
// Space is char with code 0x20 and length 1 in multiple-byte codes. // Space is char with code 0x20 and length 1 in multiple-byte codes.
const isSpace = length === 1 && chars.charCodeAt(i - 1) === 0x20; const glyph = this._charToGlyph(
glyph = this._charToGlyph(charcode, isSpace); charcode,
length === 1 && chars.charCodeAt(i - 1) === 0x20
);
glyphs.push(glyph); glyphs.push(glyph);
} }
} else { } else {
for (i = 0, ii = chars.length; i < ii; ++i) { for (let i = 0, ii = chars.length; i < ii; ++i) {
charcode = chars.charCodeAt(i); const charcode = chars.charCodeAt(i);
glyph = this._charToGlyph(charcode, charcode === 0x20); const glyph = this._charToGlyph(charcode, charcode === 0x20);
glyphs.push(glyph); glyphs.push(glyph);
} }
} }
// Enter the translated string into the cache // Enter the translated string into the cache.
return (charsCache[charsCacheKey] = glyphs); return (this._charsCache[chars] = glyphs);
} }
/** /**
@ -3052,7 +3042,7 @@ class Font {
} }
get glyphCacheValues() { get glyphCacheValues() {
return Object.values(this.glyphCache); return Object.values(this._glyphCache);
} }
/** /**