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