Skip to content

Commit

Permalink
Merge pull request #2154 from iced-rs/fix/text-clipping
Browse files Browse the repository at this point in the history
Fix text clipping
  • Loading branch information
hecrj authored Dec 2, 2023
2 parents 7f8b176 + b526ce4 commit 8727b3f
Show file tree
Hide file tree
Showing 24 changed files with 183 additions and 113 deletions.
3 changes: 3 additions & 0 deletions core/src/renderer/null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ impl text::Renderer for Null {
_paragraph: &Self::Paragraph,
_position: Point,
_color: Color,
_clip_bounds: Rectangle,
) {
}

Expand All @@ -72,6 +73,7 @@ impl text::Renderer for Null {
_editor: &Self::Editor,
_position: Point,
_color: Color,
_clip_bounds: Rectangle,
) {
}

Expand All @@ -80,6 +82,7 @@ impl text::Renderer for Null {
_paragraph: Text<'_, Self::Font>,
_position: Point,
_color: Color,
_clip_bounds: Rectangle,
) {
}
}
Expand Down
5 changes: 4 additions & 1 deletion core/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub use highlighter::Highlighter;
pub use paragraph::Paragraph;

use crate::alignment;
use crate::{Color, Pixels, Point, Size};
use crate::{Color, Pixels, Point, Rectangle, Size};

use std::borrow::Cow;
use std::hash::{Hash, Hasher};
Expand Down Expand Up @@ -202,6 +202,7 @@ pub trait Renderer: crate::Renderer {
text: &Self::Paragraph,
position: Point,
color: Color,
clip_bounds: Rectangle,
);

/// Draws the given [`Editor`] at the given position and with the given
Expand All @@ -211,6 +212,7 @@ pub trait Renderer: crate::Renderer {
editor: &Self::Editor,
position: Point,
color: Color,
clip_bounds: Rectangle,
);

/// Draws the given [`Text`] at the given position and with the given
Expand All @@ -220,5 +222,6 @@ pub trait Renderer: crate::Renderer {
text: Text<'_, Self::Font>,
position: Point,
color: Color,
clip_bounds: Rectangle,
);
}
5 changes: 4 additions & 1 deletion core/src/widget/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ where
style: &renderer::Style,
layout: Layout<'_>,
_cursor_position: mouse::Cursor,
_viewport: &Rectangle,
viewport: &Rectangle,
) {
let state = tree.state.downcast_ref::<State<Renderer::Paragraph>>();

Expand All @@ -182,6 +182,7 @@ where
layout,
state,
theme.appearance(self.style.clone()),
viewport,
);
}
}
Expand Down Expand Up @@ -244,6 +245,7 @@ pub fn draw<Renderer>(
layout: Layout<'_>,
state: &State<Renderer::Paragraph>,
appearance: Appearance,
viewport: &Rectangle,
) where
Renderer: text::Renderer,
{
Expand All @@ -266,6 +268,7 @@ pub fn draw<Renderer>(
paragraph,
Point::new(x, y),
appearance.color.unwrap_or(style.text_color),
*viewport,
);
}

Expand Down
26 changes: 16 additions & 10 deletions graphics/src/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,26 @@ use std::sync::Arc;
pub enum Primitive<T> {
/// A text primitive
Text {
/// The contents of the text
/// The contents of the text.
content: String,
/// The bounds of the text
/// The bounds of the text.
bounds: Rectangle,
/// The color of the text
/// The color of the text.
color: Color,
/// The size of the text in logical pixels
/// The size of the text in logical pixels.
size: Pixels,
/// The line height of the text
/// The line height of the text.
line_height: text::LineHeight,
/// The font of the text
/// The font of the text.
font: Font,
/// The horizontal alignment of the text
/// The horizontal alignment of the text.
horizontal_alignment: alignment::Horizontal,
/// The vertical alignment of the text
/// The vertical alignment of the text.
vertical_alignment: alignment::Vertical,
/// The shaping strategy of the text.
shaping: text::Shaping,
/// The clip bounds of the text.
clip_bounds: Rectangle,
},
/// A paragraph primitive
Paragraph {
Expand All @@ -41,15 +43,19 @@ pub enum Primitive<T> {
position: Point,
/// The color of the paragraph.
color: Color,
/// The clip bounds of the paragraph.
clip_bounds: Rectangle,
},
/// An editor primitive
Editor {
/// The [`editor::Weak`] reference.
editor: editor::Weak,
/// The position of the paragraph.
/// The position of the editor.
position: Point,
/// The color of the paragraph.
/// The color of the editor.
color: Color,
/// The clip bounds of the editor.
clip_bounds: Rectangle,
},
/// A quad primitive
Quad {
Expand Down
6 changes: 6 additions & 0 deletions graphics/src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,13 @@ where
paragraph: &Self::Paragraph,
position: Point,
color: Color,
clip_bounds: Rectangle,
) {
self.primitives.push(Primitive::Paragraph {
paragraph: paragraph.downgrade(),
position,
color,
clip_bounds,
});
}

Expand All @@ -177,11 +179,13 @@ where
editor: &Self::Editor,
position: Point,
color: Color,
clip_bounds: Rectangle,
) {
self.primitives.push(Primitive::Editor {
editor: editor.downgrade(),
position,
color,
clip_bounds,
});
}

Expand All @@ -190,6 +194,7 @@ where
text: Text<'_, Self::Font>,
position: Point,
color: Color,
clip_bounds: Rectangle,
) {
self.primitives.push(Primitive::Text {
content: text.content.to_string(),
Expand All @@ -201,6 +206,7 @@ where
horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment,
shaping: text.shaping,
clip_bounds,
});
}
}
Expand Down
7 changes: 6 additions & 1 deletion graphics/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ pub fn measure(buffer: &cosmic_text::Buffer) -> Size {
(run.line_w.max(width), total_lines + 1)
});

Size::new(width, total_lines as f32 * buffer.metrics().line_height)
let (max_width, max_height) = buffer.size();

Size::new(
width.min(max_width),
(total_lines as f32 * buffer.metrics().line_height).min(max_height),
)
}

/// Returns the attributes of the given [`Font`].
Expand Down
13 changes: 10 additions & 3 deletions renderer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,12 @@ impl<T> text::Renderer for Renderer<T> {
paragraph: &Self::Paragraph,
position: Point,
color: Color,
clip_bounds: Rectangle,
) {
delegate!(
self,
renderer,
renderer.fill_paragraph(paragraph, position, color)
renderer.fill_paragraph(paragraph, position, color, clip_bounds)
);
}

Expand All @@ -188,11 +189,12 @@ impl<T> text::Renderer for Renderer<T> {
editor: &Self::Editor,
position: Point,
color: Color,
clip_bounds: Rectangle,
) {
delegate!(
self,
renderer,
renderer.fill_editor(editor, position, color)
renderer.fill_editor(editor, position, color, clip_bounds)
);
}

Expand All @@ -201,8 +203,13 @@ impl<T> text::Renderer for Renderer<T> {
text: Text<'_, Self::Font>,
position: Point,
color: Color,
clip_bounds: Rectangle,
) {
delegate!(self, renderer, renderer.fill_text(text, position, color));
delegate!(
self,
renderer,
renderer.fill_text(text, position, color, clip_bounds)
);
}
}

Expand Down
14 changes: 7 additions & 7 deletions tiny_skia/src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::core::{Background, Color, Gradient, Rectangle, Vector};
use crate::graphics::backend;
use crate::graphics::{Damage, Viewport};
use crate::graphics::Viewport;
use crate::primitive::{self, Primitive};

use std::borrow::Cow;
Expand Down Expand Up @@ -361,11 +361,10 @@ impl Backend {
paragraph,
position,
color,
clip_bounds: text_clip_bounds,
} => {
let physical_bounds =
(Rectangle::new(*position, paragraph.min_bounds)
+ translation)
* scale_factor;
(*text_clip_bounds + translation) * scale_factor;

if !clip_bounds.intersects(&physical_bounds) {
return;
Expand All @@ -387,10 +386,10 @@ impl Backend {
editor,
position,
color,
clip_bounds: text_clip_bounds,
} => {
let physical_bounds =
(Rectangle::new(*position, editor.bounds) + translation)
* scale_factor;
(*text_clip_bounds + translation) * scale_factor;

if !clip_bounds.intersects(&physical_bounds) {
return;
Expand Down Expand Up @@ -418,9 +417,10 @@ impl Backend {
horizontal_alignment,
vertical_alignment,
shaping,
clip_bounds: text_clip_bounds,
} => {
let physical_bounds =
(primitive.bounds() + translation) * scale_factor;
(*text_clip_bounds + translation) * scale_factor;

if !clip_bounds.intersects(&physical_bounds) {
return;
Expand Down
15 changes: 9 additions & 6 deletions tiny_skia/src/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,25 @@ impl Frame {
Point::new(transformed[0].x, transformed[0].y)
};

let bounds = Rectangle {
x: position.x,
y: position.y,
width: f32::INFINITY,
height: f32::INFINITY,
};

// TODO: Use vectorial text instead of primitive
self.primitives.push(Primitive::Text {
content: text.content,
bounds: Rectangle {
x: position.x,
y: position.y,
width: f32::INFINITY,
height: f32::INFINITY,
},
bounds,
color: text.color,
size: text.size,
line_height: text.line_height,
font: text.font,
horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment,
shaping: text.shaping,
clip_bounds: Rectangle::with_size(Size::INFINITY),
});
}

Expand Down
15 changes: 9 additions & 6 deletions wgpu/src/geometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,22 +328,25 @@ impl Frame {
Point::new(transformed.x, transformed.y)
};

let bounds = Rectangle {
x: position.x,
y: position.y,
width: f32::INFINITY,
height: f32::INFINITY,
};

// TODO: Use vectorial text instead of primitive
self.primitives.push(Primitive::Text {
content: text.content,
bounds: Rectangle {
x: position.x,
y: position.y,
width: f32::INFINITY,
height: f32::INFINITY,
},
bounds,
color: text.color,
size: text.size,
line_height: text.line_height,
font: text.font,
horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment,
shaping: text.shaping,
clip_bounds: Rectangle::with_size(Size::INFINITY),
});
}

Expand Down
Loading

0 comments on commit 8727b3f

Please sign in to comment.