@weasel-js/text 1.11.0 → 1.11.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-HI4VEOYP.js → chunk-JOVZEHBJ.js} +24 -26
- package/dist/chunk-JOVZEHBJ.js.map +1 -0
- package/dist/index.d.ts +35 -6
- package/dist/index.js +89 -48
- package/dist/index.js.map +1 -1
- package/dist/test-seams.js +1 -1
- package/package.json +6 -6
- package/dist/chunk-HI4VEOYP.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { DEFAULT_TAB_SIZE, resolveTextStyle, cachedLayoutRuns, graphemeCount, wrapLines, hangs, tabAdvance, widthWithTabs, layoutRuns } from './chunk-
|
|
2
|
-
export { BREAK_ALLOWED, BREAK_MANDATORY, DEFAULT_TEXT_STYLE, LAYOUT_CACHE_STRUCTURAL_LIMIT, LAYOUT_CACHE_VARIANT_LIMIT, NO_BREAK, cachedLayoutRuns, fontString, isHardLineBreak, layoutRuns, lineBreakOpportunities, paragraphDirection, registerBidi, resolveAlign, resolveTextStyle } from './chunk-
|
|
1
|
+
import { DEFAULT_TAB_SIZE, resolveTextStyle, cachedLayoutRuns, graphemeCount, wrapLines, hangs, tabAdvance, widthWithTabs, layoutRuns } from './chunk-JOVZEHBJ.js';
|
|
2
|
+
export { BREAK_ALLOWED, BREAK_MANDATORY, DEFAULT_TEXT_STYLE, LAYOUT_CACHE_STRUCTURAL_LIMIT, LAYOUT_CACHE_VARIANT_LIMIT, NO_BREAK, cachedLayoutRuns, fontString, isHardLineBreak, layoutRuns, lineBreakOpportunities, paragraphDirection, registerBidi, resolveAlign, resolveTextStyle } from './chunk-JOVZEHBJ.js';
|
|
3
3
|
import { resolveScreenLength, fillHasInk, strokeHasInk, paintKey, strokeKey } from '@weasel-js/paint';
|
|
4
|
-
import { faceMetricsOf, resolveFontVariant, glyphGeneration, loadFontOutlines, faceMetricsFor, glyphOutline, outlineStatus, cssFamilyName
|
|
4
|
+
import { faceMetricsOf, resolveFontVariant, syntheticBoldGrowth, glyphGeneration, loadFontOutlines, faceMetricsFor, glyphOutline, outlineStatus, cssFamilyName } from '@weasel-js/font';
|
|
5
|
+
import { pathToD, pathFromD, mergeRegion, growRegion, transformPath, poseFrameOf, pathSignedArea, reversePath, PATH_M, PATH_L, PATH_Z } from '@weasel-js/geom';
|
|
5
6
|
import { MIXED, deepEqual } from '@weasel-js/registry';
|
|
6
7
|
export { MIXED } from '@weasel-js/registry';
|
|
7
|
-
import { transformPath, poseFrameOf, growRegion, pathFromD, pathSignedArea, reversePath, PATH_M, PATH_L, PATH_Z } from '@weasel-js/geom';
|
|
8
8
|
|
|
9
9
|
// src/runs.ts
|
|
10
10
|
function toRuns(input) {
|
|
@@ -413,8 +413,8 @@ function lineDecorations(glyphs, runs, faceOf, paintOf) {
|
|
|
413
413
|
};
|
|
414
414
|
for (const g of glyphs) {
|
|
415
415
|
const style = runs[g.run];
|
|
416
|
-
const paint = paintOf(g.run);
|
|
417
|
-
if (paint === null
|
|
416
|
+
const paint = style.underline || style.strikethrough || style.overline ? paintOf(g.run) : null;
|
|
417
|
+
if (paint === null) {
|
|
418
418
|
close();
|
|
419
419
|
continue;
|
|
420
420
|
}
|
|
@@ -465,13 +465,61 @@ function layoutTextPose(pose, scale = 1) {
|
|
|
465
465
|
y: pose.y + verticalAlignOffset(pose.verticalAlign, pose.height, laid.bounds.height)
|
|
466
466
|
};
|
|
467
467
|
}
|
|
468
|
+
var SYNTHETIC_BOLD_TOLERANCE = 5e-4;
|
|
469
|
+
var CACHE_LIMIT = 4096;
|
|
470
|
+
var cache = /* @__PURE__ */ new Map();
|
|
471
|
+
var dCache = /* @__PURE__ */ new Map();
|
|
472
|
+
function syntheticBoldOffset(resolved2) {
|
|
473
|
+
if (!resolved2.synthetic.bold) return null;
|
|
474
|
+
const { source } = resolved2;
|
|
475
|
+
if (source !== "atlas" && source !== "canvas") return null;
|
|
476
|
+
const { family, weight, style } = resolved2.resolved;
|
|
477
|
+
const growth = syntheticBoldGrowth(source, family, weight, style);
|
|
478
|
+
if (growth === void 0 || !(growth > 0)) return null;
|
|
479
|
+
return { growth, join: source === "atlas" ? "miter" : "round" };
|
|
480
|
+
}
|
|
481
|
+
function emboldenGlyph(em, d, resolved2) {
|
|
482
|
+
const offset = syntheticBoldOffset(resolved2);
|
|
483
|
+
if (offset === null) return em;
|
|
484
|
+
const key = `${offset.growth}|${offset.join}|${d}`;
|
|
485
|
+
let grown = cache.get(key);
|
|
486
|
+
if (grown) return grown;
|
|
487
|
+
grown = mergeRegion(
|
|
488
|
+
growRegion(em, offset.growth, { join: offset.join, tolerance: SYNTHETIC_BOLD_TOLERANCE }),
|
|
489
|
+
{ tolerance: SYNTHETIC_BOLD_TOLERANCE }
|
|
490
|
+
);
|
|
491
|
+
if (cache.size >= CACHE_LIMIT) cache.clear();
|
|
492
|
+
cache.set(key, grown);
|
|
493
|
+
return grown;
|
|
494
|
+
}
|
|
495
|
+
function emboldenGlyphD(d, resolved2) {
|
|
496
|
+
const offset = syntheticBoldOffset(resolved2);
|
|
497
|
+
if (offset === null) return null;
|
|
498
|
+
const tag = `bold:${offset.growth}:${offset.join}`;
|
|
499
|
+
const key = `${tag}|${d}`;
|
|
500
|
+
let grown = dCache.get(key);
|
|
501
|
+
if (grown === void 0) {
|
|
502
|
+
grown = pathToD(emboldenGlyph(pathFromD(d), d, resolved2));
|
|
503
|
+
if (dCache.size >= CACHE_LIMIT) dCache.clear();
|
|
504
|
+
dCache.set(key, grown);
|
|
505
|
+
}
|
|
506
|
+
return { d: grown, tag };
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// src/layout/paintRuns.ts
|
|
468
510
|
function glyphOutlineD(g, run, minSize) {
|
|
469
|
-
|
|
511
|
+
const outlineOnly = g.resolved.source === "outline";
|
|
512
|
+
if (!outlineOnly) {
|
|
470
513
|
if (minSize === void 0) return null;
|
|
471
514
|
if (run.fontSize < minSize && !strokeHasInk(run.stroke)) return null;
|
|
472
|
-
if (g.resolved.synthetic.bold) return null;
|
|
473
515
|
}
|
|
474
|
-
|
|
516
|
+
const d = faceOutlineD(g);
|
|
517
|
+
if (d === null) return null;
|
|
518
|
+
const { family, weight, style } = g.resolved.resolved;
|
|
519
|
+
const key = `${family}|${weight}|${style}|${g.cp}`;
|
|
520
|
+
if (outlineOnly || !g.resolved.synthetic.bold) return { d, key };
|
|
521
|
+
const bold = emboldenGlyphD(d, g.resolved);
|
|
522
|
+
return bold && { d: bold.d, key: `${key}|${bold.tag}` };
|
|
475
523
|
}
|
|
476
524
|
function faceOutlineD(g) {
|
|
477
525
|
if (g.glyph?.color) return null;
|
|
@@ -501,10 +549,13 @@ function runFaces(runs) {
|
|
|
501
549
|
const faces = runs.map((r) => faceMetricsOf(resolveFontVariant(r.fontFamily, r.fontWeight, r.fontStyle)));
|
|
502
550
|
return (run) => faces[run];
|
|
503
551
|
}
|
|
504
|
-
function groupFor(groups, g, run, source) {
|
|
552
|
+
function groupFor(groups, g, run, source, last) {
|
|
505
553
|
const { family, weight, style } = g.resolved.resolved;
|
|
506
554
|
const { synthetic } = g.resolved;
|
|
507
555
|
const page = source === "outline" ? 0 : g.glyph.page;
|
|
556
|
+
if (last.group !== null && last.run === g.run && last.source === source && last.page === page && last.family === family && last.weight === weight && last.style === style && last.bold === synthetic.bold && last.italic === synthetic.italic) {
|
|
557
|
+
return last.group;
|
|
558
|
+
}
|
|
508
559
|
const stroke = source === "outline" && strokeHasInk(run.stroke) ? run.stroke : void 0;
|
|
509
560
|
const key = `${family}|${weight}|${style}|${synthetic.bold ? 1 : 0}${synthetic.italic ? 1 : 0}|${paintKey(run.fill?.paint)}|${strokeKey(stroke)}|${source}|${page}`;
|
|
510
561
|
let group = groups.get(key);
|
|
@@ -523,23 +574,41 @@ function groupFor(groups, g, run, source) {
|
|
|
523
574
|
};
|
|
524
575
|
groups.set(key, group);
|
|
525
576
|
}
|
|
577
|
+
last.group = group;
|
|
578
|
+
last.run = g.run;
|
|
579
|
+
last.family = family;
|
|
580
|
+
last.weight = weight;
|
|
581
|
+
last.style = style;
|
|
582
|
+
last.bold = synthetic.bold;
|
|
583
|
+
last.italic = synthetic.italic;
|
|
584
|
+
last.source = source;
|
|
585
|
+
last.page = page;
|
|
526
586
|
return group;
|
|
527
587
|
}
|
|
528
588
|
function paintRuns(laid, runs, opts = {}) {
|
|
529
589
|
const groups = /* @__PURE__ */ new Map();
|
|
590
|
+
const last = {
|
|
591
|
+
group: null,
|
|
592
|
+
run: -1,
|
|
593
|
+
family: "",
|
|
594
|
+
weight: 0,
|
|
595
|
+
style: "normal",
|
|
596
|
+
bold: false,
|
|
597
|
+
italic: false,
|
|
598
|
+
source: "atlas",
|
|
599
|
+
page: 0
|
|
600
|
+
};
|
|
530
601
|
const decorations = [];
|
|
531
602
|
const faceOf = runFaces(runs);
|
|
532
603
|
const rulePaint = (run) => fillHasInk(runs[run].fill) ? paintKey(runs[run].fill.paint) : null;
|
|
533
604
|
for (const line of laid.lines) {
|
|
534
605
|
for (const g of line.glyphs) {
|
|
535
606
|
const run = runs[g.run];
|
|
536
|
-
const
|
|
537
|
-
if (!fillHasInk(run.fill) && !(
|
|
538
|
-
if (
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
d,
|
|
542
|
-
key: `${family}|${weight}|${style}|${g.cp}`,
|
|
607
|
+
const outline = glyphOutlineD(g, run, opts.outlineMinSize);
|
|
608
|
+
if (!fillHasInk(run.fill) && !(outline !== null && strokeHasInk(run.stroke))) continue;
|
|
609
|
+
if (outline !== null) {
|
|
610
|
+
groupFor(groups, g, run, "outline", last).glyphs.push({
|
|
611
|
+
...outline,
|
|
543
612
|
x: g.x,
|
|
544
613
|
baselineY: g.baselineY,
|
|
545
614
|
scale: g.fontSize
|
|
@@ -548,8 +617,8 @@ function paintRuns(laid, runs, opts = {}) {
|
|
|
548
617
|
}
|
|
549
618
|
const quad = glyphQuad(g);
|
|
550
619
|
if (!quad) continue;
|
|
551
|
-
if (g.glyph?.color) groupFor(groups, g, run, "color").quads.push({ ...quad, colorGlyph: g.glyph });
|
|
552
|
-
else groupFor(groups, g, run, g.resolved.source).quads.push(quad);
|
|
620
|
+
if (g.glyph?.color) groupFor(groups, g, run, "color", last).quads.push({ ...quad, colorGlyph: g.glyph });
|
|
621
|
+
else groupFor(groups, g, run, g.resolved.source, last).quads.push(quad);
|
|
553
622
|
}
|
|
554
623
|
for (const rule of lineDecorations(line.glyphs, runs, faceOf, rulePaint)) {
|
|
555
624
|
const { run, ...rect } = rule;
|
|
@@ -1233,34 +1302,6 @@ function effectiveRangeStyle(range, style, paint) {
|
|
|
1233
1302
|
|
|
1234
1303
|
// src/syntheticItalic.ts
|
|
1235
1304
|
var SYNTHETIC_ITALIC_RADIANS = 0.2094;
|
|
1236
|
-
var SYNTHETIC_BOLD_TOLERANCE = 5e-4;
|
|
1237
|
-
var CACHE_LIMIT = 4096;
|
|
1238
|
-
var cache = /* @__PURE__ */ new Map();
|
|
1239
|
-
function syntheticBoldOffset(resolved2) {
|
|
1240
|
-
if (!resolved2.synthetic.bold) return null;
|
|
1241
|
-
const { source } = resolved2;
|
|
1242
|
-
if (source !== "atlas" && source !== "canvas") return null;
|
|
1243
|
-
const { family, weight, style } = resolved2.resolved;
|
|
1244
|
-
const growth = syntheticBoldGrowth(source, family, weight, style);
|
|
1245
|
-
if (growth === void 0 || !(growth > 0)) return null;
|
|
1246
|
-
return { growth, join: source === "atlas" ? "miter" : "round" };
|
|
1247
|
-
}
|
|
1248
|
-
function emboldenGlyph(em, d, resolved2) {
|
|
1249
|
-
const offset = syntheticBoldOffset(resolved2);
|
|
1250
|
-
if (offset === null) return em;
|
|
1251
|
-
const key = `${offset.growth}|${offset.join}|${d}`;
|
|
1252
|
-
let grown = cache.get(key);
|
|
1253
|
-
if (grown) return grown;
|
|
1254
|
-
grown = growRegion(em, offset.growth, {
|
|
1255
|
-
join: offset.join,
|
|
1256
|
-
tolerance: SYNTHETIC_BOLD_TOLERANCE
|
|
1257
|
-
});
|
|
1258
|
-
if (cache.size >= CACHE_LIMIT) cache.clear();
|
|
1259
|
-
cache.set(key, grown);
|
|
1260
|
-
return grown;
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
|
-
// src/textToPath.ts
|
|
1264
1305
|
var TextOutlinesError = class extends Error {
|
|
1265
1306
|
reason;
|
|
1266
1307
|
family;
|
|
@@ -1447,6 +1488,6 @@ async function loadTextOutlines(data, opts = {}) {
|
|
|
1447
1488
|
await Promise.all(facesOf(runs).map((f) => loadFontOutlines(f.family, { weight: f.weight, style: f.style })));
|
|
1448
1489
|
}
|
|
1449
1490
|
|
|
1450
|
-
export { DEFAULT_DECORATION_METRICS, MARKDOWN_RUN_GRAMMAR, SCRIPT_METRICS, SMALL_CAPS_SCALE, SYNTHETIC_ITALIC_RADIANS, TextOutlinesError, applyStyleToRange, cachedPaintRuns, caretIndexAt, createMarkdownRenderer, decorationMetrics, defaultLabelTextRenderer, effectiveRangeStyle, fitTextPose, isBoldWeight, isSmallCapsLetter, isTextData, layoutMarkdown, layoutTextPose, loadTextOutlines, markdownToRuns, measureText, measureTextBounds, measuredWidth, nodeHasFlag, numericWeight, paintRuns, patchRangeStyle, pointInTextPose, rangeWeight, renderLabel, resolveRunFace, resolveRuns, runsCarryStyling, runsToMarkdown, runsToPlainText, scriptMetrics, scriptMetricsFor, setFlagOverRange, smallCapsScale, smallCapsScaleFor, smallCapsText, styleAtRange, supersededKey, textLineBoxes, textPoseLayoutInput, textToPath, textToPathsByPaint, toRuns, transformRunTexts, unboldPatch, verticalAlignOffset };
|
|
1491
|
+
export { DEFAULT_DECORATION_METRICS, MARKDOWN_RUN_GRAMMAR, SCRIPT_METRICS, SMALL_CAPS_SCALE, SYNTHETIC_ITALIC_RADIANS, TextOutlinesError, applyStyleToRange, cachedPaintRuns, caretIndexAt, createMarkdownRenderer, decorationMetrics, defaultLabelTextRenderer, effectiveRangeStyle, emboldenGlyphD, fitTextPose, isBoldWeight, isSmallCapsLetter, isTextData, layoutMarkdown, layoutTextPose, loadTextOutlines, markdownToRuns, measureText, measureTextBounds, measuredWidth, nodeHasFlag, numericWeight, paintRuns, patchRangeStyle, pointInTextPose, rangeWeight, renderLabel, resolveRunFace, resolveRuns, runsCarryStyling, runsToMarkdown, runsToPlainText, scriptMetrics, scriptMetricsFor, setFlagOverRange, smallCapsScale, smallCapsScaleFor, smallCapsText, styleAtRange, supersededKey, syntheticBoldOffset, textLineBoxes, textPoseLayoutInput, textToPath, textToPathsByPaint, toRuns, transformRunTexts, unboldPatch, verticalAlignOffset };
|
|
1451
1492
|
//# sourceMappingURL=index.js.map
|
|
1452
1493
|
//# sourceMappingURL=index.js.map
|