From ea1ff9127f9a66d431d79533643ec4ed5c96d59e Mon Sep 17 00:00:00 2001 From: Anders Hartvoll Ruud Date: Fri, 16 Dec 2022 22:06:41 +0000 Subject: [PATCH] [StyleBuilder] Remove ComputedStyle from CSSToLengthConversionData CSSToLengthConversionData currently does a const_cast of an incoming ComputedStyle in order to set certain flags on that ComputedStyle. This is bad, because CSSToLengthConversionData is used in several situations outside of style recalc, i.e. in situations where it's too late to modify the ComputedStyle. It's also a major hurdle for the StyleBuilder project, because just replacing the ComputedStyle pointer with a ComputedStyleBuilder pointer isn't possible: we don't have a ComputedStyleBuilder at all outside of style resolution. This CL addresses this by propagating the unit flags to CSSToLengthConversionData's call site. Bug: 1377295 Change-Id: I9d162aebf813418c15a494a1d18581b75272aa10 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4107634 Reviewed-by: Rune Lillesveen Commit-Queue: Anders Hartvoll Ruud Cr-Commit-Position: refs/heads/main@{#1084547} --- .../renderer/core/animation/view_timeline.cc | 5 +- .../renderer/core/css/css_gradient_value.cc | 5 +- .../core/css/css_math_expression_node_test.cc | 4 +- .../core/css/css_to_length_conversion_data.cc | 76 ++++++---------- .../core/css/css_to_length_conversion_data.h | 44 +++++++-- .../css/css_to_length_conversion_data_test.cc | 91 ++++++++++++++++++- .../parser/sizes_math_function_parser_test.cc | 5 +- .../css/resolver/filter_operation_resolver.cc | 5 +- .../core/css/resolver/font_style_resolver.cc | 9 +- .../css/resolver/style_builder_converter.cc | 11 ++- .../css/resolver/style_builder_converter.h | 2 +- .../core/css/resolver/style_resolver.cc | 45 ++++++++- .../core/css/resolver/style_resolver_state.cc | 15 ++- .../core/css/resolver/style_resolver_state.h | 13 ++- ...to_length_conversion_data_threaded_test.cc | 25 +++-- .../renderer/core/svg/svg_length_context.cc | 3 +- 16 files changed, 257 insertions(+), 101 deletions(-) diff --git a/third_party/blink/renderer/core/animation/view_timeline.cc b/third_party/blink/renderer/core/animation/view_timeline.cc index f4d84c4633d6e..56c4616e2cf63 100644 --- a/third_party/blink/renderer/core/animation/view_timeline.cc +++ b/third_party/blink/renderer/core/animation/view_timeline.cc @@ -159,11 +159,14 @@ Length InsetValueToLength(const CSSValue* inset_value, if (inset_value->IsPrimitiveValue()) { ElementResolveContext element_resolve_context(*subject); Document& document = subject->GetDocument(); + // Flags can be ignored, because we re-resolve any value that's not px or + // percentage, see IsStyleDependent. + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData length_conversion_data( subject->GetComputedStyle(), element_resolve_context.ParentStyle(), element_resolve_context.RootElementStyle(), document.GetLayoutView(), CSSToLengthConversionData::ContainerSizes(subject), - subject->GetComputedStyle()->EffectiveZoom()); + subject->GetComputedStyle()->EffectiveZoom(), ignored_flags); return DynamicTo(inset_value) ->ConvertToLength(length_conversion_data); diff --git a/third_party/blink/renderer/core/css/css_gradient_value.cc b/third_party/blink/renderer/core/css/css_gradient_value.cc index 273d0b589d8ae..1064d2b73888f 100644 --- a/third_party/blink/renderer/core/css/css_gradient_value.cc +++ b/third_party/blink/renderer/core/css/css_gradient_value.cc @@ -135,9 +135,12 @@ scoped_refptr CSSGradientValue::GetImage( // We need to create an image. const ComputedStyle* root_style = document.documentElement()->GetComputedStyle(); + + // TODO(crbug.com/947377): Conversion is not supposed to happen here. + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( &style, &style, root_style, document.GetLayoutView(), container_sizes, - style.EffectiveZoom()); + style.EffectiveZoom(), ignored_flags); scoped_refptr gradient; switch (GetClassType()) { diff --git a/third_party/blink/renderer/core/css/css_math_expression_node_test.cc b/third_party/blink/renderer/core/css/css_math_expression_node_test.cc index 34ea20495ee9b..6c846701dc80c 100644 --- a/third_party/blink/renderer/core/css/css_math_expression_node_test.cc +++ b/third_party/blink/renderer/core/css/css_math_expression_node_test.cc @@ -94,9 +94,11 @@ TEST(CSSCalculationValue, AccumulatePixelsAndPercent) { ComputedStyleBuilder builder(*ComputedStyle::CreateInitialStyleSingleton()); builder.SetEffectiveZoom(5); scoped_refptr style = builder.TakeStyle(); + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( style.get(), style.get(), style.get(), nullptr, - CSSToLengthConversionData::ContainerSizes(), style->EffectiveZoom()); + CSSToLengthConversionData::ContainerSizes(), style->EffectiveZoom(), + ignored_flags); TestAccumulatePixelsAndPercent( conversion_data, diff --git a/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc b/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc index de70ebad75658..4f013b1ee3740 100644 --- a/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc +++ b/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc @@ -60,11 +60,6 @@ absl::optional FindSizeForContainerAxis(PhysicalAxes requested_axis, return evaluator->Height(); } -void SetHasContainerRelativeUnits(const ComputedStyle* style) { - const_cast(style)->SetHasContainerRelativeUnits(); - const_cast(style)->SetDependsOnSizeContainerQueries(true); -} - } // namespace CSSToLengthConversionData::FontSizes::FontSizes(float em, @@ -193,21 +188,21 @@ void CSSToLengthConversionData::ContainerSizes::CacheSizeIfNeeded( } CSSToLengthConversionData::CSSToLengthConversionData( - const ComputedStyle* element_style, WritingMode writing_mode, const FontSizes& font_sizes, const LineHeightSize& line_height_size, const ViewportSize& viewport_size, const ContainerSizes& container_sizes, - float zoom) + float zoom, + Flags& flags) : CSSLengthResolver( ClampTo(zoom, std::numeric_limits::denorm_min())), - style_(element_style), writing_mode_(writing_mode), font_sizes_(font_sizes), line_height_size_(line_height_size), viewport_size_(viewport_size), - container_sizes_(container_sizes) {} + container_sizes_(container_sizes), + flags_(&flags) {} CSSToLengthConversionData::CSSToLengthConversionData( const ComputedStyle* element_style, @@ -215,114 +210,95 @@ CSSToLengthConversionData::CSSToLengthConversionData( const ComputedStyle* root_style, const LayoutView* layout_view, const ContainerSizes& container_sizes, - float zoom) + float zoom, + Flags& flags) : CSSToLengthConversionData( - element_style, element_style->GetWritingMode(), FontSizes(element_style, root_style), LineHeightSize(parent_style ? *parent_style : *element_style), ViewportSize(layout_view), container_sizes, - zoom) {} + zoom, + flags) {} float CSSToLengthConversionData::EmFontSize(float zoom) const { - // FIXME: Remove style_ from this class. Plumb viewport and font unit - // information through as output parameters on functions involved in length - // resolution. - if (style_) - const_cast(style_)->SetHasEmUnits(); + SetFlag(Flag::kEm); return font_sizes_.Em(zoom); } float CSSToLengthConversionData::RemFontSize(float zoom) const { - if (style_) - const_cast(style_)->SetHasRemUnits(); + SetFlag(Flag::kRem); return font_sizes_.Rem(zoom); } float CSSToLengthConversionData::ExFontSize(float zoom) const { - if (style_) - const_cast(style_)->SetHasGlyphRelativeUnits(); + SetFlag(Flag::kGlyphRelative); return font_sizes_.Ex(zoom); } float CSSToLengthConversionData::ChFontSize(float zoom) const { - if (style_) - const_cast(style_)->SetHasGlyphRelativeUnits(); + SetFlag(Flag::kGlyphRelative); return font_sizes_.Ch(zoom); } float CSSToLengthConversionData::IcFontSize(float zoom) const { - if (style_) - const_cast(style_)->SetHasGlyphRelativeUnits(); + SetFlag(Flag::kGlyphRelative); return font_sizes_.Ic(zoom); } float CSSToLengthConversionData::LineHeight(float zoom) const { - if (style_) { - const_cast(style_)->SetHasGlyphRelativeUnits(); - const_cast(style_)->SetHasLineHeightRelativeUnits(); - } + SetFlag(Flag::kGlyphRelative); + SetFlag(Flag::kLineHeightRelative); return line_height_size_.Lh(zoom); } double CSSToLengthConversionData::ViewportWidth() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.LargeWidth(); } double CSSToLengthConversionData::ViewportHeight() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.LargeHeight(); } double CSSToLengthConversionData::SmallViewportWidth() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.SmallWidth(); } double CSSToLengthConversionData::SmallViewportHeight() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.SmallHeight(); } double CSSToLengthConversionData::LargeViewportWidth() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.LargeWidth(); } double CSSToLengthConversionData::LargeViewportHeight() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.LargeHeight(); } double CSSToLengthConversionData::DynamicViewportWidth() const { - if (style_) - const_cast(style_)->SetHasDynamicViewportUnits(); + SetFlag(Flag::kDynamicViewport); return viewport_size_.DynamicWidth(); } double CSSToLengthConversionData::DynamicViewportHeight() const { - if (style_) - const_cast(style_)->SetHasDynamicViewportUnits(); + SetFlag(Flag::kDynamicViewport); return viewport_size_.DynamicHeight(); } double CSSToLengthConversionData::ContainerWidth() const { - if (style_) - SetHasContainerRelativeUnits(style_); + SetFlag(Flag::kContainerRelative); return container_sizes_.Width().value_or(SmallViewportWidth()); } double CSSToLengthConversionData::ContainerHeight() const { - if (style_) - SetHasContainerRelativeUnits(style_); + SetFlag(Flag::kContainerRelative); return container_sizes_.Height().value_or(SmallViewportHeight()); } @@ -332,7 +308,7 @@ WritingMode CSSToLengthConversionData::GetWritingMode() const { CSSToLengthConversionData::ContainerSizes CSSToLengthConversionData::PreCachedContainerSizesCopy() const { - SetHasContainerRelativeUnits(style_); + SetFlag(Flag::kContainerRelative); return container_sizes_.PreCachedCopy(); } diff --git a/third_party/blink/renderer/core/css/css_to_length_conversion_data.h b/third_party/blink/renderer/core/css/css_to_length_conversion_data.h index fbc1c4a24f821..1697862f9c689 100644 --- a/third_party/blink/renderer/core/css/css_to_length_conversion_data.h +++ b/third_party/blink/renderer/core/css/css_to_length_conversion_data.h @@ -176,20 +176,43 @@ class CORE_EXPORT CSSToLengthConversionData : public CSSLengthResolver { mutable absl::optional cached_height_; }; + using Flags = uint8_t; + + // Flags represent the units seen in a conversion. They are used for targeted + // invalidation, e.g. when root font-size changes, only elements dependent on + // rem units are recalculated. + enum class Flag : Flags { + // em + kEm = 1u << 0, + // rem + kRem = 1u << 1, + // ex, ch, ic, lh + kGlyphRelative = 1u << 2, + // lh + kLineHeightRelative = 1u << 3, + // sv*, lv*, v* + kStaticViewport = 1u << 4, + // dv* + kDynamicViewport = 1u << 5, + // cq* + kContainerRelative = 1u << 6, + }; + CSSToLengthConversionData() : CSSLengthResolver(1 /* zoom */) {} - CSSToLengthConversionData(const ComputedStyle* element_style, - WritingMode, + CSSToLengthConversionData(WritingMode, const FontSizes&, const LineHeightSize&, const ViewportSize&, const ContainerSizes&, - float zoom); + float zoom, + Flags&); CSSToLengthConversionData(const ComputedStyle* element_style, const ComputedStyle* parent_style, const ComputedStyle* root_style, const LayoutView*, const ContainerSizes&, - float zoom); + float zoom, + Flags&); float EmFontSize(float zoom) const override; float RemFontSize(float zoom) const override; @@ -221,21 +244,28 @@ class CORE_EXPORT CSSToLengthConversionData : public CSSLengthResolver { ContainerSizes PreCachedContainerSizesCopy() const; CSSToLengthConversionData CopyWithAdjustedZoom(float new_zoom) const { - return CSSToLengthConversionData(style_, writing_mode_, font_sizes_, + DCHECK(flags_); + return CSSToLengthConversionData(writing_mode_, font_sizes_, line_height_size_, viewport_size_, - container_sizes_, new_zoom); + container_sizes_, new_zoom, *flags_); } CSSToLengthConversionData Unzoomed() const { return CopyWithAdjustedZoom(1.0f); } private: - const ComputedStyle* style_ = nullptr; + void SetFlag(Flag flag) const { + if (flags_) { + *flags_ |= static_cast(flag); + } + } + WritingMode writing_mode_ = WritingMode::kHorizontalTb; FontSizes font_sizes_; LineHeightSize line_height_size_; ViewportSize viewport_size_; ContainerSizes container_sizes_; + mutable Flags* flags_ = nullptr; }; class ScopedCSSToLengthConversionData : public CSSToLengthConversionData { diff --git a/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc b/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc index 872a22b233153..6f36bf71d41de 100644 --- a/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc +++ b/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc @@ -29,8 +29,9 @@ class CSSToLengthConversionDataTest : public PageTestBase { // css_zoom - The zoom to apply to :root. // data_zoom - The zoom to pass to the CSSToLengthConversionData constructor. CSSToLengthConversionData ConversionData( - absl::optional css_zoom = absl::nullopt, - absl::optional data_zoom = absl::nullopt) { + absl::optional css_zoom, + absl::optional data_zoom, + CSSToLengthConversionData::Flags& flags) { Element* root = GetDocument().documentElement(); DCHECK(root); if (css_zoom.has_value()) { @@ -50,7 +51,18 @@ class CSSToLengthConversionDataTest : public PageTestBase { GetDocument().documentElement()->GetComputedStyle(), GetDocument().GetLayoutView(), CSSToLengthConversionData::ContainerSizes(), - data_zoom.value_or(div->GetComputedStyle()->EffectiveZoom())); + data_zoom.value_or(div->GetComputedStyle()->EffectiveZoom()), flags); + } + + CSSToLengthConversionData ConversionData( + absl::optional css_zoom = absl::nullopt, + absl::optional data_zoom = absl::nullopt) { + return ConversionData(css_zoom, data_zoom, ignored_flags_); + } + + CSSToLengthConversionData ConversionData( + CSSToLengthConversionData::Flags& flags) { + return ConversionData(absl::nullopt, absl::nullopt, flags); } float Convert(const CSSToLengthConversionData& data, String value) { @@ -60,10 +72,20 @@ class CSSToLengthConversionDataTest : public PageTestBase { return primitive_value->ConvertToLength(data).Pixels(); } + CSSToLengthConversionData::Flags ConversionFlags(String value) { + CSSToLengthConversionData::Flags flags = 0; + CSSToLengthConversionData data = ConversionData(flags); + Convert(data, value); + return flags; + } + void SetLineHeightSize(Element& element, CSSToLengthConversionData& data) { data.SetLineHeightSize( CSSToLengthConversionData::LineHeightSize(element.ComputedStyleRef())); } + + private: + CSSToLengthConversionData::Flags ignored_flags_ = 0; }; TEST_F(CSSToLengthConversionDataTest, Normal) { @@ -141,4 +163,67 @@ TEST_F(CSSToLengthConversionDataTest, SetLineHeightSize) { EXPECT_FLOAT_EQ(20.0f, Convert(data, "1lh")); } +TEST_F(CSSToLengthConversionDataTest, Flags) { + using Flag = CSSToLengthConversionData::Flag; + using Flags = CSSToLengthConversionData::Flags; + + Flags em = static_cast(Flag::kEm); + Flags rem = static_cast(Flag::kRem); + Flags glyph = static_cast(Flag::kGlyphRelative); + Flags lh = static_cast(Flag::kLineHeightRelative); + Flags sv = static_cast(Flag::kStaticViewport); + Flags dv = static_cast(Flag::kDynamicViewport); + Flags cq = static_cast(Flag::kContainerRelative); + + EXPECT_EQ(0u, ConversionFlags("1px")); + + EXPECT_EQ(em, ConversionFlags("1em")); + + EXPECT_EQ(rem, ConversionFlags("1rem")); + + EXPECT_EQ(glyph, ConversionFlags("1ex")); + EXPECT_EQ(glyph, ConversionFlags("1ch")); + EXPECT_EQ(glyph, ConversionFlags("1ic")); + + EXPECT_EQ(glyph | lh, ConversionFlags("1lh")); + + EXPECT_EQ(sv, ConversionFlags("1svw")); + EXPECT_EQ(sv, ConversionFlags("1svh")); + EXPECT_EQ(sv, ConversionFlags("1svi")); + EXPECT_EQ(sv, ConversionFlags("1svb")); + EXPECT_EQ(sv, ConversionFlags("1svmin")); + EXPECT_EQ(sv, ConversionFlags("1svmax")); + + EXPECT_EQ(sv, ConversionFlags("1lvw")); + EXPECT_EQ(sv, ConversionFlags("1lvh")); + EXPECT_EQ(sv, ConversionFlags("1lvi")); + EXPECT_EQ(sv, ConversionFlags("1lvb")); + EXPECT_EQ(sv, ConversionFlags("1lvmin")); + EXPECT_EQ(sv, ConversionFlags("1lvmax")); + + EXPECT_EQ(sv, ConversionFlags("1vw")); + EXPECT_EQ(sv, ConversionFlags("1vh")); + EXPECT_EQ(sv, ConversionFlags("1vi")); + EXPECT_EQ(sv, ConversionFlags("1vb")); + EXPECT_EQ(sv, ConversionFlags("1vmin")); + EXPECT_EQ(sv, ConversionFlags("1vmax")); + + EXPECT_EQ(dv, ConversionFlags("1dvw")); + EXPECT_EQ(dv, ConversionFlags("1dvh")); + EXPECT_EQ(dv, ConversionFlags("1dvi")); + EXPECT_EQ(dv, ConversionFlags("1dvb")); + EXPECT_EQ(dv, ConversionFlags("1dvmin")); + EXPECT_EQ(dv, ConversionFlags("1dvmax")); + + // Since there is no container, these units fall back to the small viewport. + EXPECT_EQ(cq | sv, ConversionFlags("1cqh")); + EXPECT_EQ(cq | sv, ConversionFlags("1cqw")); + EXPECT_EQ(cq | sv, ConversionFlags("1cqi")); + EXPECT_EQ(cq | sv, ConversionFlags("1cqb")); + EXPECT_EQ(cq | sv, ConversionFlags("1cqmin")); + EXPECT_EQ(cq | sv, ConversionFlags("1cqmax")); + + EXPECT_EQ(em | glyph, ConversionFlags("calc(1em + 1ex)")); +} + } // namespace blink diff --git a/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc b/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc index c1a7378ac5f35..095187b884dfc 100644 --- a/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc +++ b/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc @@ -61,9 +61,10 @@ static void VerifyCSSCalc(String text, CSSToLengthConversionData::ViewportSize viewport_size(viewport_width, viewport_height); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1.0); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1.0, ignored_flags); EXPECT_APPROX_EQ(value, math_value->ComputeLength(conversion_data)); } diff --git a/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc b/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc index 4ef9a36618f11..5ac502149fb00 100644 --- a/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc @@ -266,9 +266,10 @@ FilterOperations FilterOperationResolver::CreateOffscreenFilterOperations( CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr /* element_style */, WritingMode::kHorizontalTb, font_sizes, - line_height_size, viewport_size, container_sizes, 1 /* zoom */); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1 /* zoom */, ignored_flags); for (auto& curr_value : To(in_value)) { if (curr_value->IsURIValue()) diff --git a/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc b/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc index 94711af6775d6..2bcf2df7eb77f 100644 --- a/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc @@ -23,9 +23,10 @@ FontDescription FontStyleResolver::ComputeFont( CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; - CSSToLengthConversionData conversionData(nullptr, WritingMode::kHorizontalTb, - font_sizes, line_height_size, - viewport_size, container_sizes, 1); + CSSToLengthConversionData::Flags ignored_flags = 0; + CSSToLengthConversionData conversion_data( + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); // CSSPropertyID::kFontSize if (property_set.HasProperty(CSSPropertyID::kFontSize)) { @@ -38,7 +39,7 @@ FontDescription FontStyleResolver::ComputeFont( } else { builder.SetSize(StyleBuilderConverterBase::ConvertFontSize( *property_set.GetPropertyCSSValue(CSSPropertyID::kFontSize), - conversionData, FontDescription::Size(0, 0.0f, false), nullptr)); + conversion_data, FontDescription::Size(0, 0.0f, false), nullptr)); } } diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index 9e7ba8ceb5bce..baac19732b739 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc @@ -1419,7 +1419,7 @@ Length StyleBuilderConverter::ConvertLength( } UnzoomedLength StyleBuilderConverter::ConvertUnzoomedLength( - const StyleResolverState& state, + StyleResolverState& state, const CSSValue& value) { return UnzoomedLength(To(value).ConvertToLength( state.UnzoomedLengthConversionData())); @@ -2390,10 +2390,11 @@ const CSSValue& StyleBuilderConverter::ConvertRegisteredPropertyInitialValue( CSSToLengthConversionData::ViewportSize viewport_size( document.GetLayoutView()); CSSToLengthConversionData::ContainerSizes container_sizes; - CSSToLengthConversionData conversion_data( - /* element_style */ nullptr, WritingMode::kHorizontalTb, font_sizes, - line_height_size, viewport_size, container_sizes, - /* zoom */ 1.0f); + CSSToLengthConversionData::Flags ignored_flags = 0; + CSSToLengthConversionData conversion_data(WritingMode::kHorizontalTb, + font_sizes, line_height_size, + viewport_size, container_sizes, + /* zoom */ 1.0f, ignored_flags); const CSSParserContext* parser_context = document.ElementSheet().Contents()->ParserContext(); diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h index bd42bde4a24fc..17afea970b7ef 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h @@ -190,7 +190,7 @@ class StyleBuilderConverter { const CSSValue&); static Length ConvertLength(const StyleResolverState&, const CSSValue&); static Length ConvertLength(const StyleResolverState&, const ScopedCSSValue&); - static UnzoomedLength ConvertUnzoomedLength(const StyleResolverState&, + static UnzoomedLength ConvertUnzoomedLength(StyleResolverState&, const CSSValue&); static float ConvertZoom(const StyleResolverState&, const CSSValue&); static Length ConvertLengthOrAuto(const StyleResolverState&, const CSSValue&); diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index 98a4999cbf1f0..bec428c3fe800 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc @@ -324,6 +324,41 @@ void UseCountLegacyOverlapping(Document& document, } } +void ApplyLengthConversionFlags(StyleResolverState& state) { + using Flags = CSSToLengthConversionData::Flags; + using Flag = CSSToLengthConversionData::Flag; + + Flags flags = state.TakeLengthConversionFlags(); + if (!flags) { + return; + } + + ComputedStyle* style = state.Style(); + + if (flags & static_cast(Flag::kEm)) { + style->SetHasEmUnits(); + } + if (flags & static_cast(Flag::kRem)) { + style->SetHasRemUnits(); + } + if (flags & static_cast(Flag::kGlyphRelative)) { + style->SetHasGlyphRelativeUnits(); + } + if (flags & static_cast(Flag::kLineHeightRelative)) { + style->SetHasLineHeightRelativeUnits(); + } + if (flags & static_cast(Flag::kStaticViewport)) { + style->SetHasStaticViewportUnits(); + } + if (flags & static_cast(Flag::kDynamicViewport)) { + style->SetHasDynamicViewportUnits(); + } + if (flags & static_cast(Flag::kContainerRelative)) { + style->SetDependsOnSizeContainerQueries(true); + style->SetHasContainerRelativeUnits(); + } +} + } // namespace static CSSPropertyValueSet* LeftToRightDeclaration() { @@ -1754,6 +1789,10 @@ bool StyleResolver::ApplyAnimatedStyle(StyleResolverState& state, // Start loading resources used by animations. state.LoadPendingResources(); + // Apply any length conversion flags produced by CSS/Web animations (e.g. + // animations involving viewport units would set such flags). + ApplyLengthConversionFlags(state); + DCHECK(!state.GetFontBuilder().FontDirty()); } @@ -2140,9 +2179,11 @@ void StyleResolver::CascadeAndApplyMatchedProperties(StyleResolverState& state, UseCountLegacyOverlapping(GetDocument(), *non_legacy_style, *state.Style()); } - // NOTE: This flag needs to be set before the entry is added to the - // matched properties cache, or it will be wrong on cache hits. + // NOTE: This flag (and the length conversion flags) need to be set before the + // entry is added to the matched properties cache, or it will be wrong on + // cache hits. state.StyleBuilder().SetInlineStyleLostCascade(cascade.InlineStyleLost()); + ApplyLengthConversionFlags(state); MaybeAddToMatchedPropertiesCache(state, cache_success, result); diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc index fe23d761cd2a0..b6022b52adcc6 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc @@ -118,13 +118,13 @@ void StyleResolverState::UpdateLengthConversionData() { css_to_length_conversion_data_ = CSSToLengthConversionData( Style(), ParentStyle(), RootElementStyle(), GetDocument().GetLayoutView(), CSSToLengthConversionData::ContainerSizes(container_unit_context_), - StyleBuilder().EffectiveZoom()); + StyleBuilder().EffectiveZoom(), length_conversion_flags_); element_style_resources_.UpdateLengthConversionData( &css_to_length_conversion_data_); } CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData( - const ComputedStyle* font_style) const { + const ComputedStyle* font_style) { float em = font_style->SpecifiedFontSize(); float rem = RootElementStyle() ? RootElementStyle()->SpecifiedFontSize() : 1; CSSToLengthConversionData::FontSizes font_sizes( @@ -136,17 +136,16 @@ CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData( CSSToLengthConversionData::ContainerSizes container_sizes( container_unit_context_); - return CSSToLengthConversionData(Style(), StyleBuilder().GetWritingMode(), - font_sizes, line_height_size, viewport_size, - container_sizes, 1); + return CSSToLengthConversionData( + StyleBuilder().GetWritingMode(), font_sizes, line_height_size, + viewport_size, container_sizes, 1, length_conversion_flags_); } -CSSToLengthConversionData StyleResolverState::FontSizeConversionData() const { +CSSToLengthConversionData StyleResolverState::FontSizeConversionData() { return UnzoomedLengthConversionData(ParentStyle()); } -CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData() - const { +CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData() { return UnzoomedLengthConversionData(Style()); } diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h index cb5e433fea2c5..600e16f3bbb09 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h +++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h @@ -98,8 +98,8 @@ class CORE_EXPORT StyleResolverState { const CSSToLengthConversionData& CssToLengthConversionData() const { return css_to_length_conversion_data_; } - CSSToLengthConversionData FontSizeConversionData() const; - CSSToLengthConversionData UnzoomedLengthConversionData() const; + CSSToLengthConversionData FontSizeConversionData(); + CSSToLengthConversionData UnzoomedLengthConversionData(); ScopedCSSToLengthConversionData GetScopedCSSToLengthConversionData( const TreeScope* scope) const { @@ -107,6 +107,12 @@ class CORE_EXPORT StyleResolverState { scope); } + CSSToLengthConversionData::Flags TakeLengthConversionFlags() { + CSSToLengthConversionData::Flags flags = length_conversion_flags_; + length_conversion_flags_ = 0; + return flags; + } + void SetConversionFontSizes( const CSSToLengthConversionData::FontSizes& font_sizes) { css_to_length_conversion_data_.SetFontSizes(font_sizes); @@ -210,7 +216,7 @@ class CORE_EXPORT StyleResolverState { private: void UpdateLengthConversionData(); CSSToLengthConversionData UnzoomedLengthConversionData( - const ComputedStyle* font_style) const; + const ComputedStyle* font_style); ElementResolveContext element_context_; Document* document_; @@ -218,6 +224,7 @@ class CORE_EXPORT StyleResolverState { // The primary output for each element's style resolve. ComputedStyleBuilder style_builder_; + CSSToLengthConversionData::Flags length_conversion_flags_ = 0; CSSToLengthConversionData css_to_length_conversion_data_; // parent_style_ is not always just ElementResolveContext::ParentStyle(), diff --git a/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc b/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc index 11257c5a08b38..156fc5228324b 100644 --- a/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc +++ b/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc @@ -22,9 +22,10 @@ TSAN_TEST(CSSToLengthConversionDataThreadedTest, Construction) { CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); }); } @@ -36,9 +37,10 @@ TSAN_TEST(CSSToLengthConversionDataThreadedTest, ConversionEm) { CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create( 3.14, CSSPrimitiveValue::UnitType::kEms); @@ -56,9 +58,10 @@ TSAN_TEST(CSSToLengthConversionDataThreadedTest, ConversionPixel) { CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create( 44, CSSPrimitiveValue::UnitType::kPixels); @@ -76,9 +79,10 @@ TSAN_TEST(CSSToLengthConversionDataThreadedTest, ConversionViewport) { CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create( 1, CSSPrimitiveValue::UnitType::kViewportWidth); @@ -96,9 +100,10 @@ TSAN_TEST(CSSToLengthConversionDataThreadedTest, ConversionRem) { CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create(1, CSSPrimitiveValue::UnitType::kRems); diff --git a/third_party/blink/renderer/core/svg/svg_length_context.cc b/third_party/blink/renderer/core/svg/svg_length_context.cc index abe6a175c3927..761d859f9325b 100644 --- a/third_party/blink/renderer/core/svg/svg_length_context.cc +++ b/third_party/blink/renderer/core/svg/svg_length_context.cc @@ -562,11 +562,12 @@ float SVGLengthContext::ResolveValue(const CSSPrimitiveValue& primitive_value, return 0; DCHECK(context_); + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data = CSSToLengthConversionData( style, style, root_style, context_->GetDocument().GetLayoutView(), CSSToLengthConversionData::ContainerSizes( context_->ParentOrShadowHostElement()), - 1.0f); + 1.0f, ignored_flags); Length length = primitive_value.ConvertToLength(conversion_data); return ValueForLength(length, 1.0f, mode); }