1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
//! Items related to the styling of text.
use crate::text::{Align, Font, FontSize, Justify, Scalar, Wrap};
/// A context for building a text layout.
#[derive(Clone, Debug, Default)]
pub struct Builder {
pub line_spacing: Option<Scalar>,
pub line_wrap: Option<Option<Wrap>>,
pub font_size: Option<FontSize>,
pub justify: Option<Justify>,
pub font: Option<Option<Font>>,
pub y_align: Option<Align>,
}
/// Properties related to the layout of multi-line text for a single font and font size.
#[derive(Clone, Debug)]
pub struct Layout {
pub line_spacing: Scalar,
pub line_wrap: Option<Wrap>,
pub justify: Justify,
pub font_size: FontSize,
pub font: Option<Font>,
pub y_align: Align,
}
pub const DEFAULT_LINE_WRAP: Option<Wrap> = Some(Wrap::Whitespace);
pub const DEFAULT_FONT_SIZE: u32 = 12;
pub const DEFAULT_LINE_SPACING: f32 = 0.0;
pub const DEFAULT_JUSTIFY: Justify = Justify::Center;
pub const DEFAULT_Y_ALIGN: Align = Align::Middle;
impl Builder {
/// The font size to use for the text.
pub fn font_size(mut self, size: FontSize) -> Self {
self.font_size = Some(size);
self
}
/// Specify whether or not text should be wrapped around some width and how to do so.
///
/// The default value is `DEFAULT_LINE_WRAP`.
pub fn line_wrap(mut self, line_wrap: Option<Wrap>) -> Self {
self.line_wrap = Some(line_wrap);
self
}
/// Specify that the **Text** should not wrap lines around the width.
///
/// Shorthand for `builder.line_wrap(None)`.
pub fn no_line_wrap(self) -> Self {
self.line_wrap(None)
}
/// Line wrap the **Text** at the beginning of the first word that exceeds the width.
///
/// Shorthand for `builder.line_wrap(Some(Wrap::Whitespace))`.
pub fn wrap_by_word(self) -> Self {
self.line_wrap(Some(Wrap::Whitespace))
}
/// Line wrap the **Text** at the beginning of the first character that exceeds the width.
///
/// Shorthand for `builder.line_wrap(Some(Wrap::Character))`.
pub fn wrap_by_character(self) -> Self {
self.line_wrap(Some(Wrap::Character))
}
/// A method for specifying the `Font` used for displaying the `Text`.
pub fn font(mut self, font: Font) -> Self {
self.font = Some(Some(font));
self
}
/// Describe the end along the *x* axis to which the text should be aligned.
pub fn justify(mut self, justify: Justify) -> Self {
self.justify = Some(justify);
self
}
/// Align the text to the left of its bounding **Rect**'s *x* axis range.
pub fn left_justify(self) -> Self {
self.justify(Justify::Left)
}
/// Align the text to the middle of its bounding **Rect**'s *x* axis range.
pub fn center_justify(self) -> Self {
self.justify(Justify::Center)
}
/// Align the text to the right of its bounding **Rect**'s *x* axis range.
pub fn right_justify(self) -> Self {
self.justify(Justify::Right)
}
/// Specify how much vertical space should separate each line of text.
pub fn line_spacing(mut self, spacing: Scalar) -> Self {
self.line_spacing = Some(spacing);
self
}
/// Specify how the whole text should be aligned along the y axis of its bounding rectangle
pub fn y_align(mut self, align: Align) -> Self {
self.y_align = Some(align);
self
}
/// Align the top edge of the text with the top edge of its bounding rectangle.
pub fn align_top(self) -> Self {
self.y_align(Align::End)
}
/// Align the middle of the text with the middle of the bounding rect along the y axis..
///
/// This is the default behaviour.
pub fn align_middle_y(self) -> Self {
self.y_align(Align::Middle)
}
/// Align the bottom edge of the text with the bottom edge of its bounding rectangle.
pub fn align_bottom(self) -> Self {
self.y_align(Align::Start)
}
/// Set all the parameters via an existing `Layout`
pub fn layout(mut self, layout: &Layout) -> Self {
self.font = Some(layout.font.clone());
self.line_spacing(layout.line_spacing)
.line_wrap(layout.line_wrap)
.justify(layout.justify)
.font_size(layout.font_size)
.y_align(layout.y_align)
}
/// Build the text layout.
pub fn build(self) -> Layout {
Layout {
line_spacing: self.line_spacing.unwrap_or(DEFAULT_LINE_SPACING),
line_wrap: self.line_wrap.unwrap_or(DEFAULT_LINE_WRAP),
justify: self.justify.unwrap_or(DEFAULT_JUSTIFY),
font_size: self.font_size.unwrap_or(DEFAULT_FONT_SIZE),
font: self.font.unwrap_or(None),
y_align: self.y_align.unwrap_or(DEFAULT_Y_ALIGN),
}
}
}
impl Default for Layout {
fn default() -> Self {
Layout {
line_spacing: DEFAULT_LINE_SPACING,
line_wrap: DEFAULT_LINE_WRAP,
justify: DEFAULT_JUSTIFY,
font_size: DEFAULT_FONT_SIZE,
font: None,
y_align: DEFAULT_Y_ALIGN,
}
}
}