ntk 8.12.5 → 8.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/text/font.js +41 -0
- package/package.json +1 -1
package/lib/text/font.js
CHANGED
|
@@ -69,8 +69,49 @@ export function variationKey(coords) {
|
|
|
69
69
|
* Fonts are cheap-ish to open (tables parse lazily) and are cached by the
|
|
70
70
|
* FontManager — always obtain them via `app.fonts`.
|
|
71
71
|
*/
|
|
72
|
+
/**
|
|
73
|
+
* fontkit keeps one Glyph object per id and gives it the characters of
|
|
74
|
+
* whichever call made it first. A glyph asked for by id alone — its extents,
|
|
75
|
+
* its outline, or a component of a composite, which fontkit makes from inside
|
|
76
|
+
* the composite's path with no characters — is made with none, and every
|
|
77
|
+
* later shaping of that letter was handed the same object: a run read `e` as
|
|
78
|
+
* no characters at all, so every caret, selection edge and hit test after it
|
|
79
|
+
* on the line was a character over. Two code points that share a glyph (a
|
|
80
|
+
* space and a no-break space) had the same trouble the other way round.
|
|
81
|
+
*
|
|
82
|
+
* Asked with characters the cached glyph does not carry, the face answers a
|
|
83
|
+
* view of it that does — its prototype is the cached glyph, so the outline,
|
|
84
|
+
* the metrics and every cache on it stay shared — one view per glyph and
|
|
85
|
+
* characters. Installed once per fontkit font, on the instance, which is
|
|
86
|
+
* where fontkit's own shaping looks it up.
|
|
87
|
+
*/
|
|
88
|
+
function answerWithCharacters(fk) {
|
|
89
|
+
if (fk.__ntkCharacters) return;
|
|
90
|
+
const getGlyph = fk.getGlyph;
|
|
91
|
+
const views = new Map();
|
|
92
|
+
fk.getGlyph = function (id, characters = []) {
|
|
93
|
+
const glyph = getGlyph.call(this, id, characters);
|
|
94
|
+
if (!glyph || characters.length === 0) return glyph;
|
|
95
|
+
const had = glyph.codePoints;
|
|
96
|
+
if (had.length === characters.length && had.every((cp, i) => cp === characters[i])) {
|
|
97
|
+
return glyph;
|
|
98
|
+
}
|
|
99
|
+
const key = `${id}:${characters.join(',')}`;
|
|
100
|
+
let view = views.get(key);
|
|
101
|
+
if (view === undefined) {
|
|
102
|
+
view = Object.create(glyph, {
|
|
103
|
+
codePoints: { value: characters.slice(), enumerable: true }
|
|
104
|
+
});
|
|
105
|
+
views.set(key, view);
|
|
106
|
+
}
|
|
107
|
+
return view;
|
|
108
|
+
};
|
|
109
|
+
Object.defineProperty(fk, '__ntkCharacters', { value: true });
|
|
110
|
+
}
|
|
111
|
+
|
|
72
112
|
export default class Font {
|
|
73
113
|
constructor(fkFont, path, postscriptName) {
|
|
114
|
+
answerWithCharacters(fkFont);
|
|
74
115
|
this.fk = fkFont;
|
|
75
116
|
this.path = path;
|
|
76
117
|
/** stable cache key for glyph pages and font caches */
|