ntk 8.12.1 → 8.12.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/lib/renderingcontext_2d.js +9 -1
- package/lib/text/glyphs.js +34 -5
- package/package.json +1 -1
|
@@ -2716,7 +2716,14 @@ class RenderingContext2d {
|
|
|
2716
2716
|
if (rect.w === 0 || rect.h === 0) return;
|
|
2717
2717
|
this._setPictureClip(rect);
|
|
2718
2718
|
}
|
|
2719
|
-
drawGlyphRuns(
|
|
2719
|
+
drawGlyphRuns(
|
|
2720
|
+
app,
|
|
2721
|
+
op,
|
|
2722
|
+
src.id,
|
|
2723
|
+
this._dst(),
|
|
2724
|
+
positioned,
|
|
2725
|
+
rect ?? { x: 0, y: 0, w: this.width, h: this.height },
|
|
2726
|
+
);
|
|
2720
2727
|
if (rect) this._invalidatePictureClip();
|
|
2721
2728
|
this._markDirty();
|
|
2722
2729
|
return;
|
|
@@ -2737,6 +2744,7 @@ class RenderingContext2d {
|
|
|
2737
2744
|
this._glyphSource.id,
|
|
2738
2745
|
this.fillMask.id,
|
|
2739
2746
|
positioned,
|
|
2747
|
+
{ x: 0, y: 0, w: this.width, h: this.height },
|
|
2740
2748
|
);
|
|
2741
2749
|
R.Composite(
|
|
2742
2750
|
R.PictOp.In,
|
package/lib/text/glyphs.js
CHANGED
|
@@ -571,8 +571,11 @@ export function routeGlyphSize(app, font, size, policy = policyOf(app), textRend
|
|
|
571
571
|
* @param {number} srcId source picture (fill color/gradient)
|
|
572
572
|
* @param {number} dstId destination picture
|
|
573
573
|
* @param {Array<{run, x, y}>} positioned visual-order runs with baseline origins
|
|
574
|
+
* @param {{x: number, y: number, w: number, h: number}} [bounds] the part of
|
|
575
|
+
* the destination that can show anything — the clip, or the surface. A
|
|
576
|
+
* glyph wholly outside it is not sent (`visibleGlyph`).
|
|
574
577
|
*/
|
|
575
|
-
export function drawGlyphRuns(app, op, srcId, dstId, positioned) {
|
|
578
|
+
export function drawGlyphRuns(app, op, srcId, dstId, positioned, bounds = null) {
|
|
576
579
|
const policy = policyOf(app);
|
|
577
580
|
let bitmap = positioned;
|
|
578
581
|
let vector = null;
|
|
@@ -590,11 +593,35 @@ export function drawGlyphRuns(app, op, srcId, dstId, positioned) {
|
|
|
590
593
|
bitmap.push(positioned[i]);
|
|
591
594
|
}
|
|
592
595
|
}
|
|
593
|
-
if (bitmap.length) drawBitmapGlyphRuns(app, op, srcId, dstId, bitmap, policy);
|
|
594
|
-
if (vector) drawVectorGlyphRuns(app, op, srcId, dstId, vector);
|
|
596
|
+
if (bitmap.length) drawBitmapGlyphRuns(app, op, srcId, dstId, bitmap, policy, bounds);
|
|
597
|
+
if (vector) drawVectorGlyphRuns(app, op, srcId, dstId, vector, bounds);
|
|
595
598
|
}
|
|
596
599
|
|
|
597
|
-
|
|
600
|
+
/**
|
|
601
|
+
* Whether a glyph whose origin is at (x, y) can put any ink inside `bounds`,
|
|
602
|
+
* give or take two ems — no glyph reaches further from its origin than that,
|
|
603
|
+
* swashes and all.
|
|
604
|
+
*
|
|
605
|
+
* Not only a saving: the glyphs of a line wider than 32767 device pixels —
|
|
606
|
+
* a minified file in a code editor, a long label in a narrow cell — have
|
|
607
|
+
* origins no request can carry. CompositeGlyphs places its first glyph and
|
|
608
|
+
* every element after it in 16-bit coordinates, and the vector path's trap
|
|
609
|
+
* mask would span the whole line, so drawing such a line threw a RangeError
|
|
610
|
+
* out of the paint however little of it was on screen. What is left after
|
|
611
|
+
* the cull sits inside a surface, and every coordinate in it fits.
|
|
612
|
+
*/
|
|
613
|
+
function visibleGlyph(bounds, x, y, size) {
|
|
614
|
+
if (bounds === null) return true;
|
|
615
|
+
const reach = size * 2;
|
|
616
|
+
return (
|
|
617
|
+
x + reach > bounds.x &&
|
|
618
|
+
x - reach < bounds.x + bounds.w &&
|
|
619
|
+
y + reach > bounds.y &&
|
|
620
|
+
y - reach < bounds.y + bounds.h
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
function drawBitmapGlyphRuns(app, op, srcId, dstId, positioned, policy, bounds) {
|
|
598
625
|
const Render = app.display.Render;
|
|
599
626
|
const items = [];
|
|
600
627
|
let bits = 8;
|
|
@@ -608,6 +635,7 @@ function drawBitmapGlyphRuns(app, op, srcId, dstId, positioned, policy) {
|
|
|
608
635
|
if (page.bits > bits) bits = page.bits;
|
|
609
636
|
}
|
|
610
637
|
for (const pos of positionGlyphs(positioned)) {
|
|
638
|
+
if (!visibleGlyph(bounds, pos.x, pos.y, pos.run.size)) continue;
|
|
611
639
|
const page = pages.get(pos.run);
|
|
612
640
|
const e = page.entry(pos.glyph.id);
|
|
613
641
|
items.push({ gs: e.gs, lid: e.lid, adv: e.adv, x: pos.x, y: pos.y });
|
|
@@ -646,7 +674,7 @@ const MAX_TRAPS_PER_REQUEST = 6000;
|
|
|
646
674
|
* Positions are intentionally NOT rounded to whole pixels — fractional
|
|
647
675
|
* advances and origins keep zoom animations smooth.
|
|
648
676
|
*/
|
|
649
|
-
function drawVectorGlyphRuns(app, op, srcId, dstId, positioned) {
|
|
677
|
+
function drawVectorGlyphRuns(app, op, srcId, dstId, positioned, bounds = null) {
|
|
650
678
|
// unrounded glyph origins + ink bounding box
|
|
651
679
|
const placed = [];
|
|
652
680
|
let minX = Infinity;
|
|
@@ -657,6 +685,7 @@ function drawVectorGlyphRuns(app, op, srcId, dstId, positioned) {
|
|
|
657
685
|
const gx = cursor + g.dx;
|
|
658
686
|
const gy = y - g.dy;
|
|
659
687
|
cursor += g.ax;
|
|
688
|
+
if (!visibleGlyph(bounds, gx, gy, run.size)) continue;
|
|
660
689
|
const e = run.font.glyphExtents(g.id, run.size);
|
|
661
690
|
if (!Number.isFinite(e.minX) || e.maxX <= e.minX) continue; // blank glyph
|
|
662
691
|
placed.push({ run, glyph: g, x: gx, y: gy });
|