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

@ -5,6 +5,7 @@
use std::cell::{OnceCell, RefCell};
use std::sync::Arc;
use app_units::Au;
use base::id::BrowsingContextId;
use base::WebRenderEpochToU16;
use embedder_traits::Cursor;
@ -34,7 +35,7 @@ use crate::display_list::stacking_context::StackingContextSection;
use crate::fragment_tree::{
BackgroundMode, BoxFragment, Fragment, FragmentFlags, FragmentTree, Tag, TextFragment,
};
use crate::geom::{LogicalRect, PhysicalPoint, PhysicalRect};
use crate::geom::{PhysicalPoint, PhysicalRect};
use crate::replaced::IntrinsicSizes;
use crate::style_ext::ComputedValuesExt;
@ -230,7 +231,7 @@ impl Fragment {
pub(crate) fn build_display_list(
&self,
builder: &mut DisplayListBuilder,
containing_block: &PhysicalRect<Length>,
containing_block: &PhysicalRect<Au>,
section: StackingContextSection,
) {
match self {
@ -288,7 +289,7 @@ impl Fragment {
builder.iframe_sizes.insert(
iframe.browsing_context_id,
Size2D::new(rect.size.width.px(), rect.size.height.px()),
Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px()),
);
let common = builder.common_properties(rect.to_webrender(), &iframe.style);
@ -321,7 +322,7 @@ impl Fragment {
builder: &mut DisplayListBuilder,
style: &ComputedValues,
tag: Option<Tag>,
rect: PhysicalRect<Length>,
rect: PhysicalRect<Au>,
cursor: Cursor,
) {
let hit_info = builder.hit_info(style, tag, cursor);
@ -345,7 +346,7 @@ impl Fragment {
&self,
fragment: &TextFragment,
builder: &mut DisplayListBuilder,
containing_block: &PhysicalRect<Length>,
containing_block: &PhysicalRect<Au>,
) {
// NB: The order of painting text components (CSS Text Decoration Module Level 3) is:
// shadows, underline, overline, text, text-emphasis, and then line-through.
@ -357,7 +358,7 @@ impl Fragment {
.to_physical(fragment.parent_style.writing_mode, containing_block)
.translate(containing_block.origin.to_vector());
let mut baseline_origin = rect.origin;
baseline_origin.y += Length::from(fragment.font_metrics.ascent);
baseline_origin.y += fragment.font_metrics.ascent;
let glyphs = glyphs(
&fragment.glyphs,
baseline_origin,
@ -404,8 +405,8 @@ impl Fragment {
.contains(TextDecorationLine::UNDERLINE)
{
let mut rect = rect;
rect.origin.y += Length::from(font_metrics.ascent - font_metrics.underline_offset);
rect.size.height = Length::new(font_metrics.underline_size.to_nearest_pixel(dppx));
rect.origin.y += font_metrics.ascent - font_metrics.underline_offset;
rect.size.height = Au::from_f32_px(font_metrics.underline_size.to_nearest_pixel(dppx));
self.build_display_list_for_text_decoration(fragment, builder, &rect, &color);
}
@ -415,7 +416,7 @@ impl Fragment {
.contains(TextDecorationLine::OVERLINE)
{
let mut rect = rect;
rect.size.height = Length::new(font_metrics.underline_size.to_nearest_pixel(dppx));
rect.size.height = Au::from_f32_px(font_metrics.underline_size.to_nearest_pixel(dppx));
self.build_display_list_for_text_decoration(fragment, builder, &rect, &color);
}
@ -435,8 +436,8 @@ impl Fragment {
.contains(TextDecorationLine::LINE_THROUGH)
{
let mut rect = rect;
rect.origin.y += Length::from(font_metrics.ascent - font_metrics.strikeout_offset);
rect.size.height = Length::new(font_metrics.strikeout_size.to_nearest_pixel(dppx));
rect.origin.y += font_metrics.ascent - font_metrics.strikeout_offset;
rect.size.height = Au::from_f32_px(font_metrics.strikeout_size.to_nearest_pixel(dppx));
self.build_display_list_for_text_decoration(fragment, builder, &rect, &color);
}
@ -449,7 +450,7 @@ impl Fragment {
&self,
fragment: &TextFragment,
builder: &mut DisplayListBuilder,
rect: &PhysicalRect<Length>,
rect: &PhysicalRect<Au>,
color: &AbsoluteColor,
) {
let rect = rect.to_webrender();
@ -476,7 +477,7 @@ impl Fragment {
struct BuilderForBoxFragment<'a> {
fragment: &'a BoxFragment,
containing_block: &'a PhysicalRect<Length>,
containing_block: &'a PhysicalRect<Au>,
border_rect: units::LayoutRect,
padding_rect: OnceCell<units::LayoutRect>,
content_rect: OnceCell<units::LayoutRect>,
@ -487,7 +488,7 @@ struct BuilderForBoxFragment<'a> {
}
impl<'a> BuilderForBoxFragment<'a> {
fn new(fragment: &'a BoxFragment, containing_block: &'a PhysicalRect<Length>) -> Self {
fn new(fragment: &'a BoxFragment, containing_block: &'a PhysicalRect<Au>) -> Self {
let border_rect: units::LayoutRect = fragment
.border_rect()
.to_physical(fragment.style.writing_mode, containing_block)
@ -711,7 +712,7 @@ impl<'a> BuilderForBoxFragment<'a> {
// is used).
if let BackgroundMode::Extra(ref extra_backgrounds) = self.fragment.background_mode {
for extra_background in extra_backgrounds {
let positioning_area: LogicalRect<Length> = extra_background.rect.clone().into();
let positioning_area = extra_background.rect.clone();
let painter = BackgroundPainter {
style: &extra_background.style,
painting_area_override: None,
@ -959,7 +960,7 @@ fn rgba(color: AbsoluteColor) -> wr::ColorF {
fn glyphs(
glyph_runs: &[Arc<GlyphStore>],
mut baseline_origin: PhysicalPoint<Length>,
mut baseline_origin: PhysicalPoint<Au>,
justification_adjustment: Length,
) -> Vec<wr::GlyphInstance> {
use fonts_traits::ByteIndex;
@ -971,8 +972,8 @@ fn glyphs(
if !run.is_whitespace() {
let glyph_offset = glyph.offset().unwrap_or(Point2D::zero());
let point = units::LayoutPoint::new(
baseline_origin.x.px() + glyph_offset.x.to_f32_px(),
baseline_origin.y.px() + glyph_offset.y.to_f32_px(),
baseline_origin.x.to_f32_px() + glyph_offset.x.to_f32_px(),
baseline_origin.y.to_f32_px() + glyph_offset.y.to_f32_px(),
);
let glyph = wr::GlyphInstance {
index: glyph.id(),
@ -982,9 +983,9 @@ fn glyphs(
}
if glyph.char_is_word_separator() {
baseline_origin.x += justification_adjustment;
baseline_origin.x += justification_adjustment.into();
}
baseline_origin.x += Length::from(glyph.advance());
baseline_origin.x += glyph.advance();
}
}
glyphs

View file

@ -5,8 +5,9 @@
use std::cell::RefCell;
use std::mem;
use app_units::Au;
use base::print_tree::PrintTree;
use euclid::default::Rect;
use euclid::default::{Point2D, Rect, Size2D};
use euclid::SideOffsets2D;
use log::warn;
use servo_arc::Arc as ServoArc;
@ -34,7 +35,7 @@ use crate::display_list::DisplayListBuilder;
use crate::fragment_tree::{
BoxFragment, ContainingBlockManager, Fragment, FragmentFlags, FragmentTree, PositioningFragment,
};
use crate::geom::{PhysicalRect, PhysicalSides};
use crate::geom::{AuOrAuto, PhysicalRect, PhysicalSides};
use crate::style_ext::ComputedValuesExt;
#[derive(Clone)]
@ -53,12 +54,12 @@ pub(crate) struct ContainingBlock {
clip_chain_id: wr::ClipChainId,
/// The physical rect of this containing block.
rect: PhysicalRect<Length>,
rect: PhysicalRect<Au>,
}
impl ContainingBlock {
pub(crate) fn new(
rect: PhysicalRect<Length>,
rect: PhysicalRect<Au>,
scroll_node_id: ScrollTreeNodeId,
scroll_frame_size: Option<LayoutSize>,
clip_chain_id: wr::ClipChainId,
@ -71,7 +72,7 @@ impl ContainingBlock {
}
}
pub(crate) fn new_replacing_rect(&self, rect: &PhysicalRect<Length>) -> Self {
pub(crate) fn new_replacing_rect(&self, rect: &PhysicalRect<Au>) -> Self {
ContainingBlock {
rect: *rect,
..*self
@ -246,7 +247,7 @@ pub(crate) enum StackingContextContent {
reference_frame_scroll_node_id: ScrollTreeNodeId,
clip_chain_id: wr::ClipChainId,
section: StackingContextSection,
containing_block: PhysicalRect<Length>,
containing_block: PhysicalRect<Au>,
fragment: ArcRefCell<Fragment>,
},
@ -528,7 +529,7 @@ impl StackingContext {
&self,
builder: &mut DisplayListBuilder,
fragment_tree: &crate::FragmentTree,
containing_block_rect: &PhysicalRect<Length>,
containing_block_rect: &PhysicalRect<Au>,
) {
let style = if let Some(style) = &fragment_tree.canvas_background.style {
style
@ -896,7 +897,7 @@ impl Fragment {
}
struct ReferenceFrameData {
origin: crate::geom::PhysicalPoint<Length>,
origin: crate::geom::PhysicalPoint<Au>,
transform: LayoutTransform,
kind: wr::ReferenceFrameKind,
}
@ -1220,7 +1221,7 @@ impl BoxFragment {
display_list: &mut DisplayList,
parent_scroll_node_id: &ScrollTreeNodeId,
parent_clip_chain_id: &wr::ClipChainId,
containing_block_rect: &PhysicalRect<Length>,
containing_block_rect: &PhysicalRect<Au>,
) -> Option<wr::ClipChainId> {
let position = self.style.get_box().position;
// https://drafts.csswg.org/css2/#clipping
@ -1254,7 +1255,7 @@ impl BoxFragment {
display_list: &mut DisplayList,
parent_scroll_node_id: &ScrollTreeNodeId,
parent_clip_id: &wr::ClipChainId,
containing_block_rect: &PhysicalRect<Length>,
containing_block_rect: &PhysicalRect<Au>,
) -> Option<(ScrollTreeNodeId, wr::ClipChainId, LayoutSize)> {
let overflow_x = self.style.get_box().overflow_x;
let overflow_y = self.style.get_box().overflow_y;
@ -1316,7 +1317,7 @@ impl BoxFragment {
&mut self,
display_list: &mut DisplayList,
parent_scroll_node_id: &ScrollTreeNodeId,
containing_block_rect: &PhysicalRect<Length>,
containing_block_rect: &PhysicalRect<Au>,
scroll_frame_size: &Option<LayoutSize>,
) -> Option<ScrollTreeNodeId> {
if self.style.get_box().position != ComputedPosition::Sticky {
@ -1335,19 +1336,23 @@ impl BoxFragment {
// nearest scroll frame instead of the containing block like for other types
// of positioning.
let position = self.style.get_position();
let offsets = PhysicalSides::new(
position
.top
.map(|v| v.resolve(Length::new(scroll_frame_size_for_resolve.height))),
position
.right
.map(|v| v.resolve(Length::new(scroll_frame_size_for_resolve.width))),
position
.bottom
.map(|v| v.resolve(Length::new(scroll_frame_size_for_resolve.height))),
position
.left
.map(|v| v.resolve(Length::new(scroll_frame_size_for_resolve.width))),
let offsets = PhysicalSides::<AuOrAuto>::new(
position.top.map(|v| {
v.resolve(Length::new(scroll_frame_size_for_resolve.height))
.into()
}),
position.right.map(|v| {
v.resolve(Length::new(scroll_frame_size_for_resolve.width))
.into()
}),
position.bottom.map(|v| {
v.resolve(Length::new(scroll_frame_size_for_resolve.height))
.into()
}),
position.left.map(|v| {
v.resolve(Length::new(scroll_frame_size_for_resolve.width))
.into()
}),
);
self.resolved_sticky_insets = Some(offsets);
@ -1385,10 +1390,10 @@ impl BoxFragment {
);
let margins = SideOffsets2D::new(
offsets.top.non_auto().map(|v| v.px()),
offsets.right.non_auto().map(|v| v.px()),
offsets.bottom.non_auto().map(|v| v.px()),
offsets.left.non_auto().map(|v| v.px()),
offsets.top.non_auto().map(|v| v.to_f32_px()),
offsets.right.non_auto().map(|v| v.to_f32_px()),
offsets.bottom.non_auto().map(|v| v.to_f32_px()),
offsets.left.non_auto().map(|v| v.to_f32_px()),
);
let sticky_node_id = display_list.define_sticky_frame(
@ -1405,7 +1410,7 @@ impl BoxFragment {
/// Optionally returns the data for building a reference frame, without yet building it.
fn reference_frame_data_if_necessary(
&self,
containing_block_rect: &PhysicalRect<Length>,
containing_block_rect: &PhysicalRect<Au>,
) -> Option<ReferenceFrameData> {
if !self.style.has_transform_or_perspective(self.base.flags) {
return None;
@ -1451,22 +1456,24 @@ impl BoxFragment {
}
/// Returns true if the given style contains a transform that is not invertible.
fn has_non_invertible_transform_or_zero_scale(&self, containing_block: &Rect<Length>) -> bool {
fn has_non_invertible_transform_or_zero_scale(&self, containing_block: &Rect<Au>) -> bool {
let list = &self.style.get_box().transform;
match list.to_transform_3d_matrix(Some(containing_block)) {
match list.to_transform_3d_matrix(Some(&au_rect_to_length_rect(containing_block))) {
Ok(t) => !t.0.is_invertible() || t.0.m11 == 0. || t.0.m22 == 0.,
Err(_) => false,
}
}
/// Returns the 4D matrix representing this fragment's transform.
pub fn calculate_transform_matrix(
&self,
border_rect: &Rect<Length>,
) -> Option<LayoutTransform> {
pub fn calculate_transform_matrix(&self, border_rect: &Rect<Au>) -> Option<LayoutTransform> {
let list = &self.style.get_box().transform;
let transform =
LayoutTransform::from_untyped(&list.to_transform_3d_matrix(Some(border_rect)).ok()?.0);
let transform = LayoutTransform::from_untyped(
&list
.to_transform_3d_matrix(Some(&au_rect_to_length_rect(border_rect)))
.ok()?
.0,
);
// WebRender will end up dividing by the scale value of this transform, so we
// want to ensure we don't feed it a divisor of 0.
assert_ne!(transform.m11, 0.);
@ -1475,11 +1482,11 @@ impl BoxFragment {
let transform_origin = &self.style.get_box().transform_origin;
let transform_origin_x = transform_origin
.horizontal
.percentage_relative_to(border_rect.size.width)
.percentage_relative_to(border_rect.size.width.into())
.px();
let transform_origin_y = transform_origin
.vertical
.percentage_relative_to(border_rect.size.height)
.percentage_relative_to(border_rect.size.height.into())
.px();
let transform_origin_z = transform_origin.depth.px();
@ -1498,21 +1505,18 @@ impl BoxFragment {
}
/// Returns the 4D matrix representing this fragment's perspective.
pub fn calculate_perspective_matrix(
&self,
border_rect: &Rect<Length>,
) -> Option<LayoutTransform> {
pub fn calculate_perspective_matrix(&self, border_rect: &Rect<Au>) -> Option<LayoutTransform> {
match self.style.get_box().perspective {
Perspective::Length(length) => {
let perspective_origin = &self.style.get_box().perspective_origin;
let perspective_origin = LayoutPoint::new(
perspective_origin
.horizontal
.percentage_relative_to(border_rect.size.width)
.percentage_relative_to(border_rect.size.width.into())
.px(),
perspective_origin
.vertical
.percentage_relative_to(border_rect.size.height)
.percentage_relative_to(border_rect.size.height.into())
.px(),
);
@ -1563,3 +1567,10 @@ impl PositioningFragment {
}
}
}
pub fn au_rect_to_length_rect(rect: &Rect<Au>) -> Rect<Length> {
Rect::new(
Point2D::new(rect.origin.x.into(), rect.origin.y.into()),
Size2D::new(rect.size.width.into(), rect.size.height.into()),
)
}

View file

@ -433,7 +433,7 @@ impl FlexContainer {
},
};
for (fragment, _) in &mut line.item_fragments {
fragment.content_rect.start_corner += &flow_relative_line_position
fragment.content_rect.start_corner += &flow_relative_line_position.into()
}
line.item_fragments
});
@ -965,7 +965,7 @@ impl FlexLine<'_> {
item.box_.base_fragment_info(),
item.box_.style().clone(),
item_result.fragments,
content_rect,
content_rect.into(),
flex_context.sides_to_flow_relative(item.padding),
flex_context.sides_to_flow_relative(item.border),
margin,

View file

@ -991,7 +991,7 @@ impl FloatBox {
self.contents.base_fragment_info(),
style.clone(),
children,
content_rect,
content_rect.into(),
pbm.padding,
pbm.border,
margin,
@ -1209,7 +1209,7 @@ impl SequentialLayoutState {
);
let pbm_sums = &(&box_fragment.padding + &box_fragment.border) + &box_fragment.margin;
let content_rect: LogicalRect<Au> = box_fragment.content_rect.clone().into();
let content_rect = box_fragment.content_rect.clone();
let margin_box_start_corner = self.floats.add_float(&PlacementInfo {
size: &content_rect.size + &pbm_sums.sum(),
side: FloatSide::from_style(&box_fragment.style).expect("Float box wasn't floated!"),
@ -1227,6 +1227,6 @@ impl SequentialLayoutState {
block: new_position_in_bfc.block - block_start_of_containing_block_in_bfc,
};
box_fragment.content_rect.start_corner = new_position_in_containing_block.into();
box_fragment.content_rect.start_corner = new_position_in_containing_block;
}
}

View file

@ -240,7 +240,7 @@ impl TextRunLineItem {
Some(TextFragment {
base: self.base_fragment_info.into(),
parent_style: self.parent_style,
rect,
rect: rect.into(),
font_metrics: self.font_metrics,
font_key: self.font_key,
glyphs: self.text,
@ -366,14 +366,15 @@ impl InlineBoxLineItem {
// Relative adjustment should not affect the rest of line layout, so we can
// do it right before creating the Fragment.
if style.clone_position().is_relative() {
content_rect.start_corner += &relative_adjustement(&style, state.ifc_containing_block);
content_rect.start_corner +=
&relative_adjustement(&style, state.ifc_containing_block).into();
}
let mut fragment = BoxFragment::new(
self.base_fragment_info,
self.style.clone(),
fragments,
content_rect,
content_rect.into(),
padding,
border,
margin,
@ -460,13 +461,13 @@ impl AtomicLineItem {
// The initial `start_corner` of the Fragment is only the PaddingBorderMargin sum start
// offset, which is the sum of the start component of the padding, border, and margin.
// This needs to be added to the calculated block and inline positions.
self.fragment.content_rect.start_corner.inline += state.inline_position;
self.fragment.content_rect.start_corner.inline += state.inline_position.into();
self.fragment.content_rect.start_corner.block +=
self.calculate_block_start(state.line_metrics);
self.calculate_block_start(state.line_metrics).into();
// Make the final result relative to the parent box.
self.fragment.content_rect.start_corner =
&self.fragment.content_rect.start_corner - &state.parent_offset;
&self.fragment.content_rect.start_corner - &state.parent_offset.into();
if self.fragment.style.clone_position().is_relative() {
self.fragment.content_rect.start_corner +=
@ -571,7 +572,7 @@ impl FloatLineItem {
block: state.line_metrics.block_offset + state.parent_offset.block,
};
self.fragment.content_rect.start_corner =
&self.fragment.content_rect.start_corner - &distance_from_parent_to_ifc;
&self.fragment.content_rect.start_corner - &distance_from_parent_to_ifc.into();
self.fragment
}
}

View file

@ -381,13 +381,13 @@ impl LineBlockSizes {
}
}
fn resolve(&self) -> Length {
fn resolve(&self) -> Au {
let height_from_ascent_and_descent = self
.baseline_relative_size_for_line_height
.as_ref()
.map(|size| (size.ascent + size.descent).abs())
.unwrap_or_else(Au::zero);
self.line_height.max(height_from_ascent_and_descent.into())
Au::from(self.line_height).max(height_from_ascent_and_descent)
}
fn max(&self, other: &LineBlockSizes) -> LineBlockSizes {
@ -431,7 +431,7 @@ impl LineBlockSizes {
None => {
// This is the case mentinoned above where there are multiple solutions.
// This code is putting the baseline roughly in the middle of the line.
let leading = Au::from(self.resolve()) -
let leading = self.resolve() -
(self.size_for_baseline_positioning.ascent +
self.size_for_baseline_positioning.descent);
leading.scale_by(0.5) + self.size_for_baseline_positioning.ascent
@ -900,7 +900,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
LineBlockSizes::zero()
};
let resolved_block_advance = effective_block_advance.resolve().into();
let resolved_block_advance = effective_block_advance.resolve();
let mut block_end_position = block_start_position + resolved_block_advance;
if let Some(sequential_layout_state) = self.sequential_layout_state.as_mut() {
// This amount includes both the block size of the line and any extra space
@ -942,7 +942,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
justification_adjustment,
line_metrics: &LineMetrics {
block_offset: block_start_position.into(),
block_size: effective_block_advance.resolve(),
block_size: effective_block_advance.resolve().into(),
baseline_block_offset: baseline_offset,
},
};
@ -973,11 +973,11 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
// the inline start of the line in `calculate_inline_start_for_current_line` so
// we do not need to include it in the `start_corner` of the line's main Fragment.
start_corner: LogicalVec2 {
inline: Length::zero(),
block: block_start_position.into(),
inline: Au::zero(),
block: block_start_position,
},
size: LogicalVec2 {
inline: self.containing_block.inline_size.into(),
inline: self.containing_block.inline_size,
block: effective_block_advance.resolve(),
},
};
@ -1134,8 +1134,8 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
let margin_box = float_item
.fragment
.border_rect()
.inflate(&float_item.fragment.margin.map(|t| (*t).into()));
let inline_size = margin_box.size.inline.max(Length::zero());
.inflate(&float_item.fragment.margin);
let inline_size = margin_box.size.inline.max(Au::zero());
let available_inline_size = match self.current_line.placement_among_floats.get() {
Some(placement_among_floats) => placement_among_floats.size.inline,
@ -1148,7 +1148,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
// parenting in their stacking contexts). Once all the line content is gathered we
// will place them later.
let has_content = self.current_line.has_content || self.current_line_segment.has_content;
let fits_on_line = !has_content || inline_size <= available_inline_size;
let fits_on_line = !has_content || inline_size <= available_inline_size.into();
let needs_placement_later =
self.current_line.has_floats_waiting_to_be_placed || !fits_on_line;
@ -1165,7 +1165,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
// start position.
let new_placement = self.place_line_among_floats(&LogicalVec2 {
inline: line_inline_size_without_trailing_whitespace,
block: self.current_line.max_block_size.resolve(),
block: self.current_line.max_block_size.resolve().into(),
});
self.current_line
.replace_placement_among_floats(new_placement);
@ -1472,7 +1472,8 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
block: self
.current_line_max_block_size_including_nested_containers()
.max(&self.current_line_segment.max_block_size)
.resolve(),
.resolve()
.into(),
};
if self.new_potential_line_size_causes_line_break(&potential_line_size) {
@ -1520,7 +1521,7 @@ impl<'a, 'b> InlineFormattingContextState<'a, 'b> {
if self.current_line.line_items.is_empty() {
let will_break = self.new_potential_line_size_causes_line_break(&LogicalVec2 {
inline: line_inline_size_without_trailing_whitespace,
block: self.current_line_segment.max_block_size.resolve(),
block: self.current_line_segment.max_block_size.resolve().into(),
});
assert!(!will_break);
}
@ -1938,13 +1939,13 @@ impl InlineContainerState {
block_size
.resolve()
.scale_by(FONT_SUBSCRIPT_OFFSET_RATIO)
.px(),
.to_f32_px(),
),
VerticalAlign::Keyword(VerticalAlignKeyword::Super) => -Au::from_f32_px(
block_size
.resolve()
.scale_by(FONT_SUPERSCRIPT_OFFSET_RATIO)
.px(),
.to_f32_px(),
),
VerticalAlign::Keyword(VerticalAlignKeyword::TextTop) => {
child_block_size.size_for_baseline_positioning.ascent - self.font_metrics.ascent
@ -2047,7 +2048,7 @@ impl IndependentFormattingContext {
replaced.base_fragment_info,
replaced.style.clone(),
fragments,
content_rect.into(),
content_rect,
pbm.padding,
pbm.border,
margin,
@ -2136,7 +2137,7 @@ impl IndependentFormattingContext {
non_replaced.base_fragment_info,
non_replaced.style.clone(),
independent_layout.fragments,
content_rect.into(),
content_rect,
pbm.padding,
pbm.border,
margin,
@ -2155,22 +2156,22 @@ impl IndependentFormattingContext {
ifc.process_soft_wrap_opportunity();
}
let size = &pbm_sums.sum().into() + &fragment.content_rect.size;
let size = &pbm_sums.sum() + &fragment.content_rect.size;
let baseline_offset = self
.pick_baseline(&fragment.baselines)
.map(|baseline| pbm_sums.block_start + baseline)
.unwrap_or(size.block.into());
.unwrap_or(size.block);
let (block_sizes, baseline_offset_in_parent) =
self.get_block_sizes_and_baseline_offset(ifc, size.block, baseline_offset);
self.get_block_sizes_and_baseline_offset(ifc, size.block.into(), baseline_offset);
ifc.update_unbreakable_segment_for_new_content(
&block_sizes,
size.inline,
size.inline.into(),
SegmentContentFlags::empty(),
);
ifc.push_line_item_to_unbreakable_segment(LineItem::Atomic(AtomicLineItem {
fragment,
size,
size: size.into(),
positioning_context: child_positioning_context,
baseline_offset_in_parent,
baseline_offset_in_item: baseline_offset,

View file

@ -244,10 +244,10 @@ impl OutsideMarker {
let max_inline_size = flow_layout.fragments.iter().fold(
Length::zero(),
|current_max, fragment| match fragment {
Fragment::Text(text) => current_max.max(text.rect.max_inline_position()),
Fragment::Image(image) => current_max.max(image.rect.max_inline_position()),
Fragment::Text(text) => current_max.max(text.rect.max_inline_position().into()),
Fragment::Image(image) => current_max.max(image.rect.max_inline_position().into()),
Fragment::Positioning(positioning) => {
current_max.max(positioning.rect.max_inline_position())
current_max.max(positioning.rect.max_inline_position().into())
},
Fragment::Box(_) |
Fragment::Float(_) |
@ -286,7 +286,7 @@ impl OutsideMarker {
base_fragment_info,
self.marker_style.clone(),
flow_layout.fragments,
content_rect,
content_rect.into(),
LogicalSides::zero(),
LogicalSides::zero(),
LogicalSides::zero(),
@ -910,7 +910,7 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context(
base_fragment_info,
style.clone(),
flow_layout.fragments,
content_rect.into(),
content_rect,
pbm.padding,
pbm.border,
margin,
@ -996,7 +996,7 @@ impl NonReplacedFormattingContext {
self.base_fragment_info,
self.style.clone(),
layout.fragments,
content_rect.into(),
content_rect,
pbm.padding,
pbm.border,
margin,
@ -1248,7 +1248,7 @@ impl NonReplacedFormattingContext {
self.base_fragment_info,
self.style.clone(),
layout.fragments,
content_rect.into(),
content_rect,
pbm.padding,
pbm.border,
margin,
@ -1353,7 +1353,7 @@ fn layout_in_flow_replaced_block_level(
base_fragment_info,
style.clone(),
fragments,
content_rect.into(),
content_rect,
pbm.padding,
pbm.border,
margin,
@ -1668,7 +1668,7 @@ impl PlacementState {
return;
}
let box_block_offset = box_fragment.content_rect.start_corner.block.into();
let box_block_offset = box_fragment.content_rect.start_corner.block;
if let (None, Some(first)) = (self.inflow_baselines.first, box_fragment.baselines.first) {
self.inflow_baselines.first = Some(first + box_block_offset);
}
@ -1700,14 +1700,14 @@ impl PlacementState {
.contains(FragmentFlags::IS_OUTSIDE_LIST_ITEM_MARKER);
if is_outside_marker {
assert!(self.marker_block_size.is_none());
self.marker_block_size = Some(fragment.content_rect.size.block.into());
self.marker_block_size = Some(fragment.content_rect.size.block);
return;
}
let fragment_block_margins = &fragment.block_margins_collapsed_with_children;
let mut fragment_block_size = fragment.padding.block_sum() +
fragment.border.block_sum() +
fragment.content_rect.size.block.into();
fragment.content_rect.size.block;
// We use `last_in_flow_margin_collapses_with_parent_end_margin` to implement
// this quote from https://drafts.csswg.org/css2/#collapsing-margins
@ -1744,7 +1744,7 @@ impl PlacementState {
.adjoin_assign(&fragment_block_margins.start);
}
fragment.content_rect.start_corner.block +=
(self.current_margin.solve() + self.current_block_direction_position).into();
self.current_margin.solve() + self.current_block_direction_position;
if fragment_block_margins.collapsed_through {
// `fragment_block_size` is typically zero when collapsing through,

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 app_units::Au;
use atomic_refcell::AtomicRef;
use script_layout_interface::wrapper_traits::{
LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
@ -11,7 +12,7 @@ use serde::Serialize;
use servo_arc::Arc;
use style::dom::OpaqueNode;
use style::properties::ComputedValues;
use style::values::computed::{Length, Overflow};
use style::values::computed::Overflow;
use style_traits::CSSPixel;
use webrender_traits::display_list::ScrollSensitivity;
@ -306,12 +307,15 @@ impl BoxTree {
// https://drafts.csswg.org/css-writing-modes/#principal-flow
let physical_containing_block = PhysicalRect::new(
PhysicalPoint::zero(),
PhysicalSize::new(Length::new(viewport.width), Length::new(viewport.height)),
PhysicalSize::new(
Au::from_f32_px(viewport.width),
Au::from_f32_px(viewport.height),
),
);
let initial_containing_block = DefiniteContainingBlock {
size: LogicalVec2 {
inline: physical_containing_block.size.width.into(),
block: physical_containing_block.size.height.into(),
inline: physical_containing_block.size.width,
block: physical_containing_block.size.height,
},
style,
};

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 {

View file

@ -216,6 +216,19 @@ impl fmt::Debug for LogicalRect<Length> {
}
}
impl fmt::Debug for LogicalRect<Au> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"Rect(i{}×b{} @ (i{},b{}))",
self.size.inline.to_px(),
self.size.block.to_px(),
self.start_corner.inline.to_px(),
self.start_corner.block.to_px(),
)
}
}
impl<T: Clone> LogicalVec2<T> {
pub fn to_physical(&self, mode: WritingMode) -> PhysicalSize<T> {
// https://drafts.csswg.org/css-writing-modes/#logical-to-physical
@ -525,17 +538,3 @@ impl From<LogicalRect<CSSPixelLength>> for LogicalRect<Au> {
}
}
}
/// Convert a `PhysicalRect<Length>` (one that uses CSSPixel as the unit) to an untyped `Rect<Au>`.
pub fn physical_rect_to_au_rect(rect: PhysicalRect<Length>) -> euclid::default::Rect<Au> {
euclid::default::Rect::new(
euclid::default::Point2D::new(
Au::from_f32_px(rect.origin.x.px()),
Au::from_f32_px(rect.origin.y.px()),
),
euclid::default::Size2D::new(
Au::from_f32_px(rect.size.width.px()),
Au::from_f32_px(rect.size.height.px()),
),
)
}

View file

@ -8,7 +8,7 @@ use rayon::prelude::{IndexedParallelIterator, ParallelIterator};
use serde::Serialize;
use style::computed_values::position::T as Position;
use style::properties::ComputedValues;
use style::values::computed::{CSSPixelLength, Length};
use style::values::computed::Length;
use style::values::specified::text::TextDecorationLine;
use style::Zero;
@ -190,16 +190,16 @@ impl PositioningContext {
/// See documentation for [PositioningContext::adjust_static_position_of_hoisted_fragments].
pub(crate) fn adjust_static_position_of_hoisted_fragments_with_offset(
&mut self,
start_offset: &LogicalVec2<CSSPixelLength>,
start_offset: &LogicalVec2<Au>,
index: PositioningContextLength,
) {
let update_fragment_if_needed = |hoisted_fragment: &mut HoistedAbsolutelyPositionedBox| {
let mut fragment = hoisted_fragment.fragment.borrow_mut();
if let AbsoluteBoxOffsets::StaticStart { start } = &mut fragment.box_offsets.inline {
*start += start_offset.inline.into();
*start += start_offset.inline;
}
if let AbsoluteBoxOffsets::StaticStart { start } = &mut fragment.box_offsets.block {
*start += start_offset.block.into();
*start += start_offset.block;
}
};
@ -259,9 +259,9 @@ impl PositioningContext {
// Ignore the content rects position in its own containing block:
start_corner: LogicalVec2::zero(),
}
.inflate(&new_fragment.padding.map(|t| (*t).into()));
.inflate(&new_fragment.padding);
let containing_block = DefiniteContainingBlock {
size: padding_rect.size.into(),
size: padding_rect.size,
style: &new_fragment.style,
};
@ -719,7 +719,7 @@ impl HoistedAbsolutelyPositionedBox {
absolutely_positioned_box.context.base_fragment_info(),
absolutely_positioned_box.context.style().clone(),
fragments,
content_rect.into(),
content_rect,
pbm.padding,
pbm.border,
margin,
@ -889,7 +889,7 @@ fn vec_append_owned<T>(a: &mut Vec<T>, mut b: Vec<T>) {
pub(crate) fn relative_adjustement(
style: &ComputedValues,
containing_block: &ContainingBlock,
) -> LogicalVec2<Length> {
) -> LogicalVec2<Au> {
// It's not completely clear what to do with indefinite percentages
// (https://github.com/w3c/csswg-drafts/issues/9353), so we match
// other browsers and treat them as 'auto' offsets.
@ -898,20 +898,20 @@ pub(crate) fn relative_adjustement(
let box_offsets = style
.box_offsets(containing_block)
.map_inline_and_block_axes(
|v| v.percentage_relative_to(cbis.into()),
|v| v.percentage_relative_to(cbis.into()).map(Au::from),
|v| match cbbs.non_auto() {
Some(cbbs) => v.percentage_relative_to(cbbs.into()),
Some(cbbs) => v.percentage_relative_to(cbbs.into()).map(Au::from),
None => match v.non_auto().and_then(|v| v.to_length()) {
Some(v) => LengthOrAuto::LengthPercentage(v),
None => LengthOrAuto::Auto,
Some(v) => AuOrAuto::LengthPercentage(v.into()),
None => AuOrAuto::Auto,
},
},
);
fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length {
fn adjust(start: AuOrAuto, end: AuOrAuto) -> Au {
match (start, end) {
(LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(),
(LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => -end,
(LengthOrAuto::LengthPercentage(start), _) => start,
(AuOrAuto::Auto, AuOrAuto::Auto) => Au::zero(),
(AuOrAuto::Auto, AuOrAuto::LengthPercentage(end)) => -end,
(AuOrAuto::LengthPercentage(start), _) => start,
}
}
LogicalVec2 {

View file

@ -81,8 +81,8 @@ pub fn process_node_scroll_area_request(
};
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()),
)
.round()
.to_i32()
@ -232,14 +232,14 @@ pub fn process_resolved_style_request<'dom>(
LonghandId::Height if resolved_size_should_be_used_value(fragment) => {
Some(content_rect.size.height)
},
LonghandId::MarginBottom => Some(margins.bottom.into()),
LonghandId::MarginTop => Some(margins.top.into()),
LonghandId::MarginLeft => Some(margins.left.into()),
LonghandId::MarginRight => Some(margins.right.into()),
LonghandId::PaddingBottom => Some(padding.bottom.into()),
LonghandId::PaddingTop => Some(padding.top.into()),
LonghandId::PaddingLeft => Some(padding.left.into()),
LonghandId::PaddingRight => Some(padding.right.into()),
LonghandId::MarginBottom => Some(margins.bottom),
LonghandId::MarginTop => Some(margins.top),
LonghandId::MarginLeft => Some(margins.left),
LonghandId::MarginRight => Some(margins.right),
LonghandId::PaddingBottom => Some(padding.bottom),
LonghandId::PaddingTop => Some(padding.top),
LonghandId::PaddingLeft => Some(padding.left),
LonghandId::PaddingRight => Some(padding.right),
_ => None,
}
.map(|value| value.to_css_string())
@ -383,18 +383,8 @@ fn process_offset_parent_query_inner(
Fragment::Image(_) |
Fragment::IFrame(_) => unreachable!(),
};
let border_box = fragment_relative_rect.translate(containing_block.origin.to_vector());
let mut border_box = Rect::new(
Point2D::new(
Au::from_f32_px(border_box.origin.x.px()),
Au::from_f32_px(border_box.origin.y.px()),
),
Size2D::new(
Au::from_f32_px(border_box.size.width.px()),
Au::from_f32_px(border_box.size.height.px()),
),
);
let mut border_box = fragment_relative_rect.translate(containing_block.origin.to_vector()).to_untyped();
// "If any of the following holds true return null and terminate
// this algorithm: [...] The elements computed value of the
@ -477,10 +467,7 @@ fn process_offset_parent_query_inner(
.origin
.to_vector() +
containing_block.origin.to_vector();
let padding_box_corner = Vector2D::new(
Au::from_f32_px(padding_box_corner.x.px()),
Au::from_f32_px(padding_box_corner.y.px()),
);
let padding_box_corner = padding_box_corner.to_untyped();
Some(padding_box_corner)
} else {
None

View file

@ -279,7 +279,7 @@ impl ReplacedContent {
style: style.clone(),
rect: LogicalRect {
start_corner: LogicalVec2::zero(),
size: size.into(),
size,
},
image_key,
})
@ -291,7 +291,7 @@ impl ReplacedContent {
style: style.clone(),
rect: LogicalRect {
start_corner: LogicalVec2::zero(),
size: size.into(),
size,
},
image_key: video.image_key,
})],
@ -303,7 +303,7 @@ impl ReplacedContent {
browsing_context_id: iframe.browsing_context_id,
rect: LogicalRect {
start_corner: LogicalVec2::zero(),
size: size.into(),
size,
},
})]
},
@ -337,7 +337,7 @@ impl ReplacedContent {
style: style.clone(),
rect: LogicalRect {
start_corner: LogicalVec2::zero(),
size: size.into(),
size,
},
image_key,
})]

View file

@ -13,9 +13,7 @@ use style::computed_values::empty_cells::T as EmptyCells;
use style::computed_values::visibility::T as Visibility;
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
use style::values::computed::{
CSSPixelLength, Length, LengthPercentage as ComputedLengthPercentage, Percentage,
};
use style::values::computed::{Length, LengthPercentage as ComputedLengthPercentage, Percentage};
use style::values::generics::box_::{GenericVerticalAlign as VerticalAlign, VerticalAlignKeyword};
use style::values::generics::length::GenericLengthPercentageOrAuto::{Auto, LengthPercentage};
use style::Zero;
@ -39,8 +37,8 @@ use crate::ContainingBlock;
/// covered by spans or empty.
struct CellLayout {
layout: IndependentLayout,
padding: LogicalSides<Length>,
border: LogicalSides<Length>,
padding: LogicalSides<Au>,
border: LogicalSides<Au>,
positioning_context: PositioningContext,
}
@ -54,7 +52,7 @@ impl CellLayout {
/// The block size of this laid out cell including its border and padding.
fn outer_block_size(&self) -> Au {
self.layout.content_block_size + (self.border.block_sum() + self.padding.block_sum()).into()
self.layout.content_block_size + self.border.block_sum() + self.padding.block_sum()
}
/// Whether the cell has no in-flow or out-of-flow contents, other than collapsed whitespace.
@ -1043,7 +1041,7 @@ impl<'a> TableLayout<'a> {
total_width += self.distributed_column_widths[width_index];
}
let border = self
let border: LogicalSides<Au> = self
.get_collapsed_borders_for_cell(
cell,
TableSlotCoordinates::new(column_index, row_index),
@ -1051,19 +1049,19 @@ impl<'a> TableLayout<'a> {
.unwrap_or_else(|| {
cell.style
.border_width(containing_block_for_table.style.writing_mode)
});
})
.into();
let padding = cell
let padding: LogicalSides<Au> = cell
.style
.padding(containing_block_for_table.style.writing_mode)
.percentages_relative_to(self.basis_for_cell_padding_percentage.into());
.percentages_relative_to(self.basis_for_cell_padding_percentage.into())
.into();
let inline_border_padding_sum = border.inline_sum() + padding.inline_sum();
let mut total_width: CSSPixelLength =
Length::from(total_width) - inline_border_padding_sum;
total_width = total_width.max(Length::zero());
let total_width = (total_width - inline_border_padding_sum).max(Au::zero());
let containing_block_for_children = ContainingBlock {
inline_size: total_width.into(),
inline_size: total_width,
block_size: AuOrAuto::Auto,
style: &cell.style,
};
@ -1131,15 +1129,14 @@ impl<'a> TableLayout<'a> {
let border_padding_start =
layout.border.block_start + layout.padding.block_start;
let border_padding_end = layout.border.block_end + layout.padding.block_end;
max_ascent.max_assign(ascent + border_padding_start.into());
max_ascent.max_assign(ascent + border_padding_start);
// Only take into account the descent of this cell if doesn't span
// rows. The descent portion of the cell in cells that do span rows
// may extend into other rows.
if cell.rowspan == 1 {
max_descent.max_assign(
layout.layout.content_block_size - ascent +
border_padding_end.into(),
layout.layout.content_block_size - ascent + border_padding_end,
);
}
}
@ -1721,7 +1718,7 @@ impl<'a> TableLayout<'a> {
if !column_group.is_empty() {
fragments.push(Fragment::Positioning(PositioningFragment::new_empty(
column_group.base_fragment_info,
dimensions.get_column_group_rect(column_group).into(),
dimensions.get_column_group_rect(column_group),
column_group.style.clone(),
)));
}
@ -1730,7 +1727,7 @@ impl<'a> TableLayout<'a> {
for (column_index, column) in self.table.columns.iter().enumerate() {
fragments.push(Fragment::Positioning(PositioningFragment::new_empty(
column.base_fragment_info,
dimensions.get_column_rect(column_index).into(),
dimensions.get_column_rect(column_index),
column.style.clone(),
)));
}
@ -1826,22 +1823,19 @@ impl<'a> RowFragmentLayout<'a> {
containing_block: &ContainingBlock,
row_group_fragment_layout: &mut Option<RowGroupFragmentLayout>,
) -> BoxFragment {
let mut row_rect: LogicalRect<Length> = self.rect.into();
if self.positioning_context.is_some() {
row_rect.start_corner += relative_adjustement(&self.row.style, containing_block);
self.rect.start_corner += relative_adjustement(&self.row.style, containing_block);
}
if let Some(ref row_group_layout) = row_group_fragment_layout {
let row_group_start_corner: LogicalVec2<Length> =
row_group_layout.rect.start_corner.into();
row_rect.start_corner -= row_group_start_corner;
self.rect.start_corner -= row_group_layout.rect.start_corner;
}
let mut row_fragment = BoxFragment::new(
self.row.base_fragment_info,
self.row.style.clone(),
self.fragments,
row_rect,
self.rect,
LogicalSides::zero(), /* padding */
LogicalSides::zero(), /* border */
LogicalSides::zero(), /* margin */
@ -1896,16 +1890,15 @@ impl RowGroupFragmentLayout {
table_positioning_context: &mut PositioningContext,
containing_block: &ContainingBlock,
) -> BoxFragment {
let mut content_rect: LogicalRect<Length> = self.rect.into();
if self.positioning_context.is_some() {
content_rect.start_corner += relative_adjustement(&self.style, containing_block);
self.rect.start_corner += relative_adjustement(&self.style, containing_block);
}
let mut row_group_fragment = BoxFragment::new(
self.base_fragment_info,
self.style,
self.fragments,
content_rect,
self.rect,
LogicalSides::zero(), /* padding */
LogicalSides::zero(), /* border */
LogicalSides::zero(), /* margin */
@ -2207,19 +2200,18 @@ impl TableSlotCell {
// This must be scoped to this function because it conflicts with euclid's Zero.
use style::Zero as StyleZero;
let cell_rect: LogicalRect<Length> = cell_rect.into();
let cell_content_rect = cell_rect.deflate(&(&layout.padding + &layout.border));
let content_block_size = layout.layout.content_block_size.into();
let content_block_size = layout.layout.content_block_size;
let vertical_align_offset = match self.effective_vertical_align() {
VerticalAlignKeyword::Top => Length::new(0.),
VerticalAlignKeyword::Top => Au::zero(),
VerticalAlignKeyword::Bottom => cell_content_rect.size.block - content_block_size,
VerticalAlignKeyword::Middle => {
(cell_content_rect.size.block - content_block_size).scale_by(0.5)
},
_ => {
Length::from(cell_baseline) -
cell_baseline -
(layout.padding.block_start + layout.border.block_start) -
Length::from(layout.ascent())
layout.ascent()
},
};
@ -2234,7 +2226,7 @@ impl TableSlotCell {
// Create an `AnonymousFragment` to move the cell contents to the cell baseline.
let mut vertical_align_fragment_rect = cell_content_rect.clone();
vertical_align_fragment_rect.start_corner = LogicalVec2 {
inline: Length::new(0.),
inline: Au::zero(),
block: vertical_align_offset,
};
let vertical_align_fragment = PositioningFragment::new_anonymous(
@ -2263,8 +2255,8 @@ impl TableSlotCell {
self.style.clone(),
vec![Fragment::Positioning(vertical_align_fragment)],
cell_content_rect,
layout.padding.into(),
layout.border.into(),
layout.padding,
layout.border,
LogicalSides::zero(), /* margin */
None, /* clearance */
CollapsedBlockMargins::zero(),

View file

@ -1,2 +0,0 @@
[position-relative-032.xht]
expected: FAIL

View file

@ -1,3 +0,0 @@
[mix-blend-mode-parent-with-3D-transform.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-align-self-baseline-horiz-004.xhtml]
expected: FAIL