1#![allow(non_snake_case)]
2
3use std::collections::HashMap;
4use std::rc::Rc;
5use std::sync::Arc;
6
7use repose_core::*;
8use repose_tree::{NodeId, TreeStats, ViewTree};
9use rustc_hash::FxHashMap;
10use taffy::TaffyTree;
11
12pub(crate) struct ScopeLayoutTree {
13 pub(crate) key: String,
14 pub(crate) taffy: TaffyTree<NodeContext>,
15 pub(crate) taffy_map: FxHashMap<NodeId, taffy::NodeId>,
16 pub(crate) reverse_map: FxHashMap<taffy::NodeId, NodeId>,
17 pub(crate) root_taffy_id: Option<taffy::NodeId>,
18 pub(crate) last_constraints:
19 Option<(taffy::Size<Option<f32>>, taffy::Size<taffy::AvailableSpace>)>,
20 pub(crate) cached_size: Option<taffy::Size<f32>>,
21 pub(crate) text_cache: FxHashMap<NodeId, TextLayout>,
22 pub(crate) valid: bool,
23}
24
25impl ScopeLayoutTree {
26 pub(crate) fn new(key: String) -> Self {
27 Self {
28 key,
29 taffy: TaffyTree::new(),
30 taffy_map: FxHashMap::default(),
31 reverse_map: FxHashMap::default(),
32 root_taffy_id: None,
33 last_constraints: None,
34 cached_size: None,
35 text_cache: FxHashMap::default(),
36 valid: false,
37 }
38 }
39}
40
41pub struct LayoutEngine {
42 pub(crate) tree: ViewTree,
44
45 pub(crate) taffy: TaffyTree<NodeContext>,
47
48 pub(crate) taffy_map: FxHashMap<NodeId, taffy::NodeId>,
50
51 pub(crate) reverse_map: FxHashMap<taffy::NodeId, NodeId>,
53
54 pub(crate) scope_trees: HashMap<String, ScopeLayoutTree>,
56
57 pub(crate) scope_root_map: FxHashMap<NodeId, String>,
59
60 pub(crate) node_to_scope: FxHashMap<NodeId, String>,
62
63 pub(crate) text_cache: FxHashMap<NodeId, TextLayout>,
65
66 pub(crate) last_size_px: Option<(u32, u32)>,
68
69 pub(crate) layout_valid: bool,
71
72 pub(crate) paint_cache: FxHashMap<NodeId, PaintCacheEntry>,
74
75 pub stats: LayoutStats,
77
78 pub(crate) prev_focused: Option<u64>,
80
81 pub(crate) focus_callbacks: FxHashMap<u64, Rc<dyn Fn(bool)>>,
83
84 pub(crate) last_locals_stamp: Option<u64>,
86
87 pub(crate) view_ids: FxHashMap<NodeId, u64>,
89 pub(crate) next_view_id: u64,
90
91 pub(crate) layer_id_counter: u32,
93
94 pub(crate) prev_observed_rects: FxHashMap<u64, repose_core::Rect>,
96
97 pub(crate) focus_group_stack: Vec<u64>,
101
102 pub(crate) focus_interaction_sources: FxHashMap<u64, InteractionSource>,
105}
106
107#[derive(Clone, Debug, Default)]
109pub struct LayoutStats {
110 pub tree: TreeStats,
112
113 pub taffy_created: usize,
115
116 pub taffy_reused: usize,
118
119 pub layout_hits: usize,
121
122 pub layout_misses: usize,
124
125 pub paint_cache_hits: usize,
127
128 pub paint_cache_misses: usize,
130
131 pub paint_culled: usize,
133
134 pub layout_time_ms: f32,
136
137 pub paint_time_ms: f32,
139}
140
141#[derive(Clone)]
142pub(crate) struct PaintCacheEntry {
143 pub(crate) subtree_hash: u64,
144 pub(crate) stamp: u64,
145 pub(crate) rect: repose_core::Rect,
146 pub(crate) parent_offset_px: (f32, f32),
147 pub(crate) sem_parent: Option<u64>,
148 pub(crate) alpha_q: u8,
149 pub(crate) nodes: Arc<Vec<SceneNode>>,
150 pub(crate) hits: Arc<Vec<HitRegion>>,
151 pub(crate) sems: Arc<Vec<SemNode>>,
152}
153
154#[derive(Clone, Copy, Debug, PartialEq, Eq)]
156pub enum IntrinsicSizeMode {
157 MinContent,
159 MaxContent,
161}
162
163#[derive(Clone)]
165pub(crate) enum NodeContext {
166 Text {
167 text: String,
168 color: Color,
169 font_dp: f32,
170 soft_wrap: bool,
171 max_lines: Option<usize>,
172 overflow: TextOverflow,
173 font_family: Option<&'static str>,
174 annotations: Option<Arc<[TextSpan]>>,
175 text_align: TextAlign,
176 font_weight: FontWeight,
177 font_style: FontStyle,
178 text_decoration: TextDecoration,
179 letter_spacing: f32,
180 line_height: f32,
181 font_variation_settings: Option<Arc<str>>,
182 },
183 Container,
184 ScrollContainer,
185 TextInput {
186 multiline: bool,
187 },
188}
189
190#[derive(Clone)]
191pub(crate) struct TextLayout {
192 pub(crate) lines: Vec<String>,
193 pub(crate) line_ranges: Vec<(usize, usize)>,
195 pub(crate) size_px: f32,
196 pub(crate) line_h_px: f32,
197 pub(crate) line_widths: Vec<f32>,
199}