emf-converter 4.8.7 → 4.8.9
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/browser.js +423 -295
- package/dist/browser.mjs +423 -295
- package/dist/index.js +423 -295
- package/dist/index.mjs +423 -295
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -27797,10 +27797,10 @@ function parseEmfHeader(view) {
|
|
|
27797
27797
|
};
|
|
27798
27798
|
}
|
|
27799
27799
|
function getRenderableEmfBounds(header) {
|
|
27800
|
-
const boundsW = header.bounds.right - header.bounds.left;
|
|
27801
|
-
const boundsH = header.bounds.bottom - header.bounds.top;
|
|
27800
|
+
const boundsW = header.bounds.right - header.bounds.left + 1;
|
|
27801
|
+
const boundsH = header.bounds.bottom - header.bounds.top + 1;
|
|
27802
27802
|
if (boundsW > 0 && boundsH > 0) {
|
|
27803
|
-
return header.bounds;
|
|
27803
|
+
return { ...header.bounds, right: header.bounds.right + 1, bottom: header.bounds.bottom + 1 };
|
|
27804
27804
|
}
|
|
27805
27805
|
if (header.frameW > 0 && header.frameH > 0) {
|
|
27806
27806
|
emfLog(
|
|
@@ -30832,6 +30832,13 @@ function insetFixBox(box, inset) {
|
|
|
30832
30832
|
}
|
|
30833
30833
|
return framed;
|
|
30834
30834
|
}
|
|
30835
|
+
function sameEllipseRay(l, t, r, b, sx, sy, ex, ey) {
|
|
30836
|
+
const ax = BigInt(2 * sx - l - r);
|
|
30837
|
+
const ay = BigInt(2 * sy - t - b);
|
|
30838
|
+
const bx = BigInt(2 * ex - l - r);
|
|
30839
|
+
const by = BigInt(2 * ey - t - b);
|
|
30840
|
+
return ax * by === ay * bx && ax * bx + ay * by > 0n;
|
|
30841
|
+
}
|
|
30835
30842
|
function handleSetPixelV(rCtx, dataOff, recSize) {
|
|
30836
30843
|
const { ctx, view } = rCtx;
|
|
30837
30844
|
if (recSize >= 20) {
|
|
@@ -31189,7 +31196,9 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
|
|
|
31189
31196
|
const rx = Math.abs(r - l) / 2;
|
|
31190
31197
|
const ry = Math.abs(b - t) / 2;
|
|
31191
31198
|
const startAngle = Math.atan2((startY - cyA) / (ry || 1), (startX - cxA) / (rx || 1));
|
|
31192
|
-
const
|
|
31199
|
+
const clockwise = state.arcDirection === 2;
|
|
31200
|
+
const fullEllipse = recType !== EMR_PIE && rx > 0 && ry > 0 && sameEllipseRay(l, t, r, b, startX, startY, endX, endY);
|
|
31201
|
+
const endAngle = fullEllipse ? startAngle + (clockwise ? 2 : -2) * Math.PI : Math.atan2((endY - cyA) / (ry || 1), (endX - cxA) / (rx || 1));
|
|
31193
31202
|
const rotated = hasWorldRotation(rCtx);
|
|
31194
31203
|
const unframed = fixBox(rCtx, l, t, r, b);
|
|
31195
31204
|
const inset = insideFrameInset(rCtx, unframed);
|
|
@@ -31203,13 +31212,18 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
|
|
|
31203
31212
|
};
|
|
31204
31213
|
const isArcTo = recType === EMR_ARCTO;
|
|
31205
31214
|
const needsFill = recType === EMR_PIE || recType === EMR_CHORD;
|
|
31206
|
-
const clockwise = state.arcDirection === 2;
|
|
31207
31215
|
const startPoint = rotated ? gmapPoint(rCtx, cxA + rx * Math.cos(startAngle), cyA + ry * Math.sin(startAngle)) : { x: params.cx + params.rx * Math.cos(startAngle), y: params.cy + params.ry * Math.sin(startAngle) };
|
|
31208
31216
|
const build = (c) => {
|
|
31209
31217
|
if (recType === EMR_PIE) {
|
|
31210
31218
|
c.moveTo(params.cx, params.cy);
|
|
31219
|
+
} else if (!isArcTo && inPath) {
|
|
31220
|
+
c.moveTo(startPoint.x, startPoint.y);
|
|
31211
31221
|
}
|
|
31212
31222
|
if (isArcTo) {
|
|
31223
|
+
if (!inPath) {
|
|
31224
|
+
const from = currentFix(rCtx);
|
|
31225
|
+
c.moveTo(from[0] / 16, from[1] / 16);
|
|
31226
|
+
}
|
|
31213
31227
|
c.lineTo(startPoint.x, startPoint.y);
|
|
31214
31228
|
}
|
|
31215
31229
|
c.ellipse(params.cx, params.cy, params.rx, params.ry, params.rotation, startAngle, endAngle, !clockwise);
|
|
@@ -31229,7 +31243,9 @@ function handleArcFamily(rCtx, recType, dataOff, recSize) {
|
|
|
31229
31243
|
const rasterArgs = (immediate = false) => ({
|
|
31230
31244
|
box: inset ? framed : immediate && needsFill ? curvedFixBox(rCtx, l, t, r, b) : unframed,
|
|
31231
31245
|
s: radialOnBox(fixPoint(rCtx, startX, startY)),
|
|
31232
|
-
|
|
31246
|
+
// Device FIX rounding can separate distinct radial points on the
|
|
31247
|
+
// same logical ray. Preserve their proven endpoint identity.
|
|
31248
|
+
e: fullEllipse ? radialOnBox(fixPoint(rCtx, startX, startY)) : radialOnBox(fixPoint(rCtx, endX, endY)),
|
|
31233
31249
|
from: currentFix(rCtx)
|
|
31234
31250
|
});
|
|
31235
31251
|
if (inPath) {
|
|
@@ -35694,15 +35710,243 @@ function handleEmfObjectRecord(rCtx, recType, dataOff, recSize) {
|
|
|
35694
35710
|
}
|
|
35695
35711
|
}
|
|
35696
35712
|
|
|
35713
|
+
// src/wmf-mapping.ts
|
|
35714
|
+
var MM_TEXT = 1;
|
|
35715
|
+
var MM_LOMETRIC = 2;
|
|
35716
|
+
var MM_HIMETRIC = 3;
|
|
35717
|
+
var MM_LOENGLISH = 4;
|
|
35718
|
+
var MM_HIENGLISH = 5;
|
|
35719
|
+
var MM_TWIPS = 6;
|
|
35720
|
+
var MM_ISOTROPIC = 7;
|
|
35721
|
+
var MM_ANISOTROPIC = 8;
|
|
35722
|
+
var DEVICE_DPI = 96;
|
|
35723
|
+
function cloneMapping(m) {
|
|
35724
|
+
return {
|
|
35725
|
+
...m.dpi ? { dpi: { ...m.dpi } } : {},
|
|
35726
|
+
mode: m.mode,
|
|
35727
|
+
winOrg: { ...m.winOrg },
|
|
35728
|
+
winExt: { ...m.winExt },
|
|
35729
|
+
vpOrg: { ...m.vpOrg },
|
|
35730
|
+
vpExt: { ...m.vpExt }
|
|
35731
|
+
};
|
|
35732
|
+
}
|
|
35733
|
+
var METRIC_UNITS_PER_INCH = {
|
|
35734
|
+
[MM_LOMETRIC]: 254,
|
|
35735
|
+
[MM_HIMETRIC]: 2540,
|
|
35736
|
+
[MM_LOENGLISH]: 100,
|
|
35737
|
+
[MM_HIENGLISH]: 1e3,
|
|
35738
|
+
[MM_TWIPS]: 1440
|
|
35739
|
+
};
|
|
35740
|
+
function fixIsotropic(m) {
|
|
35741
|
+
if (m.mode !== MM_ISOTROPIC || !m.winExt.cx || !m.winExt.cy) {
|
|
35742
|
+
return;
|
|
35743
|
+
}
|
|
35744
|
+
const xdim = Math.abs(m.vpExt.cx / m.winExt.cx) / (m.dpi?.x ?? DEVICE_DPI);
|
|
35745
|
+
const ydim = Math.abs(m.vpExt.cy / m.winExt.cy) / (m.dpi?.y ?? DEVICE_DPI);
|
|
35746
|
+
if (xdim > ydim) {
|
|
35747
|
+
const min = m.vpExt.cx >= 0 ? 1 : -1;
|
|
35748
|
+
m.vpExt.cx = Math.floor(m.vpExt.cx * ydim / xdim + 0.5) || min;
|
|
35749
|
+
} else if (ydim > xdim) {
|
|
35750
|
+
const min = m.vpExt.cy >= 0 ? 1 : -1;
|
|
35751
|
+
m.vpExt.cy = Math.floor(m.vpExt.cy * xdim / ydim + 0.5) || min;
|
|
35752
|
+
}
|
|
35753
|
+
}
|
|
35754
|
+
function setMapMode(m, mode) {
|
|
35755
|
+
if (mode < MM_TEXT || mode > MM_ANISOTROPIC) {
|
|
35756
|
+
return;
|
|
35757
|
+
}
|
|
35758
|
+
const units = METRIC_UNITS_PER_INCH[mode === MM_ISOTROPIC ? MM_LOMETRIC : mode];
|
|
35759
|
+
if (mode === MM_TEXT) {
|
|
35760
|
+
m.winExt = { cx: 1, cy: 1 };
|
|
35761
|
+
m.vpExt = { cx: 1, cy: 1 };
|
|
35762
|
+
} else if (units !== void 0 && (mode !== MM_ISOTROPIC || m.mode !== MM_ISOTROPIC)) {
|
|
35763
|
+
m.winExt = { cx: units, cy: units };
|
|
35764
|
+
m.vpExt = { cx: m.dpi?.x ?? DEVICE_DPI, cy: -(m.dpi?.y ?? DEVICE_DPI) };
|
|
35765
|
+
}
|
|
35766
|
+
m.mode = mode;
|
|
35767
|
+
}
|
|
35768
|
+
function extentsSettable(m) {
|
|
35769
|
+
return m.mode === MM_ISOTROPIC || m.mode === MM_ANISOTROPIC;
|
|
35770
|
+
}
|
|
35771
|
+
function setWindowExt(m, cx, cy) {
|
|
35772
|
+
if (!extentsSettable(m) || cx === 0 || cy === 0) {
|
|
35773
|
+
return;
|
|
35774
|
+
}
|
|
35775
|
+
m.winExt = { cx, cy };
|
|
35776
|
+
fixIsotropic(m);
|
|
35777
|
+
}
|
|
35778
|
+
function setViewportExt(m, cx, cy) {
|
|
35779
|
+
if (!extentsSettable(m) || cx === 0 || cy === 0) {
|
|
35780
|
+
return;
|
|
35781
|
+
}
|
|
35782
|
+
m.vpExt = { cx, cy };
|
|
35783
|
+
fixIsotropic(m);
|
|
35784
|
+
}
|
|
35785
|
+
function scaled(v, num, den) {
|
|
35786
|
+
return Math.trunc(v * num / den);
|
|
35787
|
+
}
|
|
35788
|
+
function scaleWindowExt(m, xNum, xDen, yNum, yDen) {
|
|
35789
|
+
if (!extentsSettable(m) || !xDen || !yDen) {
|
|
35790
|
+
return;
|
|
35791
|
+
}
|
|
35792
|
+
const cx = scaled(m.winExt.cx, xNum, xDen);
|
|
35793
|
+
const cy = scaled(m.winExt.cy, yNum, yDen);
|
|
35794
|
+
if (cx === 0 || cy === 0) {
|
|
35795
|
+
return;
|
|
35796
|
+
}
|
|
35797
|
+
m.winExt = { cx, cy };
|
|
35798
|
+
fixIsotropic(m);
|
|
35799
|
+
}
|
|
35800
|
+
function scaleViewportExt(m, xNum, xDen, yNum, yDen) {
|
|
35801
|
+
if (!extentsSettable(m) || !xDen || !yDen) {
|
|
35802
|
+
return;
|
|
35803
|
+
}
|
|
35804
|
+
const cx = scaled(m.vpExt.cx, xNum, xDen);
|
|
35805
|
+
const cy = scaled(m.vpExt.cy, yNum, yDen);
|
|
35806
|
+
if (cx === 0 || cy === 0) {
|
|
35807
|
+
return;
|
|
35808
|
+
}
|
|
35809
|
+
m.vpExt = { cx, cy };
|
|
35810
|
+
fixIsotropic(m);
|
|
35811
|
+
}
|
|
35812
|
+
function applyWmfMapping(rCtx, m, kx, ky, mirrorWidth = 0) {
|
|
35813
|
+
rCtx.wmfLayoutRtl = mirrorWidth > 0;
|
|
35814
|
+
rCtx.useMappingMode = true;
|
|
35815
|
+
rCtx.windowOrg = { x: m.winOrg.x, y: m.winOrg.y };
|
|
35816
|
+
rCtx.windowExt = { cx: m.winExt.cx || 1, cy: m.winExt.cy || 1 };
|
|
35817
|
+
rCtx.viewportOrg = { x: m.vpOrg.x * kx, y: m.vpOrg.y * ky };
|
|
35818
|
+
rCtx.viewportExt = { cx: (m.vpExt.cx || 1) * kx, cy: (m.vpExt.cy || 1) * ky };
|
|
35819
|
+
if (mirrorWidth > 0) {
|
|
35820
|
+
rCtx.viewportOrg.x = mirrorWidth * kx - rCtx.viewportOrg.x;
|
|
35821
|
+
rCtx.viewportExt.cx = -rCtx.viewportExt.cx;
|
|
35822
|
+
}
|
|
35823
|
+
}
|
|
35824
|
+
function scanMappingRecords(view, start) {
|
|
35825
|
+
const out = {
|
|
35826
|
+
mode: null,
|
|
35827
|
+
winExt: null,
|
|
35828
|
+
vpExt: null
|
|
35829
|
+
};
|
|
35830
|
+
let off = start;
|
|
35831
|
+
let guard = 0;
|
|
35832
|
+
while (off + 6 <= view.byteLength && guard++ < 1e6) {
|
|
35833
|
+
const size = view.getUint32(off, true) * 2;
|
|
35834
|
+
const type = view.getUint16(off + 4, true);
|
|
35835
|
+
if (size < 6 || off + size > view.byteLength || type === 0) {
|
|
35836
|
+
break;
|
|
35837
|
+
}
|
|
35838
|
+
const d = off + 6;
|
|
35839
|
+
if (type === 259 && size >= 8 && out.mode === null) {
|
|
35840
|
+
out.mode = view.getUint16(d, true);
|
|
35841
|
+
} else if (type === 524 && size >= 10 && !out.winExt) {
|
|
35842
|
+
out.winExt = { cy: view.getInt16(d, true), cx: view.getInt16(d + 2, true) };
|
|
35843
|
+
} else if (type === 526 && size >= 10 && !out.vpExt) {
|
|
35844
|
+
out.vpExt = { cy: view.getInt16(d, true), cx: view.getInt16(d + 2, true) };
|
|
35845
|
+
}
|
|
35846
|
+
off += size;
|
|
35847
|
+
}
|
|
35848
|
+
return out;
|
|
35849
|
+
}
|
|
35850
|
+
function wmfPlayback(view, header, referenceDpi) {
|
|
35851
|
+
const valid = (v) => typeof v === "number" && Number.isFinite(v) && v > 0 ? v : DEVICE_DPI;
|
|
35852
|
+
const dpi = { x: valid(typeof referenceDpi === "number" ? referenceDpi : referenceDpi?.x), y: valid(typeof referenceDpi === "number" ? referenceDpi : referenceDpi?.y) };
|
|
35853
|
+
const density = referenceDpi === void 0 ? {} : { dpi };
|
|
35854
|
+
const bw = header.boundsRight - header.boundsLeft;
|
|
35855
|
+
const bh = header.boundsBottom - header.boundsTop;
|
|
35856
|
+
if (header.placeable !== false) {
|
|
35857
|
+
const inch = header.unitsPerInch > 0 ? header.unitsPerInch : DEVICE_DPI;
|
|
35858
|
+
const width2 = Math.max(1, Math.round(Math.abs(bw) * dpi.x / inch));
|
|
35859
|
+
const height2 = Math.max(1, Math.round(Math.abs(bh) * dpi.y / inch));
|
|
35860
|
+
return {
|
|
35861
|
+
width: width2,
|
|
35862
|
+
height: height2,
|
|
35863
|
+
mapping: {
|
|
35864
|
+
...density,
|
|
35865
|
+
mode: MM_ANISOTROPIC,
|
|
35866
|
+
winOrg: { x: header.boundsLeft, y: header.boundsTop },
|
|
35867
|
+
winExt: { cx: bw || 1, cy: bh || 1 },
|
|
35868
|
+
vpOrg: { x: 0, y: 0 },
|
|
35869
|
+
vpExt: { cx: width2, cy: height2 }
|
|
35870
|
+
}
|
|
35871
|
+
};
|
|
35872
|
+
}
|
|
35873
|
+
const scan = scanMappingRecords(view, header.headerSize);
|
|
35874
|
+
const scalable = scan.mode === MM_ISOTROPIC || scan.mode === MM_ANISOTROPIC;
|
|
35875
|
+
const ext = scalable && scan.vpExt ? scan.vpExt : scan.winExt;
|
|
35876
|
+
const width = ext ? Math.abs(ext.cx) : Math.abs(bw);
|
|
35877
|
+
const height = ext ? Math.abs(ext.cy) : Math.abs(bh);
|
|
35878
|
+
const w = Math.max(1, width || 1);
|
|
35879
|
+
const h = Math.max(1, height || 1);
|
|
35880
|
+
return {
|
|
35881
|
+
width: w,
|
|
35882
|
+
height: h,
|
|
35883
|
+
mapping: {
|
|
35884
|
+
...density,
|
|
35885
|
+
mode: MM_ANISOTROPIC,
|
|
35886
|
+
winOrg: { x: 0, y: 0 },
|
|
35887
|
+
winExt: { cx: w, cy: h },
|
|
35888
|
+
vpOrg: { x: 0, y: 0 },
|
|
35889
|
+
vpExt: { cx: w, cy: h }
|
|
35890
|
+
}
|
|
35891
|
+
};
|
|
35892
|
+
}
|
|
35893
|
+
|
|
35697
35894
|
// src/emf-gdi-transform-handlers.ts
|
|
35895
|
+
function emfDeviceDpi(view) {
|
|
35896
|
+
if (view.byteLength < 88 || view.getUint32(0, true) !== 1) {
|
|
35897
|
+
return void 0;
|
|
35898
|
+
}
|
|
35899
|
+
const devW = view.getInt32(72, true);
|
|
35900
|
+
const devH = view.getInt32(76, true);
|
|
35901
|
+
const mmW = view.getInt32(80, true);
|
|
35902
|
+
const mmH = view.getInt32(84, true);
|
|
35903
|
+
if (devW <= 0 || devH <= 0 || mmW <= 0 || mmH <= 0) {
|
|
35904
|
+
return void 0;
|
|
35905
|
+
}
|
|
35906
|
+
return { x: devW * 25.4 / mmW, y: devH * 25.4 / mmH };
|
|
35907
|
+
}
|
|
35908
|
+
function emfMapping(r) {
|
|
35909
|
+
const dpi = emfDeviceDpi(r.view);
|
|
35910
|
+
return {
|
|
35911
|
+
...dpi ? { dpi } : {},
|
|
35912
|
+
mode: r.mapMode ?? MM_TEXT,
|
|
35913
|
+
winOrg: r.windowOrg,
|
|
35914
|
+
winExt: { ...r.windowExt },
|
|
35915
|
+
vpOrg: r.viewportOrg,
|
|
35916
|
+
vpExt: { ...r.viewportExt }
|
|
35917
|
+
};
|
|
35918
|
+
}
|
|
35919
|
+
function storeMapping(r, m) {
|
|
35920
|
+
r.mapMode = m.mode;
|
|
35921
|
+
r.windowExt = m.winExt;
|
|
35922
|
+
r.viewportExt = m.vpExt;
|
|
35923
|
+
}
|
|
35924
|
+
function setExtent(r, viewport, cx, cy) {
|
|
35925
|
+
const m = emfMapping(r);
|
|
35926
|
+
if (!extentsSettable(m) || cx === 0 || cy === 0) {
|
|
35927
|
+
return;
|
|
35928
|
+
}
|
|
35929
|
+
if (viewport) {
|
|
35930
|
+
m.vpExt = { cx, cy };
|
|
35931
|
+
} else {
|
|
35932
|
+
m.winExt = { cx, cy };
|
|
35933
|
+
}
|
|
35934
|
+
fixIsotropic(m);
|
|
35935
|
+
storeMapping(r, m);
|
|
35936
|
+
activateGdiMappingMode(r);
|
|
35937
|
+
}
|
|
35938
|
+
function scaleExtent(r, viewport, xNum, xDenom, yNum, yDenom) {
|
|
35939
|
+
const ext = viewport ? r.viewportExt : r.windowExt;
|
|
35940
|
+
const cx = xDenom !== 0 ? Math.round(ext.cx * xNum / xDenom) : ext.cx;
|
|
35941
|
+
const cy = yDenom !== 0 ? Math.round(ext.cy * yNum / yDenom) : ext.cy;
|
|
35942
|
+
setExtent(r, viewport, cx, cy);
|
|
35943
|
+
}
|
|
35698
35944
|
function handleCoordinateRecord(rCtx, recType, dataOff, recSize) {
|
|
35699
35945
|
const { view } = rCtx;
|
|
35700
35946
|
switch (recType) {
|
|
35701
35947
|
case EMR_SETWINDOWEXTEX: {
|
|
35702
35948
|
if (recSize >= 16) {
|
|
35703
|
-
rCtx.
|
|
35704
|
-
rCtx.windowExt.cy = view.getInt32(dataOff + 4, true);
|
|
35705
|
-
activateGdiMappingMode(rCtx);
|
|
35949
|
+
setExtent(rCtx, false, view.getInt32(dataOff, true), view.getInt32(dataOff + 4, true));
|
|
35706
35950
|
}
|
|
35707
35951
|
return true;
|
|
35708
35952
|
}
|
|
@@ -35716,9 +35960,7 @@ function handleCoordinateRecord(rCtx, recType, dataOff, recSize) {
|
|
|
35716
35960
|
}
|
|
35717
35961
|
case EMR_SETVIEWPORTEXTEX: {
|
|
35718
35962
|
if (recSize >= 16) {
|
|
35719
|
-
rCtx.
|
|
35720
|
-
rCtx.viewportExt.cy = view.getInt32(dataOff + 4, true);
|
|
35721
|
-
activateGdiMappingMode(rCtx);
|
|
35963
|
+
setExtent(rCtx, true, view.getInt32(dataOff, true), view.getInt32(dataOff + 4, true));
|
|
35722
35964
|
}
|
|
35723
35965
|
return true;
|
|
35724
35966
|
}
|
|
@@ -35733,41 +35975,26 @@ function handleCoordinateRecord(rCtx, recType, dataOff, recSize) {
|
|
|
35733
35975
|
case EMR_SETMAPMODE: {
|
|
35734
35976
|
if (recSize >= 12) {
|
|
35735
35977
|
const mode = view.getUint32(dataOff, true);
|
|
35736
|
-
if (mode
|
|
35978
|
+
if (mode >= MM_TEXT && mode <= MM_ANISOTROPIC) {
|
|
35979
|
+
const m = emfMapping(rCtx);
|
|
35980
|
+
setMapMode(m, mode);
|
|
35981
|
+
storeMapping(rCtx, m);
|
|
35737
35982
|
activateGdiMappingMode(rCtx);
|
|
35738
35983
|
}
|
|
35739
35984
|
}
|
|
35740
35985
|
return true;
|
|
35741
35986
|
}
|
|
35742
|
-
case EMR_SCALEVIEWPORTEXTEX:
|
|
35743
|
-
if (recSize >= 24) {
|
|
35744
|
-
const xNum = view.getInt32(dataOff, true);
|
|
35745
|
-
const xDenom = view.getInt32(dataOff + 4, true);
|
|
35746
|
-
const yNum = view.getInt32(dataOff + 8, true);
|
|
35747
|
-
const yDenom = view.getInt32(dataOff + 12, true);
|
|
35748
|
-
if (xDenom !== 0) {
|
|
35749
|
-
rCtx.viewportExt.cx = Math.round(rCtx.viewportExt.cx * xNum / xDenom);
|
|
35750
|
-
}
|
|
35751
|
-
if (yDenom !== 0) {
|
|
35752
|
-
rCtx.viewportExt.cy = Math.round(rCtx.viewportExt.cy * yNum / yDenom);
|
|
35753
|
-
}
|
|
35754
|
-
activateGdiMappingMode(rCtx);
|
|
35755
|
-
}
|
|
35756
|
-
return true;
|
|
35757
|
-
}
|
|
35987
|
+
case EMR_SCALEVIEWPORTEXTEX:
|
|
35758
35988
|
case EMR_SCALEWINDOWEXTEX: {
|
|
35759
35989
|
if (recSize >= 24) {
|
|
35760
|
-
|
|
35761
|
-
|
|
35762
|
-
|
|
35763
|
-
|
|
35764
|
-
|
|
35765
|
-
|
|
35766
|
-
|
|
35767
|
-
|
|
35768
|
-
rCtx.windowExt.cy = Math.round(rCtx.windowExt.cy * yNum / yDenom);
|
|
35769
|
-
}
|
|
35770
|
-
activateGdiMappingMode(rCtx);
|
|
35990
|
+
scaleExtent(
|
|
35991
|
+
rCtx,
|
|
35992
|
+
recType === EMR_SCALEVIEWPORTEXTEX,
|
|
35993
|
+
view.getInt32(dataOff, true),
|
|
35994
|
+
view.getInt32(dataOff + 4, true),
|
|
35995
|
+
view.getInt32(dataOff + 8, true),
|
|
35996
|
+
view.getInt32(dataOff + 12, true)
|
|
35997
|
+
);
|
|
35771
35998
|
}
|
|
35772
35999
|
return true;
|
|
35773
36000
|
}
|
|
@@ -35907,6 +36134,15 @@ function handleEmfGdiStateRecord(rCtx, recType, _offset, dataOff, recSize) {
|
|
|
35907
36134
|
}
|
|
35908
36135
|
rCtx.clipStack ?? (rCtx.clipStack = []);
|
|
35909
36136
|
rCtx.clipStack.push({ region: rCtx.clipRegion ?? null });
|
|
36137
|
+
rCtx.mappingStack ?? (rCtx.mappingStack = []);
|
|
36138
|
+
rCtx.mappingStack.push({
|
|
36139
|
+
mapMode: rCtx.mapMode,
|
|
36140
|
+
windowOrg: { ...rCtx.windowOrg },
|
|
36141
|
+
windowExt: { ...rCtx.windowExt },
|
|
36142
|
+
viewportOrg: { ...rCtx.viewportOrg },
|
|
36143
|
+
viewportExt: { ...rCtx.viewportExt },
|
|
36144
|
+
useMappingMode: rCtx.useMappingMode
|
|
36145
|
+
});
|
|
35910
36146
|
rCtx.stateStack.push(cloneState(state));
|
|
35911
36147
|
ctx.save();
|
|
35912
36148
|
if (rCtx.clipRegion) {
|
|
@@ -35916,23 +36152,31 @@ function handleEmfGdiStateRecord(rCtx, recType, _offset, dataOff, recSize) {
|
|
|
35916
36152
|
}
|
|
35917
36153
|
case EMR_RESTOREDC: {
|
|
35918
36154
|
if (recSize >= 12) {
|
|
35919
|
-
while (rCtx.clipSaveDepth > 0) {
|
|
35920
|
-
ctx.restore();
|
|
35921
|
-
rCtx.clipSaveDepth--;
|
|
35922
|
-
}
|
|
35923
36155
|
let rel = view.getInt32(dataOff, true);
|
|
35924
36156
|
if (rel < 0) {
|
|
35925
36157
|
rel = rCtx.stateStack.length + rel + 1;
|
|
35926
36158
|
}
|
|
35927
|
-
|
|
36159
|
+
if (rel < 1 || rel > rCtx.stateStack.length) {
|
|
36160
|
+
return true;
|
|
36161
|
+
}
|
|
36162
|
+
while (rCtx.clipSaveDepth > 0) {
|
|
36163
|
+
ctx.restore();
|
|
36164
|
+
rCtx.clipSaveDepth--;
|
|
36165
|
+
}
|
|
36166
|
+
while (rCtx.stateStack.length > rel) {
|
|
35928
36167
|
rCtx.stateStack.pop();
|
|
35929
36168
|
rCtx.clipStack?.pop();
|
|
36169
|
+
rCtx.mappingStack?.pop();
|
|
35930
36170
|
ctx.restore();
|
|
35931
36171
|
}
|
|
35932
36172
|
const restored = rCtx.stateStack.pop();
|
|
35933
36173
|
if (restored) {
|
|
35934
36174
|
const clipSnapshot = rCtx.clipStack?.pop();
|
|
36175
|
+
const mappingSnapshot = rCtx.mappingStack?.pop();
|
|
35935
36176
|
Object.assign(state, restored);
|
|
36177
|
+
if (mappingSnapshot) {
|
|
36178
|
+
Object.assign(rCtx, mappingSnapshot);
|
|
36179
|
+
}
|
|
35936
36180
|
ctx.restore();
|
|
35937
36181
|
rCtx.clipRegion = clipSnapshot?.region ?? null;
|
|
35938
36182
|
if (rCtx.clipRegion) {
|
|
@@ -36742,24 +36986,22 @@ function rgbaToHex(c) {
|
|
|
36742
36986
|
}
|
|
36743
36987
|
return /^#[0-9a-f]{6}$/i.test(c) ? c : null;
|
|
36744
36988
|
}
|
|
36745
|
-
function
|
|
36989
|
+
function realizePlusEngineFont(rCtx, font, paint, brushSampler2) {
|
|
36746
36990
|
const fonts = rCtx.fonts;
|
|
36747
36991
|
const color = typeof paint === "string" ? rgbaToHex(paint) : null;
|
|
36748
|
-
const
|
|
36749
|
-
const graySmooth =
|
|
36992
|
+
const hint = rCtx.textRenderingHint ?? 0;
|
|
36993
|
+
const graySmooth = hint === 3 || hint === 4 || hint === 5;
|
|
36750
36994
|
const solidViaCoverage = !!color && graySmooth && !isSvgContext(rCtx.ctx);
|
|
36751
36995
|
const sampler = isSvgContext(rCtx.ctx) ? null : solidViaCoverage ? solidSampler(cssColorToArgb(paint) ?? 4278190080) : color ? null : brushSampler2;
|
|
36752
36996
|
const unit = font.unit ?? 0;
|
|
36753
|
-
if (!fonts || !color && !sampler ||
|
|
36754
|
-
return
|
|
36997
|
+
if (!fonts || !color && !sampler || unit !== 0 && unit !== 2) {
|
|
36998
|
+
return null;
|
|
36755
36999
|
}
|
|
36756
37000
|
const m = plusWorldMatrix(rCtx);
|
|
36757
37001
|
if (m[1] !== 0 || m[2] !== 0 || m[0] <= 0 || m[3] <= 0) {
|
|
36758
|
-
return
|
|
37002
|
+
return null;
|
|
36759
37003
|
}
|
|
36760
37004
|
const emPx = font.emSize * m[3];
|
|
36761
|
-
const hint = rCtx.textRenderingHint ?? 0;
|
|
36762
|
-
const quality = HINT_QUALITY[hint] ?? NONANTIALIASED_QUALITY;
|
|
36763
37005
|
const spec = {
|
|
36764
37006
|
face: font.family,
|
|
36765
37007
|
height: -Math.round(emPx),
|
|
@@ -36768,7 +37010,7 @@ function drawPlusStringWithEngine(rCtx, font, text, layoutX, layoutY, paint, ali
|
|
|
36768
37010
|
italic: (font.flags & 2) !== 0,
|
|
36769
37011
|
charSet: 1,
|
|
36770
37012
|
pitchAndFamily: 0,
|
|
36771
|
-
quality,
|
|
37013
|
+
quality: HINT_QUALITY[hint] ?? NONANTIALIASED_QUALITY,
|
|
36772
37014
|
unhinted: hint === 2 || hint === 4,
|
|
36773
37015
|
// AntiAlias ignores the font's gasp table (measured: Arial 16 px is
|
|
36774
37016
|
// grayscale there, but single-bit under AntiAliasGridFit, as in GDI).
|
|
@@ -36776,31 +37018,32 @@ function drawPlusStringWithEngine(rCtx, font, text, layoutX, layoutY, paint, ali
|
|
|
36776
37018
|
};
|
|
36777
37019
|
const realized = fonts.realize(spec, rCtx.fontFamilyMap);
|
|
36778
37020
|
if (!realized) {
|
|
36779
|
-
return
|
|
36780
|
-
}
|
|
36781
|
-
const ttf = realized.ttf;
|
|
36782
|
-
const unhinted = spec.unhinted === true;
|
|
36783
|
-
const exactAscent = emPx * ttf.winAscent / ttf.unitsPerEm;
|
|
36784
|
-
const ascent = unhinted ? exactAscent : Math.ceil(exactAscent);
|
|
36785
|
-
const x = m[0] * layoutX + m[4] + emPx * (format?.leadingMargin ?? PLUS_LEADING_EM);
|
|
36786
|
-
const y = m[3] * layoutY + m[5] + ascent;
|
|
36787
|
-
const codes = [];
|
|
36788
|
-
for (let i = 0; i < text.length; i++) {
|
|
36789
|
-
codes.push(text.charCodeAt(i));
|
|
37021
|
+
return null;
|
|
36790
37022
|
}
|
|
36791
|
-
|
|
36792
|
-
|
|
36793
|
-
|
|
36794
|
-
|
|
36795
|
-
|
|
36796
|
-
|
|
36797
|
-
|
|
36798
|
-
|
|
36799
|
-
|
|
36800
|
-
|
|
36801
|
-
|
|
36802
|
-
|
|
36803
|
-
|
|
37023
|
+
return {
|
|
37024
|
+
realized,
|
|
37025
|
+
emPx,
|
|
37026
|
+
m,
|
|
37027
|
+
unhinted: spec.unhinted === true,
|
|
37028
|
+
color,
|
|
37029
|
+
sampler,
|
|
37030
|
+
solidViaCoverage,
|
|
37031
|
+
underline: (font.flags & 4) !== 0,
|
|
37032
|
+
strikeOut: (font.flags & 8) !== 0
|
|
37033
|
+
};
|
|
37034
|
+
}
|
|
37035
|
+
function paintPlusEngineRun(rCtx, ef, run) {
|
|
37036
|
+
const base = {
|
|
37037
|
+
...run,
|
|
37038
|
+
textAlign: 24,
|
|
37039
|
+
bkColor: "#ffffff",
|
|
37040
|
+
bkMode: 1,
|
|
37041
|
+
options: 0,
|
|
37042
|
+
rect: null,
|
|
37043
|
+
matrix: null
|
|
37044
|
+
};
|
|
37045
|
+
if ((!ef.color || ef.solidViaCoverage) && ef.sampler) {
|
|
37046
|
+
const cov = gdiTextCoverage(ef.realized, { ...base});
|
|
36804
37047
|
if (!cov) {
|
|
36805
37048
|
return true;
|
|
36806
37049
|
}
|
|
@@ -36810,7 +37053,7 @@ function drawPlusStringWithEngine(rCtx, font, text, layoutX, layoutY, paint, ali
|
|
|
36810
37053
|
}
|
|
36811
37054
|
return compositeBrushCoverage(
|
|
36812
37055
|
rCtx,
|
|
36813
|
-
sampler,
|
|
37056
|
+
ef.sampler,
|
|
36814
37057
|
{ x: cov.x, y: cov.y, w: cov.width, h: cov.height },
|
|
36815
37058
|
cov.data,
|
|
36816
37059
|
cov.channels,
|
|
@@ -36818,25 +37061,82 @@ function drawPlusStringWithEngine(rCtx, font, text, layoutX, layoutY, paint, ali
|
|
|
36818
37061
|
cov.channels === 3 ? gamma : 1
|
|
36819
37062
|
);
|
|
36820
37063
|
}
|
|
36821
|
-
paintGdiTextRun(
|
|
36822
|
-
|
|
36823
|
-
|
|
36824
|
-
|
|
36825
|
-
|
|
36826
|
-
|
|
36827
|
-
dy: null,
|
|
36828
|
-
textAlign: 24,
|
|
36829
|
-
textColor: color,
|
|
36830
|
-
bkColor: "#ffffff",
|
|
36831
|
-
bkMode: 1,
|
|
36832
|
-
options: 0,
|
|
36833
|
-
rect: null,
|
|
36834
|
-
matrix: null,
|
|
36835
|
-
underline: (font.flags & 4) !== 0,
|
|
36836
|
-
strikeOut: (font.flags & 8) !== 0
|
|
36837
|
-
}, rCtx.fontFamilyMap);
|
|
37064
|
+
paintGdiTextRun(
|
|
37065
|
+
rCtx.ctx,
|
|
37066
|
+
ef.realized,
|
|
37067
|
+
{ ...base, textColor: ef.color, underline: ef.underline, strikeOut: ef.strikeOut },
|
|
37068
|
+
rCtx.fontFamilyMap
|
|
37069
|
+
);
|
|
36838
37070
|
return true;
|
|
36839
37071
|
}
|
|
37072
|
+
function drawPlusStringWithEngine(rCtx, font, text, layoutX, layoutY, paint, alignment, format, brushSampler2 = null) {
|
|
37073
|
+
if (alignment !== 0) {
|
|
37074
|
+
return false;
|
|
37075
|
+
}
|
|
37076
|
+
const ef = realizePlusEngineFont(rCtx, font, paint, brushSampler2);
|
|
37077
|
+
if (!ef) {
|
|
37078
|
+
return false;
|
|
37079
|
+
}
|
|
37080
|
+
const { realized, emPx, m, unhinted } = ef;
|
|
37081
|
+
const ttf = realized.ttf;
|
|
37082
|
+
const exactAscent = emPx * ttf.winAscent / ttf.unitsPerEm;
|
|
37083
|
+
const ascent = unhinted ? exactAscent : Math.ceil(exactAscent);
|
|
37084
|
+
const x = m[0] * layoutX + m[4] + emPx * (format?.leadingMargin ?? PLUS_LEADING_EM);
|
|
37085
|
+
const y = m[3] * layoutY + m[5] + ascent;
|
|
37086
|
+
const codes = [];
|
|
37087
|
+
for (let i = 0; i < text.length; i++) {
|
|
37088
|
+
codes.push(text.charCodeAt(i));
|
|
37089
|
+
}
|
|
37090
|
+
const tracking = format?.tracking ?? PLUS_DEFAULT_TRACKING;
|
|
37091
|
+
const dx = unhinted ? codes.map((c) => realized.advance(realized.glyphIndex(c)) * tracking) : null;
|
|
37092
|
+
return paintPlusEngineRun(rCtx, ef, { codes, glyphIndices: false, x, y, dx, dy: null });
|
|
37093
|
+
}
|
|
37094
|
+
var DRIVER_STRING_CMAP_LOOKUP = 1;
|
|
37095
|
+
var DRIVER_STRING_VERTICAL = 2;
|
|
37096
|
+
var DRIVER_STRING_REALIZED_ADVANCE = 4;
|
|
37097
|
+
function drawPlusDriverString(rCtx, recFlags, brushVal, font, codes, positions, options2) {
|
|
37098
|
+
const cmap = (options2 & DRIVER_STRING_CMAP_LOOKUP) !== 0;
|
|
37099
|
+
const realizedAdvance = (options2 & DRIVER_STRING_REALIZED_ADVANCE) !== 0;
|
|
37100
|
+
if (!(options2 & DRIVER_STRING_VERTICAL)) {
|
|
37101
|
+
const paint = resolveBrushPaint(rCtx, recFlags, brushVal);
|
|
37102
|
+
const ef = realizePlusEngineFont(rCtx, font, paint, rCtx.fonts ? deviceBrushSampler(rCtx, recFlags, brushVal) : null);
|
|
37103
|
+
if (ef) {
|
|
37104
|
+
const { m } = ef;
|
|
37105
|
+
const dev = positions.map((p) => ({ x: m[0] * p.x + m[4], y: m[3] * p.y + m[5] }));
|
|
37106
|
+
const step = (axis) => dev.map((p, i) => i + 1 < dev.length ? dev[i + 1][axis] - p[axis] : 0);
|
|
37107
|
+
paintPlusEngineRun(rCtx, ef, {
|
|
37108
|
+
codes,
|
|
37109
|
+
glyphIndices: !cmap,
|
|
37110
|
+
x: dev[0].x,
|
|
37111
|
+
y: dev[0].y,
|
|
37112
|
+
dx: realizedAdvance ? null : step("x"),
|
|
37113
|
+
dy: realizedAdvance ? null : step("y")
|
|
37114
|
+
});
|
|
37115
|
+
return;
|
|
37116
|
+
}
|
|
37117
|
+
}
|
|
37118
|
+
if (!cmap) {
|
|
37119
|
+
return;
|
|
37120
|
+
}
|
|
37121
|
+
const { ctx } = rCtx;
|
|
37122
|
+
const bold = font.flags & 1 ? "bold " : "";
|
|
37123
|
+
const italic = font.flags & 2 ? "italic " : "";
|
|
37124
|
+
const family = mapFontFamily(font.family, rCtx.fontFamilyMap);
|
|
37125
|
+
const setFont = () => {
|
|
37126
|
+
ctx.font = `${italic}${bold}${font.emSize}px ${family}`;
|
|
37127
|
+
ctx.textBaseline = "alphabetic";
|
|
37128
|
+
ctx.textAlign = "left";
|
|
37129
|
+
};
|
|
37130
|
+
if (realizedAdvance) {
|
|
37131
|
+
setFont();
|
|
37132
|
+
fillPlusText(rCtx, recFlags, brushVal, String.fromCharCode(...codes), positions[0].x, positions[0].y, font.emSize);
|
|
37133
|
+
return;
|
|
37134
|
+
}
|
|
37135
|
+
for (let i = 0; i < codes.length; i++) {
|
|
37136
|
+
setFont();
|
|
37137
|
+
fillPlusText(rCtx, recFlags, brushVal, String.fromCharCode(codes[i]), positions[i].x, positions[i].y, font.emSize);
|
|
37138
|
+
}
|
|
37139
|
+
}
|
|
36840
37140
|
function handleEmfPlusTextImageRecord(rCtx, recType, recFlags, dataOff, recDataSize) {
|
|
36841
37141
|
const { ctx, view, objectTable } = rCtx;
|
|
36842
37142
|
switch (recType) {
|
|
@@ -36920,24 +37220,31 @@ function handleEmfPlusTextImageRecord(rCtx, recType, recFlags, dataOff, recDataS
|
|
|
36920
37220
|
case EMFPLUS_DRAWDRIVERSTRING: {
|
|
36921
37221
|
if (recDataSize >= 16) {
|
|
36922
37222
|
const brushVal = view.getUint32(dataOff, true);
|
|
37223
|
+
const options2 = view.getUint32(dataOff + 4, true);
|
|
37224
|
+
const matrixPresent = view.getUint32(dataOff + 8, true) !== 0;
|
|
36923
37225
|
const glyphCount = view.getUint32(dataOff + 12, true);
|
|
36924
|
-
const
|
|
36925
|
-
const font = objectTable.get(fontId);
|
|
37226
|
+
const font = objectTable.get(recFlags & 255);
|
|
36926
37227
|
const glyphsOff = dataOff + 16;
|
|
36927
37228
|
const posOff = glyphsOff + glyphCount * 2;
|
|
36928
|
-
const
|
|
36929
|
-
if (glyphCount > 0 && glyphCount < 1e5 &&
|
|
36930
|
-
const
|
|
36931
|
-
|
|
36932
|
-
|
|
36933
|
-
|
|
36934
|
-
|
|
36935
|
-
|
|
36936
|
-
|
|
36937
|
-
|
|
36938
|
-
const
|
|
36939
|
-
|
|
36940
|
-
|
|
37229
|
+
const matrixOff = posOff + glyphCount * 8;
|
|
37230
|
+
if (glyphCount > 0 && glyphCount < 1e5 && matrixOff + (matrixPresent ? 24 : 0) <= dataOff + recDataSize && font && font.kind === "plus-font") {
|
|
37231
|
+
const codes = [];
|
|
37232
|
+
const positions = [];
|
|
37233
|
+
for (let i = 0; i < glyphCount; i++) {
|
|
37234
|
+
codes.push(view.getUint16(glyphsOff + i * 2, true));
|
|
37235
|
+
positions.push({ x: view.getFloat32(posOff + i * 8, true), y: view.getFloat32(posOff + i * 8 + 4, true) });
|
|
37236
|
+
}
|
|
37237
|
+
const world = rCtx.worldTransform;
|
|
37238
|
+
if (matrixPresent) {
|
|
37239
|
+
const xf = [0, 4, 8, 12, 16, 20].map((k) => view.getFloat32(matrixOff + k, true));
|
|
37240
|
+
if (xf.every(Number.isFinite)) {
|
|
37241
|
+
rCtx.worldTransform = mulMatrix(world, xf);
|
|
37242
|
+
}
|
|
37243
|
+
}
|
|
37244
|
+
try {
|
|
37245
|
+
drawPlusDriverString(rCtx, recFlags, brushVal, font, codes, positions, options2);
|
|
37246
|
+
} finally {
|
|
37247
|
+
rCtx.worldTransform = world;
|
|
36941
37248
|
}
|
|
36942
37249
|
}
|
|
36943
37250
|
}
|
|
@@ -37716,7 +38023,7 @@ function parseEmfPlusRegionObject(view, off, maxLen) {
|
|
|
37716
38023
|
}
|
|
37717
38024
|
view.getUint32(off, true);
|
|
37718
38025
|
const regionNodeCount = view.getUint32(off + 4, true);
|
|
37719
|
-
if (regionNodeCount
|
|
38026
|
+
if (regionNodeCount > 1e5) {
|
|
37720
38027
|
return null;
|
|
37721
38028
|
}
|
|
37722
38029
|
const endOff = off + maxLen;
|
|
@@ -38031,9 +38338,11 @@ function replayEmfRecords(view, ctx, bounds, canvasW, canvasH, dpiScale = 1, rep
|
|
|
38031
38338
|
// canvas like every other device coordinate (bounds' top-left to the
|
|
38032
38339
|
// canvas origin, scaled by sx/sy); see `deviceToCanvas`.
|
|
38033
38340
|
windowOrg: { x: 0, y: 0 },
|
|
38034
|
-
windowExt: { cx:
|
|
38341
|
+
windowExt: { cx: 1, cy: 1 },
|
|
38035
38342
|
viewportOrg: { x: 0, y: 0 },
|
|
38036
|
-
viewportExt: { cx:
|
|
38343
|
+
viewportExt: { cx: 1, cy: 1 },
|
|
38344
|
+
mapMode: 1,
|
|
38345
|
+
// MM_TEXT: the default DC uses one-to-one page/device units.
|
|
38037
38346
|
useMappingMode: false,
|
|
38038
38347
|
deviceToCanvas: true,
|
|
38039
38348
|
clipSaveDepth: 0,
|
|
@@ -38230,187 +38539,6 @@ function extractEmbeddedEmf(view, start) {
|
|
|
38230
38539
|
return out.buffer;
|
|
38231
38540
|
}
|
|
38232
38541
|
|
|
38233
|
-
// src/wmf-mapping.ts
|
|
38234
|
-
var MM_TEXT = 1;
|
|
38235
|
-
var MM_LOMETRIC = 2;
|
|
38236
|
-
var MM_HIMETRIC = 3;
|
|
38237
|
-
var MM_LOENGLISH = 4;
|
|
38238
|
-
var MM_HIENGLISH = 5;
|
|
38239
|
-
var MM_TWIPS = 6;
|
|
38240
|
-
var MM_ISOTROPIC = 7;
|
|
38241
|
-
var MM_ANISOTROPIC = 8;
|
|
38242
|
-
var DEVICE_DPI = 96;
|
|
38243
|
-
function cloneMapping(m) {
|
|
38244
|
-
return {
|
|
38245
|
-
...m.dpi ? { dpi: { ...m.dpi } } : {},
|
|
38246
|
-
mode: m.mode,
|
|
38247
|
-
winOrg: { ...m.winOrg },
|
|
38248
|
-
winExt: { ...m.winExt },
|
|
38249
|
-
vpOrg: { ...m.vpOrg },
|
|
38250
|
-
vpExt: { ...m.vpExt }
|
|
38251
|
-
};
|
|
38252
|
-
}
|
|
38253
|
-
var METRIC_UNITS_PER_INCH = {
|
|
38254
|
-
[MM_LOMETRIC]: 254,
|
|
38255
|
-
[MM_HIMETRIC]: 2540,
|
|
38256
|
-
[MM_LOENGLISH]: 100,
|
|
38257
|
-
[MM_HIENGLISH]: 1e3,
|
|
38258
|
-
[MM_TWIPS]: 1440
|
|
38259
|
-
};
|
|
38260
|
-
function fixIsotropic(m) {
|
|
38261
|
-
if (m.mode !== MM_ISOTROPIC || !m.winExt.cx || !m.winExt.cy) {
|
|
38262
|
-
return;
|
|
38263
|
-
}
|
|
38264
|
-
const xdim = Math.abs(m.vpExt.cx / m.winExt.cx) / (m.dpi?.x ?? DEVICE_DPI);
|
|
38265
|
-
const ydim = Math.abs(m.vpExt.cy / m.winExt.cy) / (m.dpi?.y ?? DEVICE_DPI);
|
|
38266
|
-
if (xdim > ydim) {
|
|
38267
|
-
const min = m.vpExt.cx >= 0 ? 1 : -1;
|
|
38268
|
-
m.vpExt.cx = Math.floor(m.vpExt.cx * ydim / xdim + 0.5) || min;
|
|
38269
|
-
} else if (ydim > xdim) {
|
|
38270
|
-
const min = m.vpExt.cy >= 0 ? 1 : -1;
|
|
38271
|
-
m.vpExt.cy = Math.floor(m.vpExt.cy * xdim / ydim + 0.5) || min;
|
|
38272
|
-
}
|
|
38273
|
-
}
|
|
38274
|
-
function setMapMode(m, mode) {
|
|
38275
|
-
if (mode < MM_TEXT || mode > MM_ANISOTROPIC) {
|
|
38276
|
-
return;
|
|
38277
|
-
}
|
|
38278
|
-
const units = METRIC_UNITS_PER_INCH[mode === MM_ISOTROPIC ? MM_LOMETRIC : mode];
|
|
38279
|
-
if (mode === MM_TEXT) {
|
|
38280
|
-
m.winExt = { cx: 1, cy: 1 };
|
|
38281
|
-
m.vpExt = { cx: 1, cy: 1 };
|
|
38282
|
-
} else if (units !== void 0 && (mode !== MM_ISOTROPIC || m.mode !== MM_ISOTROPIC)) {
|
|
38283
|
-
m.winExt = { cx: units, cy: units };
|
|
38284
|
-
m.vpExt = { cx: m.dpi?.x ?? DEVICE_DPI, cy: -(m.dpi?.y ?? DEVICE_DPI) };
|
|
38285
|
-
}
|
|
38286
|
-
m.mode = mode;
|
|
38287
|
-
}
|
|
38288
|
-
function extentsSettable(m) {
|
|
38289
|
-
return m.mode === MM_ISOTROPIC || m.mode === MM_ANISOTROPIC;
|
|
38290
|
-
}
|
|
38291
|
-
function setWindowExt(m, cx, cy) {
|
|
38292
|
-
if (!extentsSettable(m) || cx === 0 || cy === 0) {
|
|
38293
|
-
return;
|
|
38294
|
-
}
|
|
38295
|
-
m.winExt = { cx, cy };
|
|
38296
|
-
fixIsotropic(m);
|
|
38297
|
-
}
|
|
38298
|
-
function setViewportExt(m, cx, cy) {
|
|
38299
|
-
if (!extentsSettable(m) || cx === 0 || cy === 0) {
|
|
38300
|
-
return;
|
|
38301
|
-
}
|
|
38302
|
-
m.vpExt = { cx, cy };
|
|
38303
|
-
fixIsotropic(m);
|
|
38304
|
-
}
|
|
38305
|
-
function scaled(v, num, den) {
|
|
38306
|
-
return Math.trunc(v * num / den);
|
|
38307
|
-
}
|
|
38308
|
-
function scaleWindowExt(m, xNum, xDen, yNum, yDen) {
|
|
38309
|
-
if (!extentsSettable(m) || !xDen || !yDen) {
|
|
38310
|
-
return;
|
|
38311
|
-
}
|
|
38312
|
-
const cx = scaled(m.winExt.cx, xNum, xDen);
|
|
38313
|
-
const cy = scaled(m.winExt.cy, yNum, yDen);
|
|
38314
|
-
if (cx === 0 || cy === 0) {
|
|
38315
|
-
return;
|
|
38316
|
-
}
|
|
38317
|
-
m.winExt = { cx, cy };
|
|
38318
|
-
fixIsotropic(m);
|
|
38319
|
-
}
|
|
38320
|
-
function scaleViewportExt(m, xNum, xDen, yNum, yDen) {
|
|
38321
|
-
if (!extentsSettable(m) || !xDen || !yDen) {
|
|
38322
|
-
return;
|
|
38323
|
-
}
|
|
38324
|
-
const cx = scaled(m.vpExt.cx, xNum, xDen);
|
|
38325
|
-
const cy = scaled(m.vpExt.cy, yNum, yDen);
|
|
38326
|
-
if (cx === 0 || cy === 0) {
|
|
38327
|
-
return;
|
|
38328
|
-
}
|
|
38329
|
-
m.vpExt = { cx, cy };
|
|
38330
|
-
fixIsotropic(m);
|
|
38331
|
-
}
|
|
38332
|
-
function applyWmfMapping(rCtx, m, kx, ky, mirrorWidth = 0) {
|
|
38333
|
-
rCtx.wmfLayoutRtl = mirrorWidth > 0;
|
|
38334
|
-
rCtx.useMappingMode = true;
|
|
38335
|
-
rCtx.windowOrg = { x: m.winOrg.x, y: m.winOrg.y };
|
|
38336
|
-
rCtx.windowExt = { cx: m.winExt.cx || 1, cy: m.winExt.cy || 1 };
|
|
38337
|
-
rCtx.viewportOrg = { x: m.vpOrg.x * kx, y: m.vpOrg.y * ky };
|
|
38338
|
-
rCtx.viewportExt = { cx: (m.vpExt.cx || 1) * kx, cy: (m.vpExt.cy || 1) * ky };
|
|
38339
|
-
if (mirrorWidth > 0) {
|
|
38340
|
-
rCtx.viewportOrg.x = mirrorWidth * kx - rCtx.viewportOrg.x;
|
|
38341
|
-
rCtx.viewportExt.cx = -rCtx.viewportExt.cx;
|
|
38342
|
-
}
|
|
38343
|
-
}
|
|
38344
|
-
function scanMappingRecords(view, start) {
|
|
38345
|
-
const out = {
|
|
38346
|
-
mode: null,
|
|
38347
|
-
winExt: null,
|
|
38348
|
-
vpExt: null
|
|
38349
|
-
};
|
|
38350
|
-
let off = start;
|
|
38351
|
-
let guard = 0;
|
|
38352
|
-
while (off + 6 <= view.byteLength && guard++ < 1e6) {
|
|
38353
|
-
const size = view.getUint32(off, true) * 2;
|
|
38354
|
-
const type = view.getUint16(off + 4, true);
|
|
38355
|
-
if (size < 6 || off + size > view.byteLength || type === 0) {
|
|
38356
|
-
break;
|
|
38357
|
-
}
|
|
38358
|
-
const d = off + 6;
|
|
38359
|
-
if (type === 259 && size >= 8 && out.mode === null) {
|
|
38360
|
-
out.mode = view.getUint16(d, true);
|
|
38361
|
-
} else if (type === 524 && size >= 10 && !out.winExt) {
|
|
38362
|
-
out.winExt = { cy: view.getInt16(d, true), cx: view.getInt16(d + 2, true) };
|
|
38363
|
-
} else if (type === 526 && size >= 10 && !out.vpExt) {
|
|
38364
|
-
out.vpExt = { cy: view.getInt16(d, true), cx: view.getInt16(d + 2, true) };
|
|
38365
|
-
}
|
|
38366
|
-
off += size;
|
|
38367
|
-
}
|
|
38368
|
-
return out;
|
|
38369
|
-
}
|
|
38370
|
-
function wmfPlayback(view, header, referenceDpi) {
|
|
38371
|
-
const valid = (v) => typeof v === "number" && Number.isFinite(v) && v > 0 ? v : DEVICE_DPI;
|
|
38372
|
-
const dpi = { x: valid(typeof referenceDpi === "number" ? referenceDpi : referenceDpi?.x), y: valid(typeof referenceDpi === "number" ? referenceDpi : referenceDpi?.y) };
|
|
38373
|
-
const density = referenceDpi === void 0 ? {} : { dpi };
|
|
38374
|
-
const bw = header.boundsRight - header.boundsLeft;
|
|
38375
|
-
const bh = header.boundsBottom - header.boundsTop;
|
|
38376
|
-
if (header.placeable !== false) {
|
|
38377
|
-
const inch = header.unitsPerInch > 0 ? header.unitsPerInch : DEVICE_DPI;
|
|
38378
|
-
const width2 = Math.max(1, Math.round(Math.abs(bw) * dpi.x / inch));
|
|
38379
|
-
const height2 = Math.max(1, Math.round(Math.abs(bh) * dpi.y / inch));
|
|
38380
|
-
return {
|
|
38381
|
-
width: width2,
|
|
38382
|
-
height: height2,
|
|
38383
|
-
mapping: {
|
|
38384
|
-
...density,
|
|
38385
|
-
mode: MM_ANISOTROPIC,
|
|
38386
|
-
winOrg: { x: header.boundsLeft, y: header.boundsTop },
|
|
38387
|
-
winExt: { cx: bw || 1, cy: bh || 1 },
|
|
38388
|
-
vpOrg: { x: 0, y: 0 },
|
|
38389
|
-
vpExt: { cx: width2, cy: height2 }
|
|
38390
|
-
}
|
|
38391
|
-
};
|
|
38392
|
-
}
|
|
38393
|
-
const scan = scanMappingRecords(view, header.headerSize);
|
|
38394
|
-
const scalable = scan.mode === MM_ISOTROPIC || scan.mode === MM_ANISOTROPIC;
|
|
38395
|
-
const ext = scalable && scan.vpExt ? scan.vpExt : scan.winExt;
|
|
38396
|
-
const width = ext ? Math.abs(ext.cx) : Math.abs(bw);
|
|
38397
|
-
const height = ext ? Math.abs(ext.cy) : Math.abs(bh);
|
|
38398
|
-
const w = Math.max(1, width || 1);
|
|
38399
|
-
const h = Math.max(1, height || 1);
|
|
38400
|
-
return {
|
|
38401
|
-
width: w,
|
|
38402
|
-
height: h,
|
|
38403
|
-
mapping: {
|
|
38404
|
-
...density,
|
|
38405
|
-
mode: MM_ANISOTROPIC,
|
|
38406
|
-
winOrg: { x: 0, y: 0 },
|
|
38407
|
-
winExt: { cx: w, cy: h },
|
|
38408
|
-
vpOrg: { x: 0, y: 0 },
|
|
38409
|
-
vpExt: { cx: w, cy: h }
|
|
38410
|
-
}
|
|
38411
|
-
};
|
|
38412
|
-
}
|
|
38413
|
-
|
|
38414
38542
|
// src/wmf-emf-bridge.ts
|
|
38415
38543
|
var EmfRecordWriter = class {
|
|
38416
38544
|
constructor(type, capacity = 64) {
|