Skip to main content

ferroui_pretext_contracts/
text_measurement_contracts.rs

1use std::rc::Rc;
2
3use crate::{IPretextTextShaperFactory, PretextError};
4
5/// Measures an entire string in one fixed font, including contextual advances.
6pub trait IPretextTextMeasurer {
7    fn measure_text(&self, text: &str) -> f64;
8}
9
10/// An explicitly registered, platform-independent measurement backend.
11pub trait IPretextTextMeasurerFactory {
12    fn name(&self) -> &str;
13
14    fn is_supported(&self) -> bool {
15        true
16    }
17
18    fn priority(&self) -> i32 {
19        0
20    }
21
22    fn create(&self, font: &str) -> Result<Rc<dyn IPretextTextMeasurer>, PretextError>;
23
24    /// A combined backend can supply shaping without a second registration.
25    fn shaper_factory(&self) -> Option<Rc<dyn IPretextTextShaperFactory>> {
26        None
27    }
28}
29
30/// Adapter for renderers that already expose a string/font measurement function.
31pub struct DelegateTextMeasurerFactory<F> {
32    measure: Rc<F>,
33}
34
35impl<F: Fn(&str, &str) -> f64 + 'static> DelegateTextMeasurerFactory<F> {
36    pub fn new(measure: F) -> Self {
37        Self {
38            measure: Rc::new(measure),
39        }
40    }
41}
42
43struct DelegateTextMeasurer<F> {
44    font: String,
45    measure: Rc<F>,
46}
47
48impl<F: Fn(&str, &str) -> f64 + 'static> IPretextTextMeasurerFactory
49    for DelegateTextMeasurerFactory<F>
50{
51    fn name(&self) -> &str {
52        "Delegate"
53    }
54
55    fn create(&self, font: &str) -> Result<Rc<dyn IPretextTextMeasurer>, PretextError> {
56        Ok(Rc::new(DelegateTextMeasurer {
57            font: font.into(),
58            measure: self.measure.clone(),
59        }))
60    }
61}
62
63impl<F: Fn(&str, &str) -> f64> IPretextTextMeasurer for DelegateTextMeasurer<F> {
64    fn measure_text(&self, text: &str) -> f64 {
65        (self.measure)(text, &self.font)
66    }
67}