Skip to content

Commit

Permalink
Implement support for 'lh' unit
Browse files Browse the repository at this point in the history
Missing:

- Support for SVG
- Support for cycle detection in custom properties
- Support for lh unit animations

Bug: 937104
Change-Id: I777da60470e4b8426ad5e09e418448ed107d9c24
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3859336
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1047877}
  • Loading branch information
lilles authored and Chromium LUCI CQ committed Sep 16, 2022
1 parent 4dcf89b commit a28c7c1
Show file tree
Hide file tree
Showing 49 changed files with 286 additions and 62 deletions.
7 changes: 7 additions & 0 deletions third_party/blink/renderer/core/css/css_container_values.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"

namespace blink {

Expand Down Expand Up @@ -51,6 +52,12 @@ float CSSContainerValues::IcFontSize() const {
return font_sizes_.Ic();
}

float CSSContainerValues::LineHeight() const {
return AdjustForAbsoluteZoom::AdjustFloat(
element_->ComputedStyleRef().ComputedLineHeight(),
element_->ComputedStyleRef());
}

double CSSContainerValues::ContainerWidth() const {
return container_sizes_.Width().value_or(SmallViewportWidth());
}
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/css/css_container_values.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class CSSContainerValues : public MediaValuesDynamic {
float ExFontSize() const override;
float ChFontSize() const override;
float IcFontSize() const override;
float LineHeight() const override;
// Note that ContainerWidth/ContainerHeight are used to resolve
// container *units*. See `container_sizes_`.
Element* ContainerElement() const override { return element_; }
Expand Down
2 changes: 1 addition & 1 deletion third_party/blink/renderer/core/css/css_gradient_value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ scoped_refptr<Image> CSSGradientValue::GetImage(
const ComputedStyle* root_style =
document.documentElement()->GetComputedStyle();
CSSToLengthConversionData conversion_data(
&style, root_style, document.GetLayoutView(), container_sizes,
&style, &style, root_style, document.GetLayoutView(), container_sizes,
style.EffectiveZoom());

scoped_refptr<Gradient> gradient;
Expand Down
2 changes: 1 addition & 1 deletion third_party/blink/renderer/core/css/css_gradient_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class CSSGradientValue : public CSSImageGeneratorValue {

scoped_refptr<Image> GetImage(const ImageResourceObserver&,
const Document&,
const ComputedStyle&,
const ComputedStyle& style,
const ContainerSizes&,
const gfx::SizeF&) const;

Expand Down
3 changes: 3 additions & 0 deletions third_party/blink/renderer/core/css/css_length_resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ double CSSLengthResolver::ZoomedComputedPixels(
case CSSPrimitiveValue::UnitType::kContainerMax:
return value * ContainerMaxPercent() * Zoom();

case CSSPrimitiveValue::UnitType::kLhs:
return value * LineHeight() * Zoom();

// Note that functions for font-relative units already account for the
// zoom factor.
case CSSPrimitiveValue::UnitType::kEms:
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/css/css_length_resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class CORE_EXPORT CSSLengthResolver {
virtual double DynamicViewportHeight() const = 0;
virtual double ContainerWidth() const = 0;
virtual double ContainerHeight() const = 0;
virtual float LineHeight() const = 0;

virtual WritingMode GetWritingMode() const = 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ static CalculationCategory UnitCategory(CSSPrimitiveValue::UnitType type) {
case CSSPrimitiveValue::UnitType::kIcs:
return RuntimeEnabledFeatures::CSSIcUnitEnabled() ? kCalcLength
: kCalcOther;
case CSSPrimitiveValue::UnitType::kLhs:
return RuntimeEnabledFeatures::CSSLhUnitEnabled() ? kCalcLength
: kCalcOther;
case CSSPrimitiveValue::UnitType::kDegrees:
case CSSPrimitiveValue::UnitType::kGradians:
case CSSPrimitiveValue::UnitType::kRadians:
Expand All @@ -128,6 +131,7 @@ static bool HasDoubleValue(CSSPrimitiveValue::UnitType type) {
case CSSPrimitiveValue::UnitType::kExs:
case CSSPrimitiveValue::UnitType::kChs:
case CSSPrimitiveValue::UnitType::kIcs:
case CSSPrimitiveValue::UnitType::kLhs:
case CSSPrimitiveValue::UnitType::kRems:
case CSSPrimitiveValue::UnitType::kPixels:
case CSSPrimitiveValue::UnitType::kCentimeters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ TEST(CSSCalculationValue, AccumulatePixelsAndPercent) {
ComputedStyle::CreateInitialStyleSingleton();
style->SetEffectiveZoom(5);
CSSToLengthConversionData conversion_data(
style.get(), style.get(), nullptr,
style.get(), style.get(), style.get(), nullptr,
CSSToLengthConversionData::ContainerSizes(), style->EffectiveZoom());

TestAccumulatePixelsAndPercent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ String CSSNumericLiteralValue::CustomCSSText() const {
case UnitType::kRems:
case UnitType::kChs:
case UnitType::kIcs:
case UnitType::kLhs:
case UnitType::kPixels:
case UnitType::kCentimeters:
case UnitType::kDotsPerPixel:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class CORE_EXPORT CSSNumericLiteralValue : public CSSPrimitiveValue {
bool IsFontRelativeLength() const {
return GetType() == UnitType::kQuirkyEms || GetType() == UnitType::kEms ||
GetType() == UnitType::kExs || GetType() == UnitType::kRems ||
GetType() == UnitType::kChs || GetType() == UnitType::kIcs;
GetType() == UnitType::kChs || GetType() == UnitType::kIcs ||
GetType() == UnitType::kLhs;
}
bool IsQuirkyEms() const { return GetType() == UnitType::kQuirkyEms; }
bool IsViewportPercentageLength() const {
Expand Down
7 changes: 7 additions & 0 deletions third_party/blink/renderer/core/css/css_primitive_value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,9 @@ bool CSSPrimitiveValue::UnitTypeToLengthUnitType(UnitType unit_type,
case CSSPrimitiveValue::UnitType::kIcs:
length_type = kUnitTypeIdeographicFullWidth;
return true;
case CSSPrimitiveValue::UnitType::kLhs:
length_type = kUnitTypeLineHeight;
return true;
case CSSPrimitiveValue::UnitType::kPercentage:
length_type = kUnitTypePercentage;
return true;
Expand Down Expand Up @@ -651,6 +654,8 @@ CSSPrimitiveValue::UnitType CSSPrimitiveValue::LengthUnitTypeToUnitType(
return CSSPrimitiveValue::UnitType::kChs;
case kUnitTypeIdeographicFullWidth:
return CSSPrimitiveValue::UnitType::kIcs;
case kUnitTypeLineHeight:
return CSSPrimitiveValue::UnitType::kLhs;
case kUnitTypePercentage:
return CSSPrimitiveValue::UnitType::kPercentage;
case kUnitTypeViewportWidth:
Expand Down Expand Up @@ -739,6 +744,8 @@ const char* CSSPrimitiveValue::UnitTypeToString(UnitType type) {
return "ch";
case UnitType::kIcs:
return "ic";
case UnitType::kLhs:
return "lh";
case UnitType::kPixels:
return "px";
case UnitType::kCentimeters:
Expand Down
4 changes: 3 additions & 1 deletion third_party/blink/renderer/core/css/css_primitive_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class CORE_EXPORT CSSPrimitiveValue : public CSSValue {
kRems,
kChs,
kIcs,
kLhs,
kUserUnits, // The SVG term for unitless lengths
// Angle units
kDegrees,
Expand Down Expand Up @@ -190,6 +191,7 @@ class CORE_EXPORT CSSPrimitiveValue : public CSSValue {
kUnitTypeContainerMin,
kUnitTypeContainerMax,
kUnitTypeIdeographicFullWidth,
kUnitTypeLineHeight,

// This value must come after the last length unit type to enable iteration
// over the length unit types.
Expand Down Expand Up @@ -285,7 +287,7 @@ class CORE_EXPORT CSSPrimitiveValue : public CSSValue {
return type == UnitType::kPercentage || type == UnitType::kEms ||
type == UnitType::kExs || type == UnitType::kRems ||
type == UnitType::kChs || type == UnitType::kIcs ||
IsViewportPercentageLength(type) ||
type == UnitType::kLhs || IsViewportPercentageLength(type) ||
IsContainerPercentageLength(type);
}
bool IsLength() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@
name: "ic",
unit_type: "kIcs",
},
{
name: "lh",
unit_type: "kLhs",
},
{
name: "__qem",
unit_type: "kQuirkyEms",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/style/computed_style.h"

Expand Down Expand Up @@ -190,15 +191,17 @@ void CSSToLengthConversionData::ContainerSizes::CacheSizeIfNeeded(
}

CSSToLengthConversionData::CSSToLengthConversionData(
const ComputedStyle* style,
const ComputedStyle* element_style,
const ComputedStyle* parent_style,
WritingMode writing_mode,
const FontSizes& font_sizes,
const ViewportSize& viewport_size,
const ContainerSizes& container_sizes,
float zoom)
: CSSLengthResolver(
ClampTo<float>(zoom, std::numeric_limits<float>::denorm_min())),
style_(style),
style_(element_style),
lh_style_(parent_style),
writing_mode_(writing_mode),
font_sizes_(font_sizes),
viewport_size_(viewport_size),
Expand All @@ -208,14 +211,16 @@ CSSToLengthConversionData::CSSToLengthConversionData(
}

CSSToLengthConversionData::CSSToLengthConversionData(
const ComputedStyle* style,
const ComputedStyle* element_style,
const ComputedStyle* parent_style,
const ComputedStyle* root_style,
const LayoutView* layout_view,
const ContainerSizes& container_sizes,
float zoom)
: CSSToLengthConversionData(style,
style->GetWritingMode(),
FontSizes(style, root_style),
: CSSToLengthConversionData(element_style,
parent_style,
element_style->GetWritingMode(),
FontSizes(element_style, root_style),
ViewportSize(layout_view),
container_sizes,
zoom) {}
Expand Down Expand Up @@ -253,6 +258,22 @@ float CSSToLengthConversionData::IcFontSize() const {
return font_sizes_.Ic();
}

float CSSToLengthConversionData::LineHeight() const {
const ComputedStyle* style = lh_style_ ? lh_style_ : style_;
if (!style)
return 0;
// TODO(crbug.com/937104): Needs test coverage for glyph relative unit
// invalidation.
if (style_)
const_cast<ComputedStyle*>(style_)->SetHasGlyphRelativeUnits();
// The line-height is zoom'ed given the zoom factor of its style origin which
// may be the zoom factor of this element or the parent element.
// We need to unzoom the line-height's applied zoom before always applying
// the current Zoom() factor in CSSLengthResolver.
return AdjustForAbsoluteZoom::AdjustFloat(style->ComputedLineHeight(),
*style);
}

double CSSToLengthConversionData::ViewportWidth() const {
if (style_)
const_cast<ComputedStyle*>(style_)->SetHasStaticViewportUnits();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,16 @@ class CORE_EXPORT CSSToLengthConversionData : public CSSLengthResolver {
mutable absl::optional<double> cached_height_;
};

CSSToLengthConversionData()
: CSSLengthResolver(1 /* zoom */), style_(nullptr) {}
CSSToLengthConversionData(const ComputedStyle*,
CSSToLengthConversionData() : CSSLengthResolver(1 /* zoom */) {}
CSSToLengthConversionData(const ComputedStyle* element_style,
const ComputedStyle* parent_style,
WritingMode,
const FontSizes&,
const ViewportSize&,
const ContainerSizes&,
float zoom);
CSSToLengthConversionData(const ComputedStyle* curr_style,
CSSToLengthConversionData(const ComputedStyle* element_style,
const ComputedStyle* parent_style,
const ComputedStyle* root_style,
const LayoutView*,
const ContainerSizes&,
Expand All @@ -179,6 +180,7 @@ class CORE_EXPORT CSSToLengthConversionData : public CSSLengthResolver {
float ExFontSize() const override;
float ChFontSize() const override;
float IcFontSize() const override;
float LineHeight() const override;
double ViewportWidth() const override;
double ViewportHeight() const override;
double SmallViewportWidth() const override;
Expand All @@ -192,6 +194,7 @@ class CORE_EXPORT CSSToLengthConversionData : public CSSLengthResolver {
WritingMode GetWritingMode() const override;

void SetFontSizes(const FontSizes& font_sizes) { font_sizes_ = font_sizes; }
void ClearLhStyle() { lh_style_ = nullptr; }

// See ContainerSizes::PreCachedCopy.
//
Expand All @@ -200,17 +203,18 @@ class CORE_EXPORT CSSToLengthConversionData : public CSSLengthResolver {
ContainerSizes PreCachedContainerSizesCopy() const;

CSSToLengthConversionData CopyWithAdjustedZoom(float new_zoom) const {
return CSSToLengthConversionData(style_, writing_mode_, font_sizes_,
viewport_size_, container_sizes_,
new_zoom);
return CSSToLengthConversionData(style_, lh_style_, writing_mode_,
font_sizes_, viewport_size_,
container_sizes_, new_zoom);
}
CSSToLengthConversionData Unzoomed() const {
return CopyWithAdjustedZoom(1.0f);
}

private:
const ComputedStyle* style_;
WritingMode writing_mode_;
const ComputedStyle* style_ = nullptr;
const ComputedStyle* lh_style_ = nullptr;
WritingMode writing_mode_ = WritingMode::kHorizontalTb;
FontSizes font_sizes_;
ViewportSize viewport_size_;
ContainerSizes container_sizes_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class CSSToLengthConversionDataTest : public PageTestBase {
GetDocument().body()->AppendChild(div);
UpdateAllLifecyclePhasesForTest();
return CSSToLengthConversionData(
div->GetComputedStyle(), root->GetComputedStyle(),
GetDocument().GetLayoutView(),
div->GetComputedStyle(), GetDocument().body()->GetComputedStyle(),
root->GetComputedStyle(), GetDocument().GetLayoutView(),
CSSToLengthConversionData::ContainerSizes(),
data_zoom.value_or(div->GetComputedStyle()->EffectiveZoom()));
}
Expand All @@ -65,8 +65,10 @@ TEST_F(CSSToLengthConversionDataTest, Normal) {
EXPECT_FLOAT_EQ(16.0f, Convert(data, "1ex"));
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1ch"));
EXPECT_FLOAT_EQ(10.0f, Convert(data, "1rem"));
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1em"));
EXPECT_FLOAT_EQ(36.0f, Convert(data, "calc(1em + 1ex)"));
EXPECT_FLOAT_EQ(10.0f, Convert(data, "1lh"));
data.ClearLhStyle();
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1lh"));
}

TEST_F(CSSToLengthConversionDataTest, Zoomed) {
Expand All @@ -77,6 +79,9 @@ TEST_F(CSSToLengthConversionDataTest, Zoomed) {
EXPECT_FLOAT_EQ(40.0f, Convert(data, "1ch"));
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1rem"));
EXPECT_FLOAT_EQ(72.0f, Convert(data, "calc(1em + 1ex)"));
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1lh"));
data.ClearLhStyle();
EXPECT_FLOAT_EQ(40.0f, Convert(data, "1lh"));
}

TEST_F(CSSToLengthConversionDataTest, AdjustedZoom) {
Expand All @@ -87,6 +92,9 @@ TEST_F(CSSToLengthConversionDataTest, AdjustedZoom) {
EXPECT_FLOAT_EQ(40.0f, Convert(data, "1ch"));
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1rem"));
EXPECT_FLOAT_EQ(72.0f, Convert(data, "calc(1em + 1ex)"));
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1lh"));
data.ClearLhStyle();
EXPECT_FLOAT_EQ(40.0f, Convert(data, "1lh"));
}

TEST_F(CSSToLengthConversionDataTest, DifferentZoom) {
Expand All @@ -99,6 +107,9 @@ TEST_F(CSSToLengthConversionDataTest, DifferentZoom) {
EXPECT_FLOAT_EQ(40.0f, Convert(data, "1ch"));
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1rem"));
EXPECT_FLOAT_EQ(72.0f, Convert(data, "calc(1em + 1ex)"));
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1lh"));
data.ClearLhStyle();
EXPECT_FLOAT_EQ(40.0f, Convert(data, "1lh"));
}

TEST_F(CSSToLengthConversionDataTest, Unzoomed) {
Expand All @@ -109,6 +120,9 @@ TEST_F(CSSToLengthConversionDataTest, Unzoomed) {
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1ch"));
EXPECT_FLOAT_EQ(10.0f, Convert(data, "1rem"));
EXPECT_FLOAT_EQ(36.0f, Convert(data, "calc(1em + 1ex)"));
EXPECT_FLOAT_EQ(10.0f, Convert(data, "1lh"));
data.ClearLhStyle();
EXPECT_FLOAT_EQ(20.0f, Convert(data, "1lh"));
}

TEST_F(CSSToLengthConversionDataTest, StyleLessContainerUnitConversion) {
Expand Down
3 changes: 3 additions & 0 deletions third_party/blink/renderer/core/css/css_variable_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ static bool IsFontUnitToken(CSSParserToken token) {
case CSSPrimitiveValue::UnitType::kChs:
case CSSPrimitiveValue::UnitType::kExs:
case CSSPrimitiveValue::UnitType::kIcs:
// TODO(crbug.com/937104): This probably needs to be a separate
// IsLhUnitToken().
case CSSPrimitiveValue::UnitType::kLhs:
return true;
default:
return false;
Expand Down
2 changes: 2 additions & 0 deletions third_party/blink/renderer/core/css/css_variable_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ class CORE_EXPORT CSSVariableData : public RefCounted<CSSVariableData> {
const bool needs_variable_resolution_ = false;
bool has_font_units_ = false;
bool has_root_font_units_ = false;
// TODO(crbug.com/937104): Detect lh cycles.
bool has_lh_units_ = false;
String base_url_;
WTF::TextEncoding charset_;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ CSSNumericValueType::BaseType UnitTypeToBaseType(
case UnitType::kRems:
case UnitType::kChs:
case UnitType::kIcs:
case UnitType::kLhs:
return BaseType::kLength;
case UnitType::kMilliseconds:
case UnitType::kSeconds:
Expand Down
Loading

0 comments on commit a28c7c1

Please sign in to comment.