Auto merge of #26037 - mrobinson:arcrefcell-fragment-tree, r=SimonSapin

layout_2020: Use ArcRefCell in the fragment tree

This will allow mutability which is useful for things like animations.

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #___ (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because they should not change behavior.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
bors-servo 2020-03-26 10:23:23 -04:00 committed by GitHub
commit 4dbe3b30cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 133 additions and 114 deletions

View file

@ -2,6 +2,7 @@
* 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 crate::cell::ArcRefCell;
use crate::geom::flow_relative::{Rect, Sides};
use crate::geom::{PhysicalPoint, PhysicalRect};
#[cfg(debug_assertions)]
@ -41,7 +42,7 @@ pub(crate) struct BoxFragment {
pub debug_id: DebugId,
#[serde(skip_serializing)]
pub style: ServoArc<ComputedValues>,
pub children: Vec<Fragment>,
pub children: Vec<ArcRefCell<Fragment>>,
/// From the containing blocks start corner…?
/// This might be broken when the containing block is in a different writing mode:
@ -81,7 +82,7 @@ pub(crate) struct CollapsedMargin {
pub(crate) struct AnonymousFragment {
pub debug_id: DebugId,
pub rect: Rect<Length>,
pub children: Vec<Fragment>,
pub children: Vec<ArcRefCell<Fragment>>,
pub mode: WritingMode,
/// The scrollable overflow of this anonymous fragment's children.
@ -189,6 +190,40 @@ impl Fragment {
_ => None,
}
}
pub(crate) fn find<T>(
&self,
containing_block: &PhysicalRect<Length>,
process_func: &mut impl FnMut(&Fragment, &PhysicalRect<Length>) -> Option<T>,
) -> Option<T> {
if let Some(result) = process_func(self, containing_block) {
return Some(result);
}
match self {
Fragment::Box(fragment) => {
let new_containing_block = fragment
.content_rect
.to_physical(fragment.style.writing_mode, containing_block)
.translate(containing_block.origin.to_vector());
fragment
.children
.iter()
.find_map(|child| child.borrow().find(&new_containing_block, process_func))
},
Fragment::Anonymous(fragment) => {
let new_containing_block = fragment
.rect
.to_physical(fragment.mode, containing_block)
.translate(containing_block.origin.to_vector());
fragment
.children
.iter()
.find_map(|child| child.borrow().find(&new_containing_block, process_func))
},
_ => None,
}
}
}
impl AbsoluteOrFixedPositionedFragment {
@ -223,7 +258,10 @@ impl AnonymousFragment {
AnonymousFragment {
debug_id: DebugId::new(),
rect,
children,
children: children
.into_iter()
.map(|fragment| ArcRefCell::new(fragment))
.collect(),
mode,
scrollable_overflow,
}
@ -238,7 +276,7 @@ impl AnonymousFragment {
));
for child in &self.children {
child.print(tree);
child.borrow().print(tree);
}
tree.end_level();
}
@ -267,7 +305,10 @@ impl BoxFragment {
tag,
debug_id: DebugId::new(),
style,
children,
children: children
.into_iter()
.map(|fragment| ArcRefCell::new(fragment))
.collect(),
content_rect,
padding,
border,
@ -326,7 +367,7 @@ impl BoxFragment {
));
for child in &self.children {
child.print(tree);
child.borrow().print(tree);
}
tree.end_level();
}