summaryrefslogtreecommitdiffstats
path: root/wgpu
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-05-08 16:41:42 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-05-08 16:41:42 +0200
commit9a8b30d7e9cf76c097d68c84736e7687b452d5c0 (patch)
treee08118a92d562fe5f93640fa519d40b773849520 /wgpu
parentc6d9221ee42b2838ca07b79df710d3d224e1c52a (diff)
downloadiced-9a8b30d7e9cf76c097d68c84736e7687b452d5c0.tar.gz
iced-9a8b30d7e9cf76c097d68c84736e7687b452d5c0.tar.bz2
iced-9a8b30d7e9cf76c097d68c84736e7687b452d5c0.zip
Clip text that exceeds section bounds in `iced_wgpu`
Diffstat (limited to 'wgpu')
-rw-r--r--wgpu/src/text.rs124
1 files changed, 68 insertions, 56 deletions
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs
index cf9fbad3..714e0400 100644
--- a/wgpu/src/text.rs
+++ b/wgpu/src/text.rs
@@ -96,64 +96,76 @@ impl Pipeline {
})
.collect();
- let bounds = glyphon::TextBounds {
- left: (bounds.x * scale_factor) as i32,
- top: (bounds.y * scale_factor) as i32,
- right: ((bounds.x + bounds.width) * scale_factor) as i32,
- bottom: ((bounds.y + bounds.height) * scale_factor) as i32,
- };
+ let bounds = bounds * scale_factor;
let text_areas =
- sections.iter().zip(keys.iter()).map(|(section, key)| {
- let buffer =
- self.render_cache.get(key).expect("Get cached buffer");
-
- let x = section.bounds.x * scale_factor;
- let y = section.bounds.y * scale_factor;
-
- let (total_lines, max_width) = buffer
- .layout_runs()
- .enumerate()
- .fold((0, 0.0), |(_, max), (i, buffer)| {
- (i + 1, buffer.line_w.max(max))
- });
-
- let total_height =
- total_lines as f32 * buffer.metrics().line_height;
-
- let left = match section.horizontal_alignment {
- alignment::Horizontal::Left => x,
- alignment::Horizontal::Center => x - max_width / 2.0,
- alignment::Horizontal::Right => x - max_width,
- };
-
- let top = match section.vertical_alignment {
- alignment::Vertical::Top => y,
- alignment::Vertical::Center => y - total_height / 2.0,
- alignment::Vertical::Bottom => y - total_height,
- };
-
- // TODO: Subpixel glyph positioning
- let left = left.round() as i32;
- let top = top.round() as i32;
-
- glyphon::TextArea {
- buffer,
- left,
- top,
- bounds,
- default_color: {
- let [r, g, b, a] = section.color.into_linear();
-
- glyphon::Color::rgba(
- (r * 255.0) as u8,
- (g * 255.0) as u8,
- (b * 255.0) as u8,
- (a * 255.0) as u8,
- )
- },
- }
- });
+ sections
+ .iter()
+ .zip(keys.iter())
+ .filter_map(|(section, key)| {
+ let buffer =
+ self.render_cache.get(key).expect("Get cached buffer");
+
+ let (total_lines, max_width) = buffer
+ .layout_runs()
+ .enumerate()
+ .fold((0, 0.0), |(_, max), (i, buffer)| {
+ (i + 1, buffer.line_w.max(max))
+ });
+
+ let total_height =
+ total_lines as f32 * buffer.metrics().line_height;
+
+ let x = section.bounds.x * scale_factor;
+ let y = section.bounds.y * scale_factor;
+
+ let left = match section.horizontal_alignment {
+ alignment::Horizontal::Left => x,
+ alignment::Horizontal::Center => x - max_width / 2.0,
+ alignment::Horizontal::Right => x - max_width,
+ };
+
+ let top = match section.vertical_alignment {
+ alignment::Vertical::Top => y,
+ alignment::Vertical::Center => y - total_height / 2.0,
+ alignment::Vertical::Bottom => y - total_height,
+ };
+
+ let section_bounds = Rectangle {
+ x: left,
+ y: top,
+ width: section.bounds.width * scale_factor,
+ height: section.bounds.height * scale_factor,
+ };
+
+ let clip_bounds = bounds.intersection(&section_bounds)?;
+
+ // TODO: Subpixel glyph positioning
+ let left = left.round() as i32;
+ let top = top.round() as i32;
+
+ Some(glyphon::TextArea {
+ buffer,
+ left,
+ top,
+ bounds: glyphon::TextBounds {
+ left: clip_bounds.x as i32,
+ top: clip_bounds.y as i32,
+ right: (clip_bounds.x + clip_bounds.width) as i32,
+ bottom: (clip_bounds.y + clip_bounds.height) as i32,
+ },
+ default_color: {
+ let [r, g, b, a] = section.color.into_linear();
+
+ glyphon::Color::rgba(
+ (r * 255.0) as u8,
+ (g * 255.0) as u8,
+ (b * 255.0) as u8,
+ (a * 255.0) as u8,
+ )
+ },
+ })
+ });
let result = renderer.prepare(
device,