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