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.mjs
CHANGED
|
@@ -19839,11 +19839,16 @@ function recordDeviceFigures(buildPath, device) {
|
|
|
19839
19839
|
const f = fig;
|
|
19840
19840
|
f.curved = true;
|
|
19841
19841
|
const n = f.pts.length;
|
|
19842
|
+
const near = (qx, qy) => Math.abs(qx - f.pts[n - 2]) < 1e-3 && Math.abs(qy - f.pts[n - 1]) < 1e-3;
|
|
19843
|
+
const degenerate = near(dx(c1x, c1y), dy(c1x, c1y)) && near(dx(c2x, c2y), dy(c2x, c2y)) && near(dx(x, y), dy(x, y));
|
|
19842
19844
|
const fix2 = (v) => toPlusFix(v);
|
|
19843
19845
|
const p0x = fix2(f.pts[n - 2]);
|
|
19844
19846
|
const p0y = fix2(f.pts[n - 1]);
|
|
19845
19847
|
f.pts[n - 2] = p0x / 16;
|
|
19846
19848
|
f.pts[n - 1] = p0y / 16;
|
|
19849
|
+
if (degenerate) {
|
|
19850
|
+
(f.splits ?? (f.splits = [])).push({ x: p0x / 16, y: p0y / 16 });
|
|
19851
|
+
}
|
|
19847
19852
|
const out = [];
|
|
19848
19853
|
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))];
|
|
19849
19854
|
flattenBezierGdiplus(ctrl, out);
|
|
@@ -20217,7 +20222,7 @@ function sidePoints(pts, closed, o, pen) {
|
|
|
20217
20222
|
}
|
|
20218
20223
|
return out;
|
|
20219
20224
|
}
|
|
20220
|
-
function dashFigure(pts, closed, pen) {
|
|
20225
|
+
function dashFigure(pts, closed, pen, splits) {
|
|
20221
20226
|
const shorten = pen.dashCap !== 0 ? 2 * pen.half : 0;
|
|
20222
20227
|
const dash = pen.dash.map((v, i) => {
|
|
20223
20228
|
if (i % 2 === 0) {
|
|
@@ -20271,6 +20276,11 @@ function dashFigure(pts, closed, pen) {
|
|
|
20271
20276
|
remaining -= segLen - t0;
|
|
20272
20277
|
if (on && cur) {
|
|
20273
20278
|
cur.push(b);
|
|
20279
|
+
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)) {
|
|
20280
|
+
out.push({ pts: cur, first: curFirst, last: false });
|
|
20281
|
+
cur = [b];
|
|
20282
|
+
curFirst = false;
|
|
20283
|
+
}
|
|
20274
20284
|
}
|
|
20275
20285
|
segLen = 0;
|
|
20276
20286
|
}
|
|
@@ -20400,7 +20410,7 @@ function widenFigures(figures, pen) {
|
|
|
20400
20410
|
bands.push([lo, hi]);
|
|
20401
20411
|
}
|
|
20402
20412
|
const dashPen = pen.inset && closed ? { ...pen, dashOffset: pen.dashOffset * 2 } : pen;
|
|
20403
|
-
const pieces = pen.dash ? dashFigure(pts, closed, dashPen) : [{ pts, first: true, last: true }];
|
|
20413
|
+
const pieces = pen.dash ? dashFigure(pts, closed, dashPen, fig.splits) : [{ pts, first: true, last: true }];
|
|
20404
20414
|
const pieceClosed = !pen.dash && closed;
|
|
20405
20415
|
for (const piece of pieces) {
|
|
20406
20416
|
const pp = cleanPoints(
|
|
@@ -20445,6 +20455,17 @@ function widenFigures(figures, pen) {
|
|
|
20445
20455
|
const startCap = startCapOverride ?? (piece.first && !(pen.dash && closed) ? pen.startCap : pen.dashCap);
|
|
20446
20456
|
const capEnd = capPoints(pp[pp.length - 1], fEnd, o1, o2, endCap, h);
|
|
20447
20457
|
const capStart = capPoints(pp[0], f0, -o2, -o1, startCap, h);
|
|
20458
|
+
if (endCap === 0 && capEnd.length === 2 && left.length > 2 && right.length > 2) {
|
|
20459
|
+
const behind = (c2, q) => (c2.x - q.x) * fEnd.ux + (c2.y - q.y) * fEnd.uy < -1e-9;
|
|
20460
|
+
const lq = left[left.length - 2];
|
|
20461
|
+
const rq = right[1];
|
|
20462
|
+
if (behind(capEnd[0], lq)) {
|
|
20463
|
+
capEnd[0] = { x: lq.x, y: lq.y };
|
|
20464
|
+
}
|
|
20465
|
+
if (behind(capEnd[1], rq)) {
|
|
20466
|
+
capEnd[1] = { x: rq.x, y: rq.y };
|
|
20467
|
+
}
|
|
20468
|
+
}
|
|
20448
20469
|
const poly = [...left.slice(startCap === 1 ? 1 : 0, -1), ...capEnd, ...right.slice(1, -1), ...capStart];
|
|
20449
20470
|
polys.push(poly);
|
|
20450
20471
|
const sign = Math.sign(signedArea(poly));
|
|
@@ -22014,6 +22035,10 @@ var HQ_REDUCTION_STEP_NUDGE = 0.027;
|
|
|
22014
22035
|
function hqReductionStep(reciprocal) {
|
|
22015
22036
|
return Math.floor(reciprocal + 0.5 + HQ_REDUCTION_STEP_NUDGE);
|
|
22016
22037
|
}
|
|
22038
|
+
function hqStartShift(edge) {
|
|
22039
|
+
return edge > 512 ? 0 : edge > 256 ? 2 : edge > 64 ? 1 : 0;
|
|
22040
|
+
}
|
|
22041
|
+
var HQ_START_SHIFT_FRACTION_LIMIT = 0.9375 - 1e-9;
|
|
22017
22042
|
function hqTentCdf(j) {
|
|
22018
22043
|
if (j <= -128) {
|
|
22019
22044
|
return -32768;
|
|
@@ -22113,9 +22138,12 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
22113
22138
|
const fraction2 = rawLeftEdge - Math.floor(rawLeftEdge);
|
|
22114
22139
|
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;
|
|
22115
22140
|
const offsetV = dy > 1e-9 ? Math.round(dy * stepV) : 0;
|
|
22141
|
+
const fractionU = rawLeftEdge - Math.floor(rawLeftEdge);
|
|
22142
|
+
const startShiftU = mirrorU || fractionU >= HQ_START_SHIFT_FRACTION_LIMIT ? 0 : -hqStartShift(rawLeftEdge);
|
|
22143
|
+
const startShiftV = hqStartShift(rawTop);
|
|
22116
22144
|
const filterU = axisFilter(kernel, scaleU, false);
|
|
22117
22145
|
const filterV = axisFilter(kernel, scaleV, false);
|
|
22118
|
-
const tapsFor = (filter, step, offset, origin, from, to, scale, mirror2 = false) => {
|
|
22146
|
+
const tapsFor = (filter, step, offset, origin, from, to, scale, startShift, mirror2 = false) => {
|
|
22119
22147
|
const taps = [];
|
|
22120
22148
|
const farBias = ((step & step - 1) === 0 ? 0 : Math.round(spec.srcW / 170)) + (mirror2 ? mirroredBias(spec, scale, dx > 1e-9) : 0);
|
|
22121
22149
|
const position = (k) => mirror2 ? Math.round((mirroredPixels - k) * step) + farBias : k * step + offset;
|
|
@@ -22128,7 +22156,7 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
22128
22156
|
const originBins = origin * HQ_PHASES;
|
|
22129
22157
|
const wholeBins = Math.abs(originBins - Math.round(originBins)) < 1e-6;
|
|
22130
22158
|
if (scale < 1 && wholeBins) {
|
|
22131
|
-
return hqReductionTaps(cubic, scale, step, position, origin, from, to);
|
|
22159
|
+
return hqReductionTaps(cubic, scale, step, (k) => position(k) + startShift, origin, from, to);
|
|
22132
22160
|
}
|
|
22133
22161
|
const tabulated = cubic && wholeBins;
|
|
22134
22162
|
for (let k = from; k <= to; k++) {
|
|
@@ -22153,8 +22181,8 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
22153
22181
|
}
|
|
22154
22182
|
return taps;
|
|
22155
22183
|
};
|
|
22156
|
-
const colTaps = tapsFor(filterU, stepU, offsetU, spec.srcX, cx0 - xFirst, cx1 - xFirst, scaleU, mirrorU);
|
|
22157
|
-
const rowTaps = tapsFor(filterV, stepV, offsetV, spec.srcY, cy0 - yFirst, cy1 - yFirst, scaleV);
|
|
22184
|
+
const colTaps = tapsFor(filterU, stepU, offsetU, spec.srcX, cx0 - xFirst, cx1 - xFirst, scaleU, startShiftU, mirrorU);
|
|
22185
|
+
const rowTaps = tapsFor(filterV, stepV, offsetV, spec.srcY, cy0 - yFirst, cy1 - yFirst, scaleV, startShiftV);
|
|
22158
22186
|
let rowMin = Infinity;
|
|
22159
22187
|
let rowMax = -Infinity;
|
|
22160
22188
|
for (const t of rowTaps) {
|
|
@@ -22174,11 +22202,19 @@ function resampleHqAxisAligned(rgba, width, height, spec, surface, m, premultOut
|
|
|
22174
22202
|
rowMax = Math.min(height - 1, rowMax);
|
|
22175
22203
|
}
|
|
22176
22204
|
const rows = Math.max(0, rowMax - rowMin + 1);
|
|
22177
|
-
const rowMargin =
|
|
22205
|
+
const rowMargin = Math.abs(scaleV - 1) < 1e-9 ? Infinity : Math.ceil((cubic ? 2 : 1) / Math.min(1, scaleV));
|
|
22178
22206
|
const inter = new Uint8Array(rows * w * 4);
|
|
22179
22207
|
for (let r = 0; r < rows; r++) {
|
|
22180
|
-
|
|
22181
|
-
if (
|
|
22208
|
+
let rowTexel = rowMin + r;
|
|
22209
|
+
if (edge) {
|
|
22210
|
+
if (Number.isFinite(rowMargin)) {
|
|
22211
|
+
rowTexel = wrapTap(rowTexel, Math.max(0, spec.srcY - rowMargin), Math.min(height, spec.srcY + spec.srcH + rowMargin), edge.mirrorY, edge);
|
|
22212
|
+
}
|
|
22213
|
+
if (rowTexel !== OUTSIDE_TRANSPARENT && rowTexel !== OUTSIDE_CLAMP) {
|
|
22214
|
+
rowTexel = wrapTap(rowTexel, 0, height, edge.mirrorY, edge);
|
|
22215
|
+
}
|
|
22216
|
+
}
|
|
22217
|
+
if (rowTexel === OUTSIDE_TRANSPARENT || rowTexel !== OUTSIDE_CLAMP && (rowTexel < spec.srcY - rowMargin || rowTexel > spec.srcY + spec.srcH + rowMargin - 1)) {
|
|
22182
22218
|
continue;
|
|
22183
22219
|
}
|
|
22184
22220
|
const srcRow = rowTexel * width;
|
|
@@ -26641,6 +26677,7 @@ var ceil64 = (x) => floor64(x + 63);
|
|
|
26641
26677
|
var ON_CURVE = 1;
|
|
26642
26678
|
var TOUCH_X = 8;
|
|
26643
26679
|
var STEM_MIN_WIDTH = 16;
|
|
26680
|
+
var STEM_SMALL_SHIFT = 4;
|
|
26644
26681
|
var TOUCH_Y = 16;
|
|
26645
26682
|
var Zone = class _Zone {
|
|
26646
26683
|
constructor(n, endPts = []) {
|
|
@@ -26729,6 +26766,8 @@ var HintedSize = class _HintedSize {
|
|
|
26729
26766
|
this.iupy = false;
|
|
26730
26767
|
/** IUP[x] has run in the current glyph program. */
|
|
26731
26768
|
this.iupx = false;
|
|
26769
|
+
/** Points that belong to a stem pair shifted so far in the glyph program (compatible-width ClearType). */
|
|
26770
|
+
this.stemPoints = /* @__PURE__ */ new Set();
|
|
26732
26771
|
this.count = 0;
|
|
26733
26772
|
this.hintingGlyph = 0;
|
|
26734
26773
|
this.font = font;
|
|
@@ -26809,8 +26848,10 @@ var HintedSize = class _HintedSize {
|
|
|
26809
26848
|
const { advance } = this.font.hMetrics(g);
|
|
26810
26849
|
const res2 = this.loadRecursive(g, 0);
|
|
26811
26850
|
const n = res2.zone.n - 4;
|
|
26812
|
-
const pp1x = res2.zone.curX[n];
|
|
26813
26851
|
const pp2x = res2.zone.curX[n + 1];
|
|
26852
|
+
const pp1x = res2.zone.curX[n];
|
|
26853
|
+
const init = res2.zone.pp1Init ?? pp1x;
|
|
26854
|
+
const rasterShift = pp1x - (init + round64(pp1x - init));
|
|
26814
26855
|
const xs = new Float64Array(n);
|
|
26815
26856
|
const ys = new Float64Array(n);
|
|
26816
26857
|
const onCurve = new Uint8Array(n);
|
|
@@ -26825,6 +26866,7 @@ var HintedSize = class _HintedSize {
|
|
|
26825
26866
|
onCurve,
|
|
26826
26867
|
endPts: res2.zone.endPts,
|
|
26827
26868
|
advance: pp2x - pp1x,
|
|
26869
|
+
rasterShift,
|
|
26828
26870
|
linearAdvance: mulFix(advance, this.xScale),
|
|
26829
26871
|
scanControl: res2.scanControl,
|
|
26830
26872
|
scanSet: res2.scanSet,
|
|
@@ -27003,15 +27045,30 @@ var HintedSize = class _HintedSize {
|
|
|
27003
27045
|
return hinted;
|
|
27004
27046
|
}
|
|
27005
27047
|
if (this.hinting && !metricsFrom) {
|
|
27006
|
-
zone.curX[total] = round64(zone.curX[total]);
|
|
27007
|
-
zone.curX[total + 1] = round64(zone.curX[total + 1]);
|
|
27008
27048
|
this.hintingGlyph = g;
|
|
27049
|
+
this.roundHorizontalPhantoms(zone, total, round64);
|
|
27009
27050
|
this.compatAdvance(zone, total + 1);
|
|
27010
27051
|
zone.curY[total + 2] = round64(zone.curY[total + 2]);
|
|
27011
27052
|
zone.curY[total + 3] = round64(zone.curY[total + 3]);
|
|
27012
27053
|
}
|
|
27054
|
+
zone.pp1Init = zone.curX[total];
|
|
27013
27055
|
return { zone, ...lastScan };
|
|
27014
27056
|
}
|
|
27057
|
+
/**
|
|
27058
|
+
* Places the horizontal phantom points `zone.curX[a]` (left) and `zone.curX[a + 1]` (advance) before the program runs.
|
|
27059
|
+
* GDI's own interpreter leaves the left point where scaling put it and rounds the advance, so `pp2 = pp1 + round(width)`:
|
|
27060
|
+
* Times New Roman Italic < and > (lsb 150 against xMin 39 and 37 units) start 39/64 pixel off the grid and native
|
|
27061
|
+
* GGO_NATIVE shows it from the first instruction on (`prefix-timesi`, 58 prefixes at 11 and 17 px). Every other
|
|
27062
|
+
* interpreter rounds both points.
|
|
27063
|
+
*/
|
|
27064
|
+
roundHorizontalPhantoms(zone, a, round) {
|
|
27065
|
+
if (this.gdiMath && !this.env.clearType) {
|
|
27066
|
+
zone.curX[a + 1] = zone.curX[a] + round64(zone.curX[a + 1] - zone.curX[a]);
|
|
27067
|
+
return;
|
|
27068
|
+
}
|
|
27069
|
+
zone.curX[a] = round(zone.curX[a]);
|
|
27070
|
+
zone.curX[a + 1] = round(zone.curX[a + 1]);
|
|
27071
|
+
}
|
|
27015
27072
|
/** Under compatible-width ClearType the advance phantom point is held at the black-and-white advance. */
|
|
27016
27073
|
compatAdvance(zone, k) {
|
|
27017
27074
|
const bw = this.env.clearType && this.env.compatibleWidths !== false ? this.env.bwAdvance?.(this.hintingGlyph) : void 0;
|
|
@@ -27024,12 +27081,12 @@ var HintedSize = class _HintedSize {
|
|
|
27024
27081
|
const n = zone.n;
|
|
27025
27082
|
if (this.hinting && roundPhantoms) {
|
|
27026
27083
|
const rx = this.env.clearType ? (v) => Math.floor((v + 2) / 4) * 4 : round64;
|
|
27027
|
-
zone
|
|
27028
|
-
zone.curX[n - 3] = rx(zone.curX[n - 3]);
|
|
27084
|
+
this.roundHorizontalPhantoms(zone, n - 4, rx);
|
|
27029
27085
|
this.compatAdvance(zone, n - 3);
|
|
27030
27086
|
zone.curY[n - 2] = round64(zone.curY[n - 2]);
|
|
27031
27087
|
zone.curY[n - 1] = round64(zone.curY[n - 1]);
|
|
27032
27088
|
}
|
|
27089
|
+
zone.pp1Init = zone.curX[n - 4];
|
|
27033
27090
|
if (!this.glyphHinting || instructions.length === 0) {
|
|
27034
27091
|
return { zone, ...this.defaultScan };
|
|
27035
27092
|
}
|
|
@@ -27042,6 +27099,7 @@ var HintedSize = class _HintedSize {
|
|
|
27042
27099
|
this.stack = [];
|
|
27043
27100
|
this.iupy = false;
|
|
27044
27101
|
this.iupx = false;
|
|
27102
|
+
this.stemPoints.clear();
|
|
27045
27103
|
this.computeFuncs();
|
|
27046
27104
|
try {
|
|
27047
27105
|
this.execute(instructions);
|
|
@@ -27374,6 +27432,22 @@ var HintedSize = class _HintedSize {
|
|
|
27374
27432
|
}
|
|
27375
27433
|
return def.sizeTweak;
|
|
27376
27434
|
}
|
|
27435
|
+
/**
|
|
27436
|
+
* GDI+ grayscale text (`shpixX`): which SHPIX shifts along x native honours. Measured with prefix copies of Arial Bold
|
|
27437
|
+
* `y` (40 ppem), Arial `W` (12), Times New Roman Italic `T` (22) and Courier New `R` (22) and the 31,584 real glyphs
|
|
27438
|
+
* (see docs/outstanding-work.md): a shift made by a function call (not a generic per-size helper, `inSizeTweak`)
|
|
27439
|
+
* applies; one made inline in the glyph program applies to a point touched in exactly one direction, or in both once
|
|
27440
|
+
* both IUPs have run, or in neither once both have run when it moves at least 32/64 px (Arial Bold `2`); smaller
|
|
27441
|
+
* shifts of untouched points (Courier New `R` 22) and points touched in both before the IUPs (Times New Roman Italic
|
|
27442
|
+
* `T` 22) are not applied: either costs pixels in the pinned controls.
|
|
27443
|
+
*/
|
|
27444
|
+
plusShpixX(p, amt) {
|
|
27445
|
+
if (!this.env.shpixX) return false;
|
|
27446
|
+
if (this.callFrames.length > 0) return true;
|
|
27447
|
+
const t = this.zp2.tags[p];
|
|
27448
|
+
const tx = (t & TOUCH_X) !== 0, ty = (t & TOUCH_Y) !== 0;
|
|
27449
|
+
return tx !== ty || this.iupx && this.iupy && (tx || Math.abs(amt) >= 32);
|
|
27450
|
+
}
|
|
27377
27451
|
/**
|
|
27378
27452
|
* Whether backward-compatible ClearType (and the GDI+ grayscale text that runs the same interpreter) shifts a point by
|
|
27379
27453
|
* a SHPIX along y: it must be touched in y, and a generic per-size helper function (`isSizeTweak`) stops shifting once
|
|
@@ -27874,7 +27948,7 @@ var HintedSize = class _HintedSize {
|
|
|
27874
27948
|
while (gs.loop > 0) {
|
|
27875
27949
|
const p = this.pop();
|
|
27876
27950
|
if (p >= 0 && p < this.zp2.n) {
|
|
27877
|
-
const keep = !this.ctCompat() || this.inComposite || gs.fvx === 0 && this.shpixAlongY(p) || gs.fvx !== 0 && !this.env.grayscale
|
|
27951
|
+
const keep = !this.ctCompat() || this.inComposite || gs.fvx === 0 && this.shpixAlongY(p) || gs.fvx !== 0 && !this.inSizeTweak() && (!this.env.grayscale || this.plusShpixX(p, amt));
|
|
27878
27952
|
if (keep) {
|
|
27879
27953
|
this.moveZp2(p, dx, dy, true);
|
|
27880
27954
|
}
|
|
@@ -27917,7 +27991,7 @@ var HintedSize = class _HintedSize {
|
|
|
27917
27991
|
}
|
|
27918
27992
|
this.move(this.zp1, p, target - dist);
|
|
27919
27993
|
this.carryFrom(p);
|
|
27920
|
-
this.pairShift(gs.rp0, p);
|
|
27994
|
+
this.pairShift(gs.rp0, p, true);
|
|
27921
27995
|
gs.rp1 = gs.rp0;
|
|
27922
27996
|
gs.rp2 = p;
|
|
27923
27997
|
if (op & 1) {
|
|
@@ -28483,7 +28557,7 @@ var HintedSize = class _HintedSize {
|
|
|
28483
28557
|
}
|
|
28484
28558
|
}
|
|
28485
28559
|
/** A MIRP or MSIRP just placed `p` relative to rp0: if the two are the sides of a stem, shift the stem. */
|
|
28486
|
-
pairShift(rp0, p) {
|
|
28560
|
+
pairShift(rp0, p, black) {
|
|
28487
28561
|
if (!this.widthShiftOn() || this.iupx) {
|
|
28488
28562
|
return;
|
|
28489
28563
|
}
|
|
@@ -28506,6 +28580,18 @@ var HintedSize = class _HintedSize {
|
|
|
28506
28580
|
z.shifted ?? (z.shifted = new Uint8Array(z.n));
|
|
28507
28581
|
const centre = (z.orgX[rp0] + z.orgX[p]) / 2;
|
|
28508
28582
|
const shift = Math.round(centre * (bw / org2 - 1));
|
|
28583
|
+
if (!black && Math.abs(shift) >= STEM_SMALL_SHIFT) {
|
|
28584
|
+
return;
|
|
28585
|
+
}
|
|
28586
|
+
if (this.stemPoints.has(rp0) && Math.abs(shift) >= STEM_SMALL_SHIFT) {
|
|
28587
|
+
z.applied ?? (z.applied = new Float64Array(z.n));
|
|
28588
|
+
const own = Math.round(z.orgX[p] * (bw / org2 - 1)) - (z.carry ? z.carry[p] * (bw - org2) : 0);
|
|
28589
|
+
z.curX[p] += own - z.applied[p];
|
|
28590
|
+
z.applied[p] = own;
|
|
28591
|
+
return;
|
|
28592
|
+
}
|
|
28593
|
+
this.stemPoints.add(rp0);
|
|
28594
|
+
this.stemPoints.add(p);
|
|
28509
28595
|
const offset = bw - org2;
|
|
28510
28596
|
const lo = Math.min(z.curX[rp0], z.curX[p]);
|
|
28511
28597
|
const hi = Math.max(z.curX[rp0], z.curX[p]);
|
|
@@ -28638,7 +28724,7 @@ var HintedSize = class _HintedSize {
|
|
|
28638
28724
|
}
|
|
28639
28725
|
this.move(this.zp1, p, distance - curDist);
|
|
28640
28726
|
this.carryFrom(p);
|
|
28641
|
-
this.pairShift(gs.rp0, p);
|
|
28727
|
+
this.pairShift(gs.rp0, p, (op & 3) === 1);
|
|
28642
28728
|
gs.rp1 = gs.rp0;
|
|
28643
28729
|
if (op & 16) gs.rp0 = p;
|
|
28644
28730
|
gs.rp2 = p;
|
|
@@ -30418,7 +30504,7 @@ var RasterRealizedFont = class {
|
|
|
30418
30504
|
}
|
|
30419
30505
|
};
|
|
30420
30506
|
var RealizedFont = class {
|
|
30421
|
-
constructor(ttf, ppem, ppemX, mode, syntheticBold, syntheticItalic, cellHeight = 0, stretchWidth = 0, gridFit = true, gdiPlus = false, playbackStretched = false) {
|
|
30507
|
+
constructor(ttf, ppem, ppemX, mode, syntheticBold, syntheticItalic, cellHeight = 0, stretchWidth = 0, gridFit = true, gdiPlus = false, playbackStretched = false, plusUnscaled = false) {
|
|
30422
30508
|
this.gdiPlus = gdiPlus;
|
|
30423
30509
|
this.playbackStretched = playbackStretched;
|
|
30424
30510
|
this.rotatedSizes = /* @__PURE__ */ new Map();
|
|
@@ -30474,7 +30560,7 @@ var RealizedFont = class {
|
|
|
30474
30560
|
ttf,
|
|
30475
30561
|
ppemX,
|
|
30476
30562
|
ppem,
|
|
30477
|
-
gdiPlus && mode === "gray" ? { version: 40, grayscale: true, clearType: true, compatibleWidths: false, grayClearType: true } : { version: 35, grayscale: mode !== "mono", gdiArithmetic: !gdiPlus, reportStretched: playbackStretched },
|
|
30563
|
+
gdiPlus && mode === "gray" ? { version: 40, grayscale: true, clearType: true, compatibleWidths: false, grayClearType: true, shpixX: plusUnscaled } : { version: 35, grayscale: mode !== "mono", gdiArithmetic: !gdiPlus, reportStretched: playbackStretched },
|
|
30478
30564
|
gridFit || gdiPlus && mode === "gray"
|
|
30479
30565
|
);
|
|
30480
30566
|
this.hdmx = ppemX === ppem ? ttf.hdmx.get(ppem) : void 0;
|
|
@@ -30557,7 +30643,7 @@ var RealizedFont = class {
|
|
|
30557
30643
|
gdiArithmetic: !this.gdiPlus,
|
|
30558
30644
|
smoothingBit18: !this.gdiPlus && gridFit && clearTypeSmoothsVertically(this.ttf, this.ppem),
|
|
30559
30645
|
reportStretched: this.playbackStretched,
|
|
30560
|
-
bwAdvance: !this.gdiPlus && !this.naturalWidths && gridFit ? (g) => this.advance(g) : void 0
|
|
30646
|
+
bwAdvance: !this.gdiPlus && !this.naturalWidths && gridFit ? (g) => this.advance(g, true) : void 0
|
|
30561
30647
|
}, gridFit));
|
|
30562
30648
|
const u = this.ctSize.hintGlyph(gi);
|
|
30563
30649
|
o = { xs: u.xs, ys: u.ys, onCurve: u.onCurve, endPts: u.endPts };
|
|
@@ -30587,8 +30673,22 @@ var RealizedFont = class {
|
|
|
30587
30673
|
}
|
|
30588
30674
|
return g;
|
|
30589
30675
|
}
|
|
30676
|
+
/** The scaled advance of glyph `index`, rounded once. */
|
|
30677
|
+
linearAdvance(index) {
|
|
30678
|
+
const { advance } = this.ttf.hMetrics(index < this.ttf.numGlyphs ? index : NOTDEF);
|
|
30679
|
+
return Math.floor(advance * this.ppemX / this.ttf.unitsPerEm + 0.5);
|
|
30680
|
+
}
|
|
30681
|
+
/** Whether glyph `index` advances linearly at this size: `head.flags` bit 4 clear, or `LTSH` (an `hdmx` record for the size comes first). */
|
|
30682
|
+
ltshLinear(index) {
|
|
30683
|
+
if (this.gdiPlus || this.ppemX !== this.ppem) return false;
|
|
30684
|
+
const hd = this.hdmx;
|
|
30685
|
+
if (hd && index < hd.length) return false;
|
|
30686
|
+
if ((this.ttf.headFlags & 16) === 0) return true;
|
|
30687
|
+
const lt = this.ttf.ltsh;
|
|
30688
|
+
return !!lt && index < lt.length && lt[index] > 0 && this.ppem >= lt[index];
|
|
30689
|
+
}
|
|
30590
30690
|
/** Integer advance width of glyph `index`, as GetCharWidth32 reports it (GDI+ ClearType: its hinted phantom advance rounded). */
|
|
30591
|
-
advance(index) {
|
|
30691
|
+
advance(index, hintedOnly = false) {
|
|
30592
30692
|
const hd = this.hdmx;
|
|
30593
30693
|
let base;
|
|
30594
30694
|
if (this.stretchWidth > 0) {
|
|
@@ -30596,6 +30696,8 @@ var RealizedFont = class {
|
|
|
30596
30696
|
base = Math.round(advance * this.stretchWidth / this.ttf.xAvgCharWidth);
|
|
30597
30697
|
} else if (!this.gridFit) {
|
|
30598
30698
|
base = this.outline(index).linearAdvance / 64;
|
|
30699
|
+
} else if (!hintedOnly && this.ltshLinear(index)) {
|
|
30700
|
+
base = this.linearAdvance(index);
|
|
30599
30701
|
} else if (this.advanceSize) {
|
|
30600
30702
|
let g = this.advanceOutlines.get(index);
|
|
30601
30703
|
if (!g) {
|
|
@@ -30658,6 +30760,12 @@ var RealizedFont = class {
|
|
|
30658
30760
|
m = roundedRotationMatrix(m, this.ppem);
|
|
30659
30761
|
}
|
|
30660
30762
|
let o = this.mode === "cleartype" && !m && !this.syntheticItalic ? this.ctOutline(index) : src;
|
|
30763
|
+
const shift = this.gdiPlus || m || this.mode === "cleartype" ? 0 : src.rasterShift ?? 0;
|
|
30764
|
+
if (shift !== 0) {
|
|
30765
|
+
const xs = new Float64Array(o.xs.length);
|
|
30766
|
+
for (let i = 0; i < xs.length; i++) xs[i] = o.xs[i] + shift;
|
|
30767
|
+
o = { ...o, xs };
|
|
30768
|
+
}
|
|
30661
30769
|
if (this.syntheticItalic || m || subX || subY) {
|
|
30662
30770
|
const base = o;
|
|
30663
30771
|
const n = base.xs.length;
|
|
@@ -30923,7 +31031,8 @@ var GdiFontCollection = class _GdiFontCollection {
|
|
|
30923
31031
|
spec.width,
|
|
30924
31032
|
!spec.unhinted,
|
|
30925
31033
|
spec.gdiPlus,
|
|
30926
|
-
!!spec.playbackStretch && playbackStretchReacts(best, spec.height, spec.playbackStretch)
|
|
31034
|
+
!!spec.playbackStretch && playbackStretchReacts(best, spec.height, spec.playbackStretch),
|
|
31035
|
+
!!spec.unscaledText
|
|
30927
31036
|
);
|
|
30928
31037
|
tt2.naturalWidths = spec.quality === CLEARTYPE_NATURAL_QUALITY;
|
|
30929
31038
|
return tt2;
|
|
@@ -33805,7 +33914,6 @@ function withoutOutline(spans, path) {
|
|
|
33805
33914
|
var fix = (v) => Math.floor(v * 16 + 0.5) / 16;
|
|
33806
33915
|
var TIE = 1e-6;
|
|
33807
33916
|
var STRIP_TIE = 5e-3;
|
|
33808
|
-
var CONTAINMENT_TIE = 5e-4;
|
|
33809
33917
|
var SLANTED_NEAR = 5e-6;
|
|
33810
33918
|
var CEIL_EPSILON = 1e-9;
|
|
33811
33919
|
function prepareCopies(shape, full, steps) {
|
|
@@ -34015,7 +34123,6 @@ function anisotropicTieStep(g, q, tie, dx, dy, px, py) {
|
|
|
34015
34123
|
const hit = edgeAt(g, scaleX, scaleY, px, py);
|
|
34016
34124
|
const half = g.steps - tie - 0.5;
|
|
34017
34125
|
if (hit?.kind === "slanted") return half;
|
|
34018
|
-
if (hit === null && Math.abs(q - tie) >= CONTAINMENT_TIE) return half;
|
|
34019
34126
|
if (hit === null) return g.steps - tie - (insideCopy(g, scaleX, px, py, scaleY) ? 0 : 1);
|
|
34020
34127
|
let odd = g.steps;
|
|
34021
34128
|
while (odd % 2 === 0) odd /= 2;
|
|
@@ -42514,7 +42621,8 @@ function realizePlusEngineFont(rCtx, font, paint, brushSampler2) {
|
|
|
42514
42621
|
// AntiAlias ignores the font's gasp table (measured: Arial 16 px is
|
|
42515
42622
|
// grayscale there, but single-bit under AntiAliasGridFit, as in GDI).
|
|
42516
42623
|
ignoreGasp: hint === 4,
|
|
42517
|
-
gdiPlus: true
|
|
42624
|
+
gdiPlus: true,
|
|
42625
|
+
unscaledText: m[0] === 1 && m[3] === 1
|
|
42518
42626
|
};
|
|
42519
42627
|
const realized = fonts.realize(spec, rCtx.fontFamilyMap);
|
|
42520
42628
|
if (!realized) {
|