layout/
lib.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5#![deny(unsafe_code)]
6
7//! Layout. Performs layout on the DOM, builds display lists and sends them to be
8//! painted.
9
10mod accessibility_tree;
11mod cell;
12mod context;
13mod display_list;
14mod dom;
15mod dom_traversal;
16mod flexbox;
17pub mod flow;
18mod formatting_contexts;
19mod fragment_tree;
20pub mod geom;
21mod layout_box_base;
22mod layout_impl;
23mod taffy;
24#[macro_use]
25mod construct_modern;
26mod lists;
27mod positioned;
28mod query;
29mod quotes;
30mod replaced;
31mod sizing;
32mod style_ext;
33pub mod table;
34mod traversal;
35
36use app_units::Au;
37pub use cell::ArcRefCell;
38pub(crate) use flow::BoxTree;
39pub(crate) use fragment_tree::FragmentTree;
40pub use layout_impl::LayoutFactoryImpl;
41use malloc_size_of_derive::MallocSizeOf;
42use servo_arc::Arc as ServoArc;
43use style::logical_geometry::WritingMode;
44use style::properties::ComputedValues;
45
46use crate::geom::LogicalVec2;
47use crate::sizing::SizeConstraint;
48use crate::style_ext::AspectRatio;
49
50/// At times, a style is "owned" by more than one layout object. For example, text
51/// fragments need a handle on their parent inline box's style. In order to make
52/// incremental layout easier to implement, another layer of shared ownership is added via
53/// [`SharedStyle`]. This allows updating the style in originating layout object and
54/// having all "depdendent" objects update automatically.
55///
56///  Note that this is not a cost-free data structure, so should only be
57/// used when necessary.
58pub(crate) type SharedStyle = ArcRefCell<ServoArc<ComputedValues>>;
59
60/// Represents the set of constraints that we use when computing the min-content
61/// and max-content inline sizes of an element.
62pub(crate) struct ConstraintSpace<'a> {
63    pub block_size: SizeConstraint,
64    pub style: &'a ComputedValues,
65    pub preferred_aspect_ratio: Option<AspectRatio>,
66}
67
68impl<'a> ConstraintSpace<'a> {
69    fn new(
70        block_size: SizeConstraint,
71        style: &'a ComputedValues,
72        preferred_aspect_ratio: Option<AspectRatio>,
73    ) -> Self {
74        Self {
75            block_size,
76            style,
77            preferred_aspect_ratio,
78        }
79    }
80}
81
82/// A variant of [`ContainingBlock`] that allows an indefinite inline size.
83/// Useful for code that is shared for both layout (where we know the inline size
84/// of the containing block) and intrinsic sizing (where we don't know it).
85pub(crate) struct IndefiniteContainingBlock<'a> {
86    pub size: LogicalVec2<Option<Au>>,
87    pub style: &'a ComputedValues,
88}
89
90impl<'a> From<&ConstraintSpace<'a>> for IndefiniteContainingBlock<'a> {
91    fn from(constraint_space: &ConstraintSpace<'a>) -> Self {
92        Self {
93            size: LogicalVec2 {
94                inline: None,
95                block: constraint_space.block_size.to_definite(),
96            },
97            style: constraint_space.style,
98        }
99    }
100}
101
102impl<'a> From<&'_ ContainingBlock<'a>> for IndefiniteContainingBlock<'a> {
103    fn from(containing_block: &ContainingBlock<'a>) -> Self {
104        Self {
105            size: LogicalVec2 {
106                inline: Some(containing_block.size.inline),
107                block: containing_block.size.block.to_definite(),
108            },
109            style: containing_block.style,
110        }
111    }
112}
113
114impl<'a> From<&'_ DefiniteContainingBlock<'a>> for IndefiniteContainingBlock<'a> {
115    fn from(containing_block: &DefiniteContainingBlock<'a>) -> Self {
116        Self {
117            size: containing_block.size.map(|v| Some(*v)),
118            style: containing_block.style,
119        }
120    }
121}
122
123#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
124pub(crate) struct ContainingBlockSize {
125    inline: Au,
126    block: SizeConstraint,
127}
128
129pub(crate) struct ContainingBlock<'a> {
130    size: ContainingBlockSize,
131    style: &'a ComputedValues,
132}
133
134struct DefiniteContainingBlock<'a> {
135    size: LogicalVec2<Au>,
136    style: &'a ComputedValues,
137}
138
139impl<'a> From<&'_ DefiniteContainingBlock<'a>> for ContainingBlock<'a> {
140    fn from(definite: &DefiniteContainingBlock<'a>) -> Self {
141        ContainingBlock {
142            size: ContainingBlockSize {
143                inline: definite.size.inline,
144                block: SizeConstraint::Definite(definite.size.block),
145            },
146            style: definite.style,
147        }
148    }
149}
150
151/// Data that is propagated from ancestors to descendants during [`crate::flow::BoxTree`]
152/// construction.  This allows data to flow in the reverse direction of the typical layout
153/// propoagation, but only during `BoxTree` construction.
154#[derive(Clone, Copy, Debug, MallocSizeOf)]
155struct PropagatedBoxTreeData {
156    allow_percentage_column_in_tables: bool,
157}
158
159impl Default for PropagatedBoxTreeData {
160    fn default() -> Self {
161        Self {
162            allow_percentage_column_in_tables: true,
163        }
164    }
165}
166
167impl PropagatedBoxTreeData {
168    fn disallowing_percentage_table_columns(&self) -> PropagatedBoxTreeData {
169        Self {
170            allow_percentage_column_in_tables: false,
171        }
172    }
173}