aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/fragment_tree/positioning_fragment.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout_2020/fragment_tree/positioning_fragment.rs')
-rw-r--r--components/layout_2020/fragment_tree/positioning_fragment.rs100
1 files changed, 100 insertions, 0 deletions
diff --git a/components/layout_2020/fragment_tree/positioning_fragment.rs b/components/layout_2020/fragment_tree/positioning_fragment.rs
new file mode 100644
index 00000000000..4a629b31698
--- /dev/null
+++ b/components/layout_2020/fragment_tree/positioning_fragment.rs
@@ -0,0 +1,100 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+use gfx_traits::print_tree::PrintTree;
+use serde::Serialize;
+use servo_arc::Arc as ServoArc;
+use style::logical_geometry::WritingMode;
+use style::properties::ComputedValues;
+use style::values::computed::Length;
+
+use super::{BaseFragment, BaseFragmentInfo, Fragment};
+use crate::cell::ArcRefCell;
+use crate::geom::{LogicalRect, PhysicalRect};
+
+/// Can contain child fragments with relative coordinates, but does not contribute to painting
+/// itself. [`PositioningFragments`] may be completely anonymous, or just non-painting Fragments
+/// generated by boxes.
+#[derive(Serialize)]
+pub(crate) struct PositioningFragment {
+ pub base: BaseFragment,
+ pub rect: LogicalRect<Length>,
+ pub children: Vec<ArcRefCell<Fragment>>,
+ pub writing_mode: WritingMode,
+
+ /// The scrollable overflow of this anonymous fragment's children.
+ pub scrollable_overflow: PhysicalRect<Length>,
+
+ /// If this fragment was created with a style, the style of the fragment.
+ #[serde(skip_serializing)]
+ pub style: Option<ServoArc<ComputedValues>>,
+}
+
+impl PositioningFragment {
+ pub fn new_anonymous(
+ rect: LogicalRect<Length>,
+ children: Vec<Fragment>,
+ mode: WritingMode,
+ ) -> Self {
+ Self::new_with_base_fragment(BaseFragment::anonymous(), None, rect, children, mode)
+ }
+
+ pub fn new_empty(
+ base_fragment_info: BaseFragmentInfo,
+ rect: LogicalRect<Length>,
+ style: ServoArc<ComputedValues>,
+ ) -> Self {
+ let writing_mode = style.writing_mode;
+ Self::new_with_base_fragment(
+ base_fragment_info.into(),
+ Some(style),
+ rect,
+ Vec::new(),
+ writing_mode,
+ )
+ }
+
+ fn new_with_base_fragment(
+ base: BaseFragment,
+ style: Option<ServoArc<ComputedValues>>,
+ rect: LogicalRect<Length>,
+ children: Vec<Fragment>,
+ mode: WritingMode,
+ ) -> Self {
+ // FIXME(mrobinson, bug 25564): We should be using the containing block
+ // here to properly convert scrollable overflow to physical geometry.
+ let containing_block = PhysicalRect::zero();
+ let content_origin = rect.start_corner.to_physical(mode);
+ let scrollable_overflow = children.iter().fold(PhysicalRect::zero(), |acc, child| {
+ acc.union(
+ &child
+ .scrollable_overflow(&containing_block)
+ .translate(content_origin.to_vector()),
+ )
+ });
+ PositioningFragment {
+ base,
+ style,
+ rect,
+ children: children.into_iter().map(ArcRefCell::new).collect(),
+ writing_mode: mode,
+ scrollable_overflow,
+ }
+ }
+
+ pub fn print(&self, tree: &mut PrintTree) {
+ tree.new_level(format!(
+ "PositioningFragment\
+ \nbase={:?}\
+ \nrect={:?}\
+ \nscrollable_overflow={:?}",
+ self.base, self.rect, self.scrollable_overflow
+ ));
+
+ for child in &self.children {
+ child.borrow().print(tree);
+ }
+ tree.end_level();
+ }
+}