@effing/canvas 0.24.6 → 0.24.7
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/dist/index.js +73 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -260,12 +260,61 @@ function resolveTransformUnits(transform, viewportWidth, viewportHeight, fontSiz
|
|
|
260
260
|
import { GlobalFonts } from "@napi-rs/canvas";
|
|
261
261
|
|
|
262
262
|
// src/jsx/font-metrics.ts
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
263
|
+
import { inflateSync } from "zlib";
|
|
264
|
+
var WOFF_SIGNATURE = 2001684038;
|
|
265
|
+
function readWoffTable(view, entry) {
|
|
266
|
+
const compressed = entry.compLength < entry.origLength;
|
|
267
|
+
if (compressed) {
|
|
268
|
+
try {
|
|
269
|
+
const compData = new Uint8Array(
|
|
270
|
+
view.buffer,
|
|
271
|
+
view.byteOffset + entry.offset,
|
|
272
|
+
entry.compLength
|
|
273
|
+
);
|
|
274
|
+
const decompressed = inflateSync(compData);
|
|
275
|
+
return new DataView(
|
|
276
|
+
decompressed.buffer,
|
|
277
|
+
decompressed.byteOffset,
|
|
278
|
+
decompressed.byteLength
|
|
279
|
+
);
|
|
280
|
+
} catch {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return new DataView(
|
|
285
|
+
view.buffer,
|
|
286
|
+
view.byteOffset + entry.offset,
|
|
287
|
+
entry.origLength
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
function parseWoff(view) {
|
|
291
|
+
if (view.byteLength < 44) return null;
|
|
292
|
+
const numTables = view.getUint16(12);
|
|
293
|
+
if (view.byteLength < 44 + numTables * 20) return null;
|
|
294
|
+
let headEntry = null;
|
|
295
|
+
let hheaEntry = null;
|
|
296
|
+
for (let i = 0; i < numTables; i++) {
|
|
297
|
+
const r = 44 + i * 20;
|
|
298
|
+
const tag = String.fromCharCode(view.getUint8(r)) + String.fromCharCode(view.getUint8(r + 1)) + String.fromCharCode(view.getUint8(r + 2)) + String.fromCharCode(view.getUint8(r + 3));
|
|
299
|
+
const offset = view.getUint32(r + 4);
|
|
300
|
+
const compLength = view.getUint32(r + 8);
|
|
301
|
+
const origLength = view.getUint32(r + 12);
|
|
302
|
+
if (tag === "head") headEntry = { offset, compLength, origLength };
|
|
303
|
+
else if (tag === "hhea") hheaEntry = { offset, compLength, origLength };
|
|
304
|
+
}
|
|
305
|
+
if (!headEntry || !hheaEntry) return null;
|
|
306
|
+
const headView = readWoffTable(view, headEntry);
|
|
307
|
+
const hheaView = readWoffTable(view, hheaEntry);
|
|
308
|
+
if (!headView || !hheaView) return null;
|
|
309
|
+
if (headView.byteLength < 20 || hheaView.byteLength < 8) return null;
|
|
310
|
+
const unitsPerEm = headView.getUint16(18);
|
|
311
|
+
const ascender = hheaView.getInt16(4);
|
|
312
|
+
const descender = hheaView.getInt16(6);
|
|
313
|
+
return { unitsPerEm, ascender, descender };
|
|
314
|
+
}
|
|
315
|
+
function parseSfnt(view) {
|
|
267
316
|
const numTables = view.getUint16(4);
|
|
268
|
-
if (
|
|
317
|
+
if (view.byteLength < 12 + numTables * 16) return null;
|
|
269
318
|
let headOffset = -1;
|
|
270
319
|
let hheaOffset = -1;
|
|
271
320
|
for (let i = 0; i < numTables; i++) {
|
|
@@ -276,13 +325,23 @@ function parseFontMetrics(data) {
|
|
|
276
325
|
else if (tag === "hhea") hheaOffset = offset;
|
|
277
326
|
}
|
|
278
327
|
if (headOffset < 0 || hheaOffset < 0) return null;
|
|
279
|
-
if (
|
|
328
|
+
if (view.byteLength < headOffset + 20) return null;
|
|
280
329
|
const unitsPerEm = view.getUint16(headOffset + 18);
|
|
281
|
-
if (
|
|
330
|
+
if (view.byteLength < hheaOffset + 8) return null;
|
|
282
331
|
const ascender = view.getInt16(hheaOffset + 4);
|
|
283
332
|
const descender = view.getInt16(hheaOffset + 6);
|
|
284
333
|
return { unitsPerEm, ascender, descender };
|
|
285
334
|
}
|
|
335
|
+
function parseFontMetrics(data) {
|
|
336
|
+
const buf = data instanceof ArrayBuffer ? data : data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
337
|
+
const view = new DataView(buf);
|
|
338
|
+
if (buf.byteLength < 12) return null;
|
|
339
|
+
const signature = view.getUint32(0);
|
|
340
|
+
if (signature === WOFF_SIGNATURE) {
|
|
341
|
+
return parseWoff(view);
|
|
342
|
+
}
|
|
343
|
+
return parseSfnt(view);
|
|
344
|
+
}
|
|
286
345
|
|
|
287
346
|
// src/jsx/font.ts
|
|
288
347
|
var registeredFonts = /* @__PURE__ */ new Set();
|
|
@@ -299,10 +358,13 @@ function registerFont(font) {
|
|
|
299
358
|
registeredFonts.add(key);
|
|
300
359
|
}
|
|
301
360
|
function getFontMetrics(family, weight, style) {
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if (
|
|
361
|
+
const families = family.split(",").map((f) => f.trim().replace(/^['"]|['"]$/g, ""));
|
|
362
|
+
for (const name of families) {
|
|
363
|
+
const exact = metricsCache.get(`${name}:${weight}:${style}`);
|
|
364
|
+
if (exact) return exact;
|
|
365
|
+
for (const [key, metrics] of metricsCache) {
|
|
366
|
+
if (key.startsWith(`${name}:`)) return metrics;
|
|
367
|
+
}
|
|
306
368
|
}
|
|
307
369
|
return null;
|
|
308
370
|
}
|