pdfnative 1.3.0 → 1.5.0
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/README.md +163 -40
- package/dist/index.cjs +1577 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +800 -10
- package/dist/index.d.ts +800 -10
- package/dist/index.js +1566 -67
- package/dist/index.js.map +1 -1
- package/dist/tools/build-emoji-font.js +1139 -0
- package/dist/tools/index.cjs +657 -0
- package/dist/tools/index.cjs.map +1 -0
- package/dist/tools/index.d.cts +110 -0
- package/dist/tools/index.d.ts +110 -0
- package/dist/tools/index.js +654 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/worker/index.cjs +110 -11
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.js +110 -11
- package/dist/worker/index.js.map +1 -1
- package/fonts/noto-sans-math-data.d.ts +13 -0
- package/fonts/noto-sans-math-data.js +64 -0
- package/package.json +45 -5
package/dist/worker/index.js
CHANGED
|
@@ -225,6 +225,16 @@ var MYANMAR_EXTENDED_A_END = 43647;
|
|
|
225
225
|
var MYANMAR_EXTENDED_B_START = 43488;
|
|
226
226
|
var MYANMAR_EXTENDED_B_END = 43519;
|
|
227
227
|
var MYANMAR_VIRAMA = 4153;
|
|
228
|
+
var MATH_OPERATORS_START = 8704;
|
|
229
|
+
var MATH_OPERATORS_END = 8959;
|
|
230
|
+
var SUPPLEMENTAL_MATH_OPERATORS_START = 10752;
|
|
231
|
+
var SUPPLEMENTAL_MATH_OPERATORS_END = 11007;
|
|
232
|
+
var GEOMETRIC_SHAPES_START = 9632;
|
|
233
|
+
var GEOMETRIC_SHAPES_END = 9727;
|
|
234
|
+
var MISC_MATH_SYMBOLS_A_START = 10176;
|
|
235
|
+
var MISC_MATH_SYMBOLS_A_END = 10223;
|
|
236
|
+
var MISC_MATH_SYMBOLS_B_START = 10624;
|
|
237
|
+
var MISC_MATH_SYMBOLS_B_END = 10751;
|
|
228
238
|
var EMOJI_RANGES = [
|
|
229
239
|
[127744, 128511],
|
|
230
240
|
// Miscellaneous Symbols and Pictographs
|
|
@@ -291,6 +301,9 @@ function isMyanmarCodepoint(cp) {
|
|
|
291
301
|
function isDevanagariCodepoint(cp) {
|
|
292
302
|
return cp >= DEVANAGARI_START && cp <= DEVANAGARI_END || cp >= DEVANAGARI_EXT_START && cp <= DEVANAGARI_EXT_END;
|
|
293
303
|
}
|
|
304
|
+
function isMathCodepoint(cp) {
|
|
305
|
+
return cp >= MATH_OPERATORS_START && cp <= MATH_OPERATORS_END || cp >= SUPPLEMENTAL_MATH_OPERATORS_START && cp <= SUPPLEMENTAL_MATH_OPERATORS_END || cp >= GEOMETRIC_SHAPES_START && cp <= GEOMETRIC_SHAPES_END || cp >= MISC_MATH_SYMBOLS_A_START && cp <= MISC_MATH_SYMBOLS_A_END || cp >= MISC_MATH_SYMBOLS_B_START && cp <= MISC_MATH_SYMBOLS_B_END;
|
|
306
|
+
}
|
|
294
307
|
function isEmojiCodepoint(cp) {
|
|
295
308
|
if (cp >= FITZPATRICK_START && cp <= FITZPATRICK_END) return true;
|
|
296
309
|
for (const [lo, hi] of EMOJI_RANGES) {
|
|
@@ -386,6 +399,7 @@ function detectCharLang(cp) {
|
|
|
386
399
|
if (cp >= 1024 && cp <= 1279 || cp >= 1280 && cp <= 1327) return "ru";
|
|
387
400
|
if (cp >= 4256 && cp <= 4351 || cp >= 11520 && cp <= 11567) return "ka";
|
|
388
401
|
if (cp >= 1328 && cp <= 1423 || cp >= 64275 && cp <= 64279) return "hy";
|
|
402
|
+
if (isMathCodepoint(cp)) return "math";
|
|
389
403
|
if (isEmojiCodepoint(cp)) return "emoji";
|
|
390
404
|
return null;
|
|
391
405
|
}
|
|
@@ -3581,15 +3595,86 @@ function radialShadingDict(p, m) {
|
|
|
3581
3595
|
const s = (sx + sy) / 2 || 1;
|
|
3582
3596
|
return `<< /ShadingType 3 /ColorSpace /DeviceRGB /Coords [${n(x0)} ${n(y0)} ${n(p.r0 * s)} ${n(x1)} ${n(y1)} ${n(p.r1 * s)}] /Function ${buildGradientFunction(p.stops)} /Extend ${extendFlags(p.extend)} >>`;
|
|
3583
3597
|
}
|
|
3598
|
+
function colorAtOffset(stops, t) {
|
|
3599
|
+
if (stops.length === 0) return [0, 0, 0, 255];
|
|
3600
|
+
const sorted = stops.slice().sort((a, b) => a.offset - b.offset);
|
|
3601
|
+
if (t <= sorted[0].offset) return sorted[0].color;
|
|
3602
|
+
const last = sorted[sorted.length - 1];
|
|
3603
|
+
if (t >= last.offset) return last.color;
|
|
3604
|
+
for (let i = 0; i < sorted.length - 1; i++) {
|
|
3605
|
+
const a = sorted[i], b = sorted[i + 1];
|
|
3606
|
+
if (t >= a.offset && t <= b.offset) {
|
|
3607
|
+
const span = b.offset - a.offset || 1;
|
|
3608
|
+
const f = (t - a.offset) / span;
|
|
3609
|
+
return [
|
|
3610
|
+
Math.round(a.color[0] + (b.color[0] - a.color[0]) * f),
|
|
3611
|
+
Math.round(a.color[1] + (b.color[1] - a.color[1]) * f),
|
|
3612
|
+
Math.round(a.color[2] + (b.color[2] - a.color[2]) * f),
|
|
3613
|
+
Math.round(a.color[3] + (b.color[3] - a.color[3]) * f)
|
|
3614
|
+
];
|
|
3615
|
+
}
|
|
3616
|
+
}
|
|
3617
|
+
return last.color;
|
|
3618
|
+
}
|
|
3619
|
+
function emitSweep(p, cx, cy, maxR, body, gsFor, blendMode) {
|
|
3620
|
+
const start = p.startAngle;
|
|
3621
|
+
const end = p.endAngle;
|
|
3622
|
+
const span = end - start;
|
|
3623
|
+
if (Math.abs(span) < 0.01) {
|
|
3624
|
+
const c = colorAtOffset(p.stops, 0);
|
|
3625
|
+
const gs = gsFor(c[3] / 255, blendMode);
|
|
3626
|
+
if (gs) body.push(`/${gs} gs`);
|
|
3627
|
+
body.push(`${ch(c[0])} ${ch(c[1])} ${ch(c[2])} rg`);
|
|
3628
|
+
body.push(`${n(cx - maxR)} ${n(cy - maxR)} ${n(2 * maxR)} ${n(2 * maxR)} re`);
|
|
3629
|
+
body.push("f");
|
|
3630
|
+
return;
|
|
3631
|
+
}
|
|
3632
|
+
const steps = Math.max(12, Math.min(180, Math.ceil(Math.abs(span) / 3)));
|
|
3633
|
+
const r = maxR * 1.5;
|
|
3634
|
+
const rad = Math.PI / 180;
|
|
3635
|
+
for (let i = 0; i < steps; i++) {
|
|
3636
|
+
const a0 = start + span * i / steps;
|
|
3637
|
+
const a1 = start + span * (i + 1) / steps;
|
|
3638
|
+
const tMid = (i + 0.5) / steps;
|
|
3639
|
+
const c = colorAtOffset(p.stops, tMid);
|
|
3640
|
+
const gs = gsFor(c[3] / 255, blendMode);
|
|
3641
|
+
body.push("q");
|
|
3642
|
+
if (gs) body.push(`/${gs} gs`);
|
|
3643
|
+
body.push(`${ch(c[0])} ${ch(c[1])} ${ch(c[2])} rg`);
|
|
3644
|
+
const x0 = cx + r * Math.cos(a0 * rad), y0 = cy + r * Math.sin(a0 * rad);
|
|
3645
|
+
const x1 = cx + r * Math.cos(a1 * rad), y1 = cy + r * Math.sin(a1 * rad);
|
|
3646
|
+
body.push(`${n(cx)} ${n(cy)} m ${n(x0)} ${n(y0)} l ${n(x1)} ${n(y1)} l h`);
|
|
3647
|
+
body.push("f");
|
|
3648
|
+
body.push("Q");
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3584
3651
|
function renderColorGlyph(glyph, outlines, unitsPerEm) {
|
|
3585
3652
|
const body = [];
|
|
3586
3653
|
const shadings = [];
|
|
3587
3654
|
const extGStates = [];
|
|
3588
|
-
const
|
|
3655
|
+
const gsMap = /* @__PURE__ */ new Map();
|
|
3589
3656
|
let shadingIdx = 0;
|
|
3657
|
+
const gsFor = (alpha, bm) => {
|
|
3658
|
+
const a = Math.max(0, Math.min(1, alpha));
|
|
3659
|
+
const needAlpha = a < 0.999;
|
|
3660
|
+
const needBm = bm !== void 0 && bm !== "Normal";
|
|
3661
|
+
if (!needAlpha && !needBm) return "";
|
|
3662
|
+
const key = `${needAlpha ? a.toFixed(3) : "1"}|${needBm ? bm : ""}`;
|
|
3663
|
+
let name = gsMap.get(key);
|
|
3664
|
+
if (!name) {
|
|
3665
|
+
name = `Gs${gsMap.size}`;
|
|
3666
|
+
gsMap.set(key, name);
|
|
3667
|
+
const parts = [];
|
|
3668
|
+
if (needAlpha) parts.push(`/ca ${n(a)}`, `/CA ${n(a)}`);
|
|
3669
|
+
if (needBm) parts.push(`/BM /${bm}`);
|
|
3670
|
+
extGStates.push({ name, dict: `<< ${parts.join(" ")} >>` });
|
|
3671
|
+
}
|
|
3672
|
+
return name;
|
|
3673
|
+
};
|
|
3590
3674
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
3591
3675
|
for (const layer of glyph.layers) {
|
|
3592
3676
|
const m = layer.transform ?? ID;
|
|
3677
|
+
const bm = layer.blendMode;
|
|
3593
3678
|
const contours = outlines(layer.glyphId);
|
|
3594
3679
|
if (contours.length === 0) continue;
|
|
3595
3680
|
const path = contoursToPath(contours, m);
|
|
@@ -3604,26 +3689,36 @@ function renderColorGlyph(glyph, outlines, unitsPerEm) {
|
|
|
3604
3689
|
}
|
|
3605
3690
|
if (layer.paint.kind === "solid") {
|
|
3606
3691
|
const c = layer.paint.color;
|
|
3607
|
-
const alpha = c[3] / 255;
|
|
3608
3692
|
body.push("q");
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
if (!gs) {
|
|
3612
|
-
gs = `GsA${alphaMap.size}`;
|
|
3613
|
-
alphaMap.set(c[3], gs);
|
|
3614
|
-
extGStates.push({ name: gs, dict: `<< /ca ${n(alpha)} /CA ${n(alpha)} >>` });
|
|
3615
|
-
}
|
|
3616
|
-
body.push(`/${gs} gs`);
|
|
3617
|
-
}
|
|
3693
|
+
const gs = gsFor(c[3] / 255, bm);
|
|
3694
|
+
if (gs) body.push(`/${gs} gs`);
|
|
3618
3695
|
body.push(`${ch(c[0])} ${ch(c[1])} ${ch(c[2])} rg`);
|
|
3619
3696
|
body.push(path);
|
|
3620
3697
|
body.push("f");
|
|
3621
3698
|
body.push("Q");
|
|
3699
|
+
} else if (layer.paint.kind === "sweep") {
|
|
3700
|
+
const [cx, cy] = tx(m, layer.paint.center[0], layer.paint.center[1]);
|
|
3701
|
+
let r2 = 0;
|
|
3702
|
+
for (const contour of contours) {
|
|
3703
|
+
for (const pt of contour) {
|
|
3704
|
+
const [px, py] = tx(m, pt.x, pt.y);
|
|
3705
|
+
const d = (px - cx) * (px - cx) + (py - cy) * (py - cy);
|
|
3706
|
+
if (d > r2) r2 = d;
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
const maxR = Math.sqrt(r2) || 1;
|
|
3710
|
+
body.push("q");
|
|
3711
|
+
body.push(path);
|
|
3712
|
+
body.push("W n");
|
|
3713
|
+
emitSweep(layer.paint, cx, cy, maxR, body, gsFor, bm);
|
|
3714
|
+
body.push("Q");
|
|
3622
3715
|
} else {
|
|
3623
3716
|
const name = `Sh${shadingIdx++}`;
|
|
3624
3717
|
const dict = layer.paint.kind === "linear" ? linearShadingDict(layer.paint, m) : radialShadingDict(layer.paint, m);
|
|
3625
3718
|
shadings.push({ name, dict });
|
|
3626
3719
|
body.push("q");
|
|
3720
|
+
const gs = gsFor(1, bm);
|
|
3721
|
+
if (gs) body.push(`/${gs} gs`);
|
|
3627
3722
|
body.push(path);
|
|
3628
3723
|
body.push("W n");
|
|
3629
3724
|
body.push(`/${name} sh`);
|
|
@@ -3765,6 +3860,10 @@ function buildTextRunsWithFallback(text, fontRef, fd, sz, trackGid, pdfA = false
|
|
|
3765
3860
|
for (let i = 0; i < text.length; ) {
|
|
3766
3861
|
const rawCp = text.codePointAt(i) ?? 0;
|
|
3767
3862
|
const charLen = rawCp > 65535 ? 2 : 1;
|
|
3863
|
+
if (rawCp < 32 || rawCp === 127) {
|
|
3864
|
+
i += charLen;
|
|
3865
|
+
continue;
|
|
3866
|
+
}
|
|
3768
3867
|
const cp = rawCp === 8239 || rawCp === 160 ? 32 : rawCp;
|
|
3769
3868
|
const char = text.substring(i, i + charLen);
|
|
3770
3869
|
const gid = fd.cmap[cp] ?? 0;
|