uses app units in display_list (#33420)

Signed-off-by: atbrakhi <atbrakhi@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
atbrakhi 2024-09-13 12:49:59 +02:00 committed by GitHub
parent 52f89c95b9
commit f76692035b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 133 additions and 141 deletions

View file

@ -9,7 +9,7 @@ use style::computed_values::background_clip::single_value::T as Clip;
use style::computed_values::background_origin::single_value::T as Origin;
use style::properties::ComputedValues;
use style::values::computed::background::BackgroundSize as Size;
use style::values::computed::{Length, LengthPercentage};
use style::values::computed::LengthPercentage;
use style::values::specified::background::{
BackgroundRepeat as RepeatXY, BackgroundRepeatKeyword as Repeat,
};
@ -204,42 +204,42 @@ pub(super) fn layout_layer(
Size::Cover => size_contain_or_cover(ContainOrCover::Cover),
Size::ExplicitSize { width, height } => {
let mut width = width.non_auto().map(|lp| {
lp.0.percentage_relative_to(Length::new(positioning_area.size().width))
lp.0.to_used_value(Au::from_f32_px(positioning_area.size().width))
});
let mut height = height.non_auto().map(|lp| {
lp.0.percentage_relative_to(Length::new(positioning_area.size().height))
lp.0.to_used_value(Au::from_f32_px(positioning_area.size().height))
});
if width.is_none() && height.is_none() {
// Both computed values are 'auto':
// use intrinsic sizes, treating missing width or height as 'auto'
width = intrinsic.width.map(|v| v.into());
height = intrinsic.height.map(|v| v.into());
width = intrinsic.width;
height = intrinsic.height;
}
match (width, height) {
(Some(w), Some(h)) => units::LayoutSize::new(w.px(), h.px()),
(Some(w), Some(h)) => units::LayoutSize::new(w.to_f32_px(), h.to_f32_px()),
(Some(w), None) => {
let h = if let Some(intrinsic_ratio) = intrinsic.ratio {
w / intrinsic_ratio
w.scale_by(1.0 / intrinsic_ratio)
} else if let Some(intrinsic_height) = intrinsic.height {
intrinsic_height.into()
intrinsic_height
} else {
// Treated as 100%
Au::from_f32_px(positioning_area.size().height).into()
Au::from_f32_px(positioning_area.size().height)
};
units::LayoutSize::new(w.px(), h.px())
units::LayoutSize::new(w.to_f32_px(), h.to_f32_px())
},
(None, Some(h)) => {
let w = if let Some(intrinsic_ratio) = intrinsic.ratio {
h * intrinsic_ratio
h.scale_by(intrinsic_ratio)
} else if let Some(intrinsic_width) = intrinsic.width {
intrinsic_width.into()
intrinsic_width
} else {
// Treated as 100%
Au::from_f32_px(positioning_area.size().width).into()
Au::from_f32_px(positioning_area.size().width)
};
units::LayoutSize::new(w.px(), h.px())
units::LayoutSize::new(w.to_f32_px(), h.to_f32_px())
},
// Both comptued values were 'auto', and neither intrinsic size is present
(None, None) => size_contain_or_cover(ContainOrCover::Contain),
@ -299,8 +299,8 @@ fn layout_1d(
}
// https://drafts.csswg.org/css-backgrounds/#background-position
let mut position = position
.percentage_relative_to(Length::new(positioning_area_size - *tile_size))
.px();
.to_used_value(Au::from_f32_px(positioning_area_size - *tile_size))
.to_f32_px();
let mut tile_spacing = 0.0;
// https://drafts.csswg.org/css-backgrounds/#background-repeat
if let Repeat::Space = repeat {

View file

@ -2,9 +2,9 @@
* 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 style::values::computed::basic_shape::{BasicShape, ClipPath};
use style::values::computed::length::Length;
use style::values::computed::length_percentage::{LengthPercentage, NonNegativeLengthPercentage};
use style::values::computed::length_percentage::NonNegativeLengthPercentage;
use style::values::computed::position::Position;
use style::values::generics::basic_shape::{GenericShapeRadius, ShapeBox, ShapeGeometryBox};
use style::values::generics::position::GenericPositionOrAuto;
@ -74,11 +74,13 @@ fn build_simple_shape(
) -> Option<ClipChainId> {
match shape {
BasicShape::Rect(rect) => {
let box_height = Au::from_f32_px(layout_box.height());
let box_width = Au::from_f32_px(layout_box.width());
let insets = LayoutSideOffsets::new(
rect.rect.0.resolve(Length::new(layout_box.height())).px(),
rect.rect.1.resolve(Length::new(layout_box.width())).px(),
rect.rect.2.resolve(Length::new(layout_box.height())).px(),
rect.rect.3.resolve(Length::new(layout_box.width())).px(),
rect.rect.0.to_used_value(box_height).to_f32_px(),
rect.rect.1.to_used_value(box_width).to_f32_px(),
rect.rect.2.to_used_value(box_height).to_f32_px(),
rect.rect.3.to_used_value(box_width).to_f32_px(),
);
// `inner_rect()` will cause an assertion failure if the insets are larger than the
@ -91,13 +93,10 @@ fn build_simple_shape(
layout_box.to_rect().inner_rect(insets).to_box2d()
};
let resolve = |radius: &LengthPercentage, box_size: f32| {
radius.percentage_relative_to(Length::new(box_size)).px()
};
let corner = |corner: &style::values::computed::BorderCornerRadius| {
LayoutSize::new(
resolve(&corner.0.width.0, layout_box.size().width),
resolve(&corner.0.height.0, layout_box.size().height),
corner.0.width.0.to_used_value(box_width).to_f32_px(),
corner.0.height.0.to_used_value(box_height).to_f32_px(),
)
};
let mut radii = webrender_api::BorderRadius {
@ -120,11 +119,15 @@ fn build_simple_shape(
GenericPositionOrAuto::Position(position) => position,
GenericPositionOrAuto::Auto => Position::center(),
};
let anchor_x = center.horizontal.resolve(Length::new(layout_box.width()));
let anchor_y = center.vertical.resolve(Length::new(layout_box.height()));
let anchor_x = center
.horizontal
.to_used_value(Au::from_f32_px(layout_box.width()));
let anchor_y = center
.vertical
.to_used_value(Au::from_f32_px(layout_box.height()));
let center = layout_box
.min
.add_size(&LayoutSize::new(anchor_x.px(), anchor_y.px()));
.add_size(&LayoutSize::new(anchor_x.to_f32_px(), anchor_y.to_f32_px()));
let horizontal =
compute_shape_radius(center.x, &circle.radius, layout_box.min.x, layout_box.max.x);
@ -160,11 +163,15 @@ fn build_simple_shape(
GenericPositionOrAuto::Position(position) => position,
GenericPositionOrAuto::Auto => Position::center(),
};
let anchor_x = center.horizontal.resolve(Length::new(layout_box.width()));
let anchor_y = center.vertical.resolve(Length::new(layout_box.height()));
let anchor_x = center
.horizontal
.to_used_value(Au::from_f32_px(layout_box.width()));
let anchor_y = center
.vertical
.to_used_value(Au::from_f32_px(layout_box.height()));
let center = layout_box
.min
.add_size(&LayoutSize::new(anchor_x.px(), anchor_y.px()));
.add_size(&LayoutSize::new(anchor_x.to_f32_px(), anchor_y.to_f32_px()));
let width = compute_shape_radius(
center.x,
@ -212,9 +219,10 @@ fn compute_shape_radius(
match radius {
GenericShapeRadius::FarthestSide => distance_from_min_edge.max(distance_from_max_edge),
GenericShapeRadius::ClosestSide => distance_from_min_edge.min(distance_from_max_edge),
GenericShapeRadius::Length(length) => {
length.0.resolve(Length::new(max_edge - min_edge)).px()
},
GenericShapeRadius::Length(length) => length
.0
.to_used_value(Au::from_f32_px(max_edge - min_edge))
.to_f32_px(),
}
}
fn create_rect_clip_chain(

View file

@ -2,16 +2,16 @@
* 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 euclid::Size2D;
use style::color::mix::ColorInterpolationMethod;
use style::properties::ComputedValues;
use style::values::computed::image::{EndingShape, Gradient, LineDirection};
use style::values::computed::{
Angle, AngleOrPercentage, Color, Length, LengthPercentage, Position,
};
use style::values::computed::{Angle, AngleOrPercentage, Color, LengthPercentage, Position};
use style::values::generics::image::{
Circle, ColorStop, Ellipse, GradientFlags, GradientItem, ShapeExtent,
};
use style::Zero;
use webrender_api::units::LayoutPixel;
use webrender_api::{
self as wr, units, ConicGradient as WebRenderConicGradient,
@ -171,7 +171,7 @@ pub(super) fn build_linear(
let end_point = center + half_gradient_line;
let mut color_stops =
gradient_items_to_color_stops(style, items, Length::new(gradient_line_length));
gradient_items_to_color_stops(style, items, Au::from_f32_px(gradient_line_length));
let stops = fixup_stops(&mut color_stops);
let extend_mode = if flags.contains(GradientFlags::REPEATING) {
wr::ExtendMode::Repeat
@ -201,12 +201,12 @@ pub(super) fn build_radial(
let center = units::LayoutPoint::new(
center
.horizontal
.percentage_relative_to(Length::new(gradient_box.width))
.px(),
.to_used_value(Au::from_f32_px(gradient_box.width))
.to_f32_px(),
center
.vertical
.percentage_relative_to(Length::new(gradient_box.height))
.px(),
.to_used_value(Au::from_f32_px(gradient_box.height))
.to_f32_px(),
);
let radii = match shape {
EndingShape::Circle(circle) => {
@ -232,10 +232,10 @@ pub(super) fn build_radial(
units::LayoutSize::new(radius, radius)
},
EndingShape::Ellipse(Ellipse::Radii(rx, ry)) => units::LayoutSize::new(
rx.0.percentage_relative_to(Length::new(gradient_box.width))
.px(),
ry.0.percentage_relative_to(Length::new(gradient_box.height))
.px(),
rx.0.to_used_value(Au::from_f32_px(gradient_box.width))
.to_f32_px(),
ry.0.to_used_value(Au::from_f32_px(gradient_box.height))
.to_f32_px(),
),
EndingShape::Ellipse(Ellipse::Extent(extent)) => match extent {
ShapeExtent::ClosestSide | ShapeExtent::Contain => {
@ -275,7 +275,7 @@ pub(super) fn build_radial(
let gradient_line_length = radii.width;
let mut color_stops =
gradient_items_to_color_stops(style, items, Length::new(gradient_line_length));
gradient_items_to_color_stops(style, items, Au::from_f32_px(gradient_line_length));
let stops = fixup_stops(&mut color_stops);
let extend_mode = if flags.contains(GradientFlags::REPEATING) {
wr::ExtendMode::Repeat
@ -305,12 +305,12 @@ fn build_conic(
let center = units::LayoutPoint::new(
center
.horizontal
.percentage_relative_to(Length::new(gradient_box.width))
.px(),
.to_used_value(Au::from_f32_px(gradient_box.width))
.to_f32_px(),
center
.vertical
.percentage_relative_to(Length::new(gradient_box.height))
.px(),
.to_used_value(Au::from_f32_px(gradient_box.height))
.to_f32_px(),
);
let mut color_stops = conic_gradient_items_to_color_stops(style, items);
let stops = fixup_stops(&mut color_stops);
@ -367,7 +367,7 @@ fn conic_gradient_items_to_color_stops(
fn gradient_items_to_color_stops(
style: &ComputedValues,
items: &[GradientItem<Color, LengthPercentage>],
gradient_line_length: Length,
gradient_line_length: Au,
) -> Vec<ColorStop<ColorF, f32>> {
// Remove color transititon hints, which are not supported yet.
// https://drafts.csswg.org/css-images-4/#color-transition-hint
@ -389,11 +389,13 @@ fn gradient_items_to_color_stops(
}),
GradientItem::ComplexColorStop { color, position } => Some(ColorStop {
color: super::rgba(style.resolve_color(color.clone())),
position: Some(if gradient_line_length.px() == 0. {
position: Some(if gradient_line_length.is_zero() {
0.
} else {
position.percentage_relative_to(gradient_line_length).px() /
gradient_line_length.px()
position
.to_used_value(gradient_line_length)
.scale_by(1. / gradient_line_length.to_f32_px())
.to_f32_px()
}),
}),
// FIXME: approximate like in:

View file

@ -24,7 +24,7 @@ use style::properties::style_structs::Border;
use style::properties::ComputedValues;
use style::values::computed::image::Image;
use style::values::computed::{
BorderImageSideWidth, BorderImageWidth, BorderStyle, Color, Length, LengthPercentage,
BorderImageSideWidth, BorderImageWidth, BorderStyle, Color, LengthPercentage,
LengthPercentageOrAuto, NonNegativeLengthOrNumber, NumberOrPercentage, OutlineStyle,
};
use style::values::generics::rect::Rect;
@ -495,19 +495,19 @@ struct BuilderForBoxFragment<'a> {
impl<'a> BuilderForBoxFragment<'a> {
fn new(fragment: &'a BoxFragment, containing_block: &'a PhysicalRect<Au>) -> Self {
let border_rect: units::LayoutRect = fragment
let border_rect = fragment
.border_rect()
.translate(containing_block.origin.to_vector())
.to_webrender();
.translate(containing_block.origin.to_vector());
let webrender_border_rect = border_rect.to_webrender();
let border_radius = {
let resolve = |radius: &LengthPercentage, box_size: f32| {
radius.percentage_relative_to(Length::new(box_size)).px()
let resolve = |radius: &LengthPercentage, box_size: Au| {
radius.to_used_value(box_size).to_f32_px()
};
let corner = |corner: &style::values::computed::BorderCornerRadius| {
Size2D::new(
resolve(&corner.0.width.0, border_rect.size().width),
resolve(&corner.0.height.0, border_rect.size().height),
resolve(&corner.0.width.0, border_rect.size.width),
resolve(&corner.0.height.0, border_rect.size.height),
)
};
let b = fragment.style.get_border();
@ -517,14 +517,15 @@ impl<'a> BuilderForBoxFragment<'a> {
bottom_right: corner(&b.border_bottom_right_radius),
bottom_left: corner(&b.border_bottom_left_radius),
};
normalize_radii(&border_rect, &mut radius);
normalize_radii(&webrender_border_rect, &mut radius);
radius
};
Self {
fragment,
containing_block,
border_rect,
border_rect: webrender_border_rect,
border_radius,
margin_rect: OnceCell::new(),
padding_rect: OnceCell::new(),
@ -1343,14 +1344,14 @@ pub(super) fn compute_margin_box_radius(
let width = margin
.width
.auto_is(LengthPercentage::zero)
.resolve(Length::new(layout_rect.width));
.to_used_value(Au::from_f32_px(layout_rect.width));
let height = margin
.height
.auto_is(LengthPercentage::zero)
.resolve(Length::new(layout_rect.height));
.to_used_value(Au::from_f32_px(layout_rect.height));
LayoutSize::new(
adjust_radius(radius.width, width.px()),
adjust_radius(radius.height, height.px()),
adjust_radius(radius.width, width.to_f32_px()),
adjust_radius(radius.height, height.to_f32_px()),
)
};
wr::BorderRadius {

View file

@ -1363,23 +1363,15 @@ impl BoxFragment {
// nearest scroll frame instead of the containing block like for other types
// of positioning.
let position = self.style.get_position();
let scroll_frame_height = Au::from_f32_px(scroll_frame_size_for_resolve.height);
let scroll_frame_width = Au::from_f32_px(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()
}),
position.top.map(|v| v.to_used_value(scroll_frame_height)),
position.right.map(|v| v.to_used_value(scroll_frame_width)),
position
.bottom
.map(|v| v.to_used_value(scroll_frame_height)),
position.left.map(|v| v.to_used_value(scroll_frame_width)),
);
self.resolved_sticky_insets = Some(offsets);