Skip to main content

ferroui_base/media/text_formatting/
generic_text_paragraph_properties.rs

1use std::cell::Cell;
2use std::rc::Rc;
3
4use crate::media::text_formatting::{TextParagraphProperties, TextRunProperties};
5use crate::media::{FlowDirection, TextAlignment, TextWrapping};
6
7/// Generic implementation of `TextParagraphProperties`.
8pub struct GenericTextParagraphProperties {
9    flow_direction: Cell<FlowDirection>,
10    text_alignment: Cell<TextAlignment>,
11    text_wrap: Cell<TextWrapping>,
12    line_height: Cell<f64>,
13    first_line_in_paragraph: bool,
14    always_collapsible: bool,
15    default_text_run_properties: Rc<dyn TextRunProperties>,
16    indent: f64,
17    letter_spacing: f64,
18    line_spacing: Cell<f64>,
19}
20
21impl GenericTextParagraphProperties {
22    /// Creates left aligned, non wrapping paragraph properties with automatic
23    /// line height and no letter spacing.
24    pub fn new(default_text_run_properties: Rc<dyn TextRunProperties>) -> Self {
25        Self::with_options(default_text_run_properties, TextAlignment::Left, TextWrapping::NoWrap, 0.0, 0.0)
26    }
27
28    /// Creates paragraph properties.
29    ///
30    /// * `default_text_run_properties` — default paragraph's default run properties
31    /// * `text_alignment` — logical horizontal alignment
32    /// * `text_wrapping` — text wrap option
33    /// * `line_height` — paragraph line height
34    /// * `letter_spacing` — letter spacing
35    pub fn with_options(
36        default_text_run_properties: Rc<dyn TextRunProperties>,
37        text_alignment: TextAlignment,
38        text_wrapping: TextWrapping,
39        line_height: f64,
40        letter_spacing: f64,
41    ) -> Self {
42        Self {
43            flow_direction: Cell::new(FlowDirection::LeftToRight),
44            text_alignment: Cell::new(text_alignment),
45            text_wrap: Cell::new(text_wrapping),
46            line_height: Cell::new(line_height),
47            first_line_in_paragraph: false,
48            always_collapsible: false,
49            default_text_run_properties,
50            indent: 0.0,
51            letter_spacing,
52            line_spacing: Cell::new(0.0),
53        }
54    }
55
56    /// Creates paragraph properties with every value specified.
57    #[allow(clippy::too_many_arguments)]
58    pub fn with_all(
59        flow_direction: FlowDirection,
60        text_alignment: TextAlignment,
61        first_line_in_paragraph: bool,
62        always_collapsible: bool,
63        default_text_run_properties: Rc<dyn TextRunProperties>,
64        text_wrapping: TextWrapping,
65        line_height: f64,
66        indent: f64,
67        letter_spacing: f64,
68    ) -> Self {
69        Self {
70            flow_direction: Cell::new(flow_direction),
71            text_alignment: Cell::new(text_alignment),
72            text_wrap: Cell::new(text_wrapping),
73            line_height: Cell::new(line_height),
74            first_line_in_paragraph,
75            always_collapsible,
76            default_text_run_properties,
77            indent,
78            letter_spacing,
79            line_spacing: Cell::new(0.0),
80        }
81    }
82
83    /// Set line spacing: the additional space between lines.
84    pub fn set_line_spacing(&self, line_spacing: f64) {
85        self.line_spacing.set(line_spacing);
86    }
87
88    /// Creates a copy of other paragraph properties.
89    pub fn from_properties(text_paragraph_properties: &dyn TextParagraphProperties) -> Self {
90        Self::with_all(
91            text_paragraph_properties.flow_direction(),
92            text_paragraph_properties.text_alignment(),
93            text_paragraph_properties.first_line_in_paragraph(),
94            text_paragraph_properties.always_collapsible(),
95            text_paragraph_properties.default_text_run_properties().clone(),
96            text_paragraph_properties.text_wrapping(),
97            text_paragraph_properties.line_height(),
98            text_paragraph_properties.indent(),
99            text_paragraph_properties.letter_spacing(),
100        )
101    }
102
103    /// Set flow direction.
104    pub(crate) fn set_flow_direction(&self, flow_direction: FlowDirection) {
105        self.flow_direction.set(flow_direction);
106    }
107
108    /// Set text alignment.
109    pub(crate) fn set_text_alignment(&self, text_alignment: TextAlignment) {
110        self.text_alignment.set(text_alignment);
111    }
112
113    /// Set line height.
114    pub(crate) fn set_line_height(&self, line_height: f64) {
115        self.line_height.set(line_height);
116    }
117
118    /// Set text wrap.
119    pub(crate) fn set_text_wrapping(&self, text_wrap: TextWrapping) {
120        self.text_wrap.set(text_wrap);
121    }
122}
123
124impl TextParagraphProperties for GenericTextParagraphProperties {
125    fn flow_direction(&self) -> FlowDirection {
126        self.flow_direction.get()
127    }
128
129    fn text_alignment(&self) -> TextAlignment {
130        self.text_alignment.get()
131    }
132
133    fn line_height(&self) -> f64 {
134        self.line_height.get()
135    }
136
137    fn line_spacing(&self) -> f64 {
138        self.line_spacing.get()
139    }
140
141    fn first_line_in_paragraph(&self) -> bool {
142        self.first_line_in_paragraph
143    }
144
145    fn always_collapsible(&self) -> bool {
146        self.always_collapsible
147    }
148
149    fn default_text_run_properties(&self) -> &Rc<dyn TextRunProperties> {
150        &self.default_text_run_properties
151    }
152
153    fn text_wrapping(&self) -> TextWrapping {
154        self.text_wrap.get()
155    }
156
157    fn indent(&self) -> f64 {
158        self.indent
159    }
160
161    fn letter_spacing(&self) -> f64 {
162        self.letter_spacing
163    }
164}