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
103#[derive(Clone, Debug, Default)]
105pub struct LayoutStats {
106 pub tree: TreeStats,
108
109 pub taffy_created: usize,
111
112 pub taffy_reused: usize,
114
115 pub layout_hits: usize,
117
118 pub layout_misses: usize,
120
121 pub paint_cache_hits: usize,
123
124 pub paint_cache_misses: usize,
126
127 pub paint_culled: usize,
129
130 pub layout_time_ms: f32,
132
133 pub paint_time_ms: f32,
135}
136
137#[derive(Clone)]
138pub(crate) struct PaintCacheEntry {
139 pub(crate) subtree_hash: u64,
140 pub(crate) stamp: u64,
141 pub(crate) rect: repose_core::Rect,
142 pub(crate) parent_offset_px: (f32, f32),
143 pub(crate) sem_parent: Option<u64>,
144 pub(crate) alpha_q: u8,
145 pub(crate) nodes: Arc<Vec<SceneNode>>,
146 pub(crate) hits: Arc<Vec<HitRegion>>,
147 pub(crate) sems: Arc<Vec<SemNode>>,
148}
149
150#[derive(Clone, Copy, Debug, PartialEq, Eq)]
152pub enum IntrinsicSizeMode {
153 MinContent,
155 MaxContent,
157}
158
159#[derive(Clone)]
161pub(crate) enum NodeContext {
162 Text {
163 text: String,
164 color: Color,
165 font_dp: f32,
166 soft_wrap: bool,
167 max_lines: Option<usize>,
168 overflow: TextOverflow,
169 font_family: Option<&'static str>,
170 annotations: Option<Arc<[TextSpan]>>,
171 text_align: TextAlign,
172 font_weight: FontWeight,
173 font_style: FontStyle,
174 text_decoration: TextDecoration,
175 letter_spacing: f32,
176 line_height: f32,
177 font_variation_settings: Option<Arc<str>>,
178 },
179 Container,
180 ScrollContainer,
181 TextInput {
182 multiline: bool,
183 },
184}
185
186#[derive(Clone)]
187pub(crate) struct TextLayout {
188 pub(crate) lines: Vec<String>,
189 pub(crate) line_ranges: Vec<(usize, usize)>,
191 pub(crate) size_px: f32,
192 pub(crate) line_h_px: f32,
193 pub(crate) line_widths: Vec<f32>,
195}