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.
Files changed (2) hide show
  1. package/lib/text/font.js +41 -0
  2. 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 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ntk",
3
- "version": "8.12.5",
3
+ "version": "8.12.6",
4
4
  "description": "Desktop UI toolkit for X11 with canvas-like 2d and OpenGL rendering",
5
5
  "author": "Andrey Sidorov <sidorares@yandex.ru>",
6
6
  "license": "MIT",