emf-converter 4.21.0 → 4.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +134 -26
- package/dist/browser.mjs +134 -26
- package/dist/index.js +134 -26
- package/dist/index.mjs +134 -26
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -19841,11 +19841,16 @@ function recordDeviceFigures(buildPath, device) {
|
|
|
19841
19841
|
const f = fig;
|
|
19842
19842
|
f.curved = true;
|
|
19843
19843
|
const n = f.pts.length;
|
|
19844
|
+
const near = (qx, qy) => Math.abs(qx - f.pts[n - 2]) < 1e-3 && Math.abs(qy - f.pts[n - 1]) < 1e-3;
|
|
19845
|
+
const degenerate = near(dx(c1x, c1y), dy(c1x, c1y)) && near(dx(c2x, c2y), dy(c2x, c2y)) && near(dx(x, y), dy(x, y));
|
|
19844
19846
|
const fix2 = (v) => toPlusFix(v);
|
|
19845
19847
|
const p0x = fix2(f.pts[n - 2]);
|
|
19846
19848
|
const p0y = fix2(f.pts[n - 1]);
|
|
19847
19849
|
f.pts[n - 2] = p0x / 16;
|
|
19848
19850
|
f.pts[n - 1] = p0y / 16;
|
|
19851
|
+
if (degenerate) {
|
|
19852
|
+
(f.splits ?? (f.splits = [])).push({ x: p0x / 16, y: p0y / 16 });
|
|
19853
|
+
}
|
|
19849
19854
|
const out = [];
|
|
19850
19855
|
const ctrl = [p0x, p0y, fix2(dx(c1x, c1y)), fix2(dy(c1x, c1y)), fix2(dx(c2x, c2y)), fix2(dy(c2x, c2y)), fix2(dx(x, y)), fix2(dy(x, y))];
|
|
19851
19856
|
flattenBezierGdiplus(ctrl, out);
|
|
@@ -20219,7 +20224,7 @@ function sidePoints(pts, closed, o, pen) {
|
|
|
20219
20224
|
}
|
|
20220
20225
|
return out;
|
|
20221
20226
|
}
|
|
20222
|
-
function dashFigure(pts, closed, pen) {
|
|
20227
|
+
function dashFigure(pts, closed, pen, splits) {
|
|
20223
20228
|
const shorten = pen.dashCap !== 0 ? 2 * pen.half : 0;
|
|
20224
20229
|
const dash = pen.dash.map((v, i) => {
|
|
20225
20230
|
if (i % 2 === 0) {
|
|
@@ -20273,6 +20278,11 @@ function dashFigure(pts, closed, pen) {
|
|
|
20273
20278
|
remaining -= segLen - t0;
|
|
20274
20279
|
if (on && cur) {
|
|
20275
20280
|
cur.push(b);
|
|
20281
|
+
if (splits && i + 2 < path.length && splits.some((k) => Math.abs(k.x - b.x) < 1e-6 && Math.abs(k.y - b.y) < 1e-6)) {
|
|
20282
|
+
out.push({ pts: cur, first: curFirst, last: false });
|
|
20283
|
+
cur = [b];
|
|
20284
|
+
curFirst = false;
|
|
20285
|
+
}
|
|
20276
20286
|
}
|
|
20277
20287
|
segLen = 0;
|
|
20278
20288
|
}
|
|
@@ -20402,7 +20412,7 @@ function widenFigures(figures, pen) {
|
|
|
20402
20412
|
bands.push([lo, hi]);
|
|
20403
20413
|
}
|
|
20404
20414
|
const dashPen = pen.inset && closed ? { ...pen, dashOffset: pen.dashOffset * 2 } : pen;
|
|
20405
|
-
const pieces = pen.dash ? dashFigure(pts, closed, dashPen) : [{ pts, first: true, last: true }];
|
|
20415
|
+
const pieces = pen.dash ? dashFigure(pts, closed, dashPen, fig.splits) : [{ pts, first: true, last: true }];
|
|
20406
20416
|
const pieceClosed = !pen.dash && closed;
|
|
20407
20417
|
for (const piece of pieces) {
|
|
20408
20418
|
const pp = cleanPoints(
|
|
@@ -20447,6 +20457,17 @@ function widenFigures(figures, pen) {
|
|
|
20447
20457
|
const startCap = startCapOverride ?? (piece.first && !(pen.dash && closed) ? pen.startCap : pen.dashCap);
|
|
20448
20458
|
const capEnd = capPoints(pp[pp.length - 1], fEnd, o1, o2, endCap, h);
|
|
20449
20459
|
const capStart = capPoints(pp[0], f0, -o2, -o1, startCap, h);
|
|
20460
|
+
if (endCap === 0 && capEnd.length === 2 && left.length > 2 && right.length > 2) {
|
|
20461
|
+
const behind = (c2, q) => (c2.x - q.x) * fEnd.ux + (c2.y - q.y) * fEnd.uy < -1e-9;
|
|
20462
|
+
const lq = left[left.length - 2];
|
|
20463
|
+
const rq = right[1];
|
|
20464
|
+
if (behind(capEnd[0], lq)) {
|
|
20465
|
+
capEnd[0] = { x: lq.x, y: lq.y };
|
|
20466
|
+
}
|
|
20467
|
+
if (behind(capEnd[1], rq)) {
|
|
20468
|
+
capEnd[1] = { x: rq.x, y: rq.y };
|
|
20469
|
+
}
|
|
20470
|
+
}
|
|
20450
20471
|
const poly = [...left.slice(startCap === 1 ? 1 : 0, -1), ...capEnd, ...right.slice(1, -1), ...capStart];
|
|
20451
20472
|
polys.push(poly);
|
|
20452
20473
|
const sign = Math.sign(signedArea(poly));
|
|
@@ -22016,6 +22037,10 @@ var HQ_REDUCTION_STEP_NUDGE = 0.027;
|
|
|
22016
22037
|
function hqReductionStep(reciprocal) {
|
|
22017
22038
|
return Math.floor(reciprocal + 0.5 + HQ_REDUCTION_STEP_NUDGE);
|
|
22018
22039
|
}
|
|
22040
|
+
function hqStartShift(edge) {
|
|
22041
|
+
return edge > 512 ? 0 : edge > 256 ? 2 : edge > 64 ? 1 : 0;
|
|
22042
|
+
}
|
|
22043
|
+
var HQ_START_SHIFT_FRACTION_LIMIT = 0.9375 - 1e-9;
|
|
22019
22044
|
function hqTentCdf(j) {
|
|
22020
22045
|
if (j <= -128) {
|
|
22021
22046
|
return -32768;
|
|
@@ -22115,9 +22140,12 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
22115
22140
|
const fraction2 = rawLeftEdge - Math.floor(rawLeftEdge);
|
|
22116
22141
|
const offsetU = mirrorU ? 0 : snapsDown ? Math.round((1 + fraction2) * stepU) : snapsUp ? Math.round((fraction2 - 1) * stepU) : dx > 1e-9 ? Math.round((1 - dx) * stepU) : 0;
|
|
22117
22142
|
const offsetV = dy > 1e-9 ? Math.round(dy * stepV) : 0;
|
|
22143
|
+
const fractionU = rawLeftEdge - Math.floor(rawLeftEdge);
|
|
22144
|
+
const startShiftU = mirrorU || fractionU >= HQ_START_SHIFT_FRACTION_LIMIT ? 0 : -hqStartShift(rawLeftEdge);
|
|
22145
|
+
const startShiftV = hqStartShift(rawTop);
|
|
22118
22146
|
const filterU = axisFilter(kernel, scaleU, false);
|
|
22119
22147
|
const filterV = axisFilter(kernel, scaleV, false);
|
|
22120
|
-
const tapsFor = (filter, step, offset, origin, from, to, scale, mirror2 = false) => {
|
|
22148
|
+
const tapsFor = (filter, step, offset, origin, from, to, scale, startShift, mirror2 = false) => {
|
|
22121
22149
|
const taps = [];
|
|
22122
22150
|
const farBias = ((step & step - 1) === 0 ? 0 : Math.round(spec.srcW / 170)) + (mirror2 ? mirroredBias(spec, scale, dx > 1e-9) : 0);
|
|
22123
22151
|
const position = (k) => mirror2 ? Math.round((mirroredPixels - k) * step) + farBias : k * step + offset;
|
|
@@ -22130,7 +22158,7 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
22130
22158
|
const originBins = origin * HQ_PHASES;
|
|
22131
22159
|
const wholeBins = Math.abs(originBins - Math.round(originBins)) < 1e-6;
|
|
22132
22160
|
if (scale < 1 && wholeBins) {
|
|
22133
|
-
return hqReductionTaps(cubic, scale, step, position, origin, from, to);
|
|
22161
|
+
return hqReductionTaps(cubic, scale, step, (k) => position(k) + startShift, origin, from, to);
|
|
22134
22162
|
}
|
|
22135
22163
|
const tabulated = cubic && wholeBins;
|
|
22136
22164
|
for (let k = from; k <= to; k++) {
|
|
@@ -22155,8 +22183,8 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
22155
22183
|
}
|
|
22156
22184
|
return taps;
|
|
22157
22185
|
};
|
|
22158
|
-
const colTaps = tapsFor(filterU, stepU, offsetU, spec.srcX, cx0 - xFirst, cx1 - xFirst, scaleU, mirrorU);
|
|
22159
|
-
const rowTaps = tapsFor(filterV, stepV, offsetV, spec.srcY, cy0 - yFirst, cy1 - yFirst, scaleV);
|
|
22186
|
+
const colTaps = tapsFor(filterU, stepU, offsetU, spec.srcX, cx0 - xFirst, cx1 - xFirst, scaleU, startShiftU, mirrorU);
|
|
22187
|
+
const rowTaps = tapsFor(filterV, stepV, offsetV, spec.srcY, cy0 - yFirst, cy1 - yFirst, scaleV, startShiftV);
|
|
22160
22188
|
let rowMin = Infinity;
|
|
22161
22189
|
let rowMax = -Infinity;
|
|
22162
22190
|
for (const t of rowTaps) {
|
|
@@ -22176,11 +22204,19 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
22176
22204
|
rowMax = Math.min(height - 1, rowMax);
|
|
22177
22205
|
}
|
|
22178
22206
|
const rows = Math.max(0, rowMax - rowMin + 1);
|
|
22179
|
-
const rowMargin =
|
|
22207
|
+
const rowMargin = Math.abs(scaleV - 1) < 1e-9 ? Infinity : Math.ceil((cubic ? 2 : 1) / Math.min(1, scaleV));
|
|
22180
22208
|
const inter = new Uint8Array(rows * w * 4);
|
|
22181
22209
|
for (let r = 0; r < rows; r++) {
|
|
22182
|
-
|
|
22183
|
-
if (
|
|
22210
|
+
let rowTexel = rowMin + r;
|
|
22211
|
+
if (edge) {
|
|
22212
|
+
if (Number.isFinite(rowMargin)) {
|
|
22213
|
+
rowTexel = wrapTap(rowTexel, Math.max(0, spec.srcY - rowMargin), Math.min(height, spec.srcY + spec.srcH + rowMargin), edge.mirrorY, edge);
|
|
22214
|
+
}
|
|
22215
|
+
if (rowTexel !== OUTSIDE_TRANSPARENT && rowTexel !== OUTSIDE_CLAMP) {
|
|
22216
|
+
rowTexel = wrapTap(rowTexel, 0, height, edge.mirrorY, edge);
|
|
22217
|
+
}
|
|
22218
|
+
}
|
|
22219
|
+
if (rowTexel === OUTSIDE_TRANSPARENT || rowTexel !== OUTSIDE_CLAMP && (rowTexel < spec.srcY - rowMargin || rowTexel > spec.srcY + spec.srcH + rowMargin - 1)) {
|
|
22184
22220
|
continue;
|
|
22185
22221
|
}
|
|
22186
22222
|
const srcRow = rowTexel * width;
|
|
@@ -26643,6 +26679,7 @@ var ceil64 = (x) => floor64(x + 63);
|
|
|
26643
26679
|
var ON_CURVE = 1;
|
|
26644
26680
|
var TOUCH_X = 8;
|
|
26645
26681
|
var STEM_MIN_WIDTH = 16;
|
|
26682
|
+
var STEM_SMALL_SHIFT = 4;
|
|
26646
26683
|
var TOUCH_Y = 16;
|
|
26647
26684
|
var Zone = class _Zone {
|
|
26648
26685
|
constructor(n, endPts = []) {
|
|
@@ -26731,6 +26768,8 @@ var HintedSize = class _HintedSize {
|
|
|
26731
26768
|
this.iupy = false;
|
|
26732
26769
|
/** IUP[x] has run in the current glyph program. */
|
|
26733
26770
|
this.iupx = false;
|
|
26771
|
+
/** Points that belong to a stem pair shifted so far in the glyph program (compatible-width ClearType). */
|
|
26772
|
+
this.stemPoints = /* @__PURE__ */ new Set();
|
|
26734
26773
|
this.count = 0;
|
|
26735
26774
|
this.hintingGlyph = 0;
|
|
26736
26775
|
this.font = font;
|
|
@@ -26811,8 +26850,10 @@ var HintedSize = class _HintedSize {
|
|
|
26811
26850
|
const { advance } = this.font.hMetrics(g);
|
|
26812
26851
|
const res2 = this.loadRecursive(g, 0);
|
|
26813
26852
|
const n = res2.zone.n - 4;
|
|
26814
|
-
const pp1x = res2.zone.curX[n];
|
|
26815
26853
|
const pp2x = res2.zone.curX[n + 1];
|
|
26854
|
+
const pp1x = res2.zone.curX[n];
|
|
26855
|
+
const init = res2.zone.pp1Init ?? pp1x;
|
|
26856
|
+
const rasterShift = pp1x - (init + round64(pp1x - init));
|
|
26816
26857
|
const xs = new Float64Array(n);
|
|
26817
26858
|
const ys = new Float64Array(n);
|
|
26818
26859
|
const onCurve = new Uint8Array(n);
|
|
@@ -26827,6 +26868,7 @@ var HintedSize = class _HintedSize {
|
|
|
26827
26868
|
onCurve,
|
|
26828
26869
|
endPts: res2.zone.endPts,
|
|
26829
26870
|
advance: pp2x - pp1x,
|
|
26871
|
+
rasterShift,
|
|
26830
26872
|
linearAdvance: mulFix(advance, this.xScale),
|
|
26831
26873
|
scanControl: res2.scanControl,
|
|
26832
26874
|
scanSet: res2.scanSet,
|
|
@@ -27005,15 +27047,30 @@ var HintedSize = class _HintedSize {
|
|
|
27005
27047
|
return hinted;
|
|
27006
27048
|
}
|
|
27007
27049
|
if (this.hinting && !metricsFrom) {
|
|
27008
|
-
zone.curX[total] = round64(zone.curX[total]);
|
|
27009
|
-
zone.curX[total + 1] = round64(zone.curX[total + 1]);
|
|
27010
27050
|
this.hintingGlyph = g;
|
|
27051
|
+
this.roundHorizontalPhantoms(zone, total, round64);
|
|
27011
27052
|
this.compatAdvance(zone, total + 1);
|
|
27012
27053
|
zone.curY[total + 2] = round64(zone.curY[total + 2]);
|
|
27013
27054
|
zone.curY[total + 3] = round64(zone.curY[total + 3]);
|
|
27014
27055
|
}
|
|
27056
|
+
zone.pp1Init = zone.curX[total];
|
|
27015
27057
|
return { zone, ...lastScan };
|
|
27016
27058
|
}
|
|
27059
|
+
/**
|
|
27060
|
+
* Places the horizontal phantom points `zone.curX[a]` (left) and `zone.curX[a + 1]` (advance) before the program runs.
|
|
27061
|
+
* GDI's own interpreter leaves the left point where scaling put it and rounds the advance, so `pp2 = pp1 + round(width)`:
|
|
27062
|
+
* Times New Roman Italic < and > (lsb 150 against xMin 39 and 37 units) start 39/64 pixel off the grid and native
|
|
27063
|
+
* GGO_NATIVE shows it from the first instruction on (`prefix-timesi`, 58 prefixes at 11 and 17 px). Every other
|
|
27064
|
+
* interpreter rounds both points.
|
|
27065
|
+
*/
|
|
27066
|
+
roundHorizontalPhantoms(zone, a, round) {
|
|
27067
|
+
if (this.gdiMath && !this.env.clearType) {
|
|
27068
|
+
zone.curX[a + 1] = zone.curX[a] + round64(zone.curX[a + 1] - zone.curX[a]);
|
|
27069
|
+
return;
|
|
27070
|
+
}
|
|
27071
|
+
zone.curX[a] = round(zone.curX[a]);
|
|
27072
|
+
zone.curX[a + 1] = round(zone.curX[a + 1]);
|
|
27073
|
+
}
|
|
27017
27074
|
/** Under compatible-width ClearType the advance phantom point is held at the black-and-white advance. */
|
|
27018
27075
|
compatAdvance(zone, k) {
|
|
27019
27076
|
const bw = this.env.clearType && this.env.compatibleWidths !== false ? this.env.bwAdvance?.(this.hintingGlyph) : void 0;
|
|
@@ -27026,12 +27083,12 @@ var HintedSize = class _HintedSize {
|
|
|
27026
27083
|
const n = zone.n;
|
|
27027
27084
|
if (this.hinting && roundPhantoms) {
|
|
27028
27085
|
const rx = this.env.clearType ? (v) => Math.floor((v + 2) / 4) * 4 : round64;
|
|
27029
|
-
zone
|
|
27030
|
-
zone.curX[n - 3] = rx(zone.curX[n - 3]);
|
|
27086
|
+
this.roundHorizontalPhantoms(zone, n - 4, rx);
|
|
27031
27087
|
this.compatAdvance(zone, n - 3);
|
|
27032
27088
|
zone.curY[n - 2] = round64(zone.curY[n - 2]);
|
|
27033
27089
|
zone.curY[n - 1] = round64(zone.curY[n - 1]);
|
|
27034
27090
|
}
|
|
27091
|
+
zone.pp1Init = zone.curX[n - 4];
|
|
27035
27092
|
if (!this.glyphHinting || instructions.length === 0) {
|
|
27036
27093
|
return { zone, ...this.defaultScan };
|
|
27037
27094
|
}
|
|
@@ -27044,6 +27101,7 @@ var HintedSize = class _HintedSize {
|
|
|
27044
27101
|
this.stack = [];
|
|
27045
27102
|
this.iupy = false;
|
|
27046
27103
|
this.iupx = false;
|
|
27104
|
+
this.stemPoints.clear();
|
|
27047
27105
|
this.computeFuncs();
|
|
27048
27106
|
try {
|
|
27049
27107
|
this.execute(instructions);
|
|
@@ -27376,6 +27434,22 @@ var HintedSize = class _HintedSize {
|
|
|
27376
27434
|
}
|
|
27377
27435
|
return def.sizeTweak;
|
|
27378
27436
|
}
|
|
27437
|
+
/**
|
|
27438
|
+
* GDI+ grayscale text (`shpixX`): which SHPIX shifts along x native honours. Measured with prefix copies of Arial Bold
|
|
27439
|
+
* `y` (40 ppem), Arial `W` (12), Times New Roman Italic `T` (22) and Courier New `R` (22) and the 31,584 real glyphs
|
|
27440
|
+
* (see docs/outstanding-work.md): a shift made by a function call (not a generic per-size helper, `inSizeTweak`)
|
|
27441
|
+
* applies; one made inline in the glyph program applies to a point touched in exactly one direction, or in both once
|
|
27442
|
+
* both IUPs have run, or in neither once both have run when it moves at least 32/64 px (Arial Bold `2`); smaller
|
|
27443
|
+
* shifts of untouched points (Courier New `R` 22) and points touched in both before the IUPs (Times New Roman Italic
|
|
27444
|
+
* `T` 22) are not applied: either costs pixels in the pinned controls.
|
|
27445
|
+
*/
|
|
27446
|
+
plusShpixX(p, amt) {
|
|
27447
|
+
if (!this.env.shpixX) return false;
|
|
27448
|
+
if (this.callFrames.length > 0) return true;
|
|
27449
|
+
const t = this.zp2.tags[p];
|
|
27450
|
+
const tx = (t & TOUCH_X) !== 0, ty = (t & TOUCH_Y) !== 0;
|
|
27451
|
+
return tx !== ty || this.iupx && this.iupy && (tx || Math.abs(amt) >= 32);
|
|
27452
|
+
}
|
|
27379
27453
|
/**
|
|
27380
27454
|
* Whether backward-compatible ClearType (and the GDI+ grayscale text that runs the same interpreter) shifts a point by
|
|
27381
27455
|
* a SHPIX along y: it must be touched in y, and a generic per-size helper function (`isSizeTweak`) stops shifting once
|
|
@@ -27876,7 +27950,7 @@ var HintedSize = class _HintedSize {
|
|
|
27876
27950
|
while (gs.loop > 0) {
|
|
27877
27951
|
const p = this.pop();
|
|
27878
27952
|
if (p >= 0 && p < this.zp2.n) {
|
|
27879
|
-
const keep = !this.ctCompat() || this.inComposite || gs.fvx === 0 && this.shpixAlongY(p) || gs.fvx !== 0 && !this.env.grayscale
|
|
27953
|
+
const keep = !this.ctCompat() || this.inComposite || gs.fvx === 0 && this.shpixAlongY(p) || gs.fvx !== 0 && !this.inSizeTweak() && (!this.env.grayscale || this.plusShpixX(p, amt));
|
|
27880
27954
|
if (keep) {
|
|
27881
27955
|
this.moveZp2(p, dx, dy, true);
|
|
27882
27956
|
}
|
|
@@ -27919,7 +27993,7 @@ var HintedSize = class _HintedSize {
|
|
|
27919
27993
|
}
|
|
27920
27994
|
this.move(this.zp1, p, target - dist);
|
|
27921
27995
|
this.carryFrom(p);
|
|
27922
|
-
this.pairShift(gs.rp0, p);
|
|
27996
|
+
this.pairShift(gs.rp0, p, true);
|
|
27923
27997
|
gs.rp1 = gs.rp0;
|
|
27924
27998
|
gs.rp2 = p;
|
|
27925
27999
|
if (op & 1) {
|
|
@@ -28485,7 +28559,7 @@ var HintedSize = class _HintedSize {
|
|
|
28485
28559
|
}
|
|
28486
28560
|
}
|
|
28487
28561
|
/** A MIRP or MSIRP just placed `p` relative to rp0: if the two are the sides of a stem, shift the stem. */
|
|
28488
|
-
pairShift(rp0, p) {
|
|
28562
|
+
pairShift(rp0, p, black) {
|
|
28489
28563
|
if (!this.widthShiftOn() || this.iupx) {
|
|
28490
28564
|
return;
|
|
28491
28565
|
}
|
|
@@ -28508,6 +28582,18 @@ var HintedSize = class _HintedSize {
|
|
|
28508
28582
|
z.shifted ?? (z.shifted = new Uint8Array(z.n));
|
|
28509
28583
|
const centre = (z.orgX[rp0] + z.orgX[p]) / 2;
|
|
28510
28584
|
const shift = Math.round(centre * (bw / org2 - 1));
|
|
28585
|
+
if (!black && Math.abs(shift) >= STEM_SMALL_SHIFT) {
|
|
28586
|
+
return;
|
|
28587
|
+
}
|
|
28588
|
+
if (this.stemPoints.has(rp0) && Math.abs(shift) >= STEM_SMALL_SHIFT) {
|
|
28589
|
+
z.applied ?? (z.applied = new Float64Array(z.n));
|
|
28590
|
+
const own = Math.round(z.orgX[p] * (bw / org2 - 1)) - (z.carry ? z.carry[p] * (bw - org2) : 0);
|
|
28591
|
+
z.curX[p] += own - z.applied[p];
|
|
28592
|
+
z.applied[p] = own;
|
|
28593
|
+
return;
|
|
28594
|
+
}
|
|
28595
|
+
this.stemPoints.add(rp0);
|
|
28596
|
+
this.stemPoints.add(p);
|
|
28511
28597
|
const offset = bw - org2;
|
|
28512
28598
|
const lo = Math.min(z.curX[rp0], z.curX[p]);
|
|
28513
28599
|
const hi = Math.max(z.curX[rp0], z.curX[p]);
|
|
@@ -28640,7 +28726,7 @@ var HintedSize = class _HintedSize {
|
|
|
28640
28726
|
}
|
|
28641
28727
|
this.move(this.zp1, p, distance - curDist);
|
|
28642
28728
|
this.carryFrom(p);
|
|
28643
|
-
this.pairShift(gs.rp0, p);
|
|
28729
|
+
this.pairShift(gs.rp0, p, (op & 3) === 1);
|
|
28644
28730
|
gs.rp1 = gs.rp0;
|
|
28645
28731
|
if (op & 16) gs.rp0 = p;
|
|
28646
28732
|
gs.rp2 = p;
|
|
@@ -30420,7 +30506,7 @@ var RasterRealizedFont = class {
|
|
|
30420
30506
|
}
|
|
30421
30507
|
};
|
|
30422
30508
|
var RealizedFont = class {
|
|
30423
|
-
constructor(ttf, ppem, ppemX, mode, syntheticBold, syntheticItalic, cellHeight = 0, stretchWidth = 0, gridFit = true, gdiPlus = false, playbackStretched = false) {
|
|
30509
|
+
constructor(ttf, ppem, ppemX, mode, syntheticBold, syntheticItalic, cellHeight = 0, stretchWidth = 0, gridFit = true, gdiPlus = false, playbackStretched = false, plusUnscaled = false) {
|
|
30424
30510
|
this.gdiPlus = gdiPlus;
|
|
30425
30511
|
this.playbackStretched = playbackStretched;
|
|
30426
30512
|
this.rotatedSizes = /* @__PURE__ */ new Map();
|
|
@@ -30476,7 +30562,7 @@ var RealizedFont = class {
|
|
|
30476
30562
|
ttf,
|
|
30477
30563
|
ppemX,
|
|
30478
30564
|
ppem,
|
|
30479
|
-
gdiPlus && mode === "gray" ? { version: 40, grayscale: true, clearType: true, compatibleWidths: false, grayClearType: true } : { version: 35, grayscale: mode !== "mono", gdiArithmetic: !gdiPlus, reportStretched: playbackStretched },
|
|
30565
|
+
gdiPlus && mode === "gray" ? { version: 40, grayscale: true, clearType: true, compatibleWidths: false, grayClearType: true, shpixX: plusUnscaled } : { version: 35, grayscale: mode !== "mono", gdiArithmetic: !gdiPlus, reportStretched: playbackStretched },
|
|
30480
30566
|
gridFit || gdiPlus && mode === "gray"
|
|
30481
30567
|
);
|
|
30482
30568
|
this.hdmx = ppemX === ppem ? ttf.hdmx.get(ppem) : void 0;
|
|
@@ -30559,7 +30645,7 @@ var RealizedFont = class {
|
|
|
30559
30645
|
gdiArithmetic: !this.gdiPlus,
|
|
30560
30646
|
smoothingBit18: !this.gdiPlus && gridFit && clearTypeSmoothsVertically(this.ttf, this.ppem),
|
|
30561
30647
|
reportStretched: this.playbackStretched,
|
|
30562
|
-
bwAdvance: !this.gdiPlus && !this.naturalWidths && gridFit ? (g) => this.advance(g) : void 0
|
|
30648
|
+
bwAdvance: !this.gdiPlus && !this.naturalWidths && gridFit ? (g) => this.advance(g, true) : void 0
|
|
30563
30649
|
}, gridFit));
|
|
30564
30650
|
const u = this.ctSize.hintGlyph(gi);
|
|
30565
30651
|
o = { xs: u.xs, ys: u.ys, onCurve: u.onCurve, endPts: u.endPts };
|
|
@@ -30589,8 +30675,22 @@ var RealizedFont = class {
|
|
|
30589
30675
|
}
|
|
30590
30676
|
return g;
|
|
30591
30677
|
}
|
|
30678
|
+
/** The scaled advance of glyph `index`, rounded once. */
|
|
30679
|
+
linearAdvance(index) {
|
|
30680
|
+
const { advance } = this.ttf.hMetrics(index < this.ttf.numGlyphs ? index : NOTDEF);
|
|
30681
|
+
return Math.floor(advance * this.ppemX / this.ttf.unitsPerEm + 0.5);
|
|
30682
|
+
}
|
|
30683
|
+
/** Whether glyph `index` advances linearly at this size: `head.flags` bit 4 clear, or `LTSH` (an `hdmx` record for the size comes first). */
|
|
30684
|
+
ltshLinear(index) {
|
|
30685
|
+
if (this.gdiPlus || this.ppemX !== this.ppem) return false;
|
|
30686
|
+
const hd = this.hdmx;
|
|
30687
|
+
if (hd && index < hd.length) return false;
|
|
30688
|
+
if ((this.ttf.headFlags & 16) === 0) return true;
|
|
30689
|
+
const lt = this.ttf.ltsh;
|
|
30690
|
+
return !!lt && index < lt.length && lt[index] > 0 && this.ppem >= lt[index];
|
|
30691
|
+
}
|
|
30592
30692
|
/** Integer advance width of glyph `index`, as GetCharWidth32 reports it (GDI+ ClearType: its hinted phantom advance rounded). */
|
|
30593
|
-
advance(index) {
|
|
30693
|
+
advance(index, hintedOnly = false) {
|
|
30594
30694
|
const hd = this.hdmx;
|
|
30595
30695
|
let base;
|
|
30596
30696
|
if (this.stretchWidth > 0) {
|
|
@@ -30598,6 +30698,8 @@ var RealizedFont = class {
|
|
|
30598
30698
|
base = Math.round(advance * this.stretchWidth / this.ttf.xAvgCharWidth);
|
|
30599
30699
|
} else if (!this.gridFit) {
|
|
30600
30700
|
base = this.outline(index).linearAdvance / 64;
|
|
30701
|
+
} else if (!hintedOnly && this.ltshLinear(index)) {
|
|
30702
|
+
base = this.linearAdvance(index);
|
|
30601
30703
|
} else if (this.advanceSize) {
|
|
30602
30704
|
let g = this.advanceOutlines.get(index);
|
|
30603
30705
|
if (!g) {
|
|
@@ -30660,6 +30762,12 @@ var RealizedFont = class {
|
|
|
30660
30762
|
m = roundedRotationMatrix(m, this.ppem);
|
|
30661
30763
|
}
|
|
30662
30764
|
let o = this.mode === "cleartype" && !m && !this.syntheticItalic ? this.ctOutline(index) : src;
|
|
30765
|
+
const shift = this.gdiPlus || m || this.mode === "cleartype" ? 0 : src.rasterShift ?? 0;
|
|
30766
|
+
if (shift !== 0) {
|
|
30767
|
+
const xs = new Float64Array(o.xs.length);
|
|
30768
|
+
for (let i = 0; i < xs.length; i++) xs[i] = o.xs[i] + shift;
|
|
30769
|
+
o = { ...o, xs };
|
|
30770
|
+
}
|
|
30663
30771
|
if (this.syntheticItalic || m || subX || subY) {
|
|
30664
30772
|
const base = o;
|
|
30665
30773
|
const n = base.xs.length;
|
|
@@ -30925,7 +31033,8 @@ var GdiFontCollection = class _GdiFontCollection {
|
|
|
30925
31033
|
spec.width,
|
|
30926
31034
|
!spec.unhinted,
|
|
30927
31035
|
spec.gdiPlus,
|
|
30928
|
-
!!spec.playbackStretch && playbackStretchReacts(best, spec.height, spec.playbackStretch)
|
|
31036
|
+
!!spec.playbackStretch && playbackStretchReacts(best, spec.height, spec.playbackStretch),
|
|
31037
|
+
!!spec.unscaledText
|
|
30929
31038
|
);
|
|
30930
31039
|
tt2.naturalWidths = spec.quality === CLEARTYPE_NATURAL_QUALITY;
|
|
30931
31040
|
return tt2;
|
|
@@ -33807,7 +33916,6 @@ function withoutOutline(spans, path) {
|
|
|
33807
33916
|
var fix = (v) => Math.floor(v * 16 + 0.5) / 16;
|
|
33808
33917
|
var TIE = 1e-6;
|
|
33809
33918
|
var STRIP_TIE = 5e-3;
|
|
33810
|
-
var CONTAINMENT_TIE = 5e-4;
|
|
33811
33919
|
var SLANTED_NEAR = 5e-6;
|
|
33812
33920
|
var CEIL_EPSILON = 1e-9;
|
|
33813
33921
|
function prepareCopies(shape, full, steps) {
|
|
@@ -34017,7 +34125,6 @@ function anisotropicTieStep(g, q, tie, dx, dy, px, py) {
|
|
|
34017
34125
|
const hit = edgeAt(g, scaleX, scaleY, px, py);
|
|
34018
34126
|
const half = g.steps - tie - 0.5;
|
|
34019
34127
|
if (hit?.kind === "slanted") return half;
|
|
34020
|
-
if (hit === null && Math.abs(q - tie) >= CONTAINMENT_TIE) return half;
|
|
34021
34128
|
if (hit === null) return g.steps - tie - (insideCopy(g, scaleX, px, py, scaleY) ? 0 : 1);
|
|
34022
34129
|
let odd = g.steps;
|
|
34023
34130
|
while (odd % 2 === 0) odd /= 2;
|
|
@@ -42516,7 +42623,8 @@ function realizePlusEngineFont(rCtx, font, paint, brushSampler2) {
|
|
|
42516
42623
|
// AntiAlias ignores the font's gasp table (measured: Arial 16 px is
|
|
42517
42624
|
// grayscale there, but single-bit under AntiAliasGridFit, as in GDI).
|
|
42518
42625
|
ignoreGasp: hint === 4,
|
|
42519
|
-
gdiPlus: true
|
|
42626
|
+
gdiPlus: true,
|
|
42627
|
+
unscaledText: m[0] === 1 && m[3] === 1
|
|
42520
42628
|
};
|
|
42521
42629
|
const realized = fonts.realize(spec, rCtx.fontFamilyMap);
|
|
42522
42630
|
if (!realized) {
|