Skip to content

Commit

Permalink
Add TextFormat::extra_letter_spacing
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Sep 4, 2023
1 parent 8c84bbf commit d5f834d
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 9 deletions.
12 changes: 12 additions & 0 deletions crates/egui/src/widget_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::{
pub struct RichText {
text: String,
size: Option<f32>,
extra_letter_spacing: f32,
family: Option<FontFamily>,
text_style: Option<TextStyle>,
background_color: Color32,
Expand Down Expand Up @@ -100,6 +101,15 @@ impl RichText {
self
}

/// Extra spacing between letters, in points.
///
/// Default: 0.0. Round to whole _pixels_ for crisp text.
#[inline]
pub fn extra_letter_spacing(mut self, extra_letter_spacing: f32) -> Self {
self.extra_letter_spacing = extra_letter_spacing;
self
}

/// Select the font family.
///
/// This overrides the value from [`Self::text_style`].
Expand Down Expand Up @@ -253,6 +263,7 @@ impl RichText {
let Self {
text,
size,
extra_letter_spacing,
family,
text_style,
background_color,
Expand Down Expand Up @@ -315,6 +326,7 @@ impl RichText {
underline,
strikethrough,
valign,
extra_letter_spacing,
};

let job = LayoutJob::single_section(text, text_format);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,6 @@ fn format_from_style(
underline,
strikethrough,
valign,
..Default::default()
}
}
23 changes: 15 additions & 8 deletions crates/epaint/src/text/text_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ fn layout_section(
paragraph.cursor_x += font_impl.pair_kerning(last_glyph_id, glyph_info.id);
}
}
paragraph.cursor_x += section.format.extra_letter_spacing;

paragraph.glyphs.push(Glyph {
chr,
Expand Down Expand Up @@ -338,10 +339,13 @@ fn replace_last_glyph_with_overflow_character(

// undo kerning with previous glyph
let (font_impl, glyph_info) = font.glyph_info_and_font_impl(last_glyph.chr);
last_glyph.pos.x -= font_impl
.zip(prev_glyph_id)
.map(|(font_impl, prev_glyph_id)| font_impl.pair_kerning(prev_glyph_id, glyph_info.id))
.unwrap_or_default();
last_glyph.pos.x -= section.format.extra_letter_spacing
+ font_impl
.zip(prev_glyph_id)
.map(|(font_impl, prev_glyph_id)| {
font_impl.pair_kerning(prev_glyph_id, glyph_info.id)
})
.unwrap_or_default();

// replace the glyph
last_glyph.chr = overflow_character;
Expand All @@ -351,10 +355,13 @@ fn replace_last_glyph_with_overflow_character(
last_glyph.ascent = glyph_info.ascent;

// reapply kerning
last_glyph.pos.x += font_impl
.zip(prev_glyph_id)
.map(|(font_impl, prev_glyph_id)| font_impl.pair_kerning(prev_glyph_id, glyph_info.id))
.unwrap_or_default();
last_glyph.pos.x += section.format.extra_letter_spacing
+ font_impl
.zip(prev_glyph_id)
.map(|(font_impl, prev_glyph_id)| {
font_impl.pair_kerning(prev_glyph_id, glyph_info.id)
})
.unwrap_or_default();

row.rect.max.x = last_glyph.max_x();

Expand Down
33 changes: 32 additions & 1 deletion crates/epaint/src/text/text_layout_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,17 @@ impl std::hash::Hash for LayoutSection {

// ----------------------------------------------------------------------------

#[derive(Clone, Debug, Hash, PartialEq)]
/// Formatting option for a section of text.
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct TextFormat {
pub font_id: FontId,

/// Extra spacing between letters, in points.
///
/// Default: 0.0. Round to whole _pixels_ for crisp text.
pub extra_letter_spacing: f32,

/// Text color
pub color: Color32,

Expand All @@ -243,6 +249,30 @@ pub struct TextFormat {
// TODO(emilk): lowered
}

impl std::hash::Hash for TextFormat {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
let Self {
font_id,
extra_letter_spacing,
color,
background,
italics,
underline,
strikethrough,
valign,
} = self;
font_id.hash(state);
crate::f32_hash(state, *extra_letter_spacing);
color.hash(state);
background.hash(state);
italics.hash(state);
underline.hash(state);
strikethrough.hash(state);
valign.hash(state);
}
}

impl Default for TextFormat {
#[inline]
fn default() -> Self {
Expand All @@ -254,6 +284,7 @@ impl Default for TextFormat {
underline: Stroke::NONE,
strikethrough: Stroke::NONE,
valign: Align::BOTTOM,
extra_letter_spacing: 0.0,
}
}
}
Expand Down

0 comments on commit d5f834d

Please sign in to comment.