tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 707HTML 660Markdown 12TOML 62344 Sutichaykuna

⎇ dde8c6aa4a2faa6faea600e24ecf2ce67923c37e examples/cosmic_text.rs Rust · 119 siq'ikuna · 4.5 KB Ñawpa willay Pi imata llamkarqan ch'uya

Upgrade cosmic_text example to cosmic-text 0.11.2 (#615) ff468a44f · Nico Burns ·

1mod common {
2    pub mod image;
3}
4use common::image::{image_measure_function, ImageContext};
5use cosmic_text::{Attrs, Buffer, FontSystem, Metrics, Shaping};
6use taffy::prelude::*;
7
8pub const LOREM_IPSUM : &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
9
10struct CosmicTextContext {
11    buffer: cosmic_text::Buffer,
12}
13
14impl CosmicTextContext {
15    fn new(metrics: Metrics, text: &str, attrs: Attrs, font_system: &mut FontSystem) -> Self {
16        let mut buffer = Buffer::new_empty(metrics);
17        buffer.set_size(font_system, f32::INFINITY, f32::INFINITY);
18        buffer.set_text(font_system, text, attrs, Shaping::Advanced);
19        Self { buffer }
20    }
21
22    fn measure(
23        &mut self,
24        known_dimensions: taffy::Size<Option<f32>>,
25        available_space: taffy::Size<taffy::AvailableSpace>,
26        font_system: &mut FontSystem,
27    ) -> taffy::Size<f32> {
28        // Set width constraint
29        let width_constraint = known_dimensions.width.unwrap_or_else(|| match available_space.width {
30            AvailableSpace::MinContent => 0.0,
31            AvailableSpace::MaxContent => f32::INFINITY,
32            AvailableSpace::Definite(width) => width,
33        });
34        self.buffer.set_size(font_system, width_constraint, f32::INFINITY);
35
36        // Compute layout
37        self.buffer.shape_until_scroll(font_system, false);
38
39        // Determine measured size of text
40        let (width, total_lines) = self
41            .buffer
42            .layout_runs()
43            .fold((0.0, 0usize), |(width, total_lines), run| (run.line_w.max(width), total_lines + 1));
44        let height = total_lines as f32 * self.buffer.metrics().line_height;
45
46        taffy::Size { width, height }
47    }
48}
49
50enum NodeContext {
51    Text(CosmicTextContext),
52    Image(ImageContext),
53}
54
55impl NodeContext {
56    /// Constructor for a text node context
57    fn text(metrics: Metrics, text: &str, attrs: Attrs, font_system: &mut FontSystem) -> Self {
58        NodeContext::Text(CosmicTextContext::new(metrics, text, attrs, font_system))
59    }
60
61    /// Constructor for an image node context
62    fn image(width: f32, height: f32) -> Self {
63        NodeContext::Image(ImageContext { width, height })
64    }
65}
66
67fn measure_function(
68    known_dimensions: taffy::Size<Option<f32>>,
69    available_space: taffy::Size<taffy::AvailableSpace>,
70    node_context: Option<&mut NodeContext>,
71    font_system: &mut FontSystem,
72) -> Size<f32> {
73    if let Size { width: Some(width), height: Some(height) } = known_dimensions {
74        return Size { width, height };
75    }
76
77    match node_context {
78        None => Size::ZERO,
79        Some(NodeContext::Text(text_context)) => text_context.measure(known_dimensions, available_space, font_system),
80        Some(NodeContext::Image(image_context)) => image_measure_function(known_dimensions, image_context),
81    }
82}
83
84fn main() -> Result<(), taffy::TaffyError> {
85    let metrics = Metrics { font_size: 14.0, line_height: 16.0 };
86    let mut font_system = FontSystem::new();
87    let mut taffy: TaffyTree<NodeContext> = TaffyTree::new();
88
89    let text_node = taffy.new_leaf_with_context(
90        Style::default(),
91        NodeContext::text(metrics, LOREM_IPSUM, Attrs::new(), &mut font_system),
92    )?;
93
94    let image_node = taffy.new_leaf_with_context(Style::default(), NodeContext::image(400.0, 300.0))?;
95
96    let root = taffy.new_with_children(
97        Style {
98            display: Display::Flex,
99            flex_direction: FlexDirection::Column,
100            size: Size { width: length(200.0), height: auto() },
101            ..Default::default()
102        },
103        &[text_node, image_node],
104    )?;
105
106    // Compute layout and print result
107    taffy.compute_layout_with_measure(
108        root,
109        Size::MAX_CONTENT,
110        // Note: this closure is a FnMut closure and can be used to borrow external context for the duration of layout
111        // For example, you may wish to borrow a global font registry and pass it into your text measuring function
112        |known_dimensions, available_space, _node_id, node_context| {
113            measure_function(known_dimensions, available_space, node_context, &mut font_system)
114        },
115    )?;
116    taffy.print_tree(root);
117
118    Ok(())
119}