use app unit in box_fragement (#32349)

This commit is contained in:
atbrakhi 2024-06-21 16:54:21 +02:00 committed by GitHub
parent 66edef8065
commit 26c585a0c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 273 additions and 289 deletions

View file

@ -16,8 +16,7 @@ use super::{BaseFragment, BaseFragmentInfo, CollapsedBlockMargins, Fragment};
use crate::cell::ArcRefCell;
use crate::formatting_contexts::Baselines;
use crate::geom::{
LengthOrAuto, LogicalRect, LogicalSides, PhysicalPoint, PhysicalRect, PhysicalSides,
PhysicalSize,
AuOrAuto, LogicalRect, LogicalSides, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize,
};
use crate::style_ext::ComputedValuesExt;
@ -50,7 +49,7 @@ pub(crate) struct BoxFragment {
/// From the containing blocks start corner…?
/// This might be broken when the containing block is in a different writing mode:
/// <https://drafts.csswg.org/css-writing-modes/#orthogonal-flows>
pub content_rect: LogicalRect<Length>,
pub content_rect: LogicalRect<Au>,
pub padding: LogicalSides<Au>,
pub border: LogicalSides<Au>,
@ -72,7 +71,7 @@ pub(crate) struct BoxFragment {
pub block_margins_collapsed_with_children: CollapsedBlockMargins,
/// The scrollable overflow of this box fragment.
pub scrollable_overflow_from_children: PhysicalRect<Length>,
pub scrollable_overflow_from_children: PhysicalRect<Au>,
/// Whether or not this box was overconstrained in the given dimension.
overconstrained: PhysicalSize<bool>,
@ -80,7 +79,7 @@ pub(crate) struct BoxFragment {
/// The resolved box insets if this box is `position: sticky`. These are calculated
/// during stacking context tree construction because they rely on the size of the
/// scroll container.
pub(crate) resolved_sticky_insets: Option<PhysicalSides<LengthOrAuto>>,
pub(crate) resolved_sticky_insets: Option<PhysicalSides<AuOrAuto>>,
#[serde(skip_serializing)]
pub background_mode: BackgroundMode,
@ -92,7 +91,7 @@ impl BoxFragment {
base_fragment_info: BaseFragmentInfo,
style: ServoArc<ComputedValues>,
children: Vec<Fragment>,
content_rect: LogicalRect<Length>,
content_rect: LogicalRect<Au>,
padding: LogicalSides<Au>,
border: LogicalSides<Au>,
margin: LogicalSides<Au>,
@ -127,7 +126,7 @@ impl BoxFragment {
base_fragment_info: BaseFragmentInfo,
style: ServoArc<ComputedValues>,
children: Vec<Fragment>,
content_rect: LogicalRect<Length>,
content_rect: LogicalRect<Au>,
padding: LogicalSides<Au>,
border: LogicalSides<Au>,
margin: LogicalSides<Au>,
@ -154,10 +153,7 @@ impl BoxFragment {
let mut baselines = Baselines::default();
if style.establishes_scroll_container() {
baselines.last = Some(
Au::from(content_rect.size.block) +
padding.block_end +
border.block_end +
margin.block_end,
content_rect.size.block + padding.block_end + border.block_end + margin.block_end,
)
}
@ -203,10 +199,7 @@ impl BoxFragment {
self.background_mode = BackgroundMode::None;
}
pub fn scrollable_overflow(
&self,
containing_block: &PhysicalRect<Length>,
) -> PhysicalRect<Length> {
pub fn scrollable_overflow(&self, containing_block: &PhysicalRect<Au>) -> PhysicalRect<Au> {
let physical_padding_rect = self
.padding_rect()
.to_physical(self.style.writing_mode, containing_block);
@ -222,14 +215,12 @@ impl BoxFragment {
)
}
pub fn padding_rect(&self) -> LogicalRect<Length> {
self.content_rect
.inflate(&self.padding.map(|t| (*t).into()))
pub fn padding_rect(&self) -> LogicalRect<Au> {
self.content_rect.inflate(&self.padding)
}
pub fn border_rect(&self) -> LogicalRect<Length> {
self.padding_rect()
.inflate(&self.border.map(|t| (*t).into()))
pub fn border_rect(&self) -> LogicalRect<Au> {
self.padding_rect().inflate(&self.border)
}
pub fn print(&self, tree: &mut PrintTree) {
@ -264,8 +255,8 @@ impl BoxFragment {
pub fn scrollable_overflow_for_parent(
&self,
containing_block: &PhysicalRect<Length>,
) -> PhysicalRect<Length> {
containing_block: &PhysicalRect<Au>,
) -> PhysicalRect<Au> {
let mut overflow = self
.border_rect()
.to_physical(self.style.writing_mode, containing_block);
@ -297,8 +288,8 @@ impl BoxFragment {
pub(crate) fn calculate_resolved_insets_if_positioned(
&self,
containing_block: &PhysicalRect<CSSPixelLength>,
) -> PhysicalSides<LengthOrAuto> {
containing_block: &PhysicalRect<Au>,
) -> PhysicalSides<AuOrAuto> {
let position = self.style.get_box().position;
debug_assert_ne!(
position,
@ -315,12 +306,12 @@ impl BoxFragment {
return resolved_sticky_insets;
}
let convert_to_length_or_auto = |sides: PhysicalSides<Length>| {
let convert_to_length_or_auto = |sides: PhysicalSides<Au>| {
PhysicalSides::new(
LengthOrAuto::LengthPercentage(sides.top),
LengthOrAuto::LengthPercentage(sides.right),
LengthOrAuto::LengthPercentage(sides.bottom),
LengthOrAuto::LengthPercentage(sides.left),
AuOrAuto::LengthPercentage(sides.top),
AuOrAuto::LengthPercentage(sides.right),
AuOrAuto::LengthPercentage(sides.bottom),
AuOrAuto::LengthPercentage(sides.left),
)
};
@ -347,19 +338,25 @@ impl BoxFragment {
(Some(start), Some(end)) => (start, end),
}
};
let (left, right) = get_resolved_axis(&insets.left, &insets.right, cb_width);
let (top, bottom) = get_resolved_axis(&insets.top, &insets.bottom, cb_height);
return convert_to_length_or_auto(PhysicalSides::new(top, right, bottom, left));
let (left, right) = get_resolved_axis(&insets.left, &insets.right, cb_width.into());
let (top, bottom) = get_resolved_axis(&insets.top, &insets.bottom, cb_height.into());
return convert_to_length_or_auto(PhysicalSides::new(
top.into(),
right.into(),
bottom.into(),
left.into(),
));
}
debug_assert!(
position == ComputedPosition::Fixed || position == ComputedPosition::Absolute
);
let resolve = |value: &LengthPercentageOrAuto, container_length| {
let resolve = |value: &LengthPercentageOrAuto, container_length: Au| -> Au {
value
.auto_is(LengthPercentage::zero)
.percentage_relative_to(container_length)
.percentage_relative_to(container_length.into())
.into()
};
let (top, bottom) = if self.overconstrained.height {
@ -379,6 +376,11 @@ impl BoxFragment {
(content_rect.origin.x, cb_width - content_rect.max_x())
};
convert_to_length_or_auto(PhysicalSides::new(top, right, bottom, left))
convert_to_length_or_auto(PhysicalSides::new(
top.into(),
right.into(),
bottom.into(),
left.into(),
))
}
}

View file

@ -65,7 +65,7 @@ pub(crate) struct TextFragment {
pub base: BaseFragment,
#[serde(skip_serializing)]
pub parent_style: ServoArc<ComputedValues>,
pub rect: LogicalRect<Length>,
pub rect: LogicalRect<Au>,
pub font_metrics: FontMetrics,
#[serde(skip_serializing)]
pub font_key: FontInstanceKey,
@ -83,7 +83,7 @@ pub(crate) struct ImageFragment {
pub base: BaseFragment,
#[serde(skip_serializing)]
pub style: ServoArc<ComputedValues>,
pub rect: LogicalRect<Length>,
pub rect: LogicalRect<Au>,
#[serde(skip_serializing)]
pub image_key: ImageKey,
}
@ -93,7 +93,7 @@ pub(crate) struct IFrameFragment {
pub base: BaseFragment,
pub pipeline_id: PipelineId,
pub browsing_context_id: BrowsingContextId,
pub rect: LogicalRect<Length>,
pub rect: LogicalRect<Au>,
#[serde(skip_serializing)]
pub style: ServoArc<ComputedValues>,
}
@ -133,7 +133,7 @@ impl Fragment {
}
}
pub fn scrolling_area(&self, containing_block: &PhysicalRect<Length>) -> PhysicalRect<Length> {
pub fn scrolling_area(&self, containing_block: &PhysicalRect<Au>) -> PhysicalRect<Au> {
match self {
Fragment::Box(fragment) | Fragment::Float(fragment) => fragment
.scrollable_overflow(containing_block)
@ -142,10 +142,7 @@ impl Fragment {
}
}
pub fn scrollable_overflow(
&self,
containing_block: &PhysicalRect<Length>,
) -> PhysicalRect<Length> {
pub fn scrollable_overflow(&self, containing_block: &PhysicalRect<Au>) -> PhysicalRect<Au> {
match self {
Fragment::Box(fragment) | Fragment::Float(fragment) => {
fragment.scrollable_overflow_for_parent(containing_block)
@ -166,9 +163,9 @@ impl Fragment {
pub(crate) fn find<T>(
&self,
manager: &ContainingBlockManager<PhysicalRect<Length>>,
manager: &ContainingBlockManager<PhysicalRect<Au>>,
level: usize,
process_func: &mut impl FnMut(&Fragment, usize, &PhysicalRect<Length>) -> Option<T>,
process_func: &mut impl FnMut(&Fragment, usize, &PhysicalRect<Au>) -> Option<T>,
) -> Option<T> {
let containing_block = manager.get_containing_block_for_fragment(self);
if let Some(result) = process_func(self, level, containing_block) {

View file

@ -9,7 +9,6 @@ use fxhash::FxHashSet;
use serde::Serialize;
use style::animation::AnimationSetKey;
use style::dom::OpaqueNode;
use style::values::computed::Length;
use webrender_api::units;
use webrender_traits::display_list::ScrollSensitivity;
@ -17,7 +16,7 @@ use super::{ContainingBlockManager, Fragment, Tag};
use crate::cell::ArcRefCell;
use crate::display_list::StackingContext;
use crate::flow::CanvasBackground;
use crate::geom::{physical_rect_to_au_rect, PhysicalRect};
use crate::geom::PhysicalRect;
#[derive(Serialize)]
pub struct FragmentTree {
@ -33,10 +32,10 @@ pub struct FragmentTree {
/// The scrollable overflow rectangle for the entire tree
/// <https://drafts.csswg.org/css-overflow/#scrollable>
pub(crate) scrollable_overflow: PhysicalRect<Length>,
pub(crate) scrollable_overflow: PhysicalRect<Au>,
/// The containing block used in the layout of this fragment tree.
pub(crate) initial_containing_block: PhysicalRect<Length>,
pub(crate) initial_containing_block: PhysicalRect<Au>,
/// <https://drafts.csswg.org/css-backgrounds/#special-backgrounds>
#[serde(skip)]
@ -70,14 +69,14 @@ impl FragmentTree {
pub fn scrollable_overflow(&self) -> units::LayoutSize {
units::LayoutSize::from_untyped(Size2D::new(
self.scrollable_overflow.size.width.px(),
self.scrollable_overflow.size.height.px(),
self.scrollable_overflow.size.width.to_f32_px(),
self.scrollable_overflow.size.height.to_f32_px(),
))
}
pub(crate) fn find<T>(
&self,
mut process_func: impl FnMut(&Fragment, usize, &PhysicalRect<Length>) -> Option<T>,
mut process_func: impl FnMut(&Fragment, usize, &PhysicalRect<Au>) -> Option<T>,
) -> Option<T> {
let info = ContainingBlockManager {
for_non_absolute_descendants: &self.initial_containing_block,
@ -125,9 +124,9 @@ impl FragmentTree {
Fragment::IFrame(_) => return None,
};
content_boxes.push(physical_rect_to_au_rect(
fragment_relative_rect.translate(containing_block.origin.to_vector()),
));
let rect = fragment_relative_rect.translate(containing_block.origin.to_vector());
content_boxes.push(rect.to_untyped());
None::<()>
});
content_boxes
@ -156,10 +155,7 @@ impl FragmentTree {
.padding_rect()
.to_physical(fragment.style.writing_mode, containing_block);
Rect::new(
Point2D::new(
border.border_left_width.into(),
border.border_top_width.into(),
),
Point2D::new(border.border_left_width, border.border_top_width),
Size2D::new(padding_rect.size.width, padding_rect.size.height),
)
},
@ -171,15 +167,15 @@ impl FragmentTree {
};
let rect = Rect::new(
Point2D::new(rect.origin.x.px(), rect.origin.y.px()),
Size2D::new(rect.size.width.px(), rect.size.height.px()),
Point2D::new(rect.origin.x.to_f32_px(), rect.origin.y.to_f32_px()),
Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px()),
);
Some(rect.round().to_i32().to_untyped())
})
.unwrap_or_else(Rect::zero)
}
pub fn get_scrolling_area_for_viewport(&self) -> PhysicalRect<Length> {
pub fn get_scrolling_area_for_viewport(&self) -> PhysicalRect<Au> {
let mut scroll_area = self.initial_containing_block;
for fragment in self.root_fragments.iter() {
scroll_area = fragment
@ -190,7 +186,7 @@ impl FragmentTree {
scroll_area
}
pub fn get_scrolling_area_for_node(&self, requested_node: OpaqueNode) -> PhysicalRect<Length> {
pub fn get_scrolling_area_for_node(&self, requested_node: OpaqueNode) -> PhysicalRect<Au> {
let tag_to_find = Tag::new(requested_node);
let scroll_area = self.find(|fragment, _, containing_block| {
if fragment.tag() == Some(tag_to_find) {
@ -199,6 +195,6 @@ impl FragmentTree {
None
}
});
scroll_area.unwrap_or_else(PhysicalRect::<Length>::zero)
scroll_area.unwrap_or_else(PhysicalRect::<Au>::zero)
}
}

View file

@ -2,12 +2,12 @@
* 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 app_units::Au;
use base::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;
@ -19,12 +19,12 @@ use crate::geom::{LogicalRect, PhysicalRect};
#[derive(Serialize)]
pub(crate) struct PositioningFragment {
pub base: BaseFragment,
pub rect: LogicalRect<Length>,
pub rect: LogicalRect<Au>,
pub children: Vec<ArcRefCell<Fragment>>,
pub writing_mode: WritingMode,
/// The scrollable overflow of this anonymous fragment's children.
pub scrollable_overflow: PhysicalRect<Length>,
pub scrollable_overflow: PhysicalRect<Au>,
/// If this fragment was created with a style, the style of the fragment.
#[serde(skip_serializing)]
@ -33,7 +33,7 @@ pub(crate) struct PositioningFragment {
impl PositioningFragment {
pub fn new_anonymous(
rect: LogicalRect<Length>,
rect: LogicalRect<Au>,
children: Vec<Fragment>,
mode: WritingMode,
) -> Self {
@ -42,7 +42,7 @@ impl PositioningFragment {
pub fn new_empty(
base_fragment_info: BaseFragmentInfo,
rect: LogicalRect<Length>,
rect: LogicalRect<Au>,
style: ServoArc<ComputedValues>,
) -> Self {
let writing_mode = style.writing_mode;
@ -58,7 +58,7 @@ impl PositioningFragment {
fn new_with_base_fragment(
base: BaseFragment,
style: Option<ServoArc<ComputedValues>>,
rect: LogicalRect<Length>,
rect: LogicalRect<Au>,
children: Vec<Fragment>,
mode: WritingMode,
) -> Self {