From 80b2b5fb5e60f10ddac23429bf8c4353b6317133 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sat, 7 Dec 2019 22:04:41 +0100 Subject: [PATCH] Fix min/max-content of replaced boxes --- components/layout_2020/formatting_contexts.rs | 27 +++++----- components/layout_2020/replaced.rs | 51 ++++++++++++++----- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs index f741e44affd..eb90d62c926 100644 --- a/components/layout_2020/formatting_contexts.rs +++ b/components/layout_2020/formatting_contexts.rs @@ -59,31 +59,30 @@ impl IndependentFormattingContext { contents: Contents>, content_sizes: ContentSizesRequest, ) -> Self { - use self::IndependentFormattingContextContents as Contents; - let (contents, content_sizes) = match contents.try_into() { + match contents.try_into() { Ok(non_replaced) => match display_inside { DisplayInside::Flow | DisplayInside::FlowRoot => { - let (bfc, box_content_sizes) = BlockFormattingContext::construct( + let (bfc, content_sizes) = BlockFormattingContext::construct( context, &style, non_replaced, content_sizes, ); - (Contents::Flow(bfc), box_content_sizes) + Self { + style, + content_sizes, + contents: IndependentFormattingContextContents::Flow(bfc), + } }, }, Err(replaced) => { - // The `content_sizes` field is not used by layout code: - ( - Contents::Replaced(replaced), - BoxContentSizes::NoneWereRequested, - ) + let content_sizes = content_sizes.compute(|| replaced.inline_content_sizes(&style)); + Self { + style, + content_sizes, + contents: IndependentFormattingContextContents::Replaced(replaced), + } }, - }; - Self { - style, - contents, - content_sizes, } } diff --git a/components/layout_2020/replaced.rs b/components/layout_2020/replaced.rs index 00242f61736..16a9b86fa8e 100644 --- a/components/layout_2020/replaced.rs +++ b/components/layout_2020/replaced.rs @@ -6,6 +6,7 @@ use crate::dom_traversal::NodeExt; use crate::fragments::{Fragment, ImageFragment}; use crate::geom::flow_relative::{Rect, Vec2}; use crate::geom::physical; +use crate::sizing::ContentSizes; use crate::style_ext::ComputedValuesExt; use crate::ContainingBlock; use net_traits::image::base::Image; @@ -63,6 +64,41 @@ impl ReplacedContent { None } + fn flow_relative_intrinsic_size(&self, style: &ComputedValues) -> Vec2> { + let intrinsic_size = physical::Vec2 { + x: self.intrinsic_width, + y: self.intrinsic_height, + }; + intrinsic_size.size_to_flow_relative(style.writing_mode) + } + + fn inline_size_over_block_size_intrinsic_ratio( + &self, + style: &ComputedValues, + ) -> Option { + self.intrinsic_ratio.map(|width_over_height| { + if style.writing_mode.is_vertical() { + 1. / width_over_height + } else { + width_over_height + } + }) + } + + pub fn inline_content_sizes(&self, style: &ComputedValues) -> ContentSizes { + // FIXME: min/max-content of replaced elements is not defined in + // https://dbaron.org/css/intrinsic/ + // This seems sensible? + let inline = self + .flow_relative_intrinsic_size(style) + .inline + .unwrap_or(Length::zero()); + ContentSizes { + min_content: inline, + max_content: inline, + } + } + pub fn make_fragments<'a>( &'a self, style: &ServoArc, @@ -95,19 +131,8 @@ impl ReplacedContent { style: &ComputedValues, ) -> Vec2 { let mode = style.writing_mode; - let intrinsic_size = physical::Vec2 { - x: self.intrinsic_width, - y: self.intrinsic_height, - }; - let intrinsic_size = intrinsic_size.size_to_flow_relative(mode); - let intrinsic_ratio = self.intrinsic_ratio.map(|width_over_height| { - // inline-size over block-size - if style.writing_mode.is_vertical() { - 1. / width_over_height - } else { - width_over_height - } - }); + let intrinsic_size = self.flow_relative_intrinsic_size(style); + let intrinsic_ratio = self.inline_size_over_block_size_intrinsic_ratio(style); let box_size = style.box_size().percentages_relative_to(containing_block); let min_box_size = style