accessibility_tree/layout/
fragments.rs

1use super::*;
2use crate::text::ShapedSegment;
3
4pub enum Fragment {
5    Box(BoxFragment),
6    Anonymous(AnonymousFragment),
7    Text(TextFragment),
8}
9
10pub struct BoxFragment {
11    pub style: Arc<ComputedValues>,
12    pub children: Vec<Fragment>,
13
14    /// From the containing block’s start corner…?
15    /// This might be broken when the containing block is in a different writing mode:
16    /// <https://drafts.csswg.org/css-writing-modes/#orthogonal-flows>
17    pub content_rect: Rect<Length>,
18
19    pub padding: Sides<Length>,
20    pub border: Sides<Length>,
21    pub margin: Sides<Length>,
22
23    pub block_margins_collapsed_with_children: CollapsedBlockMargins,
24}
25
26pub struct CollapsedBlockMargins {
27    pub collapsed_through: bool,
28    pub start: CollapsedMargin,
29    pub end: CollapsedMargin,
30}
31
32#[derive(Clone, Copy)]
33pub struct CollapsedMargin {
34    max_positive: Length,
35    min_negative: Length,
36}
37
38/// Can contain child fragments with relative coordinates, but does not contribute to painting itself.
39pub struct AnonymousFragment {
40    pub rect: Rect<Length>,
41    pub children: Vec<Fragment>,
42    pub mode: (WritingMode, Direction),
43}
44
45pub struct TextFragment {
46    pub parent_style: Arc<ComputedValues>,
47    pub content_rect: Rect<Length>,
48    pub text: ShapedSegment,
49}
50
51impl AnonymousFragment {
52    pub fn no_op(mode: (WritingMode, Direction)) -> Self {
53        Self {
54            children: vec![],
55            rect: Rect::zero(),
56            mode,
57        }
58    }
59}
60
61impl BoxFragment {
62    pub fn border_rect(&self) -> Rect<Length> {
63        self.content_rect
64            .inflate(&self.padding)
65            .inflate(&self.border)
66    }
67}
68
69impl CollapsedBlockMargins {
70    pub fn from_margin(margin: &Sides<Length>) -> Self {
71        Self {
72            collapsed_through: false,
73            start: CollapsedMargin::new(margin.block_start),
74            end: CollapsedMargin::new(margin.block_end),
75        }
76    }
77
78    pub fn zero() -> Self {
79        Self {
80            collapsed_through: false,
81            start: CollapsedMargin::zero(),
82            end: CollapsedMargin::zero(),
83        }
84    }
85}
86
87impl CollapsedMargin {
88    pub fn zero() -> Self {
89        Self {
90            max_positive: Length::zero(),
91            min_negative: Length::zero(),
92        }
93    }
94
95    pub fn new(margin: Length) -> Self {
96        Self {
97            max_positive: margin.max(Length::zero()),
98            min_negative: margin.min(Length::zero()),
99        }
100    }
101
102    pub fn adjoin(&self, other: &Self) -> Self {
103        Self {
104            max_positive: self.max_positive.max(other.max_positive),
105            min_negative: self.min_negative.min(other.min_negative),
106        }
107    }
108
109    pub fn adjoin_assign(&mut self, other: &Self) {
110        *self = self.adjoin(other);
111    }
112
113    pub fn solve(&self) -> Length {
114        self.max_positive + self.min_negative
115    }
116}