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) taffy: TaffyTree<NodeContext>,
14 pub(crate) taffy_map: FxHashMap<NodeId, taffy::NodeId>,
15 pub(crate) reverse_map: FxHashMap<taffy::NodeId, NodeId>,
16 pub(crate) root_taffy_id: Option<taffy::NodeId>,
17 pub(crate) last_constraints:
18 Option<(taffy::Size<Option<f32>>, taffy::Size<taffy::AvailableSpace>)>,
19 pub(crate) cached_size: Option<taffy::Size<f32>>,
20 pub(crate) text_cache: FxHashMap<NodeId, TextLayout>,
21 pub(crate) valid: bool,
22}
23
24impl ScopeLayoutTree {
25 pub(crate) fn new() -> Self {
26 Self {
27 taffy: TaffyTree::new(),
28 taffy_map: FxHashMap::default(),
29 reverse_map: FxHashMap::default(),
30 root_taffy_id: None,
31 last_constraints: None,
32 cached_size: None,
33 text_cache: FxHashMap::default(),
34 valid: false,
35 }
36 }
37}
38
39pub struct LayoutEngine {
40 pub(crate) tree: ViewTree,
42
43 pub(crate) taffy: TaffyTree<NodeContext>,
45
46 pub(crate) taffy_map: FxHashMap<NodeId, taffy::NodeId>,
48
49 pub(crate) reverse_map: FxHashMap<taffy::NodeId, NodeId>,
51
52 pub(crate) scope_trees: HashMap<String, ScopeLayoutTree>,
54
55 pub(crate) scope_root_map: FxHashMap<NodeId, String>,
57
58 pub(crate) node_to_scope: FxHashMap<NodeId, String>,
60
61 pub(crate) text_cache: FxHashMap<NodeId, TextLayout>,
63
64 pub(crate) last_size_px: Option<(u32, u32)>,
66
67 pub(crate) layout_valid: bool,
69
70 pub(crate) paint_cache: FxHashMap<NodeId, PaintCacheEntry>,
72
73 pub stats: LayoutStats,
75
76 pub(crate) prev_focused: Option<u64>,
78
79 pub(crate) focus_callbacks: FxHashMap<u64, Rc<dyn Fn(bool)>>,
81
82 pub(crate) last_locals_stamp: Option<u64>,
84
85 pub(crate) view_ids: FxHashMap<NodeId, u64>,
87 pub(crate) next_view_id: u64,
88
89 pub(crate) layer_id_counter: u32,
91
92 pub(crate) prev_observed_rects: FxHashMap<u64, repose_core::Rect>,
94
95 pub(crate) focus_group_stack: Vec<u64>,
99
100 pub(crate) focus_interaction_sources: FxHashMap<u64, InteractionSource>,
103}
104
105#[derive(Clone, Debug, Default)]
107pub struct LayoutStats {
108 pub tree: TreeStats,
110
111 pub taffy_created: usize,
113
114 pub taffy_reused: usize,
116
117 pub layout_hits: usize,
119
120 pub layout_misses: usize,
122
123 pub paint_cache_hits: usize,
125
126 pub paint_cache_misses: usize,
128
129 pub paint_culled: usize,
131
132 pub layout_time_ms: f32,
134
135 pub paint_time_ms: f32,
137}
138
139#[derive(Clone)]
140pub(crate) struct PaintCacheEntry {
141 pub(crate) subtree_hash: u64,
142 pub(crate) stamp: u64,
143 pub(crate) rect: repose_core::Rect,
144 pub(crate) parent_offset_px: (f32, f32),
145 pub(crate) sem_parent: Option<u64>,
146 pub(crate) alpha_q: u8,
147 pub(crate) nodes: Arc<Vec<SceneNode>>,
148 pub(crate) hits: Arc<Vec<HitRegion>>,
149 pub(crate) sems: Arc<Vec<SemNode>>,
150}
151
152#[derive(Clone, Copy, Debug, PartialEq, Eq)]
154pub enum IntrinsicSizeMode {
155 MinContent,
157 MaxContent,
159}
160
161#[derive(Clone)]
163pub(crate) enum NodeContext {
164 Text {
165 text: String,
166 font_dp: f32,
167 soft_wrap: bool,
168 max_lines: Option<usize>,
169 overflow: TextOverflow,
170 font_family: Option<&'static str>,
171 font_weight: FontWeight,
172 font_style: FontStyle,
173 letter_spacing: f32,
174 line_height: f32,
175 font_variation_settings: Option<Arc<str>>,
176 },
177 Container,
178 ScrollContainer,
179 TextInput {
180 multiline: bool,
181 },
182}
183
184#[derive(Clone)]
185pub(crate) struct TextLayout {
186 pub(crate) lines: Vec<String>,
187 pub(crate) line_ranges: Vec<(usize, usize)>,
189 pub(crate) size_px: f32,
190 pub(crate) line_h_px: f32,
191 pub(crate) line_widths: Vec<f32>,
193}