diff --git a/crates/egui/src/text_selection/accesskit_text.rs b/crates/egui/src/text_selection/accesskit_text.rs index 99599d018..f56ab9edd 100644 --- a/crates/egui/src/text_selection/accesskit_text.rs +++ b/crates/egui/src/text_selection/accesskit_text.rs @@ -77,7 +77,7 @@ pub fn update_accesskit_for_text_widget( value.push(glyph.chr); character_lengths.push((value.len() - old_len) as _); character_positions.push(glyph.pos.x - row.rect.min.x); - character_widths.push(glyph.size.x); + character_widths.push(glyph.advance_width); } if row.ends_with_newline { diff --git a/crates/epaint/src/text/text_layout.rs b/crates/epaint/src/text/text_layout.rs index 149b4972b..8399b22cd 100644 --- a/crates/epaint/src/text/text_layout.rs +++ b/crates/epaint/src/text/text_layout.rs @@ -171,9 +171,11 @@ fn layout_section( paragraph.glyphs.push(Glyph { chr, pos: pos2(paragraph.cursor_x, f32::NAN), - size: vec2(glyph_info.advance_width, line_height), + advance_width: glyph_info.advance_width, + line_height, font_impl_height: font_impl.map_or(0.0, |f| f.row_height()), font_impl_ascent: font_impl.map_or(0.0, |f| f.ascent()), + font_height: font.row_height(), font_ascent: font.ascent(), uv_rect: glyph_info.uv_rect, section_index, @@ -378,7 +380,7 @@ fn replace_last_glyph_with_overflow_character( let (_, last_glyph_info) = font.font_impl_and_glyph_info(last_glyph.chr); - let mut x = last_glyph.pos.x + last_glyph.size.x; + let mut x = last_glyph.pos.x + last_glyph.advance_width; let (font_impl, replacement_glyph_info) = font.font_impl_and_glyph_info(overflow_character); @@ -393,9 +395,11 @@ fn replace_last_glyph_with_overflow_character( row.glyphs.push(Glyph { chr: overflow_character, pos: pos2(x, f32::NAN), - size: vec2(replacement_glyph_info.advance_width, line_height), + advance_width: replacement_glyph_info.advance_width, + line_height, font_impl_height: font_impl.map_or(0.0, |f| f.row_height()), font_impl_ascent: font_impl.map_or(0.0, |f| f.ascent()), + font_height: font.row_height(), font_ascent: font.ascent(), uv_rect: replacement_glyph_info.uv_rect, section_index, @@ -413,9 +417,11 @@ fn replace_last_glyph_with_overflow_character( row.glyphs.push(Glyph { chr: overflow_character, pos: pos2(x, f32::NAN), - size: vec2(replacement_glyph_info.advance_width, line_height), + advance_width: replacement_glyph_info.advance_width, + line_height, font_impl_height: font_impl.map_or(0.0, |f| f.row_height()), font_impl_ascent: font_impl.map_or(0.0, |f| f.ascent()), + font_height: font.row_height(), font_ascent: font.ascent(), uv_rect: replacement_glyph_info.uv_rect, section_index, @@ -444,7 +450,6 @@ fn replace_last_glyph_with_overflow_character( let section = &job.sections[last_glyph.section_index as usize]; let extra_letter_spacing = section.format.extra_letter_spacing; let font = fonts.font(§ion.format.font_id); - let line_height = row_height(section, font); if let Some(prev_glyph) = prev_glyph { let prev_glyph_id = font.font_impl_and_glyph_info(prev_glyph.chr).1.id; @@ -459,7 +464,9 @@ fn replace_last_glyph_with_overflow_character( // Replace the glyph: last_glyph.chr = overflow_character; let (font_impl, glyph_info) = font.font_impl_and_glyph_info(last_glyph.chr); - last_glyph.size = vec2(glyph_info.advance_width, line_height); + last_glyph.advance_width = glyph_info.advance_width; + last_glyph.font_impl_ascent = font_impl.map_or(0.0, |f| f.ascent()); + last_glyph.font_impl_height = font_impl.map_or(0.0, |f| f.row_height()); last_glyph.uv_rect = glyph_info.uv_rect; // Reapply kerning: @@ -478,8 +485,10 @@ fn replace_last_glyph_with_overflow_character( } else { // Just replace and be done with it. last_glyph.chr = overflow_character; - let (_, glyph_info) = font.font_impl_and_glyph_info(last_glyph.chr); - last_glyph.size = vec2(glyph_info.advance_width, line_height); + let (font_impl, glyph_info) = font.font_impl_and_glyph_info(last_glyph.chr); + last_glyph.advance_width = glyph_info.advance_width; + last_glyph.font_impl_ascent = font_impl.map_or(0.0, |f| f.ascent()); + last_glyph.font_impl_height = font_impl.map_or(0.0, |f| f.row_height()); last_glyph.uv_rect = glyph_info.uv_rect; return; } @@ -591,12 +600,12 @@ fn galley_from_rows( let mut min_x: f32 = 0.0; let mut max_x: f32 = 0.0; for row in &mut rows { - let mut row_height = first_row_min_height.max(row.rect.height()); + let mut max_row_height = first_row_min_height.max(row.rect.height()); first_row_min_height = 0.0; for glyph in &row.glyphs { - row_height = row_height.max(glyph.size.y); + max_row_height = max_row_height.max(glyph.line_height); } - row_height = point_scale.round_to_pixel(row_height); + max_row_height = point_scale.round_to_pixel(max_row_height); // Now position each glyph: for glyph in &mut row.glyphs { @@ -606,21 +615,21 @@ fn galley_from_rows( + glyph.font_impl_ascent // Apply valign to the different in height of the entire row, and the height of this `Font`: - + format.valign.to_factor() * (row_height - glyph.size.y) + + format.valign.to_factor() * (max_row_height - glyph.line_height) // When mixing different `FontImpl` (e.g. latin and emojis), // we always center the difference: - + 0.5 * (glyph.size.y - glyph.font_impl_height); + + 0.5 * (glyph.line_height - glyph.font_impl_height); glyph.pos.y = point_scale.round_to_pixel(glyph.pos.y); } row.rect.min.y = cursor_y; - row.rect.max.y = cursor_y + row_height; + row.rect.max.y = cursor_y + max_row_height; min_x = min_x.min(row.rect.min.x); max_x = max_x.max(row.rect.max.x); - cursor_y += row_height; + cursor_y += max_row_height; cursor_y = point_scale.round_to_pixel(cursor_y); } diff --git a/crates/epaint/src/text/text_layout_types.rs b/crates/epaint/src/text/text_layout_types.rs index c614e6ef6..856bd1edf 100644 --- a/crates/epaint/src/text/text_layout_types.rs +++ b/crates/epaint/src/text/text_layout_types.rs @@ -608,20 +608,23 @@ pub struct Glyph { /// Logical position: pos.y is the same for all chars of the same [`TextFormat`]. pub pos: Pos2, - /// `ascent` value from the `Font` + pub advance_width: f32, + + /// Height of this row + pub line_height: f32, + + /// [`Font::ascent`] pub font_ascent: f32, - /// `row_height` value from the `FontImpl` + /// [`Font::row_height`] + pub font_height: f32, + + /// [`FontImpl::row_height`] pub font_impl_height: f32, - /// `ascent` value from the `FontImpl` + /// [`FontImpl::ascent`] pub font_impl_ascent: f32, - /// Advance width and line height. - /// - /// Does not control the visual size of the glyph (see [`Self::uv_rect`] for that). - pub size: Vec2, - /// Position and size of the glyph in the font texture, in texels. pub uv_rect: UvRect, @@ -630,14 +633,20 @@ pub struct Glyph { } impl Glyph { + #[inline] + pub fn size(&self) -> Vec2 { + Vec2::new(self.advance_width, self.line_height) + } + + #[inline] pub fn max_x(&self) -> f32 { - self.pos.x + self.size.x + self.pos.x + self.advance_width } /// Same y range for all characters with the same [`TextFormat`]. #[inline] pub fn logical_rect(&self) -> Rect { - Rect::from_min_size(self.pos - vec2(0.0, self.font_ascent), self.size) + Rect::from_min_size(self.pos - vec2(0.0, self.font_ascent), self.size()) } }