Merge pull request #2836 from iced-rs/feature/justified-text

Introduce `text::Alignment` with `Justified` support
This commit is contained in:
Héctor 2025-03-11 03:05:11 +01:00 committed by GitHub
commit fd5ed0d0a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 264 additions and 205 deletions

1
Cargo.lock generated
View file

@ -6026,6 +6026,7 @@ dependencies = [
"console_error_panic_hook",
"console_log",
"iced",
"open",
"tracing-subscriber",
]

View file

@ -191,8 +191,8 @@ fn scene<'a, Message: 'a>(n: usize) -> Element<'a, Message, Theme, Renderer> {
size: Pixels::from(16),
line_height: text::LineHeight::default(),
font: Font::DEFAULT,
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
align_x: alignment::Horizontal::Left,
align_y: alignment::Vertical::Top,
shaping: text::Shaping::Basic,
});
}

View file

@ -87,11 +87,11 @@ impl text::Paragraph for () {
text::Difference::None
}
fn horizontal_alignment(&self) -> Option<alignment::Horizontal> {
None
fn align_x(&self) -> text::Alignment {
text::Alignment::Default
}
fn vertical_alignment(&self) -> alignment::Vertical {
fn align_y(&self) -> alignment::Vertical {
alignment::Vertical::Top
}

View file

@ -34,10 +34,10 @@ pub struct Text<Content = String, Font = crate::Font> {
pub font: Font,
/// The horizontal alignment of the [`Text`].
pub horizontal_alignment: Option<alignment::Horizontal>,
pub align_x: Alignment,
/// The vertical alignment of the [`Text`].
pub vertical_alignment: alignment::Vertical,
pub align_y: alignment::Vertical,
/// The [`Shaping`] strategy of the [`Text`].
pub shaping: Shaping,
@ -46,6 +46,45 @@ pub struct Text<Content = String, Font = crate::Font> {
pub wrapping: Wrapping,
}
/// The alignment of some text.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum Alignment {
/// No specific alignment.
///
/// Left-to-right text will be aligned to the left, while
/// right-to-left text will be aligned to the right.
#[default]
Default,
/// Align text to the left.
Left,
/// Center text.
Center,
/// Align text to the right.
Right,
/// Justify text.
Justified,
}
impl From<alignment::Horizontal> for Alignment {
fn from(alignment: alignment::Horizontal) -> Self {
match alignment {
alignment::Horizontal::Left => Self::Left,
alignment::Horizontal::Center => Self::Center,
alignment::Horizontal::Right => Self::Right,
}
}
}
impl From<crate::Alignment> for Alignment {
fn from(alignment: crate::Alignment) -> Self {
match alignment {
crate::Alignment::Start => Self::Left,
crate::Alignment::Center => Self::Center,
crate::Alignment::End => Self::Right,
}
}
}
/// The shaping strategy of some text.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum Shaping {

View file

@ -1,6 +1,6 @@
//! Draw paragraphs.
use crate::alignment;
use crate::text::{Difference, Hit, Span, Text};
use crate::text::{Alignment, Difference, Hit, Span, Text};
use crate::{Point, Rectangle, Size};
/// A text paragraph.
@ -24,10 +24,10 @@ pub trait Paragraph: Sized + Default {
fn compare(&self, text: Text<(), Self::Font>) -> Difference;
/// Returns the horizontal alignment of the [`Paragraph`].
fn horizontal_alignment(&self) -> Option<alignment::Horizontal>;
fn align_x(&self) -> Alignment;
/// Returns the vertical alignment of the [`Paragraph`].
fn vertical_alignment(&self) -> alignment::Vertical;
fn align_y(&self) -> alignment::Vertical;
/// Returns the minimum boundaries that can fit the contents of the
/// [`Paragraph`].
@ -92,8 +92,8 @@ impl<P: Paragraph> Plain<P> {
size: text.size,
line_height: text.line_height,
font: text.font,
horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment,
align_x: text.align_x,
align_y: text.align_y,
shaping: text.shaping,
wrapping: text.wrapping,
}) {
@ -108,13 +108,13 @@ impl<P: Paragraph> Plain<P> {
}
/// Returns the horizontal alignment of the [`Paragraph`].
pub fn horizontal_alignment(&self) -> Option<alignment::Horizontal> {
self.raw.horizontal_alignment()
pub fn align_x(&self) -> Alignment {
self.raw.align_x()
}
/// Returns the vertical alignment of the [`Paragraph`].
pub fn vertical_alignment(&self) -> alignment::Vertical {
self.raw.vertical_alignment()
pub fn align_y(&self) -> alignment::Vertical {
self.raw.align_y()
}
/// Returns the minimum boundaries that can fit the contents of the

View file

@ -32,7 +32,7 @@ use crate::{
Widget,
};
pub use text::{LineHeight, Shaping, Wrapping};
pub use text::{Alignment, LineHeight, Shaping, Wrapping};
/// A bunch of text.
///
@ -67,8 +67,8 @@ where
line_height: LineHeight,
width: Length,
height: Length,
horizontal_alignment: Option<alignment::Horizontal>,
vertical_alignment: alignment::Vertical,
align_x: text::Alignment,
align_y: alignment::Vertical,
font: Option<Renderer::Font>,
shaping: Shaping,
wrapping: Wrapping,
@ -89,8 +89,8 @@ where
font: None,
width: Length::Shrink,
height: Length::Shrink,
horizontal_alignment: None,
vertical_alignment: alignment::Vertical::Top,
align_x: text::Alignment::Default,
align_y: alignment::Vertical::Top,
shaping: Shaping::default(),
wrapping: Wrapping::default(),
class: Theme::default(),
@ -136,11 +136,8 @@ where
}
/// Sets the [`alignment::Horizontal`] of the [`Text`].
pub fn align_x(
mut self,
alignment: impl Into<alignment::Horizontal>,
) -> Self {
self.horizontal_alignment = Some(alignment.into());
pub fn align_x(mut self, alignment: impl Into<text::Alignment>) -> Self {
self.align_x = alignment.into();
self
}
@ -149,7 +146,7 @@ where
mut self,
alignment: impl Into<alignment::Vertical>,
) -> Self {
self.vertical_alignment = alignment.into();
self.align_y = alignment.into();
self
}
@ -245,8 +242,8 @@ where
self.line_height,
self.size,
self.font,
self.horizontal_alignment,
self.vertical_alignment,
self.align_x,
self.align_y,
self.shaping,
self.wrapping,
)
@ -290,8 +287,8 @@ pub fn layout<Renderer>(
line_height: LineHeight,
size: Option<Pixels>,
font: Option<Renderer::Font>,
horizontal_alignment: Option<alignment::Horizontal>,
vertical_alignment: alignment::Vertical,
align_x: text::Alignment,
align_y: alignment::Vertical,
shaping: Shaping,
wrapping: Wrapping,
) -> layout::Node
@ -312,8 +309,8 @@ where
size,
line_height,
font,
horizontal_alignment,
vertical_alignment,
align_x,
align_y,
shaping,
wrapping,
});
@ -344,13 +341,13 @@ pub fn draw<Renderer>(
{
let bounds = layout.bounds();
let x = match paragraph.horizontal_alignment() {
None | Some(alignment::Horizontal::Left) => bounds.x,
Some(alignment::Horizontal::Center) => bounds.center_x(),
Some(alignment::Horizontal::Right) => bounds.x + bounds.width,
let x = match paragraph.align_x() {
Alignment::Default | Alignment::Left | Alignment::Justified => bounds.x,
Alignment::Center => bounds.center_x(),
Alignment::Right => bounds.x + bounds.width,
};
let y = match paragraph.vertical_alignment() {
let y = match paragraph.align_y() {
alignment::Vertical::Top => bounds.y,
alignment::Vertical::Center => bounds.center_y(),
alignment::Vertical::Bottom => bounds.y + bounds.height,

View file

@ -150,12 +150,12 @@ impl<Message> canvas::Program<Message> for Clock {
-width * 2.0,
),
color: palette.secondary.strong.text,
horizontal_alignment: if rotate_factor > 0.0 {
align_x: if rotate_factor > 0.0 {
alignment::Horizontal::Right
} else {
alignment::Horizontal::Left
},
vertical_alignment: alignment::Vertical::Bottom,
align_y: alignment::Vertical::Bottom,
font: Font::MONOSPACE,
..canvas::Text::default()
});
@ -173,8 +173,8 @@ impl<Message> canvas::Program<Message> for Clock {
size: (radius / 5.0).into(),
position: Point::new(x * 0.82, y * 0.82),
color: palette.secondary.strong.text,
horizontal_alignment: alignment::Horizontal::Center,
vertical_alignment: alignment::Vertical::Center,
align_x: alignment::Horizontal::Center,
align_y: alignment::Vertical::Center,
font: Font::MONOSPACE,
..canvas::Text::default()
});

View file

@ -170,8 +170,8 @@ impl Theme {
});
let mut text = canvas::Text {
horizontal_alignment: alignment::Horizontal::Center,
vertical_alignment: alignment::Vertical::Top,
align_x: alignment::Horizontal::Center,
align_y: alignment::Vertical::Top,
size: Pixels(15.0),
color: text_color,
..canvas::Text::default()
@ -214,7 +214,7 @@ impl Theme {
});
}
text.vertical_alignment = alignment::Vertical::Bottom;
text.align_y = alignment::Vertical::Bottom;
let hsl = Hsl::from_color(Rgb::from(self.base));
for i in 0..self.len() {

View file

@ -580,8 +580,8 @@ mod grid {
color: Color::WHITE,
size: 14.0.into(),
position: Point::new(frame.width(), frame.height()),
horizontal_alignment: alignment::Horizontal::Right,
vertical_alignment: alignment::Vertical::Bottom,
align_x: alignment::Horizontal::Right,
align_y: alignment::Vertical::Bottom,
..Text::default()
};

View file

@ -11,6 +11,7 @@ iced.features = ["image", "debug"]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tracing-subscriber = "0.3"
open = "5"
[target.'cfg(target_arch = "wasm32")'.dependencies]
iced.workspace = true

View file

@ -1,9 +1,11 @@
use iced::border;
use iced::widget::{Button, Column, Container, Slider};
use iced::widget::{
button, center_x, center_y, checkbox, column, horizontal_space, image,
radio, row, scrollable, slider, text, text_input, toggler, vertical_space,
radio, rich_text, row, scrollable, slider, span, text, text_input, toggler,
vertical_space,
};
use iced::{Center, Color, Element, Fill, Font, Pixels};
use iced::{Center, Color, Element, Fill, Font, Pixels, Theme};
pub fn main() -> iced::Result {
#[cfg(target_arch = "wasm32")]
@ -54,6 +56,7 @@ pub enum Message {
ToggleTextInputIcon(bool),
DebugToggled(bool),
TogglerChanged(bool),
OpenTrunk,
}
impl Tour {
@ -130,6 +133,10 @@ impl Tour {
Message::TogglerChanged(toggler) => {
self.toggler = toggler;
}
Message::OpenTrunk => {
#[cfg(not(target_arch = "wasm32"))]
let _ = open::that_in_background("https://trunkrs.dev");
}
}
}
@ -194,8 +201,8 @@ impl Tour {
fn welcome(&self) -> Column<Message> {
Self::container("Welcome!")
.push(
"This is a simple tour meant to showcase a bunch of widgets \
that can be easily implemented on top of Iced.",
"This is a simple tour meant to showcase a bunch of \
widgets that can be easily implemented on top of Iced.",
)
.push(
"Iced is a cross-platform GUI library for Rust focused on \
@ -210,13 +217,31 @@ impl Tour {
built on top of wgpu, a graphics library supporting Vulkan, \
Metal, DX11, and DX12.",
)
.push(
"Additionally, this tour can also run on WebAssembly thanks \
to dodrio, an experimental VDOM library for Rust.",
.push({
let theme = Theme::default();
let palette = theme.extended_palette();
rich_text![
"Additionally, this tour can also run on WebAssembly ",
"by leveraging ",
span("trunk")
.color(palette.primary.base.color)
.background(palette.background.weakest.color)
.border(
border::rounded(2)
.width(1)
.color(palette.background.weak.color)
)
.padding([0, 2])
.font(Font::MONOSPACE)
.link(Message::OpenTrunk),
"."
]
.on_link_click(std::convert::identity)
})
.push(
"You will need to interact with the UI in order to reach the \
end!",
"You will need to interact with the UI in order to reach \
the end!",
)
}

View file

@ -142,8 +142,8 @@ impl<Message> canvas::Program<Message> for State {
} else {
"Vectorial Text! 🎉"
}),
horizontal_alignment: alignment::Horizontal::Center,
vertical_alignment: alignment::Vertical::Center,
align_x: alignment::Horizontal::Center,
align_y: alignment::Vertical::Center,
shaping: text::Shaping::Advanced,
..canvas::Text::default()
});

View file

@ -30,9 +30,9 @@ pub struct Text {
/// The font of the text
pub font: Font,
/// The horizontal alignment of the text
pub horizontal_alignment: alignment::Horizontal,
pub align_x: alignment::Horizontal,
/// The vertical alignment of the text
pub vertical_alignment: alignment::Vertical,
pub align_y: alignment::Vertical,
/// The shaping strategy of the text.
pub shaping: Shaping,
}
@ -60,7 +60,7 @@ impl Text {
4,
);
let translation_x = match self.horizontal_alignment {
let translation_x = match self.align_x {
alignment::Horizontal::Left => self.position.x,
alignment::Horizontal::Center | alignment::Horizontal::Right => {
let mut line_width = 0.0f32;
@ -69,7 +69,7 @@ impl Text {
line_width = line_width.max(line.w);
}
if self.horizontal_alignment == alignment::Horizontal::Center {
if self.align_x == alignment::Horizontal::Center {
self.position.x - line_width / 2.0
} else {
self.position.x - line_width
@ -80,7 +80,7 @@ impl Text {
let translation_y = {
let line_height = self.line_height.to_absolute(self.size);
match self.vertical_alignment {
match self.align_y {
alignment::Vertical::Top => self.position.y,
alignment::Vertical::Center => {
self.position.y - line_height.0 / 2.0
@ -180,8 +180,8 @@ impl Default for Text {
size: Pixels(16.0),
line_height: LineHeight::Relative(1.2),
font: Font::default(),
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top,
align_x: alignment::Horizontal::Left,
align_y: alignment::Vertical::Top,
shaping: Shaping::Basic,
}
}

View file

@ -11,7 +11,7 @@ pub use cosmic_text;
use crate::core::alignment;
use crate::core::font::{self, Font};
use crate::core::text::{Shaping, Wrapping};
use crate::core::text::{Alignment, Shaping, Wrapping};
use crate::core::{Color, Pixels, Point, Rectangle, Size, Transformation};
use std::borrow::Cow;
@ -54,9 +54,9 @@ pub enum Text {
/// The font of the text.
font: Font,
/// The horizontal alignment of the text.
horizontal_alignment: Option<alignment::Horizontal>,
align_x: Alignment,
/// The vertical alignment of the text.
vertical_alignment: alignment::Vertical,
align_y: alignment::Vertical,
/// The shaping strategy of the text.
shaping: Shaping,
/// The clip bounds of the text.
@ -73,7 +73,7 @@ pub enum Text {
impl Text {
/// Returns the visible bounds of the [`Text`].
pub fn visible_bounds(&self) -> Option<Rectangle> {
let (bounds, horizontal_alignment, vertical_alignment) = match self {
let (bounds, align_x, align_y) = match self {
Text::Paragraph {
position,
paragraph,
@ -84,8 +84,8 @@ impl Text {
Rectangle::new(*position, paragraph.min_bounds)
.intersection(clip_bounds)
.map(|bounds| bounds * *transformation),
paragraph.horizontal_alignment,
Some(paragraph.vertical_alignment),
paragraph.align_x,
Some(paragraph.align_y),
),
Text::Editor {
editor,
@ -97,38 +97,38 @@ impl Text {
Rectangle::new(*position, editor.bounds)
.intersection(clip_bounds)
.map(|bounds| bounds * *transformation),
None,
Alignment::Default,
None,
),
Text::Cached {
bounds,
clip_bounds,
horizontal_alignment,
vertical_alignment,
align_x: horizontal_alignment,
align_y: vertical_alignment,
..
} => (
bounds.intersection(clip_bounds),
*horizontal_alignment,
Some(*vertical_alignment),
),
Text::Raw { raw, .. } => (Some(raw.clip_bounds), None, None),
Text::Raw { raw, .. } => {
(Some(raw.clip_bounds), Alignment::Default, None)
}
};
let mut bounds = bounds?;
if let Some(alignment) = horizontal_alignment {
match alignment {
alignment::Horizontal::Left => {}
alignment::Horizontal::Center => {
match align_x {
Alignment::Default | Alignment::Left | Alignment::Justified => {}
Alignment::Center => {
bounds.x -= bounds.width / 2.0;
}
alignment::Horizontal::Right => {
Alignment::Right => {
bounds.x -= bounds.width;
}
}
}
if let Some(alignment) = vertical_alignment {
if let Some(alignment) = align_y {
match alignment {
alignment::Vertical::Top => {}
alignment::Vertical::Center => {
@ -313,11 +313,13 @@ fn to_style(style: font::Style) -> cosmic_text::Style {
}
}
fn to_align(alignment: alignment::Horizontal) -> cosmic_text::Align {
fn to_align(alignment: Alignment) -> Option<cosmic_text::Align> {
match alignment {
alignment::Horizontal::Left => cosmic_text::Align::Left,
alignment::Horizontal::Center => cosmic_text::Align::Center,
alignment::Horizontal::Right => cosmic_text::Align::Right,
Alignment::Default => None,
Alignment::Left => Some(cosmic_text::Align::Left),
Alignment::Center => Some(cosmic_text::Align::Center),
Alignment::Right => Some(cosmic_text::Align::Right),
Alignment::Justified => Some(cosmic_text::Align::Justified),
}
}

View file

@ -1,7 +1,7 @@
//! Draw paragraphs.
use crate::core;
use crate::core::alignment;
use crate::core::text::{Hit, Shaping, Span, Text, Wrapping};
use crate::core::text::{Alignment, Hit, Shaping, Span, Text, Wrapping};
use crate::core::{Font, Point, Rectangle, Size};
use crate::text;
@ -18,8 +18,8 @@ struct Internal {
font: Font,
shaping: Shaping,
wrapping: Wrapping,
horizontal_alignment: Option<alignment::Horizontal>,
vertical_alignment: alignment::Vertical,
align_x: Alignment,
align_y: alignment::Vertical,
bounds: Size,
min_bounds: Size,
version: text::Version,
@ -47,8 +47,8 @@ impl Paragraph {
Weak {
raw: Arc::downgrade(paragraph),
min_bounds: paragraph.min_bounds,
horizontal_alignment: paragraph.horizontal_alignment,
vertical_alignment: paragraph.vertical_alignment,
align_x: paragraph.align_x,
align_y: paragraph.align_y,
}
}
@ -89,14 +89,13 @@ impl core::text::Paragraph for Paragraph {
text::to_shaping(text.shaping),
);
let min_bounds =
align(&mut buffer, &mut font_system, text.horizontal_alignment);
let min_bounds = align(&mut buffer, &mut font_system, text.align_x);
Self(Arc::new(Internal {
buffer,
font: text.font,
horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment,
align_x: text.align_x,
align_y: text.align_y,
shaping: text.shaping,
wrapping: text.wrapping,
bounds: text.bounds,
@ -160,14 +159,13 @@ impl core::text::Paragraph for Paragraph {
None,
);
let min_bounds =
align(&mut buffer, &mut font_system, text.horizontal_alignment);
let min_bounds = align(&mut buffer, &mut font_system, text.align_x);
Self(Arc::new(Internal {
buffer,
font: text.font,
horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment,
align_x: text.align_x,
align_y: text.align_y,
shaping: text.shaping,
wrapping: text.wrapping,
bounds: text.bounds,
@ -205,8 +203,8 @@ impl core::text::Paragraph for Paragraph {
|| paragraph.font != text.font
|| paragraph.shaping != text.shaping
|| paragraph.wrapping != text.wrapping
|| paragraph.horizontal_alignment != text.horizontal_alignment
|| paragraph.vertical_alignment != text.vertical_alignment
|| paragraph.align_x != text.align_x
|| paragraph.align_y != text.align_y
{
core::text::Difference::Shape
} else if paragraph.bounds != text.bounds {
@ -216,12 +214,12 @@ impl core::text::Paragraph for Paragraph {
}
}
fn horizontal_alignment(&self) -> Option<alignment::Horizontal> {
self.internal().horizontal_alignment
fn align_x(&self) -> Alignment {
self.internal().align_x
}
fn vertical_alignment(&self) -> alignment::Vertical {
self.internal().vertical_alignment
fn align_y(&self) -> alignment::Vertical {
self.internal().align_y
}
fn min_bounds(&self) -> Size {
@ -361,12 +359,12 @@ impl core::text::Paragraph for Paragraph {
fn align(
buffer: &mut cosmic_text::Buffer,
font_system: &mut text::FontSystem,
align_x: Option<alignment::Horizontal>,
alignment: Alignment,
) -> Size {
let (min_bounds, has_rtl) = text::measure(buffer);
let mut needs_relayout = has_rtl;
if let Some(align_x) = align_x {
if let Some(align) = text::to_align(alignment) {
let has_multiple_lines = buffer.lines.len() > 1
|| buffer.lines.first().is_some_and(|line| {
line.layout_opt().is_some_and(|layout| layout.len() > 1)
@ -374,7 +372,7 @@ fn align(
if has_multiple_lines {
for line in &mut buffer.lines {
let _ = line.set_align(Some(text::to_align(align_x)));
let _ = line.set_align(Some(align));
}
needs_relayout = true;
@ -408,8 +406,8 @@ impl fmt::Debug for Paragraph {
f.debug_struct("Paragraph")
.field("font", &paragraph.font)
.field("shaping", &paragraph.shaping)
.field("horizontal_alignment", &paragraph.horizontal_alignment)
.field("vertical_alignment", &paragraph.vertical_alignment)
.field("horizontal_alignment", &paragraph.align_x)
.field("vertical_alignment", &paragraph.align_y)
.field("bounds", &paragraph.bounds)
.field("min_bounds", &paragraph.min_bounds)
.finish()
@ -420,8 +418,8 @@ impl PartialEq for Internal {
fn eq(&self, other: &Self) -> bool {
self.font == other.font
&& self.shaping == other.shaping
&& self.horizontal_alignment == other.horizontal_alignment
&& self.vertical_alignment == other.vertical_alignment
&& self.align_x == other.align_x
&& self.align_y == other.align_y
&& self.bounds == other.bounds
&& self.min_bounds == other.min_bounds
&& self.buffer.metrics() == other.buffer.metrics()
@ -438,8 +436,8 @@ impl Default for Internal {
font: Font::default(),
shaping: Shaping::default(),
wrapping: Wrapping::default(),
horizontal_alignment: None,
vertical_alignment: alignment::Vertical::Top,
align_x: Alignment::Default,
align_y: alignment::Vertical::Top,
bounds: Size::ZERO,
min_bounds: Size::ZERO,
version: text::Version::default(),
@ -454,9 +452,9 @@ pub struct Weak {
/// The minimum bounds of the [`Paragraph`].
pub min_bounds: Size,
/// The horizontal alignment of the [`Paragraph`].
pub horizontal_alignment: Option<alignment::Horizontal>,
pub align_x: Alignment,
/// The vertical alignment of the [`Paragraph`].
pub vertical_alignment: alignment::Vertical,
pub align_y: alignment::Vertical,
}
impl Weak {

View file

@ -399,8 +399,8 @@ impl Engine {
size,
line_height,
font,
horizontal_alignment,
vertical_alignment,
align_x,
align_y,
shaping,
clip_bounds: text_bounds, // TODO
} => {
@ -420,8 +420,8 @@ impl Engine {
*size,
*line_height,
*font,
*horizontal_alignment,
*vertical_alignment,
*align_x,
*align_y,
*shaping,
pixels,
clip_mask,

View file

@ -231,8 +231,8 @@ impl geometry::frame::Backend for Frame {
size,
line_height: line_height.to_absolute(size),
font: text.font,
horizontal_alignment: Some(text.horizontal_alignment),
vertical_alignment: text.vertical_alignment,
align_x: text.align_x.into(),
align_y: text.align_y,
shaping: text.shaping,
clip_bounds: Rectangle::with_size(Size::INFINITY),
});

View file

@ -86,8 +86,8 @@ impl Layer {
line_height: text.line_height.to_absolute(text.size)
* transformation.scale_factor(),
font: text.font,
horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment,
align_x: text.align_x,
align_y: text.align_y,
shaping: text.shaping,
clip_bounds: clip_bounds * transformation,
};

View file

@ -1,5 +1,5 @@
use crate::core::alignment;
use crate::core::text::Shaping;
use crate::core::text::{Alignment, Shaping};
use crate::core::{
Color, Font, Pixels, Point, Rectangle, Size, Transformation,
};
@ -61,8 +61,8 @@ impl Pipeline {
paragraph.buffer(),
Rectangle::new(position, paragraph.min_bounds()),
color,
paragraph.horizontal_alignment(),
paragraph.vertical_alignment(),
paragraph.align_x(),
paragraph.align_y(),
pixels,
clip_mask,
transformation,
@ -92,7 +92,7 @@ impl Pipeline {
editor.buffer(),
Rectangle::new(position, editor.bounds()),
color,
None,
Alignment::Default,
alignment::Vertical::Top,
pixels,
clip_mask,
@ -108,7 +108,7 @@ impl Pipeline {
size: Pixels,
line_height: Pixels,
font: Font,
horizontal_alignment: Option<alignment::Horizontal>,
horizontal_alignment: Alignment,
vertical_alignment: alignment::Vertical,
shaping: Shaping,
pixels: &mut tiny_skia::PixmapMut<'_>,
@ -177,7 +177,7 @@ impl Pipeline {
),
),
color,
None,
Alignment::Default,
alignment::Vertical::Top,
pixels,
clip_mask,
@ -197,21 +197,21 @@ fn draw(
buffer: &cosmic_text::Buffer,
bounds: Rectangle,
color: Color,
horizontal_alignment: Option<alignment::Horizontal>,
vertical_alignment: alignment::Vertical,
align_x: Alignment,
align_y: alignment::Vertical,
pixels: &mut tiny_skia::PixmapMut<'_>,
clip_mask: Option<&tiny_skia::Mask>,
transformation: Transformation,
) {
let bounds = bounds * transformation;
let x = match horizontal_alignment {
None | Some(alignment::Horizontal::Left) => bounds.x,
Some(alignment::Horizontal::Center) => bounds.x - bounds.width / 2.0,
Some(alignment::Horizontal::Right) => bounds.x - bounds.width,
let x = match align_x {
Alignment::Default | Alignment::Left | Alignment::Justified => bounds.x,
Alignment::Center => bounds.x - bounds.width / 2.0,
Alignment::Right => bounds.x - bounds.width,
};
let y = match vertical_alignment {
let y = match align_y {
alignment::Vertical::Top => bounds.y,
alignment::Vertical::Center => bounds.y - bounds.height / 2.0,
alignment::Vertical::Bottom => bounds.y - bounds.height,

View file

@ -336,8 +336,8 @@ impl geometry::frame::Backend for Frame {
size,
line_height: line_height.to_absolute(size),
font: text.font,
horizontal_alignment: Some(text.horizontal_alignment),
vertical_alignment: text.vertical_alignment,
align_x: text.align_x.into(),
align_y: text.align_y,
shaping: text.shaping,
clip_bounds: self.clip_bounds,
});

View file

@ -103,8 +103,8 @@ impl Layer {
line_height: text.line_height.to_absolute(text.size)
* transformation.scale_factor(),
font: text.font,
horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment,
align_x: text.align_x,
align_y: text.align_y,
shaping: text.shaping,
clip_bounds: clip_bounds * transformation,
};

View file

@ -417,8 +417,8 @@ impl Renderer {
size: Pixels(20.0),
line_height: core::text::LineHeight::default(),
font: Font::MONOSPACE,
horizontal_alignment: None,
vertical_alignment: alignment::Vertical::Top,
align_x: core::text::Alignment::Default,
align_y: alignment::Vertical::Top,
shaping: core::text::Shaping::Basic,
wrapping: core::text::Wrapping::Word,
};

View file

@ -1,4 +1,5 @@
use crate::core::alignment;
use crate::core::text::Alignment;
use crate::core::{Rectangle, Size, Transformation};
use crate::graphics::cache;
use crate::graphics::color;
@ -494,8 +495,8 @@ fn prepare(
let (
buffer,
bounds,
horizontal_alignment,
vertical_alignment,
align_x,
align_y,
color,
clip_bounds,
transformation,
@ -517,8 +518,8 @@ fn prepare(
(
paragraph.buffer(),
Rectangle::new(*position, paragraph.min_bounds()),
paragraph.horizontal_alignment(),
paragraph.vertical_alignment(),
paragraph.align_x(),
paragraph.align_y(),
*color,
*clip_bounds,
*transformation,
@ -540,7 +541,7 @@ fn prepare(
(
editor.buffer(),
Rectangle::new(*position, editor.bounds()),
None,
Alignment::Default,
alignment::Vertical::Top,
*color,
*clip_bounds,
@ -549,8 +550,8 @@ fn prepare(
}
Text::Cached {
bounds,
horizontal_alignment,
vertical_alignment,
align_x,
align_y,
color,
clip_bounds,
..
@ -565,8 +566,8 @@ fn prepare(
(
&entry.buffer,
Rectangle::new(bounds.position(), entry.min_bounds),
*horizontal_alignment,
*vertical_alignment,
*align_x,
*align_y,
*color,
*clip_bounds,
Transformation::IDENTITY,
@ -591,7 +592,7 @@ fn prepare(
height.unwrap_or(layer_bounds.height),
),
),
None,
Alignment::Default,
alignment::Vertical::Top,
raw.color,
raw.clip_bounds,
@ -602,15 +603,15 @@ fn prepare(
let bounds = bounds * transformation * layer_transformation;
let left = match horizontal_alignment {
None | Some(alignment::Horizontal::Left) => bounds.x,
Some(alignment::Horizontal::Center) => {
bounds.x - bounds.width / 2.0
let left = match align_x {
Alignment::Default | Alignment::Left | Alignment::Justified => {
bounds.x
}
Some(alignment::Horizontal::Right) => bounds.x - bounds.width,
Alignment::Center => bounds.x - bounds.width / 2.0,
Alignment::Right => bounds.x - bounds.width,
};
let top = match vertical_alignment {
let top = match align_y {
alignment::Vertical::Top => bounds.y,
alignment::Vertical::Center => bounds.y - bounds.height / 2.0,
alignment::Vertical::Bottom => bounds.y - bounds.height,

View file

@ -293,7 +293,7 @@ where
self.text_line_height,
self.text_size,
self.font,
None,
text::Alignment::Default,
alignment::Vertical::Top,
self.text_shaping,
self.text_wrapping,
@ -416,10 +416,8 @@ where
size,
line_height: *line_height,
bounds: bounds.size(),
horizontal_alignment: Some(
alignment::Horizontal::Center,
),
vertical_alignment: alignment::Vertical::Center,
align_x: text::Alignment::Center,
align_y: alignment::Vertical::Center,
shaping: *shaping,
wrapping: text::Wrapping::default(),
},

View file

@ -552,8 +552,8 @@ where
size: text_size,
line_height: self.text_line_height,
font: self.font.unwrap_or_else(|| renderer.default_font()),
horizontal_alignment: None,
vertical_alignment: alignment::Vertical::Center,
align_x: text::Alignment::Default,
align_y: alignment::Vertical::Center,
shaping: self.text_shaping,
wrapping: text::Wrapping::default(),
},

View file

@ -371,8 +371,8 @@ where
size: text_size,
line_height: self.text_line_height,
font,
horizontal_alignment: None,
vertical_alignment: alignment::Vertical::Center,
align_x: text::Alignment::Default,
align_y: alignment::Vertical::Center,
shaping: self.text_shaping,
wrapping: text::Wrapping::default(),
};
@ -639,8 +639,8 @@ where
bounds.width,
f32::from(line_height.to_absolute(size)),
),
horizontal_alignment: Some(alignment::Horizontal::Right),
vertical_alignment: alignment::Vertical::Center,
align_x: text::Alignment::Right,
align_y: alignment::Vertical::Center,
shaping,
wrapping: text::Wrapping::default(),
},
@ -669,8 +669,8 @@ where
bounds.width - self.padding.horizontal(),
f32::from(self.text_line_height.to_absolute(text_size)),
),
horizontal_alignment: None,
vertical_alignment: alignment::Vertical::Center,
align_x: text::Alignment::Default,
align_y: alignment::Vertical::Center,
shaping: self.text_shaping,
wrapping: text::Wrapping::default(),
},

View file

@ -314,7 +314,7 @@ where
self.text_line_height,
self.text_size,
self.font,
None,
text::Alignment::Default,
alignment::Vertical::Top,
self.text_shaping,
self.text_wrapping,

View file

@ -4,7 +4,7 @@ use crate::core::mouse;
use crate::core::renderer;
use crate::core::text::{Paragraph, Span};
use crate::core::widget::text::{
self, Catalog, LineHeight, Shaping, Style, StyleFn, Wrapping,
self, Alignment, Catalog, LineHeight, Shaping, Style, StyleFn, Wrapping,
};
use crate::core::widget::tree::{self, Tree};
use crate::core::{
@ -31,7 +31,7 @@ pub struct Rich<
width: Length,
height: Length,
font: Option<Renderer::Font>,
align_x: Option<alignment::Horizontal>,
align_x: Alignment,
align_y: alignment::Vertical,
wrapping: Wrapping,
class: Theme::Class<'a>,
@ -56,7 +56,7 @@ where
width: Length::Shrink,
height: Length::Shrink,
font: None,
align_x: None,
align_x: Alignment::Default,
align_y: alignment::Vertical::Top,
wrapping: Wrapping::default(),
class: Theme::default(),
@ -112,11 +112,8 @@ where
}
/// Sets the [`alignment::Horizontal`] of the [`Rich`] text.
pub fn align_x(
mut self,
alignment: impl Into<alignment::Horizontal>,
) -> Self {
self.align_x = Some(alignment.into());
pub fn align_x(mut self, alignment: impl Into<Alignment>) -> Self {
self.align_x = alignment.into();
self
}
@ -476,8 +473,8 @@ fn layout<Link, Renderer>(
line_height: LineHeight,
size: Option<Pixels>,
font: Option<Renderer::Font>,
horizontal_alignment: Option<alignment::Horizontal>,
vertical_alignment: alignment::Vertical,
align_x: Alignment,
align_y: alignment::Vertical,
wrapping: Wrapping,
) -> layout::Node
where
@ -496,8 +493,8 @@ where
size,
line_height,
font,
horizontal_alignment,
vertical_alignment,
align_x,
align_y,
shaping: Shaping::Advanced,
wrapping,
};
@ -513,8 +510,8 @@ where
size,
line_height,
font,
horizontal_alignment,
vertical_alignment,
align_x,
align_y,
shaping: Shaping::Advanced,
wrapping,
}) {

View file

@ -955,8 +955,8 @@ where
.unwrap_or_else(|| renderer.default_size()),
line_height: self.line_height,
font,
horizontal_alignment: None,
vertical_alignment: alignment::Vertical::Top,
align_x: text::Alignment::Default,
align_y: alignment::Vertical::Top,
shaping: text::Shaping::Advanced,
wrapping: self.wrapping,
},

View file

@ -319,8 +319,8 @@ where
content: self.placeholder.as_str(),
bounds: Size::new(f32::INFINITY, text_bounds.height),
size: text_size,
horizontal_alignment: None,
vertical_alignment: alignment::Vertical::Center,
align_x: text::Alignment::Default,
align_y: alignment::Vertical::Center,
shaping: text::Shaping::Advanced,
wrapping: text::Wrapping::default(),
};
@ -344,8 +344,8 @@ where
font: icon.font,
size: icon.size.unwrap_or_else(|| renderer.default_size()),
bounds: Size::new(f32::INFINITY, text_bounds.height),
horizontal_alignment: Some(alignment::Horizontal::Center),
vertical_alignment: alignment::Vertical::Center,
align_x: text::Alignment::Center,
align_y: alignment::Vertical::Center,
shaping: text::Shaping::Advanced,
wrapping: text::Wrapping::default(),
};
@ -1727,8 +1727,8 @@ fn replace_paragraph<Renderer>(
content: &value.to_string(),
bounds: Size::new(f32::INFINITY, text_bounds.height),
size: text_size,
horizontal_alignment: None,
vertical_alignment: alignment::Vertical::Center,
align_x: text::Alignment::Default,
align_y: alignment::Vertical::Center,
shaping: text::Shaping::Advanced,
wrapping: text::Wrapping::default(),
});

View file

@ -93,7 +93,7 @@ pub struct Toggler<
size: f32,
text_size: Option<Pixels>,
text_line_height: text::LineHeight,
text_alignment: Option<alignment::Horizontal>,
text_alignment: text::Alignment,
text_shaping: text::Shaping,
text_wrapping: text::Wrapping,
spacing: f32,
@ -127,7 +127,7 @@ where
size: Self::DEFAULT_SIZE,
text_size: None,
text_line_height: text::LineHeight::default(),
text_alignment: None,
text_alignment: text::Alignment::Default,
text_shaping: text::Shaping::default(),
text_wrapping: text::Wrapping::default(),
spacing: Self::DEFAULT_SIZE / 2.0,
@ -197,9 +197,9 @@ where
/// Sets the horizontal alignment of the text of the [`Toggler`]
pub fn text_alignment(
mut self,
alignment: impl Into<alignment::Horizontal>,
alignment: impl Into<text::Alignment>,
) -> Self {
self.text_alignment = Some(alignment.into());
self.text_alignment = alignment.into();
self
}

View file

@ -338,8 +338,8 @@ where
.unwrap_or_else(|| renderer.default_size()),
line_height: text::LineHeight::default(),
font: renderer.default_font(),
horizontal_alignment: None,
vertical_alignment: alignment::Vertical::Top,
align_x: text::Alignment::Default,
align_y: alignment::Vertical::Top,
shaping: text::Shaping::Advanced,
wrapping: text::Wrapping::None,
});