ntk 8.16.1 → 8.16.2
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 +36 -0
- package/package.json +1 -1
package/lib/text/font.js
CHANGED
|
@@ -134,9 +134,45 @@ function statedOrGlyph(fk, field, codePoint) {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
/**
|
|
138
|
+
* fontkit's TrueType glyph reads its box from the glyph's header without
|
|
139
|
+
* asking whether it has one: `_getCBox` decodes a header where the glyph's
|
|
140
|
+
* data starts, and an empty glyph — a space, or one a subsetter left with
|
|
141
|
+
* no outline — has no data, where `_decode` beside it says so and draws
|
|
142
|
+
* nothing. Mid-table it read the next glyph's box. At the table's end it
|
|
143
|
+
* read past it, and in a WOFF, whose tables are each their own buffer, that
|
|
144
|
+
* threw: a face from fonts.com ends its glyph table on four empty glyphs,
|
|
145
|
+
* the space among them, and every layout in it threw, which left a whole
|
|
146
|
+
* document blank. An empty glyph's box is its empty outline's, as the rest
|
|
147
|
+
* of fontkit has it. Installed once, on the class every TrueType glyph is.
|
|
148
|
+
*/
|
|
149
|
+
const MENDED = new WeakSet();
|
|
150
|
+
|
|
151
|
+
function mendEmptyGlyphBoxes(fk) {
|
|
152
|
+
if (!fk.directory?.tables?.glyf) return;
|
|
153
|
+
let glyph;
|
|
154
|
+
try {
|
|
155
|
+
glyph = fk.getGlyph(0);
|
|
156
|
+
} catch {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const proto = Object.getPrototypeOf(glyph);
|
|
160
|
+
if (!proto || MENDED.has(proto)) return;
|
|
161
|
+
MENDED.add(proto);
|
|
162
|
+
const own = proto._getCBox;
|
|
163
|
+
const outline = Object.getPrototypeOf(proto)?._getCBox;
|
|
164
|
+
if (typeof own !== 'function' || typeof outline !== 'function') return;
|
|
165
|
+
proto._getCBox = function (internal) {
|
|
166
|
+
const offsets = this._font.loca?.offsets;
|
|
167
|
+
if (offsets && offsets[this.id] === offsets[this.id + 1]) return outline.call(this, internal);
|
|
168
|
+
return own.call(this, internal);
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
137
172
|
export default class Font {
|
|
138
173
|
constructor(fkFont, path, postscriptName) {
|
|
139
174
|
answerWithCharacters(fkFont);
|
|
175
|
+
mendEmptyGlyphBoxes(fkFont);
|
|
140
176
|
this.fk = fkFont;
|
|
141
177
|
this.path = path;
|
|
142
178
|
/** stable cache key for glyph pages and font caches */
|