ntk 3.5.0 → 3.5.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/lib/renderingcontext_2d.js +29 -2
- package/lib/text/layout.js +7 -1
- package/package.json +1 -1
|
@@ -736,6 +736,34 @@ class RenderingContext2d {
|
|
|
736
736
|
this._markDirty();
|
|
737
737
|
}
|
|
738
738
|
|
|
739
|
+
/**
|
|
740
|
+
* Composite shaped glyph runs onto this context, honouring the clip.
|
|
741
|
+
*
|
|
742
|
+
* CompositeGlyphs writes straight to the destination picture, so it has
|
|
743
|
+
* no way to consult our clip mask — text drawn through it used to spill
|
|
744
|
+
* out of clipped boxes while every fill and stroke stayed inside. With a
|
|
745
|
+
* clip active, render the glyph coverage into the scratch a8 mask
|
|
746
|
+
* instead, intersect that with the clip, and paint the real source
|
|
747
|
+
* through the result — the same shape as _fillPolys.
|
|
748
|
+
*/
|
|
749
|
+
drawGlyphs(op, src, positioned) {
|
|
750
|
+
const app = this.window.app;
|
|
751
|
+
const R = this.Render;
|
|
752
|
+
if (!this.clipMask) {
|
|
753
|
+
drawGlyphRuns(app, op, src.id, this.picture.id, positioned);
|
|
754
|
+
this._markDirty();
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
this._ensureFillMask();
|
|
758
|
+
this._glyphSource ??= this.createSolidPicture(1, 1, 1, 1);
|
|
759
|
+
R.FillRectangles(R.PictOp.Src, this.fillMask.id, [0, 0, 0, 0], [0, 0, this.width, this.height]);
|
|
760
|
+
// solid white through the glyphs leaves their coverage in the a8 mask
|
|
761
|
+
drawGlyphRuns(app, R.PictOp.Over, this._glyphSource.id, this.fillMask.id, positioned);
|
|
762
|
+
R.Composite(R.PictOp.In, this.clipMask.id, 0, this.fillMask.id, 0, 0, 0, 0, 0, 0, this.width, this.height);
|
|
763
|
+
R.Composite(op, src.id, this.fillMask.id, this.picture.id, 0, 0, 0, 0, 0, 0, this.width, this.height);
|
|
764
|
+
this._markDirty();
|
|
765
|
+
}
|
|
766
|
+
|
|
739
767
|
// combined clip ∩ globalAlpha mask for direct composites (rect/image
|
|
740
768
|
// fast paths); returns a picture id or 0. Reuses the fill scratch mask.
|
|
741
769
|
_compositeMask() {
|
|
@@ -928,8 +956,7 @@ class RenderingContext2d {
|
|
|
928
956
|
positioned.push({ run, x: cursor, y: oy });
|
|
929
957
|
cursor += run.width;
|
|
930
958
|
}
|
|
931
|
-
|
|
932
|
-
this._markDirty();
|
|
959
|
+
this.drawGlyphs(this.Render.PictOp.Over, this._backgroundPicture, positioned);
|
|
933
960
|
}
|
|
934
961
|
|
|
935
962
|
/**
|
package/lib/text/layout.js
CHANGED
|
@@ -334,7 +334,13 @@ export class TextLayout {
|
|
|
334
334
|
const flush = () => {
|
|
335
335
|
if (batch.length === 0) return;
|
|
336
336
|
const src = batchColor ? ctx._stylePicture(batchColor) : ctx._backgroundPicture;
|
|
337
|
-
|
|
337
|
+
// via the context so the clip mask is applied (drawGlyphRuns
|
|
338
|
+
// composites straight onto the picture and cannot see it)
|
|
339
|
+
if (typeof ctx.drawGlyphs === 'function') {
|
|
340
|
+
ctx.drawGlyphs(Render.PictOp.Over, src, batch);
|
|
341
|
+
} else {
|
|
342
|
+
drawGlyphRuns(app, Render.PictOp.Over, src.id, ctx.picture.id, batch);
|
|
343
|
+
}
|
|
338
344
|
batch = [];
|
|
339
345
|
};
|
|
340
346
|
for (const r of line.runs) {
|