Skip to content

Commit

Permalink
[css-values] Implement CSS cap unit
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=242466
rdar://97025854

Reviewed by Myles C. Maxfield and Darin Adler.

https://drafts.csswg.org/css-values/#cap

> Equal to the used cap-height of the first available font [CSS3-FONTS]. [...] In the cases where it is impossible or impractical to determine the cap-height, the font’s ascent must be used.

* LayoutTests/TestExpectations:
* LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/font-relative-units-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-values/cap-invalidation-expected.txt:
* Source/WebCore/css/CSSPrimitiveValue.cpp:
(WebCore::isValidCSSUnitTypeForDoubleConversion):
(WebCore::isStringType):
(WebCore::CSSPrimitiveValue::~CSSPrimitiveValue):
(WebCore::CSSPrimitiveValue::computeUnzoomedNonCalcLengthDouble):
(WebCore::CSSPrimitiveValue::computeNonCalcLengthDouble):
(WebCore::CSSPrimitiveValue::unitTypeString):
(WebCore::CSSPrimitiveValue::serializeInternal const):
(WebCore::CSSPrimitiveValue::equals const):
(WebCore::CSSPrimitiveValue::addDerivedHash const):
(WebCore::CSSPrimitiveValue::collectComputedStyleDependencies const):
* Source/WebCore/css/CSSPrimitiveValue.h:
(WebCore::CSSPrimitiveValue::isFontRelativeLength):
(WebCore::CSSPrimitiveValue::isLength):
* Source/WebCore/css/CSSPrimitiveValueMappings.h:
(WebCore::CSSPrimitiveValue::convertingToLengthRequiresNonNullStyle const):
* Source/WebCore/css/CSSUnits.cpp:
(WebCore::unitCategory):
(WebCore::operator<<):
* Source/WebCore/css/CSSUnits.h:
* Source/WebCore/css/calc/CSSCalcCategoryMapping.cpp:
(WebCore::calcUnitCategory):
(WebCore::calculationCategoryForCombination):
(WebCore::hasDoubleValue):
* Source/WebCore/css/parser/CSSParserToken.cpp:
(WebCore::cssPrimitiveValueUnitFromTrie):
* Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::LengthRawKnownTokenTypeDimensionConsumer::consume):
* Source/WebCore/css/parser/SizesAttributeParser.cpp:
(WebCore::SizesAttributeParser::computeLength):
* Source/WebCore/css/typedom/CSSNumericFactory.h:
* Source/WebCore/css/typedom/CSSStyleValueFactory.cpp:
(WebCore::CSSStyleValueFactory::reifyValue):

Canonical link: https://commits.webkit.org/267315@main
  • Loading branch information
nt1m committed Aug 26, 2023
1 parent f005b55 commit ce1ebf3
Show file tree
Hide file tree
Showing 14 changed files with 41 additions and 9 deletions.
1 change: 0 additions & 1 deletion LayoutTests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -3685,7 +3685,6 @@ webkit.org/b/203333 imported/w3c/web-platform-tests/css/css-values/ch-unit-010.h
webkit.org/b/203338 imported/w3c/web-platform-tests/css/css-values/vh_not_refreshing_on_chrome.html [ ImageOnlyFailure ]
webkit.org/b/242465 imported/w3c/web-platform-tests/css/css-values/calc-width-table-auto-1.html [ Skip ]
webkit.org/b/242465 imported/w3c/web-platform-tests/css/css-values/calc-width-table-fixed-1.html [ Skip ]
webkit.org/b/242466 imported/w3c/web-platform-tests/css/css-values/cap-unit-001.html [ ImageOnlyFailure ]
webkit.org/b/259025 imported/w3c/web-platform-tests/css/css-values/ch-unit-018.html [ ImageOnlyFailure ]
webkit.org/b/259025 imported/w3c/web-platform-tests/css/css-values/ic-unit-015.html [ ImageOnlyFailure ]
webkit.org/b/214466 imported/w3c/web-platform-tests/css/css-values/ex-unit-004.html [ ImageOnlyFailure ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ PASS ic relative inline-size
FAIL ric relative inline-size assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
PASS lh relative inline-size
PASS rlh relative inline-size
FAIL cap relative inline-size assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"
PASS cap relative inline-size
FAIL rcap relative inline-size assert_equals: expected "rgb(0, 128, 0)" but got "rgb(0, 0, 0)"

Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
CONSOLE MESSAGE: Error: assert_not_equals: expect the capital height of Ahem and sans-serif to be different got disallowed value 784

FAIL CSS Values and Units Test: cap invalidation Error: assert_not_equals: expect the capital height of Ahem and sans-serif to be different got disallowed value 784
PASS CSS Values and Units Test: cap invalidation

16 changes: 16 additions & 0 deletions Source/WebCore/css/CSSPrimitiveValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ static inline bool isValidCSSUnitTypeForDoubleConversion(CSSUnitType unitType)
case CSSUnitType::CSS_CALC:
case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH:
case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_CM:
Expand Down Expand Up @@ -154,6 +155,7 @@ static inline bool isStringType(CSSUnitType type)
case CSSUnitType::CSS_CALC:
case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH:
case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_CM:
Expand Down Expand Up @@ -378,6 +380,7 @@ CSSPrimitiveValue::~CSSPrimitiveValue()
case CSSUnitType::CSS_QUIRKY_EMS:
case CSSUnitType::CSS_EXS:
case CSSUnitType::CSS_REMS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_PX:
Expand Down Expand Up @@ -697,6 +700,13 @@ double CSSPrimitiveValue::computeUnzoomedNonCalcLengthDouble(CSSUnitType primiti
auto& fontDescription = fontCascadeForUnit->fontDescription();
return ((propertyToCompute == CSSPropertyFontSize) ? fontDescription.specifiedSize() : fontDescription.computedSize()) / 2.0 * value;
}
case CSSUnitType::CSS_CAP: {
ASSERT(fontCascadeForUnit);
auto& fontMetrics = fontCascadeForUnit->metricsOfPrimaryFont();
if (fontMetrics.hasCapHeight())
return fontMetrics.floatCapHeight() * value;
return fontMetrics.ascent() * value;
}
case CSSUnitType::CSS_CHS:
ASSERT(fontCascadeForUnit);
return fontCascadeForUnit->metricsOfPrimaryFont().zeroWidth().value_or(fontCascadeForUnit->fontDescription().computedSize() / 2) * value;
Expand Down Expand Up @@ -812,6 +822,7 @@ double CSSPrimitiveValue::computeNonCalcLengthDouble(const CSSToLengthConversion
case CSSUnitType::CSS_EMS:
case CSSUnitType::CSS_QUIRKY_EMS:
case CSSUnitType::CSS_EXS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
// FIXME: We have a bug right now where the zoom will be applied twice to EX units.
Expand Down Expand Up @@ -1204,6 +1215,7 @@ NEVER_INLINE String CSSPrimitiveValue::formatIntegerValue(ASCIILiteral suffix) c
ASCIILiteral CSSPrimitiveValue::unitTypeString(CSSUnitType unitType)
{
switch (unitType) {
case CSSUnitType::CSS_CAP: return "cap"_s;
case CSSUnitType::CSS_CHS: return "ch"_s;
case CSSUnitType::CSS_CM: return "cm"_s;
case CSSUnitType::CSS_CQB: return "cqb"_s;
Expand Down Expand Up @@ -1292,6 +1304,7 @@ ALWAYS_INLINE String CSSPrimitiveValue::serializeInternal() const
{
auto type = primitiveUnitType();
switch (type) {
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_CM:
case CSSUnitType::CSS_CQB:
Expand Down Expand Up @@ -1430,6 +1443,7 @@ bool CSSPrimitiveValue::equals(const CSSPrimitiveValue& other) const
case CSSUnitType::CSS_QUIRKY_EMS:
case CSSUnitType::CSS_EXS:
case CSSUnitType::CSS_REMS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_PX:
Expand Down Expand Up @@ -1527,6 +1541,7 @@ bool CSSPrimitiveValue::addDerivedHash(Hasher& hasher) const
case CSSUnitType::CSS_QUIRKY_EMS:
case CSSUnitType::CSS_EXS:
case CSSUnitType::CSS_REMS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_PX:
Expand Down Expand Up @@ -1630,6 +1645,7 @@ void CSSPrimitiveValue::collectComputedStyleDependencies(ComputedStyleDependenci
case CSSUnitType::CSS_EMS:
case CSSUnitType::CSS_QUIRKY_EMS:
case CSSUnitType::CSS_EXS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
dependencies.properties.appendIfNotContains(CSSPropertyFontSize);
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/css/CSSPrimitiveValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ constexpr bool CSSPrimitiveValue::isFontRelativeLength(CSSUnitType type)
|| type == CSSUnitType::CSS_LHS
|| type == CSSUnitType::CSS_RLHS
|| type == CSSUnitType::CSS_REMS
|| type == CSSUnitType::CSS_CAP
|| type == CSSUnitType::CSS_CHS
|| type == CSSUnitType::CSS_IC
|| type == CSSUnitType::CSS_QUIRKY_EMS;
Expand All @@ -282,6 +283,7 @@ constexpr bool CSSPrimitiveValue::isLength(CSSUnitType type)
|| type == CSSUnitType::CSS_PT
|| type == CSSUnitType::CSS_PC
|| type == CSSUnitType::CSS_REMS
|| type == CSSUnitType::CSS_CAP
|| type == CSSUnitType::CSS_CHS
|| type == CSSUnitType::CSS_IC
|| type == CSSUnitType::CSS_Q
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/css/CSSPrimitiveValueMappings.h
Original file line number Diff line number Diff line change
Expand Up @@ -1963,6 +1963,7 @@ inline bool CSSPrimitiveValue::convertingToLengthRequiresNonNullStyle(int length
switch (primitiveUnitType()) {
case CSSUnitType::CSS_EMS:
case CSSUnitType::CSS_EXS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_LHS:
Expand Down
8 changes: 5 additions & 3 deletions Source/WebCore/css/CSSUnits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ CSSUnitCategory unitCategory(CSSUnitType type)
case CSSUnitType::CSS_EMS:
case CSSUnitType::CSS_REMS:
case CSSUnitType::CSS_EXS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_LHS:
Expand Down Expand Up @@ -247,9 +248,10 @@ TextStream& operator<<(TextStream& ts, CSSUnitType unitType)
case CSSUnitType::CSS_CQMAX: ts << "cqmax"; break;
case CSSUnitType::CSS_CQMIN: ts << "cqmin"; break;
case CSSUnitType::CSS_TURN: ts << "turn"; break;
case CSSUnitType::CSS_REMS: ts << "rems"; break;
case CSSUnitType::CSS_CHS: ts << "chs"; break;
case CSSUnitType::CSS_IC: ts << "ics"; break;
case CSSUnitType::CSS_REMS: ts << "rem"; break;
case CSSUnitType::CSS_CAP: ts << "cap"; break;
case CSSUnitType::CSS_CHS: ts << "ch"; break;
case CSSUnitType::CSS_IC: ts << "ic"; break;
case CSSUnitType::CSS_COUNTER_NAME: ts << "counter_name"; break;
case CSSUnitType::CSS_CALC: ts << "calc"; break;
case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER: ts << "calc_percentage_with_number"; break;
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/css/CSSUnits.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ enum class CSSUnitType : uint8_t {

CSS_TURN,
CSS_REMS,
CSS_CAP,
CSS_CHS,
CSS_IC,

Expand Down
3 changes: 3 additions & 0 deletions Source/WebCore/css/calc/CSSCalcCategoryMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ CalculationCategory calcUnitCategory(CSSUnitType type)
case CSSUnitType::CSS_LHS:
case CSSUnitType::CSS_RLHS:
case CSSUnitType::CSS_REMS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_VW:
Expand Down Expand Up @@ -142,6 +143,7 @@ CalculationCategory calculationCategoryForCombination(CSSUnitType type)
case CSSUnitType::CSS_LHS:
case CSSUnitType::CSS_REMS:
case CSSUnitType::CSS_RLHS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_VW:
Expand Down Expand Up @@ -206,6 +208,7 @@ bool hasDoubleValue(CSSUnitType type)
case CSSUnitType::CSS_PERCENTAGE:
case CSSUnitType::CSS_EMS:
case CSSUnitType::CSS_EXS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_REMS:
Expand Down
4 changes: 4 additions & 0 deletions Source/WebCore/css/parser/CSSParserToken.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ CSSUnitType cssPrimitiveValueUnitFromTrie(const CharacterType* data, unsigned le
case 3:
switch (toASCIILower(data[0])) {
case 'c':
if (toASCIILower(data[1]) == 'a') {
if (toASCIILower(data[2]) == 'p')
return CSSUnitType::CSS_CAP;
}
if (toASCIILower(data[1]) == 'q') {
switch (toASCIILower(data[2])) {
case 'b':
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ struct LengthRawKnownTokenTypeDimensionConsumer {
case CSSUnitType::CSS_REMS:
case CSSUnitType::CSS_LHS:
case CSSUnitType::CSS_RLHS:
case CSSUnitType::CSS_CAP:
case CSSUnitType::CSS_CHS:
case CSSUnitType::CSS_IC:
case CSSUnitType::CSS_EXS:
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/css/parser/SizesAttributeParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ float SizesAttributeParser::computeLength(double value, CSSUnitType type, const
// the pointer to it for the duration of the unit evaluation. This is acceptible because the style always comes from the
// RenderView, which has its font information hardcoded in resolveForDocument() to be -webkit-standard, whose operations
// don't require a font selector.
if (type == CSSUnitType::CSS_EXS || type == CSSUnitType::CSS_CHS || type == CSSUnitType::CSS_IC) {
if (type == CSSUnitType::CSS_EXS || type == CSSUnitType::CSS_CAP || type == CSSUnitType::CSS_CHS || type == CSSUnitType::CSS_IC) {
RefPtr<FontSelector> fontSelector = style.fontCascade().fontSelector();
style.fontCascade().update(nullptr);
float result = CSSPrimitiveValue::computeNonCalcLengthDouble(conversionData, type, value);
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/css/typedom/CSSNumericFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class CSSNumericFactory final : public Supplement<DOMCSSNamespace> {
// <length>
static Ref<CSSUnitValue> em(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_EMS); }
static Ref<CSSUnitValue> ex(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_EXS); }
static Ref<CSSUnitValue> cap(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_CAP); }
static Ref<CSSUnitValue> ch(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_CHS); }
static Ref<CSSUnitValue> ic(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_IC); }
static Ref<CSSUnitValue> rem(double value) { return CSSUnitValue::create(value, CSSUnitType::CSS_REMS); }
Expand Down
5 changes: 4 additions & 1 deletion Source/WebCore/css/typedom/CSSStyleValueFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,12 @@ ExceptionOr<Ref<CSSStyleValue>> CSSStyleValueFactory::reifyValue(const CSSValue&
return Ref<CSSStyleValue> { CSSNumericFactory::em(primitiveValue->doubleValue()) };
case CSSUnitType::CSS_EXS:
return Ref<CSSStyleValue> { CSSNumericFactory::ex(primitiveValue->doubleValue()) };
case CSSUnitType::CSS_CAP:
return Ref<CSSStyleValue> { CSSNumericFactory::cap(primitiveValue->doubleValue()) };
case CSSUnitType::CSS_CHS:
return Ref<CSSStyleValue> { CSSNumericFactory::ch(primitiveValue->doubleValue()) };
// FIXME: Add CSSNumericFactory::ic
case CSSUnitType::CSS_IC:
return Ref<CSSStyleValue> { CSSNumericFactory::ic(primitiveValue->doubleValue()) };
case CSSUnitType::CSS_REMS:
return Ref<CSSStyleValue> { CSSNumericFactory::rem(primitiveValue->doubleValue()) };
case CSSUnitType::CSS_LHS:
Expand Down

0 comments on commit ce1ebf3

Please sign in to comment.