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};
9
10use crate::hit_testing::HitRegionMetadata;
11use rustc_hash::FxHashMap;
12use taffy::TaffyTree;
13
14#[derive(Clone, Copy, Debug, Default)]
21pub(crate) struct TextBaselines {
22 pub(crate) first: f32,
23 pub(crate) last: f32,
24 pub(crate) content_h: f32,
25}
26
27pub(crate) struct ScopeLayoutTree {
28 pub(crate) taffy: TaffyTree<NodeContext>,
29 pub(crate) taffy_map: FxHashMap<NodeId, taffy::NodeId>,
30 pub(crate) reverse_map: FxHashMap<taffy::NodeId, NodeId>,
31 pub(crate) root_taffy_id: Option<taffy::NodeId>,
32 pub(crate) last_constraints:
33 Option<(taffy::Size<Option<f32>>, taffy::Size<taffy::AvailableSpace>)>,
34 pub(crate) cached_size: Option<taffy::Size<f32>>,
35 pub(crate) text_cache: FxHashMap<NodeId, TextLayout>,
36 pub(crate) valid: bool,
37 pub(crate) baseline_map: FxHashMap<NodeId, TextBaselines>,
40 pub(crate) baseline_shifts: FxHashMap<NodeId, f32>,
43}
44
45impl ScopeLayoutTree {
46 pub(crate) fn new() -> Self {
47 Self {
48 taffy: TaffyTree::new(),
49 taffy_map: FxHashMap::default(),
50 reverse_map: FxHashMap::default(),
51 root_taffy_id: None,
52 last_constraints: None,
53 cached_size: None,
54 text_cache: FxHashMap::default(),
55 valid: false,
56 baseline_map: FxHashMap::default(),
57 baseline_shifts: FxHashMap::default(),
58 }
59 }
60}
61
62pub struct LayoutEngine {
63 pub(crate) tree: ViewTree,
64
65 pub(crate) taffy: TaffyTree<NodeContext>,
67
68 pub(crate) taffy_map: FxHashMap<NodeId, taffy::NodeId>,
69
70 pub(crate) reverse_map: FxHashMap<taffy::NodeId, NodeId>,
72
73 pub(crate) scope_trees: HashMap<String, ScopeLayoutTree>,
75
76 pub(crate) scope_root_map: FxHashMap<NodeId, String>,
78
79 pub(crate) node_to_scope: FxHashMap<NodeId, String>,
81
82 pub(crate) scope_root_ids: FxHashMap<String, Vec<NodeId>>,
83 pub(crate) scope_maps_valid: bool,
84 pub(crate) scroll_node_ids: Vec<NodeId>,
85 pub(crate) deferred_z_cache: FxHashMap<NodeId, bool>,
86 pub(crate) transform_layer_cache: FxHashMap<NodeId, bool>,
87
88 pub(crate) text_cache: FxHashMap<NodeId, TextLayout>,
90
91 pub(crate) baseline_map: FxHashMap<NodeId, TextBaselines>,
94 pub(crate) baseline_shifts: FxHashMap<NodeId, f32>,
97
98 pub(crate) last_size_px: Option<(u32, u32)>,
100
101 pub(crate) layout_valid: bool,
103
104 pub(crate) paint_cache: FxHashMap<NodeId, PaintCacheEntry>,
106
107 pub stats: LayoutStats,
109
110 pub(crate) prev_focused: Option<u64>,
112
113 pub(crate) focus_callbacks: FxHashMap<u64, Rc<dyn Fn(bool)>>,
115
116 pub(crate) last_locals_stamp: Option<u64>,
118
119 pub(crate) view_ids: FxHashMap<NodeId, u64>,
121 pub(crate) next_view_id: u64,
122
123 pub(crate) layer_id_counter: u32,
125
126 pub(crate) paint_generation: u64,
127
128 pub(crate) prev_observed_rects: FxHashMap<u64, repose_core::Rect>,
130
131 pub(crate) focus_group_stack: Vec<u64>,
135
136 pub(crate) focus_interaction_sources: FxHashMap<u64, InteractionSource>,
139}
140
141#[derive(Clone, Debug, Default)]
143pub struct LayoutStats {
144 pub tree: TreeStats,
145
146 pub taffy_created: usize,
148
149 pub taffy_reused: usize,
151
152 pub layout_hits: usize,
154
155 pub layout_misses: usize,
157
158 pub paint_cache_hits: usize,
160
161 pub paint_cache_misses: usize,
163
164 pub paint_culled: usize,
166
167 pub layout_time_ms: f32,
169
170 pub paint_time_ms: f32,
172}
173
174#[derive(Clone)]
175pub(crate) struct PaintCacheEntry {
176 pub(crate) subtree_hash: u64,
177 pub(crate) stamp: u64,
178 pub(crate) rect: repose_core::Rect,
179 pub(crate) parent_offset_px: (f32, f32),
180 pub(crate) sem_parent: Option<u64>,
181 pub(crate) alpha_q: u8,
182 pub(crate) hit_context_key: u64,
183 pub(crate) paint_generation: u64,
184 pub(crate) nodes: Rc<Vec<SceneNode>>,
185 pub(crate) hits: Rc<Vec<HitRegion>>,
186 pub(crate) hit_metadata: Rc<Vec<Option<Arc<HitRegionMetadata>>>>,
187 pub(crate) sems: Rc<Vec<SemNode>>,
188}
189
190#[derive(Clone, Copy, Debug, PartialEq, Eq)]
192pub enum IntrinsicSizeMode {
193 MinContent,
195 MaxContent,
197}
198
199#[derive(Clone)]
203pub(crate) enum NodeContext {
204 Text {
205 text: String,
206 font_sp: Sp,
207 soft_wrap: bool,
208 max_lines: Option<usize>,
209 overflow: TextOverflow,
210 font_family: Option<&'static str>,
211 font_weight: FontWeight,
212 font_style: FontStyle,
213 letter_spacing: Sp,
214 line_height: Sp,
215 font_variation_settings: Option<Arc<str>>,
216 annotations: Option<Arc<[TextSpan]>>,
217 },
218 Container,
219 ScrollContainer,
220 TextInput {
221 multiline: bool,
222 },
223 Image {
228 w: f32,
229 h: f32,
230 fit: ImageFit,
231 },
232}
233
234#[derive(Clone)]
235pub(crate) struct TextLayout {
236 pub(crate) lines: Vec<String>,
237 pub(crate) line_ranges: Vec<(usize, usize)>,
239 pub(crate) size_px: f32,
240 pub(crate) line_h_px: f32,
241 pub(crate) line_widths: Vec<f32>,
243 pub(crate) line_heights: Vec<f32>,
246}