From c50190a7e88f0cda1766313095d8e7792fecdf86 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 30 Jan 2021 14:48:36 +0100 Subject: [PATCH] Add fake italics (tilt text) --- CHANGELOG.md | 2 +- egui/src/painter.rs | 12 ++++++++++++ egui/src/widgets/label.rs | 12 +++++++++++- epaint/src/mesh.rs | 34 +++++++++++++++------------------- epaint/src/shape.rs | 3 +++ epaint/src/tessellator.rs | 39 ++++++++++++++++++++++++++++++++++++--- 6 files changed, 78 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abc6840d..50228c0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,9 +12,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added ⭐ * Add support for secondary and middle mouse buttons. +* Add `Label` methods for code, strong, strikethrough, underline and italics. * `egui::popup::popup_below_widget`: show a popup area below another widget. * Add `Slider::clamp_to_range(bool)`: if set, clamp the incoming and outgoing values to the slider range. -* Add `Label` methods for code, strong, strikethrough and underline. ### Changed 🔧 diff --git a/egui/src/painter.rs b/egui/src/painter.rs index 8d00533a..14051a77 100644 --- a/egui/src/painter.rs +++ b/egui/src/painter.rs @@ -269,11 +269,23 @@ impl Painter { /// Paint text that has already been layed out in a `Galley`. pub fn galley(&self, pos: Pos2, galley: Galley, text_style: TextStyle, color: Color32) { + self.galley_with_italics(pos, galley, text_style, color, false) + } + + pub fn galley_with_italics( + &self, + pos: Pos2, + galley: Galley, + text_style: TextStyle, + color: Color32, + fake_italics: bool, + ) { self.add(Shape::Text { pos, galley, text_style, color, + fake_italics, }); } } diff --git a/egui/src/widgets/label.rs b/egui/src/widgets/label.rs index a7a2c044..e4348f26 100644 --- a/egui/src/widgets/label.rs +++ b/egui/src/widgets/label.rs @@ -13,6 +13,7 @@ pub struct Label { strong: bool, strikethrough: bool, underline: bool, + italics: bool, } impl Label { @@ -27,6 +28,7 @@ impl Label { strong: false, strikethrough: false, underline: false, + italics: false, } } @@ -83,6 +85,12 @@ impl Label { self } + /// tilt the characters to the right. + pub fn italics(mut self) -> Self { + self.italics = true; + self + } + pub fn small(self) -> Self { self.text_style(TextStyle::Small) } @@ -133,6 +141,7 @@ impl Label { strong, strikethrough, underline, + italics, .. } = *self; @@ -173,7 +182,8 @@ impl Label { } let text_style = self.text_style_or_default(ui.style()); - ui.painter().galley(pos, galley, text_style, text_color); + ui.painter() + .galley_with_italics(pos, galley, text_style, text_color, italics); } /// Read the text style, or get the default for the current style diff --git a/epaint/src/mesh.rs b/epaint/src/mesh.rs index 45394e7d..c532556e 100644 --- a/epaint/src/mesh.rs +++ b/epaint/src/mesh.rs @@ -114,37 +114,33 @@ impl Mesh { } /// Rectangle with a texture and color. - pub fn add_rect_with_uv(&mut self, pos: Rect, uv: Rect, color: Color32) { + pub fn add_rect_with_uv(&mut self, rect: Rect, uv: Rect, color: Color32) { #![allow(clippy::identity_op)] let idx = self.vertices.len() as u32; self.add_triangle(idx + 0, idx + 1, idx + 2); self.add_triangle(idx + 2, idx + 1, idx + 3); - let right_top = Vertex { - pos: pos.right_top(), - uv: uv.right_top(), - color, - }; - let left_top = Vertex { - pos: pos.left_top(), + self.vertices.push(Vertex { + pos: rect.left_top(), uv: uv.left_top(), color, - }; - let left_bottom = Vertex { - pos: pos.left_bottom(), + }); + self.vertices.push(Vertex { + pos: rect.right_top(), + uv: uv.right_top(), + color, + }); + self.vertices.push(Vertex { + pos: rect.left_bottom(), uv: uv.left_bottom(), color, - }; - let right_bottom = Vertex { - pos: pos.right_bottom(), + }); + self.vertices.push(Vertex { + pos: rect.right_bottom(), uv: uv.right_bottom(), color, - }; - self.vertices.push(left_top); - self.vertices.push(right_top); - self.vertices.push(left_bottom); - self.vertices.push(right_bottom); + }); } /// Uniformly colored rectangle. diff --git a/epaint/src/shape.rs b/epaint/src/shape.rs index c796a15b..9ca42c90 100644 --- a/epaint/src/shape.rs +++ b/epaint/src/shape.rs @@ -46,6 +46,8 @@ pub enum Shape { galley: Galley, text_style: TextStyle, // TODO: Font? color: Color32, + /// If true, tilt the letters for an ugly italics effect + fake_italics: bool, }, Mesh(Mesh), } @@ -138,6 +140,7 @@ impl Shape { galley, text_style, color, + fake_italics: false, } } } diff --git a/epaint/src/tessellator.rs b/epaint/src/tessellator.rs index ff2046e9..986a98a4 100644 --- a/epaint/src/tessellator.rs +++ b/epaint/src/tessellator.rs @@ -545,6 +545,7 @@ impl Tessellator { galley, text_style, color, + fake_italics, } => { if options.debug_paint_text_rects { self.tessellate_rect( @@ -557,7 +558,7 @@ impl Tessellator { out, ); } - self.tessellate_text(fonts, pos, &galley, text_style, color, out); + self.tessellate_text(fonts, pos, &galley, text_style, color, fake_italics, out); } } } @@ -592,6 +593,7 @@ impl Tessellator { stroke_path(&path.0, Closed, stroke, self.options, out); } + #[allow(clippy::too_many_arguments)] pub fn tessellate_text( &mut self, fonts: &Fonts, @@ -599,6 +601,7 @@ impl Tessellator { galley: &super::Galley, text_style: super::TextStyle, color: Color32, + fake_italics: bool, out: &mut Mesh, ) { if color == Color32::TRANSPARENT { @@ -636,12 +639,42 @@ impl Tessellator { left_top.x = font.round_to_pixel(left_top.x); // Pixel-perfection. left_top.y = font.round_to_pixel(left_top.y); // Pixel-perfection. - let pos = Rect::from_min_max(left_top, left_top + glyph.size); + let rect = Rect::from_min_max(left_top, left_top + glyph.size); let uv = Rect::from_min_max( pos2(glyph.min.0 as f32 / tex_w, glyph.min.1 as f32 / tex_h), pos2(glyph.max.0 as f32 / tex_w, glyph.max.1 as f32 / tex_h), ); - out.add_rect_with_uv(pos, uv, color); + + if fake_italics { + let idx = out.vertices.len() as u32; + out.add_triangle(idx, idx + 1, idx + 2); + out.add_triangle(idx + 2, idx + 1, idx + 3); + + let top_offset = rect.height() * 0.25 * Vec2::X; + + out.vertices.push(Vertex { + pos: rect.left_top() + top_offset, + uv: uv.left_top(), + color, + }); + out.vertices.push(Vertex { + pos: rect.right_top() + top_offset, + uv: uv.right_top(), + color, + }); + out.vertices.push(Vertex { + pos: rect.left_bottom(), + uv: uv.left_bottom(), + color, + }); + out.vertices.push(Vertex { + pos: rect.right_bottom(), + uv: uv.right_bottom(), + color, + }); + } else { + out.add_rect_with_uv(rect, uv, color); + } } } if line.ends_with_newline {