Compute content size, padding and border for each node (#573)
1// this declaration is necessary to "mount" the generated code where cargo can see it
2// this allows us to both keep code generation scoped to a singe directory for fs events
3// and to keep each test in a separate file
4mod generated;
5
6#[allow(dead_code)]
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8enum WritingMode {
9 Horizontal,
10 Vertical,
11}
12
13#[allow(dead_code)]
14struct TextMeasure {
15 text_content: &'static str,
16 writing_mode: WritingMode,
17 _aspect_ratio: Option<f32>,
18}
19
20#[allow(dead_code)]
21fn test_measure_function(
22 known_dimensions: taffy::geometry::Size<Option<f32>>,
23 available_space: taffy::geometry::Size<taffy::style::AvailableSpace>,
24 _node_id: taffy::tree::NodeId,
25 node_context: Option<&mut TextMeasure>,
26) -> taffy::geometry::Size<f32> {
27 use taffy::geometry::AbsoluteAxis;
28 use taffy::prelude::*;
29
30 const ZWS: char = '\u{200B}';
31 const H_WIDTH: f32 = 10.0;
32 const H_HEIGHT: f32 = 10.0;
33
34 if let Size { width: Some(width), height: Some(height) } = known_dimensions {
35 return Size { width, height };
36 }
37
38 let Some(node_context) = node_context else { return Size::ZERO };
39
40 let inline_axis = match node_context.writing_mode {
41 WritingMode::Horizontal => AbsoluteAxis::Horizontal,
42 WritingMode::Vertical => AbsoluteAxis::Vertical,
43 };
44 let block_axis = inline_axis.other_axis();
45 let lines: Vec<&str> = node_context.text_content.split(ZWS).collect();
46
47 if lines.is_empty() {
48 return Size::ZERO;
49 }
50
51 let min_line_length: usize = lines.iter().map(|line| line.len()).max().unwrap_or(0);
52 let max_line_length: usize = lines.iter().map(|line| line.len()).sum();
53 let inline_size = known_dimensions
54 .get_abs(inline_axis)
55 .unwrap_or_else(|| match available_space.get_abs(inline_axis) {
56 AvailableSpace::MinContent => min_line_length as f32 * H_WIDTH,
57 AvailableSpace::MaxContent => max_line_length as f32 * H_WIDTH,
58 AvailableSpace::Definite(inline_size) => inline_size.min(max_line_length as f32 * H_WIDTH),
59 })
60 .max(min_line_length as f32 * H_WIDTH);
61 let block_size = known_dimensions.get_abs(block_axis).unwrap_or_else(|| {
62 let inline_line_length = (inline_size / H_WIDTH).floor() as usize;
63 let mut line_count = 1;
64 let mut current_line_length = 0;
65 for line in &lines {
66 if current_line_length + line.len() > inline_line_length {
67 if current_line_length > 0 {
68 line_count += 1
69 };
70 current_line_length = line.len();
71 } else {
72 current_line_length += line.len();
73 };
74 }
75 (line_count as f32) * H_HEIGHT
76 });
77
78 match node_context.writing_mode {
79 WritingMode::Horizontal => Size { width: inline_size, height: block_size },
80 WritingMode::Vertical => Size { width: block_size, height: inline_size },
81 }
82}