accessibility_tree/layout/
mod.rs1use crate::dom;
2use crate::geom::flow_relative::{Rect, Sides, Vec2};
3use crate::geom::Length;
4use crate::style::values::*;
5use crate::style::{style_for_element, ComputedValues};
6use std::convert::TryInto;
7use std::sync::Arc;
8
9mod dom_traversal;
10mod element_data;
11mod flow;
12mod fragments;
13mod positioned;
14mod replaced;
15
16use dom_traversal::*;
17use flow::*;
18use positioned::*;
19use replaced::*;
20
21pub use element_data::*;
22pub use fragments::*;
23
24#[derive(Debug)]
26pub enum IndependentFormattingContext {
27 Flow(BlockFormattingContext),
28
29 Replaced(ReplacedContent),
31 }
33
34enum NonReplacedIFC<'a> {
35 Flow(&'a BlockFormattingContext),
36}
37
38impl IndependentFormattingContext {
39 fn construct<'a>(
40 context: &'a Context<'a>,
41 style: &'a Arc<ComputedValues>,
42 display_inside: DisplayInside,
43 contents: Contents,
44 ) -> Self {
45 match contents.try_into() {
46 Ok(non_replaced) => match display_inside {
47 DisplayInside::Flow | DisplayInside::FlowRoot => {
48 IndependentFormattingContext::Flow(BlockFormattingContext::construct(
49 context,
50 style,
51 non_replaced,
52 ))
53 }
54 },
55 Err(replaced) => IndependentFormattingContext::Replaced(replaced),
56 }
57 }
58
59 fn as_replaced(&self) -> Result<&ReplacedContent, NonReplacedIFC> {
60 match self {
61 IndependentFormattingContext::Replaced(r) => Ok(r),
62 IndependentFormattingContext::Flow(f) => Err(NonReplacedIFC::Flow(f)),
63 }
64 }
65
66 fn layout<'a>(
67 &'a self,
68 containing_block: &ContainingBlock,
69 tree_rank: usize,
70 absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
71 ) -> FlowChildren {
72 match self.as_replaced() {
73 Ok(replaced) => match *replaced {},
74 Err(ifc) => ifc.layout(containing_block, tree_rank, absolutely_positioned_fragments),
75 }
76 }
77}
78
79impl<'a> NonReplacedIFC<'a> {
80 fn layout(
81 &self,
82 containing_block: &ContainingBlock,
83 tree_rank: usize,
84 absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
85 ) -> FlowChildren {
86 match self {
87 NonReplacedIFC::Flow(bfc) => {
88 bfc.layout(containing_block, tree_rank, absolutely_positioned_fragments)
89 }
90 }
91 }
92}
93
94pub struct ContainingBlock {
95 inline_size: Length,
96 block_size: LengthOrAuto,
97 mode: (WritingMode, Direction),
98}
99
100pub struct DefiniteContainingBlock {
101 size: Vec2<Length>,
102 mode: (WritingMode, Direction),
103}
104
105fn relative_adjustement(
107 style: &ComputedValues,
108 inline_size: Length,
109 block_size: LengthOrAuto,
110) -> Vec2<Length> {
111 if !style.box_.position.is_relatively_positioned() {
112 return Vec2::zero();
113 }
114 fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length {
115 match (start, end) {
116 (LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(),
117 (LengthOrAuto::Auto, LengthOrAuto::Length(end)) => -end,
118 (LengthOrAuto::Length(start), _) => start,
119 }
120 }
121 let block_size = block_size.auto_is(Length::zero);
122 let box_offsets = style.box_offsets().map_inline_and_block_axes(
123 |v| v.percentage_relative_to(inline_size),
124 |v| v.percentage_relative_to(block_size),
125 );
126 Vec2 {
127 inline: adjust(box_offsets.inline_start, box_offsets.inline_end),
128 block: adjust(box_offsets.block_start, box_offsets.block_end),
129 }
130}
131
132fn take<T>(x: &mut T) -> T
135where
136 T: Default,
137{
138 std::mem::replace(x, Default::default())
139}