layout/flow/inline/
inline_box.rs1use std::sync::Arc;
6use std::vec::IntoIter;
7
8use app_units::Au;
9use fonts::{FontMetrics, FontRef};
10use malloc_size_of_derive::MallocSizeOf;
11use script::layout_dom::ServoThreadSafeLayoutNode;
12use servo_arc::Arc as ServoArc;
13use style::properties::ComputedValues;
14
15use super::{
16 InlineContainerState, InlineContainerStateFlags, SharedInlineStyles,
17 inline_container_needs_strut,
18};
19use crate::ContainingBlock;
20use crate::cell::ArcRefCell;
21use crate::context::LayoutContext;
22use crate::dom_traversal::NodeAndStyleInfo;
23use crate::fragment_tree::BaseFragmentInfo;
24use crate::layout_box_base::LayoutBoxBase;
25use crate::style_ext::{LayoutStyle, PaddingBorderMargin};
26
27#[derive(Debug, MallocSizeOf)]
28pub(crate) struct InlineBox {
29 pub base: LayoutBoxBase,
30 pub(super) shared_inline_styles: SharedInlineStyles,
33 pub(super) identifier: InlineBoxIdentifier,
35 pub default_font: Option<FontRef>,
38}
39
40impl InlineBox {
41 pub(crate) fn new(info: &NodeAndStyleInfo) -> Self {
42 Self {
43 base: LayoutBoxBase::new(info.into(), info.style.clone()),
44 shared_inline_styles: info.into(),
45 identifier: InlineBoxIdentifier::default(),
47 default_font: None,
48 }
49 }
50
51 #[inline]
52 pub(crate) fn layout_style(&self) -> LayoutStyle<'_> {
53 LayoutStyle::Default(&self.base.style)
54 }
55
56 pub(crate) fn repair_style(
57 &mut self,
58 node: &ServoThreadSafeLayoutNode,
59 new_style: &ServoArc<ComputedValues>,
60 ) {
61 self.base.repair_style(new_style);
62 *self.shared_inline_styles.style.borrow_mut() = new_style.clone();
63 *self.shared_inline_styles.selected.borrow_mut() = node.selected_style();
64 }
65}
66
67#[derive(Debug, Default, MallocSizeOf)]
68pub(crate) struct InlineBoxes {
69 inline_boxes: Vec<ArcRefCell<InlineBox>>,
71
72 inline_box_tree: Vec<InlineBoxTreePathToken>,
77}
78
79impl InlineBoxes {
80 pub(super) fn len(&self) -> usize {
81 self.inline_boxes.len()
82 }
83
84 pub(super) fn iter(&self) -> impl Iterator<Item = &ArcRefCell<InlineBox>> {
85 self.inline_boxes.iter()
86 }
87
88 pub(super) fn get(&self, identifier: &InlineBoxIdentifier) -> ArcRefCell<InlineBox> {
89 self.inline_boxes[identifier.index_in_inline_boxes as usize].clone()
90 }
91
92 pub(super) fn end_inline_box(&mut self, identifier: InlineBoxIdentifier) {
93 self.inline_box_tree
94 .push(InlineBoxTreePathToken::End(identifier));
95 }
96
97 pub(super) fn start_inline_box(
98 &mut self,
99 inline_box: ArcRefCell<InlineBox>,
100 ) -> InlineBoxIdentifier {
101 assert!(self.inline_boxes.len() <= u32::MAX as usize);
102 assert!(self.inline_box_tree.len() <= u32::MAX as usize);
103
104 let index_in_inline_boxes = self.inline_boxes.len() as u32;
105 let index_of_start_in_tree = self.inline_box_tree.len() as u32;
106
107 let identifier = InlineBoxIdentifier {
108 index_of_start_in_tree,
109 index_in_inline_boxes,
110 };
111 inline_box.borrow_mut().identifier = identifier;
112
113 self.inline_boxes.push(inline_box);
114 self.inline_box_tree
115 .push(InlineBoxTreePathToken::Start(identifier));
116
117 identifier
118 }
119
120 pub(super) fn get_path(
121 &self,
122 from: Option<InlineBoxIdentifier>,
123 to: InlineBoxIdentifier,
124 ) -> IntoIter<InlineBoxTreePathToken> {
125 if from == Some(to) {
126 return Vec::new().into_iter();
127 }
128
129 let mut from_index = match from {
130 Some(InlineBoxIdentifier {
131 index_of_start_in_tree,
132 ..
133 }) => index_of_start_in_tree as usize,
134 None => 0,
135 };
136 let mut to_index = to.index_of_start_in_tree as usize;
137 let is_reversed = to_index < from_index;
138
139 if to_index > from_index && from.is_some() {
143 from_index += 1;
144 } else if to_index < from_index {
145 to_index += 1;
146 }
147
148 let mut path = Vec::with_capacity(from_index.abs_diff(to_index));
149 let min = from_index.min(to_index);
150 let max = from_index.max(to_index);
151
152 for token in &self.inline_box_tree[min..=max] {
153 if Some(&token.reverse()) == path.last() {
155 path.pop();
156 } else {
157 path.push(*token);
158 }
159 }
160
161 if is_reversed {
162 path.reverse();
163 for token in path.iter_mut() {
164 *token = token.reverse();
165 }
166 }
167
168 path.into_iter()
169 }
170}
171
172#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
173pub(super) enum InlineBoxTreePathToken {
174 Start(InlineBoxIdentifier),
175 End(InlineBoxIdentifier),
176}
177
178impl InlineBoxTreePathToken {
179 fn reverse(&self) -> Self {
180 match self {
181 Self::Start(index) => Self::End(*index),
182 Self::End(index) => Self::Start(*index),
183 }
184 }
185}
186
187#[derive(Clone, Copy, Debug, Default, Eq, Hash, MallocSizeOf, PartialEq)]
194pub(crate) struct InlineBoxIdentifier {
195 pub index_of_start_in_tree: u32,
196 pub index_in_inline_boxes: u32,
197}
198
199pub(super) struct InlineBoxContainerState {
200 pub base: InlineContainerState,
203
204 pub identifier: InlineBoxIdentifier,
207
208 pub base_fragment_info: BaseFragmentInfo,
210
211 pub pbm: PaddingBorderMargin,
213}
214
215impl InlineBoxContainerState {
216 pub(super) fn new(
217 inline_box: &InlineBox,
218 containing_block: &ContainingBlock,
219 layout_context: &LayoutContext,
220 parent_container: &InlineContainerState,
221 font_metrics: Option<Arc<FontMetrics>>,
222 ) -> Self {
223 let style = inline_box.base.style.clone();
224 let pbm = inline_box
225 .layout_style()
226 .padding_border_margin(containing_block);
227
228 let mut flags = InlineContainerStateFlags::empty();
229 if inline_container_needs_strut(&style, layout_context, Some(&pbm)) {
230 flags.insert(InlineContainerStateFlags::CREATE_STRUT);
231 }
232
233 Self {
234 base: InlineContainerState::new(style, flags, Some(parent_container), font_metrics),
235 identifier: inline_box.identifier,
236 base_fragment_info: inline_box.base.base_fragment_info,
237 pbm,
238 }
239 }
240
241 pub(super) fn calculate_space_above_baseline(&self) -> Au {
242 let (ascent, descent, line_gap) = (
243 self.base.font_metrics.ascent,
244 self.base.font_metrics.descent,
245 self.base.font_metrics.line_gap,
246 );
247 let leading = line_gap - (ascent + descent);
248 leading.scale_by(0.5) + ascent
249 }
250}