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: 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(key: String) -> Self {
26 Self {
27 key,
28 taffy: TaffyTree::new(),
29 taffy_map: FxHashMap::default(),
30 reverse_map: FxHashMap::default(),
31 root_taffy_id: None,
32 last_constraints: None,
33 cached_size: None,
34 text_cache: FxHashMap::default(),
35 valid: false,
36 }
37 }
38}
39
40pub struct LayoutEngine {
41 pub(crate) tree: ViewTree,
43
44 pub(crate) taffy: TaffyTree<NodeContext>,
46
47 pub(crate) taffy_map: FxHashMap<NodeId, taffy::NodeId>,
49
50 pub(crate) reverse_map: FxHashMap<taffy::NodeId, NodeId>,
52
53 pub(crate) scope_trees: HashMap<String, ScopeLayoutTree>,
55
56 pub(crate) scope_root_map: FxHashMap<NodeId, String>,
58
59 pub(crate) node_to_scope: FxHashMap<NodeId, String>,
61
62 pub(crate) text_cache: FxHashMap<NodeId, TextLayout>,
64
65 pub(crate) last_size_px: Option<(u32, u32)>,
67
68 pub(crate) layout_valid: bool,
70
71 pub(crate) paint_cache: FxHashMap<NodeId, PaintCacheEntry>,
73
74 pub stats: LayoutStats,
76
77 pub(crate) prev_focused: Option<u64>,
79
80 pub(crate) focus_callbacks: FxHashMap<u64, Rc<dyn Fn(bool)>>,
82
83 pub(crate) last_locals_stamp: Option<u64>,
85
86 pub(crate) view_ids: FxHashMap<NodeId, u64>,
88 pub(crate) next_view_id: u64,
89
90 pub(crate) layer_id_counter: u32,
92
93 pub(crate) prev_observed_rects: FxHashMap<u64, repose_core::Rect>,
95
96 pub(crate) focus_group_stack: Vec<u64>,
100}
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}