Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion benches/wgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use criterion::{Bencher, Criterion, criterion_group, criterion_main};
use iced::alignment;
use iced::mouse;
use iced::widget::{canvas, scrollable, stack, text};
use iced::{Color, Element, Font, Length, Pixels, Point, Rectangle, Size, Theme};
use iced::{Color, Element, Em, Font, Length, Pixels, Point, Rectangle, Size, Theme};
use iced_wgpu::Renderer;
use iced_wgpu::wgpu;

Expand Down Expand Up @@ -186,6 +186,7 @@ fn scene<'a, Message: 'a>(n: usize) -> Element<'a, Message, Theme, Renderer> {
wrapping: text::Wrapping::default(),
ellipsis: text::Ellipsis::default(),
max_width: f32::INFINITY,
letter_spacing: Em::ZERO,
});
}
})]
Expand Down
47 changes: 47 additions & 0 deletions core/src/em.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/// A value in EM units.
///
/// An EM is a typographic unit of measurement equal to the current font size.
/// It's commonly used for sizing that scales proportionally with text, such as
/// margins, padding, widths, and spacing.
///
/// This type is normally used as an argument in a generic way
/// (e.g. `impl Into<Em>`) and, since `Em` implements `From` both for
/// `f32` and integer types, you should be able to provide both integers and float
/// literals as needed.
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
pub struct Em(pub f32);

impl Em {
/// Zero EM units.
pub const ZERO: Self = Self(0.0);
}

impl From<f32> for Em {
fn from(amount: f32) -> Self {
Self(amount)
}
}

impl From<i32> for Em {
fn from(amount: i32) -> Self {
Self(amount as f32)
}
}

impl From<u32> for Em {
fn from(amount: u32) -> Self {
Self(amount as f32)
}
}

impl From<usize> for Em {
fn from(amount: usize) -> Self {
Self(amount as f32)
}
}

impl From<Em> for f32 {
fn from(spacing: Em) -> Self {
spacing.0
}
}
2 changes: 2 additions & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ mod background;
mod color;
mod content_fit;
mod element;
mod em;
mod length;
mod pixels;
mod point;
Expand All @@ -58,6 +59,7 @@ pub use clipboard::Clipboard;
pub use color::Color;
pub use content_fit::ContentFit;
pub use element::Element;
pub use em::Em;
pub use event::Event;
pub use font::Font;
pub use gradient::Gradient;
Expand Down
7 changes: 6 additions & 1 deletion core/src/renderer/null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::image::{self, Image};
use crate::renderer::{self, Renderer};
use crate::svg;
use crate::text::{self, Text};
use crate::{Background, Color, Font, Pixels, Point, Rectangle, Size, Transformation};
use crate::{Background, Color, Em, Font, Pixels, Point, Rectangle, Size, Transformation};

impl Renderer for () {
fn start_layer(&mut self, _bounds: Rectangle) {}
Expand Down Expand Up @@ -133,6 +133,10 @@ impl text::Paragraph for () {
text::Shaping::default()
}

fn letter_spacing(&self) -> Em {
Em::ZERO
}

fn grapheme_position(&self, _line: usize, _index: usize) -> Option<Point> {
None
}
Expand Down Expand Up @@ -212,6 +216,7 @@ impl text::Editor for () {
_new_font: Self::Font,
_new_size: Pixels,
_new_line_height: text::LineHeight,
_new_letter_spacing: Em,
_new_wrapping: text::Wrapping,
_new_hint_factor: Option<f32>,
_new_highlighter: &mut impl text::Highlighter,
Expand Down
17 changes: 16 additions & 1 deletion core/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub use highlighter::Highlighter;
pub use paragraph::Paragraph;

use crate::alignment;
use crate::{Background, Border, Color, Padding, Pixels, Point, Rectangle, Size};
use crate::{Background, Border, Color, Em, Padding, Pixels, Point, Rectangle, Size};

use std::borrow::Cow;
use std::hash::{Hash, Hasher};
Expand Down Expand Up @@ -46,6 +46,9 @@ pub struct Text<Content = String, Font = crate::Font> {
/// The [`Ellipsis`] strategy of the [`Text`].
pub ellipsis: Ellipsis,

/// The letter spacing of the [`Text`].
pub letter_spacing: Em,

/// The scale factor that may be used to internally scale the layout
/// calculation of the [`Paragraph`] and leverage metrics hinting.
///
Expand Down Expand Up @@ -75,6 +78,7 @@ where
shaping: self.shaping,
wrapping: self.wrapping,
ellipsis: self.ellipsis,
letter_spacing: self.letter_spacing,
hint_factor: self.hint_factor,
}
}
Expand Down Expand Up @@ -428,6 +432,8 @@ pub struct Span<'a, Link = (), Font = crate::Font> {
pub underline: bool,
/// Whether the [`Span`] should be struck through or not.
pub strikethrough: bool,
/// The letter spacing of the [`Span`].
pub letter_spacing: Option<Em>,
}

/// A text highlight.
Expand Down Expand Up @@ -572,6 +578,12 @@ impl<'a, Link, Font> Span<'a, Link, Font> {
self
}

/// Sets the letter spacing of the [`Span`].
pub fn letter_spacing(mut self, letter_spacing: impl Into<Em>) -> Self {
self.letter_spacing = Some(letter_spacing.into());
self
}

/// Turns the [`Span`] into a static one.
pub fn to_static(self) -> Span<'static, Link, Font> {
Span {
Expand All @@ -585,6 +597,7 @@ impl<'a, Link, Font> Span<'a, Link, Font> {
padding: self.padding,
underline: self.underline,
strikethrough: self.strikethrough,
letter_spacing: self.letter_spacing,
}
}
}
Expand All @@ -602,6 +615,7 @@ impl<Link, Font> Default for Span<'_, Link, Font> {
padding: Padding::default(),
underline: false,
strikethrough: false,
letter_spacing: None,
}
}
}
Expand All @@ -619,6 +633,7 @@ impl<Link, Font: PartialEq> PartialEq for Span<'_, Link, Font> {
&& self.line_height == other.line_height
&& self.font == other.font
&& self.color == other.color
&& self.letter_spacing == other.letter_spacing
}
}

Expand Down
1 change: 1 addition & 0 deletions core/src/text/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub trait Editor: Sized + Default {
new_font: Self::Font,
new_size: Pixels,
new_line_height: LineHeight,
new_letter_spacing: crate::Em,
new_wrapping: Wrapping,
new_hint_factor: Option<f32>,
new_highlighter: &mut impl Highlighter,
Expand Down
6 changes: 5 additions & 1 deletion core/src/text/paragraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::alignment;
use crate::text::{
Alignment, Difference, Ellipsis, Hit, LineHeight, Shaping, Span, Text, Wrapping,
};
use crate::{Pixels, Point, Rectangle, Size};
use crate::{Em, Pixels, Point, Rectangle, Size};

/// A text paragraph.
pub trait Paragraph: Sized + Default {
Expand Down Expand Up @@ -50,6 +50,9 @@ pub trait Paragraph: Sized + Default {
/// Returns the [`Shaping`] strategy of the [`Paragraph`]>
fn shaping(&self) -> Shaping;

/// Returns the letter spacing of the [`Paragraph`].
fn letter_spacing(&self) -> Em;

/// Returns the available bounds used to layout the [`Paragraph`].
fn bounds(&self) -> Size;

Expand Down Expand Up @@ -174,6 +177,7 @@ impl<P: Paragraph> Plain<P> {
shaping: self.raw.shaping(),
wrapping: self.raw.wrapping(),
ellipsis: self.raw.ellipsis(),
letter_spacing: self.raw.letter_spacing(),
hint_factor: self.raw.hint_factor(),
}
}
Expand Down
11 changes: 10 additions & 1 deletion core/src/widget/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::renderer;
use crate::text;
use crate::text::paragraph::{self, Paragraph};
use crate::widget::tree::{self, Tree};
use crate::{Color, Element, Layout, Length, Pixels, Rectangle, Size, Theme, Widget};
use crate::{Color, Element, Em, Layout, Length, Pixels, Rectangle, Size, Theme, Widget};

pub use text::{Alignment, Ellipsis, LineHeight, Shaping, Wrapping};

Expand Down Expand Up @@ -154,6 +154,12 @@ where
self
}

/// Sets the letter spacing of the [`Text`].
pub fn letter_spacing(mut self, letter_spacing: impl Into<Em>) -> Self {
self.format.letter_spacing = letter_spacing.into();
self
}

/// Sets the style of the [`Text`].
pub fn style(mut self, style: impl Fn(&Theme) -> Style + 'a) -> Self
where
Expand Down Expand Up @@ -278,6 +284,7 @@ pub struct Format<Font> {
pub shaping: Shaping,
pub wrapping: Wrapping,
pub ellipsis: Ellipsis,
pub letter_spacing: Em,
}

impl<Font> Default for Format<Font> {
Expand All @@ -293,6 +300,7 @@ impl<Font> Default for Format<Font> {
shaping: Shaping::default(),
wrapping: Wrapping::default(),
ellipsis: Ellipsis::default(),
letter_spacing: Em::ZERO,
}
}
}
Expand Down Expand Up @@ -325,6 +333,7 @@ where
shaping: format.shaping,
wrapping: format.wrapping,
ellipsis: format.ellipsis,
letter_spacing: format.letter_spacing,
hint_factor: renderer.scale_factor(),
});

Expand Down
14 changes: 14 additions & 0 deletions examples/letter_spacing/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "letter_spacing"
version = "0.1.0"
authors = ["Andy Terra <tech@andyterra.com>"]
edition = "2024"
publish = false

[dependencies]
iced.workspace = true
iced.features = ["tokio"]
hyper = { version = "1", features = ["http1", "http2"] }
hyper-util = { version = "0.1", features = ["client-legacy", "http1", "http2", "tokio"] }
hyper-tls = "0.6"
http-body-util = "0.1"
Loading
Loading