@weasel-js/text 1.15.0 → 1.15.2
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-VBLWNCSV.js} +64 -38
- package/dist/chunk-VBLWNCSV.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,6 +1,7 @@
|
|
|
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
|
+
import { sameList } from '@weasel-js/registry';
|
|
4
5
|
|
|
5
6
|
var __defProp = Object.defineProperty;
|
|
6
7
|
var __export = (target, all) => {
|
|
@@ -134,16 +135,20 @@ function registerShaper(shaper) {
|
|
|
134
135
|
function registeredShaper() {
|
|
135
136
|
return registered;
|
|
136
137
|
}
|
|
137
|
-
var
|
|
138
|
-
function
|
|
139
|
-
const
|
|
138
|
+
var embeddingOf = /* @__PURE__ */ new WeakMap();
|
|
139
|
+
function shapingFace(resolved2) {
|
|
140
|
+
const { family, weight, style } = resolved2.resolved;
|
|
141
|
+
const face = resolved2.outlineFace ?? (resolved2.source === "outline" ? void 0 : outlineMetrics(family, weight, style === "italic" ? "italic" : "normal"));
|
|
140
142
|
if (!face) return null;
|
|
141
|
-
let
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
let embedding = embeddingOf.get(face);
|
|
144
|
+
if (embedding === void 0) {
|
|
145
|
+
embedding = face.embedding?.() ?? null;
|
|
146
|
+
embeddingOf.set(face, embedding);
|
|
145
147
|
}
|
|
146
|
-
return
|
|
148
|
+
return embedding;
|
|
149
|
+
}
|
|
150
|
+
function shapeableBytes(resolved2) {
|
|
151
|
+
return shapingFace(resolved2)?.sfnt ?? null;
|
|
147
152
|
}
|
|
148
153
|
function shapesWithFeature(family, weight, style, tag, shaper = registered) {
|
|
149
154
|
if (shaper === null) return false;
|
|
@@ -1122,19 +1127,23 @@ function graphemeCount(text) {
|
|
|
1122
1127
|
var NOTHING_DRAWN = Object.freeze({ d: null, key: "", glyphs: Object.freeze([]), rtl: false, text: "" });
|
|
1123
1128
|
var COVERED = Object.freeze({ cluster: NOTHING_DRAWN, advance: 0 });
|
|
1124
1129
|
var slotsOf = /* @__PURE__ */ new WeakMap();
|
|
1130
|
+
var atlasSlotsOf = /* @__PURE__ */ new WeakMap();
|
|
1125
1131
|
var fmt = (v) => String(Math.round(v * 1e5) / 1e5);
|
|
1126
1132
|
function shapeRun(run, resolved2, shaper) {
|
|
1127
1133
|
if (shaper === null) return null;
|
|
1128
|
-
const
|
|
1129
|
-
if (
|
|
1134
|
+
const embedding = shapingFace(resolved2);
|
|
1135
|
+
if (embedding === null) return null;
|
|
1136
|
+
const face = embedding.sfnt;
|
|
1130
1137
|
const glyphs = shaper.shape(face, run.text, run.fontFeatures, run.lang);
|
|
1131
|
-
|
|
1138
|
+
const cache2 = resolved2.source === "outline" ? slotsOf : atlasSlotsOf;
|
|
1139
|
+
let slots2 = cache2.get(glyphs);
|
|
1132
1140
|
if (slots2) return slots2;
|
|
1133
|
-
|
|
1134
|
-
|
|
1141
|
+
const plain2 = resolved2.source === "outline" ? null : (cp2) => embedding.glyphIndexOf(cp2);
|
|
1142
|
+
slots2 = slotsFor(shaper, face, run.text, glyphs, plain2);
|
|
1143
|
+
cache2.set(glyphs, slots2);
|
|
1135
1144
|
return slots2;
|
|
1136
1145
|
}
|
|
1137
|
-
function slotsFor(shaper, face, text, glyphs) {
|
|
1146
|
+
function slotsFor(shaper, face, text, glyphs, plain2) {
|
|
1138
1147
|
const slots2 = new Array(text.length);
|
|
1139
1148
|
const ends = graphemeEnds(text);
|
|
1140
1149
|
let g = 0;
|
|
@@ -1147,7 +1156,7 @@ function slotsFor(shaper, face, text, glyphs) {
|
|
|
1147
1156
|
while (g < ends.length && ends[g] <= start2) g++;
|
|
1148
1157
|
let inner = 0;
|
|
1149
1158
|
for (let k = g; k < ends.length && ends[k] < end; k++) inner++;
|
|
1150
|
-
if (!holdsNotdef(glyphs, i, j)) {
|
|
1159
|
+
if (!holdsNotdef(glyphs, i, j) && !(plain2 && isPlain(glyphs[i], j - i, text, start2, end, plain2))) {
|
|
1151
1160
|
const total = advanceOf(glyphs, i, j);
|
|
1152
1161
|
const share = total / (inner + 1);
|
|
1153
1162
|
const shift = glyphs[i].rtl ? share - total : 0;
|
|
@@ -1163,6 +1172,11 @@ function slotsFor(shaper, face, text, glyphs) {
|
|
|
1163
1172
|
}
|
|
1164
1173
|
return slots2;
|
|
1165
1174
|
}
|
|
1175
|
+
function isPlain(first, count, text, start2, end, plain2) {
|
|
1176
|
+
if (count !== 1 || first.dx !== 0 || first.dy !== 0) return false;
|
|
1177
|
+
const cp2 = text.codePointAt(start2);
|
|
1178
|
+
return end - start2 === (cp2 > 65535 ? 2 : 1) && plain2(cp2) === first.gid;
|
|
1179
|
+
}
|
|
1166
1180
|
function advanceOf(glyphs, from, to) {
|
|
1167
1181
|
let sum2 = 0;
|
|
1168
1182
|
for (let k = from; k < to; k++) sum2 += glyphs[k].advance;
|
|
@@ -1180,7 +1194,7 @@ function clusterSlot(shaper, face, glyphs, from, to, text, shift, advance) {
|
|
|
1180
1194
|
for (let k = from; k < to; k++) {
|
|
1181
1195
|
const g = glyphs[k];
|
|
1182
1196
|
const x = pen + g.dx, y = g.dy;
|
|
1183
|
-
placed2.push({ gid: g.gid, x, y });
|
|
1197
|
+
placed2.push({ gid: g.gid, x, y, advance: g.advance });
|
|
1184
1198
|
d += shaper.glyphD(face, g.gid, x, y) ?? "";
|
|
1185
1199
|
key += `${k === from ? "" : ";"}${g.gid}${x === 0 && y === 0 ? "" : `@${fmt(x)},${fmt(y)}`}`;
|
|
1186
1200
|
pen += g.advance;
|
|
@@ -1359,7 +1373,7 @@ function mirrorEntries(entries2, levels, mirror, runs) {
|
|
|
1359
1373
|
const odd = levels[pos] % 2 === 1;
|
|
1360
1374
|
if (entry.shaped !== null && entry.shaped.rtl !== odd) {
|
|
1361
1375
|
const flipped = mirror(entry.cp);
|
|
1362
|
-
if (flipped !== null && flipped !== entry.cp) entry =
|
|
1376
|
+
if (flipped !== null && flipped !== entry.cp) entry = unshaped(entry, runs[entry.run]);
|
|
1363
1377
|
}
|
|
1364
1378
|
if (!odd) return entry;
|
|
1365
1379
|
if (entry.shaped !== null) return entry;
|
|
@@ -1372,6 +1386,11 @@ function mirrorEntries(entries2, levels, mirror, runs) {
|
|
|
1372
1386
|
return { ...entry, cp: cp2, resolved: hit.resolved, metrics: hit.metrics, font: hit.font, glyph: hit.glyph };
|
|
1373
1387
|
});
|
|
1374
1388
|
}
|
|
1389
|
+
function unshaped(entry, run) {
|
|
1390
|
+
if (entry.resolved.source === "outline") return { ...entry, shaped: null };
|
|
1391
|
+
const hit = resolveGlyph(entry.resolved, run.fontFamily, run.fontWeight, run.fontStyle, entry.cp, false);
|
|
1392
|
+
return hit ? { ...entry, shaped: null, resolved: hit.resolved, metrics: hit.metrics, font: hit.font, glyph: hit.glyph } : { ...entry, shaped: null };
|
|
1393
|
+
}
|
|
1375
1394
|
|
|
1376
1395
|
// src/layout/lineBreak/wrapLines.ts
|
|
1377
1396
|
var hangs = (cp2) => cp2 === 32 || cp2 === 9;
|
|
@@ -1876,9 +1895,9 @@ function takeGroups(out) {
|
|
|
1876
1895
|
}
|
|
1877
1896
|
|
|
1878
1897
|
// src/layout/paintRuns.ts
|
|
1879
|
-
function glyphOutlineD(g, run, minSize) {
|
|
1898
|
+
function glyphOutlineD(g, run, minSize, ungated = false) {
|
|
1880
1899
|
const outlineOnly = g.resolved.source === "outline";
|
|
1881
|
-
if (!outlineOnly) {
|
|
1900
|
+
if (!outlineOnly && !ungated) {
|
|
1882
1901
|
if (minSize === void 0) return null;
|
|
1883
1902
|
if (run.fontSize < minSize && !strokeHasInk(run.stroke)) return null;
|
|
1884
1903
|
}
|
|
@@ -1897,6 +1916,14 @@ function faceOutlineD(g) {
|
|
|
1897
1916
|
if (g.resolved.source !== "outline" && g.glyph === null) return null;
|
|
1898
1917
|
return glyphOutline(family, weight, style, g.cp);
|
|
1899
1918
|
}
|
|
1919
|
+
function shapedQuadGlyph(g) {
|
|
1920
|
+
const face = g.resolved.dynamicFace;
|
|
1921
|
+
const shaped = g.shaped;
|
|
1922
|
+
if (!face || shaped.d === null) return null;
|
|
1923
|
+
const glyph = face.requestShaped(shaped.key, shaped.d);
|
|
1924
|
+
if (!glyph || glyph.page < 0 || glyph.width === 0) return null;
|
|
1925
|
+
return { ...g, font: face.font, glyph };
|
|
1926
|
+
}
|
|
1900
1927
|
function runFaces(runs) {
|
|
1901
1928
|
const faces = runs.map((r) => faceMetricsOf(cachedFontVariant(r.fontFamily, r.fontWeight, r.fontStyle)));
|
|
1902
1929
|
return (run) => faces[run];
|
|
@@ -1937,7 +1964,13 @@ function paintRunsInto(laid, runs, opts, out) {
|
|
|
1937
1964
|
rules?.add(g);
|
|
1938
1965
|
const run = runs[g.run];
|
|
1939
1966
|
const inks = cols !== null ? cols.drawsInk(start2, pos) : line.cells[g.cell].drawsInk;
|
|
1940
|
-
|
|
1967
|
+
let outline = inks ? glyphOutlineD(g, run, opts.outlineMinSize) : null;
|
|
1968
|
+
let q = g;
|
|
1969
|
+
if (inks && outline === null && g.shaped) {
|
|
1970
|
+
const baked = shapedQuadGlyph(g);
|
|
1971
|
+
if (baked) q = baked;
|
|
1972
|
+
else outline = glyphOutlineD(g, run, opts.outlineMinSize, true);
|
|
1973
|
+
}
|
|
1941
1974
|
if (!fillHasInk(run.fill) && !(outline !== null && strokeHasInk(run.stroke))) continue;
|
|
1942
1975
|
if (outline !== null) {
|
|
1943
1976
|
const placed2 = { ...outline, x: g.x, baselineY: g.baselineY, scale: g.fontSize };
|
|
@@ -1945,8 +1978,8 @@ function paintRunsInto(laid, runs, opts, out) {
|
|
|
1945
1978
|
groupFor(runs, g, "outline").glyphs.push(placed2);
|
|
1946
1979
|
continue;
|
|
1947
1980
|
}
|
|
1948
|
-
if (!hasGlyphQuad(
|
|
1949
|
-
const group = groupFor(runs,
|
|
1981
|
+
if (!hasGlyphQuad(q)) continue;
|
|
1982
|
+
const group = groupFor(runs, q, q.glyph.color ? "color" : q.resolved.source);
|
|
1950
1983
|
if (sized === null) {
|
|
1951
1984
|
sized = group;
|
|
1952
1985
|
group.quadData = buf;
|
|
@@ -1954,12 +1987,12 @@ function paintRunsInto(laid, runs, opts, out) {
|
|
|
1954
1987
|
let quads = group.quadData;
|
|
1955
1988
|
if (quads === NO_QUADS) group.quadData = quads = [];
|
|
1956
1989
|
if (group === sized) {
|
|
1957
|
-
writeGlyphQuad(
|
|
1990
|
+
writeGlyphQuad(q, quads, sizedAt);
|
|
1958
1991
|
sizedAt += QUAD_STRIDE;
|
|
1959
1992
|
} else {
|
|
1960
|
-
writeGlyphQuad(
|
|
1993
|
+
writeGlyphQuad(q, quads, quads.length);
|
|
1961
1994
|
}
|
|
1962
|
-
group.colorGlyphs?.push(
|
|
1995
|
+
group.colorGlyphs?.push(q.glyph);
|
|
1963
1996
|
}
|
|
1964
1997
|
if (!rules) continue;
|
|
1965
1998
|
for (const rule of rules.end()) {
|
|
@@ -2254,18 +2287,11 @@ function runsHash(runs) {
|
|
|
2254
2287
|
}
|
|
2255
2288
|
return h & 1073741823;
|
|
2256
2289
|
}
|
|
2290
|
+
var NO_STRS = [];
|
|
2257
2291
|
function sameNums(a, b) {
|
|
2258
|
-
|
|
2259
|
-
if (a === void 0 || b === void 0 || a.length !== b.length) return false;
|
|
2260
|
-
for (let i = 0; i < a.length; i++) if (!same(a[i], b[i])) return false;
|
|
2261
|
-
return true;
|
|
2262
|
-
}
|
|
2263
|
-
function sameStrs(a, b) {
|
|
2264
|
-
if (a === b) return true;
|
|
2265
|
-
if ((a?.length ?? 0) !== (b?.length ?? 0)) return false;
|
|
2266
|
-
for (let i = 0; i < (a?.length ?? 0); i++) if (a[i] !== b[i]) return false;
|
|
2267
|
-
return true;
|
|
2292
|
+
return a === b || a !== void 0 && b !== void 0 && sameList(a, b, same);
|
|
2268
2293
|
}
|
|
2294
|
+
var sameStrs = (a, b) => sameList(a ?? NO_STRS, b ?? NO_STRS);
|
|
2269
2295
|
function sameRuns(a, b) {
|
|
2270
2296
|
if (a.length !== b.length) return false;
|
|
2271
2297
|
for (let i = 0; i < a.length; i++) {
|
|
@@ -2388,5 +2414,5 @@ function _resetLayoutCacheForTests() {
|
|
|
2388
2414
|
}
|
|
2389
2415
|
|
|
2390
2416
|
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-
|
|
2417
|
+
//# sourceMappingURL=chunk-VBLWNCSV.js.map
|
|
2418
|
+
//# sourceMappingURL=chunk-VBLWNCSV.js.map
|