iris: keep text overflow masks horizontal

This commit is contained in:
iris committed 2026-09-12 20:59:54 -04:00
1 parent 93c106e2f8
commit adb8276ef4
2 files changed
+26 -5

No files matched your search

+6 -4
View File
@@ -862,10 +862,12 @@ absolute position back into this same public field; callers animating it own
stopping their animation when editing begins. Position changes and changes stopping their animation when editing begins. Position changes and changes
among the unwrapped treatments reuse shaping; entering or leaving `Wrap` among the unwrapped treatments reuse shaping; entering or leaving `Wrap`
reshapes at the viewport width, while content, font, spans, or density retain reshapes at the viewport width, while content, font, spans, or density retain
the normal shape invalidation path. `Hidden` clips at the exact pixel position the normal shape invalidation path. Overflow masks only the horizontal axis;
for continuous scrolling. `Ellipsis` keeps that same continuous position but vertical ink such as descenders and accents remains untouched. `Hidden` clips
snaps each content-mask edge outward past any shaped cluster or ligature it at the exact horizontal pixel position for continuous scrolling. `Ellipsis`
crosses, so a marker never leaves a partial shaped cluster behind. keeps that same continuous position but snaps each content-mask edge outward
past any shaped cluster or ligature it crosses, so a marker never leaves a
partial shaped cluster behind.
An ellipsis marker maps its visually omitted side to one contiguous source An ellipsis marker maps its visually omitted side to one contiguous source
range. This is exact for ordinary LTR and RTL runs; mixed-bidi text can place range. This is exact for ordinary LTR and RTL runs; mixed-bidi text can place
discontiguous logical ranges on one visual side, which Iris's deliberately discontiguous logical ranges on one visual side, which Iris's deliberately
+20 -1
View File
@@ -354,11 +354,12 @@ impl TextView {
} else { } else {
(self.overflow.content_end - self.overflow.content_start).max(0.0) (self.overflow.content_end - self.overflow.content_start).max(0.0)
}; };
let mask = vec2(content_width, self.overflow.viewport.y) let horizontal_mask = vec2(content_width, self.overflow.viewport.y)
.align(Align::TOP_LEFT) .align(Align::TOP_LEFT)
.offset(vec2(self.overflow.content_start, 0.0)) .offset(vec2(self.overflow.content_start, 0.0))
.within(&viewport) .within(&viewport)
.within(&painter.region()); .within(&painter.region());
let mask = UiRegion::new(horizontal_mask.x, UiSpan::FULL);
painter.set_mask(mask); painter.set_mask(mask);
let origin = tex let origin = tex
.size .size
@@ -656,6 +657,24 @@ mod tests {
assert_eq!(rsc.ui.widgets[text].view.overflow.trailing_marker, 0.0); assert_eq!(rsc.ui.widgets[text].view.overflow.trailing_marker, 0.0);
} }
#[test]
fn overflow_masks_only_the_horizontal_axis() {
let mut rsc = TestRsc { ui: Ui::default() };
let text = wtext("glyphs jumping")
.overflow(TextOverflow::Hidden)
.size(18)
.add(&mut rsc);
let root = text.width(abs(50)).add_strong(&mut rsc).any();
let mut render = UiRenderState::new();
render.resize((800.0, 600.0));
render.update(&root, &mut rsc);
let mask = rsc.ui.masks[render.active[&text.id()].own_mask.idx()];
let region = render.primitives.instance(mask.primitive).region;
assert_eq!(region.y, UiSpan::FULL);
assert_ne!(region.x, UiSpan::FULL);
}
#[test] #[test]
fn selecting_an_ellipsis_selects_the_omitted_source_text() { fn selecting_an_ellipsis_selects_the_omitted_source_text() {
let mut rsc = TestRsc { ui: Ui::default() }; let mut rsc = TestRsc { ui: Ui::default() };