@weasel-js/text 1.15.0 → 1.15.1
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/{chunk-ZNSU5C43.js → chunk-WUFANHTE.js} +60 -28
- package/dist/chunk-WUFANHTE.js.map +1 -0
- package/dist/index.d.ts +9 -6
- package/dist/index.js +2 -2
- package/dist/{test-seams-Ck0mfD3U.d.ts → test-seams-B2R_EedN.d.ts} +3 -1
- package/dist/test-seams.d.ts +1 -1
- package/dist/test-seams.js +1 -1
- package/package.json +6 -6
- package/dist/chunk-ZNSU5C43.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isSolidPaint, resolveFill, resolveScreenLength, fillHasInk, strokeHasInk, paintKey, strokeKey } from '@weasel-js/paint';
|
|
2
|
-
import { cssFamilyName, cachedFontVariant, syntheticBoldGrowth, glyphOutline, faceMetricsOf, glyphGeneration, faceGeneration, metricsOf, warnNoMetrics, resolveColorCluster, glyphIn, resolveGlyph } from '@weasel-js/font';
|
|
2
|
+
import { cssFamilyName, cachedFontVariant, syntheticBoldGrowth, glyphOutline, faceMetricsOf, glyphGeneration, faceGeneration, metricsOf, warnNoMetrics, resolveColorCluster, glyphIn, resolveGlyph, outlineMetrics } from '@weasel-js/font';
|
|
3
3
|
import { mergeRegion, growRegion, pathToD, pathFromD } from '@weasel-js/geom';
|
|
4
4
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -134,16 +134,20 @@ function registerShaper(shaper) {
|
|
|
134
134
|
function registeredShaper() {
|
|
135
135
|
return registered;
|
|
136
136
|
}
|
|
137
|
-
var
|
|
138
|
-
function
|
|
139
|
-
const
|
|
137
|
+
var embeddingOf = /* @__PURE__ */ new WeakMap();
|
|
138
|
+
function shapingFace(resolved2) {
|
|
139
|
+
const { family, weight, style } = resolved2.resolved;
|
|
140
|
+
const face = resolved2.outlineFace ?? (resolved2.source === "outline" ? void 0 : outlineMetrics(family, weight, style === "italic" ? "italic" : "normal"));
|
|
140
141
|
if (!face) return null;
|
|
141
|
-
let
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
let embedding = embeddingOf.get(face);
|
|
143
|
+
if (embedding === void 0) {
|
|
144
|
+
embedding = face.embedding?.() ?? null;
|
|
145
|
+
embeddingOf.set(face, embedding);
|
|
145
146
|
}
|
|
146
|
-
return
|
|
147
|
+
return embedding;
|
|
148
|
+
}
|
|
149
|
+
function shapeableBytes(resolved2) {
|
|
150
|
+
return shapingFace(resolved2)?.sfnt ?? null;
|
|
147
151
|
}
|
|
148
152
|
function shapesWithFeature(family, weight, style, tag, shaper = registered) {
|
|
149
153
|
if (shaper === null) return false;
|
|
@@ -1122,19 +1126,23 @@ function graphemeCount(text) {
|
|
|
1122
1126
|
var NOTHING_DRAWN = Object.freeze({ d: null, key: "", glyphs: Object.freeze([]), rtl: false, text: "" });
|
|
1123
1127
|
var COVERED = Object.freeze({ cluster: NOTHING_DRAWN, advance: 0 });
|
|
1124
1128
|
var slotsOf = /* @__PURE__ */ new WeakMap();
|
|
1129
|
+
var atlasSlotsOf = /* @__PURE__ */ new WeakMap();
|
|
1125
1130
|
var fmt = (v) => String(Math.round(v * 1e5) / 1e5);
|
|
1126
1131
|
function shapeRun(run, resolved2, shaper) {
|
|
1127
1132
|
if (shaper === null) return null;
|
|
1128
|
-
const
|
|
1129
|
-
if (
|
|
1133
|
+
const embedding = shapingFace(resolved2);
|
|
1134
|
+
if (embedding === null) return null;
|
|
1135
|
+
const face = embedding.sfnt;
|
|
1130
1136
|
const glyphs = shaper.shape(face, run.text, run.fontFeatures, run.lang);
|
|
1131
|
-
|
|
1137
|
+
const cache2 = resolved2.source === "outline" ? slotsOf : atlasSlotsOf;
|
|
1138
|
+
let slots2 = cache2.get(glyphs);
|
|
1132
1139
|
if (slots2) return slots2;
|
|
1133
|
-
|
|
1134
|
-
|
|
1140
|
+
const plain2 = resolved2.source === "outline" ? null : (cp2) => embedding.glyphIndexOf(cp2);
|
|
1141
|
+
slots2 = slotsFor(shaper, face, run.text, glyphs, plain2);
|
|
1142
|
+
cache2.set(glyphs, slots2);
|
|
1135
1143
|
return slots2;
|
|
1136
1144
|
}
|
|
1137
|
-
function slotsFor(shaper, face, text, glyphs) {
|
|
1145
|
+
function slotsFor(shaper, face, text, glyphs, plain2) {
|
|
1138
1146
|
const slots2 = new Array(text.length);
|
|
1139
1147
|
const ends = graphemeEnds(text);
|
|
1140
1148
|
let g = 0;
|
|
@@ -1147,7 +1155,7 @@ function slotsFor(shaper, face, text, glyphs) {
|
|
|
1147
1155
|
while (g < ends.length && ends[g] <= start2) g++;
|
|
1148
1156
|
let inner = 0;
|
|
1149
1157
|
for (let k = g; k < ends.length && ends[k] < end; k++) inner++;
|
|
1150
|
-
if (!holdsNotdef(glyphs, i, j)) {
|
|
1158
|
+
if (!holdsNotdef(glyphs, i, j) && !(plain2 && isPlain(glyphs[i], j - i, text, start2, end, plain2))) {
|
|
1151
1159
|
const total = advanceOf(glyphs, i, j);
|
|
1152
1160
|
const share = total / (inner + 1);
|
|
1153
1161
|
const shift = glyphs[i].rtl ? share - total : 0;
|
|
@@ -1163,6 +1171,11 @@ function slotsFor(shaper, face, text, glyphs) {
|
|
|
1163
1171
|
}
|
|
1164
1172
|
return slots2;
|
|
1165
1173
|
}
|
|
1174
|
+
function isPlain(first, count, text, start2, end, plain2) {
|
|
1175
|
+
if (count !== 1 || first.dx !== 0 || first.dy !== 0) return false;
|
|
1176
|
+
const cp2 = text.codePointAt(start2);
|
|
1177
|
+
return end - start2 === (cp2 > 65535 ? 2 : 1) && plain2(cp2) === first.gid;
|
|
1178
|
+
}
|
|
1166
1179
|
function advanceOf(glyphs, from, to) {
|
|
1167
1180
|
let sum2 = 0;
|
|
1168
1181
|
for (let k = from; k < to; k++) sum2 += glyphs[k].advance;
|
|
@@ -1180,7 +1193,7 @@ function clusterSlot(shaper, face, glyphs, from, to, text, shift, advance) {
|
|
|
1180
1193
|
for (let k = from; k < to; k++) {
|
|
1181
1194
|
const g = glyphs[k];
|
|
1182
1195
|
const x = pen + g.dx, y = g.dy;
|
|
1183
|
-
placed2.push({ gid: g.gid, x, y });
|
|
1196
|
+
placed2.push({ gid: g.gid, x, y, advance: g.advance });
|
|
1184
1197
|
d += shaper.glyphD(face, g.gid, x, y) ?? "";
|
|
1185
1198
|
key += `${k === from ? "" : ";"}${g.gid}${x === 0 && y === 0 ? "" : `@${fmt(x)},${fmt(y)}`}`;
|
|
1186
1199
|
pen += g.advance;
|
|
@@ -1359,7 +1372,7 @@ function mirrorEntries(entries2, levels, mirror, runs) {
|
|
|
1359
1372
|
const odd = levels[pos] % 2 === 1;
|
|
1360
1373
|
if (entry.shaped !== null && entry.shaped.rtl !== odd) {
|
|
1361
1374
|
const flipped = mirror(entry.cp);
|
|
1362
|
-
if (flipped !== null && flipped !== entry.cp) entry =
|
|
1375
|
+
if (flipped !== null && flipped !== entry.cp) entry = unshaped(entry, runs[entry.run]);
|
|
1363
1376
|
}
|
|
1364
1377
|
if (!odd) return entry;
|
|
1365
1378
|
if (entry.shaped !== null) return entry;
|
|
@@ -1372,6 +1385,11 @@ function mirrorEntries(entries2, levels, mirror, runs) {
|
|
|
1372
1385
|
return { ...entry, cp: cp2, resolved: hit.resolved, metrics: hit.metrics, font: hit.font, glyph: hit.glyph };
|
|
1373
1386
|
});
|
|
1374
1387
|
}
|
|
1388
|
+
function unshaped(entry, run) {
|
|
1389
|
+
if (entry.resolved.source === "outline") return { ...entry, shaped: null };
|
|
1390
|
+
const hit = resolveGlyph(entry.resolved, run.fontFamily, run.fontWeight, run.fontStyle, entry.cp, false);
|
|
1391
|
+
return hit ? { ...entry, shaped: null, resolved: hit.resolved, metrics: hit.metrics, font: hit.font, glyph: hit.glyph } : { ...entry, shaped: null };
|
|
1392
|
+
}
|
|
1375
1393
|
|
|
1376
1394
|
// src/layout/lineBreak/wrapLines.ts
|
|
1377
1395
|
var hangs = (cp2) => cp2 === 32 || cp2 === 9;
|
|
@@ -1876,9 +1894,9 @@ function takeGroups(out) {
|
|
|
1876
1894
|
}
|
|
1877
1895
|
|
|
1878
1896
|
// src/layout/paintRuns.ts
|
|
1879
|
-
function glyphOutlineD(g, run, minSize) {
|
|
1897
|
+
function glyphOutlineD(g, run, minSize, ungated = false) {
|
|
1880
1898
|
const outlineOnly = g.resolved.source === "outline";
|
|
1881
|
-
if (!outlineOnly) {
|
|
1899
|
+
if (!outlineOnly && !ungated) {
|
|
1882
1900
|
if (minSize === void 0) return null;
|
|
1883
1901
|
if (run.fontSize < minSize && !strokeHasInk(run.stroke)) return null;
|
|
1884
1902
|
}
|
|
@@ -1897,6 +1915,14 @@ function faceOutlineD(g) {
|
|
|
1897
1915
|
if (g.resolved.source !== "outline" && g.glyph === null) return null;
|
|
1898
1916
|
return glyphOutline(family, weight, style, g.cp);
|
|
1899
1917
|
}
|
|
1918
|
+
function shapedQuadGlyph(g) {
|
|
1919
|
+
const face = g.resolved.dynamicFace;
|
|
1920
|
+
const shaped = g.shaped;
|
|
1921
|
+
if (!face || shaped.d === null) return null;
|
|
1922
|
+
const glyph = face.requestShaped(shaped.key, shaped.d);
|
|
1923
|
+
if (!glyph || glyph.page < 0 || glyph.width === 0) return null;
|
|
1924
|
+
return { ...g, font: face.font, glyph };
|
|
1925
|
+
}
|
|
1900
1926
|
function runFaces(runs) {
|
|
1901
1927
|
const faces = runs.map((r) => faceMetricsOf(cachedFontVariant(r.fontFamily, r.fontWeight, r.fontStyle)));
|
|
1902
1928
|
return (run) => faces[run];
|
|
@@ -1937,7 +1963,13 @@ function paintRunsInto(laid, runs, opts, out) {
|
|
|
1937
1963
|
rules?.add(g);
|
|
1938
1964
|
const run = runs[g.run];
|
|
1939
1965
|
const inks = cols !== null ? cols.drawsInk(start2, pos) : line.cells[g.cell].drawsInk;
|
|
1940
|
-
|
|
1966
|
+
let outline = inks ? glyphOutlineD(g, run, opts.outlineMinSize) : null;
|
|
1967
|
+
let q = g;
|
|
1968
|
+
if (inks && outline === null && g.shaped) {
|
|
1969
|
+
const baked = shapedQuadGlyph(g);
|
|
1970
|
+
if (baked) q = baked;
|
|
1971
|
+
else outline = glyphOutlineD(g, run, opts.outlineMinSize, true);
|
|
1972
|
+
}
|
|
1941
1973
|
if (!fillHasInk(run.fill) && !(outline !== null && strokeHasInk(run.stroke))) continue;
|
|
1942
1974
|
if (outline !== null) {
|
|
1943
1975
|
const placed2 = { ...outline, x: g.x, baselineY: g.baselineY, scale: g.fontSize };
|
|
@@ -1945,8 +1977,8 @@ function paintRunsInto(laid, runs, opts, out) {
|
|
|
1945
1977
|
groupFor(runs, g, "outline").glyphs.push(placed2);
|
|
1946
1978
|
continue;
|
|
1947
1979
|
}
|
|
1948
|
-
if (!hasGlyphQuad(
|
|
1949
|
-
const group = groupFor(runs,
|
|
1980
|
+
if (!hasGlyphQuad(q)) continue;
|
|
1981
|
+
const group = groupFor(runs, q, q.glyph.color ? "color" : q.resolved.source);
|
|
1950
1982
|
if (sized === null) {
|
|
1951
1983
|
sized = group;
|
|
1952
1984
|
group.quadData = buf;
|
|
@@ -1954,12 +1986,12 @@ function paintRunsInto(laid, runs, opts, out) {
|
|
|
1954
1986
|
let quads = group.quadData;
|
|
1955
1987
|
if (quads === NO_QUADS) group.quadData = quads = [];
|
|
1956
1988
|
if (group === sized) {
|
|
1957
|
-
writeGlyphQuad(
|
|
1989
|
+
writeGlyphQuad(q, quads, sizedAt);
|
|
1958
1990
|
sizedAt += QUAD_STRIDE;
|
|
1959
1991
|
} else {
|
|
1960
|
-
writeGlyphQuad(
|
|
1992
|
+
writeGlyphQuad(q, quads, quads.length);
|
|
1961
1993
|
}
|
|
1962
|
-
group.colorGlyphs?.push(
|
|
1994
|
+
group.colorGlyphs?.push(q.glyph);
|
|
1963
1995
|
}
|
|
1964
1996
|
if (!rules) continue;
|
|
1965
1997
|
for (const rule of rules.end()) {
|
|
@@ -2388,5 +2420,5 @@ function _resetLayoutCacheForTests() {
|
|
|
2388
2420
|
}
|
|
2389
2421
|
|
|
2390
2422
|
export { BREAK_ALLOWED, BREAK_MANDATORY, DECORATION_KINDS, DEFAULT_DECORATION_METRICS, DEFAULT_TAB_SIZE, DEFAULT_TEXT_FILL, DEFAULT_TEXT_STYLE, LAYOUT_CACHE_STRUCTURAL_LIMIT, LAYOUT_CACHE_VARIANT_LIMIT, NO_BREAK, QUAD_STRIDE, _resetBidiWarningForTests, _resetLayoutCacheForTests, cachedLayoutRuns, cachedPaintRuns, clearRuns, decorationMetrics, decorationRule, dropRuns, emboldenGlyph, emboldenGlyphD, faceOutlineD, fontString, graphemeCount, hangs, hasGlyphQuad, isHardLineBreak, layoutRuns, lineBreakOpportunities, lineDecorations, paintRuns, paragraphDirection, registerBidi, registerShaper, registeredBidi, resolveAlign, resolveTextStyle, resolveTextStyleInto, runFaces, shapesWithFeature, syntheticBoldOffset, tabAdvance, warnRtlWithoutEngine, widthWithTabs, wrapLines };
|
|
2391
|
-
//# sourceMappingURL=chunk-
|
|
2392
|
-
//# sourceMappingURL=chunk-
|
|
2423
|
+
//# sourceMappingURL=chunk-WUFANHTE.js.map
|
|
2424
|
+
//# sourceMappingURL=chunk-WUFANHTE.js.map
|