Add Auto strategy to text::Shaping

This commit is contained in:
Héctor Ramón Jiménez 2025-08-30 18:15:12 +02:00
parent d31a7b6ae8
commit bc7d64987e
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
8 changed files with 47 additions and 11 deletions

View file

@ -69,6 +69,10 @@ advanced = ["iced_core/advanced", "iced_widget/advanced"]
fira-sans = ["iced_renderer/fira-sans"]
# Auto-detects light/dark mode for the built-in theme
auto-detect-theme = ["iced_core/auto-detect-theme"]
# Enables basic text shaping by default
basic-shaping = ["iced_core/basic-shaping"]
# Enables advanced text shaping by default
advanced-shaping = ["iced_core/advanced-shaping"]
# Enables strict assertions for debugging purposes at the expense of performance
strict-assertions = ["iced_renderer/strict-assertions"]
# Redraws on every runtime event, and not only when a widget requests it

View file

@ -17,6 +17,8 @@ workspace = true
auto-detect-theme = ["dep:dark-light"]
advanced = []
crisp = []
basic-shaping = []
advanced-shaping = []
[dependencies]
bitflags.workspace = true

View file

@ -130,8 +130,17 @@ impl From<Alignment> for alignment::Horizontal {
}
/// The shaping strategy of some text.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Shaping {
/// Auto-detect the best shaping strategy from the text.
///
/// This strategy will use [`Basic`](Self::Basic) shaping if the
/// text consists of only ASCII characters; otherwise, it will
/// use [`Advanced`](Self::Advanced) shaping.
///
/// This is the default, if neither the `basic-shaping` nor `advanced-shaping`
/// features are enabled.
Auto,
/// No shaping and no font fallback.
///
/// This shaping strategy is very cheap, but it will not display complex
@ -140,8 +149,8 @@ pub enum Shaping {
/// You should use this strategy when you have complete control of the text
/// and the font you are displaying in your application.
///
/// This is the default.
#[default]
/// This will be the default if the `basic-shaping` feature is enabled and
/// the `advanced-shaping` feature is disabled.
Basic,
/// Advanced text shaping and font fallback.
///
@ -150,9 +159,23 @@ pub enum Shaping {
/// may be needed to display all of the glyphs.
///
/// Advanced shaping is expensive! You should only enable it when necessary.
///
/// This will be the default if the `advanced-shaping` feature is enabled.
Advanced,
}
impl Default for Shaping {
fn default() -> Self {
if cfg!(feature = "advanced-shaping") {
Self::Advanced
} else if cfg!(feature = "basic-shaping") {
Self::Basic
} else {
Self::Auto
}
}
}
/// The wrapping strategy of some text.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum Wrapping {

View file

@ -94,14 +94,14 @@ impl Layout {
let controls = row([
(!self.example.is_first()).then_some(
button(text("← Previous").shaping(text::Shaping::Advanced))
button(text("← Previous"))
.padding([5, 10])
.on_press(Message::Previous)
.into(),
),
Some(horizontal_space().into()),
(!self.example.is_last()).then_some(
button(text("Next →").shaping(text::Shaping::Advanced))
button(text("Next →"))
.padding([5, 10])
.on_press(Message::Next)
.into(),
@ -313,7 +313,7 @@ fn quotes<'a>() -> Element<'a, Message> {
"This is another reply",
),
horizontal_rule(1),
text("A separator ↑").shaping(text::Shaping::Advanced),
text("A separator ↑"),
]
.width(Shrink)
.spacing(10)

View file

@ -1 +1 @@
0650eb2c27c21c5d48e1e00031a52d8471d8a3b4e827ad502c4628914f5c1c13
129523830df064908cfa911214ba61dadc31d8975425ba3efaae69da9514a3d0

View file

@ -323,8 +323,15 @@ fn to_align(alignment: Alignment) -> Option<cosmic_text::Align> {
}
/// Converts some [`Shaping`] strategy to a [`cosmic_text::Shaping`] strategy.
pub fn to_shaping(shaping: Shaping) -> cosmic_text::Shaping {
pub fn to_shaping(shaping: Shaping, text: &str) -> cosmic_text::Shaping {
match shaping {
Shaping::Auto => {
if text.is_ascii() {
cosmic_text::Shaping::Basic
} else {
cosmic_text::Shaping::Advanced
}
}
Shaping::Basic => cosmic_text::Shaping::Basic,
Shaping::Advanced => cosmic_text::Shaping::Advanced,
}

View file

@ -55,7 +55,7 @@ impl Cache {
font_system,
key.content,
&text::to_attributes(key.font),
text::to_shaping(key.shaping),
text::to_shaping(key.shaping, key.content),
);
let bounds = text::align(&mut buffer, font_system, key.align_x);

View file

@ -88,7 +88,7 @@ impl core::text::Paragraph for Paragraph {
font_system.raw(),
text.content,
&text::to_attributes(text.font),
text::to_shaping(text.shaping),
text::to_shaping(text.shaping, text.content),
);
let min_bounds =
@ -158,7 +158,7 @@ impl core::text::Paragraph for Paragraph {
(span.text.as_ref(), attrs.metadata(i))
}),
&text::to_attributes(text.font),
text::to_shaping(text.shaping),
cosmic_text::Shaping::Advanced,
None,
);