Skip to content

Commit

Permalink
[CSS Shape function] Add parsing support and storage for shape()
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=277347
rdar://132814728

Reviewed by NOBODY (OOPS!).

Implement parsing, property value and computed style support for the `shape()` function[1]. We support the syntax
as of the most recent edit[2] but without the flexible order of points and control points due to [3].

Added BasicShapesShapeSegmentConversion.h/cpp with helpers to convert between CSS values and the internal shapes.
CSSShapeValue::customCSSText() is implemented.

BasicShapeShape stores its segments as a vector of std::variant<>, much as we do for Paths, which avoids heap allocations
per segment.

Tentative WPT are included.

[1] https://drafts.csswg.org/css-shapes-2/#shape-function
[2] w3c/csswg-drafts@9770805c4e53
[3] w3c/csswg-drafts#10666

* LayoutTests/imported/w3c/web-platform-tests/css/css-shapes/shape-functions/shape-function-computed.tentative.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-shapes/shape-functions/shape-function-invalid.tentative.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-shapes/shape-functions/shape-function-valid.tentative.html: Added.
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/css/BasicShapeConversion.cpp:
(WebCore::valueForBasicShape):
(WebCore::convertToLengthPoint):
(WebCore::basicShapeForValue):
(WebCore::basicShapeShapeForValue):
* Source/WebCore/css/BasicShapeConversion.h:
* Source/WebCore/css/BasicShapesShapeSegmentConversion.cpp: Added.
(WebCore::lengthToCSSValue):
(WebCore::lengthPointToCSSValue):
(WebCore::lengthSizeToCSSValue):
(WebCore::toCSSShapeSegmentValue):
(WebCore::fromCSSShapeSegmentValue):
* Source/WebCore/css/BasicShapesShapeSegmentConversion.h: Copied from Source/WebCore/css/BasicShapeConversion.h.
* Source/WebCore/css/CSSBasicShapes.cpp:
(WebCore::CSSShapeValue::CSSShapeValue):
(WebCore::CSSShapeValue::customCSSText const):
(WebCore::CSSShapeValue::equals const):
* Source/WebCore/css/CSSShapeSegmentValue.cpp:
(WebCore::CSSShapeSegmentValue::customCSSText const):
(WebCore::CSSShapeSegmentValue::toShapeSegment const):
* Source/WebCore/css/CSSShapeSegmentValue.h:
* Source/WebCore/css/CSSValueKeywords.in:
* Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::consumeCoordinatePair):
(WebCore::CSSPropertyParserHelpers::consumeShapeCommand):
(WebCore::CSSPropertyParserHelpers::consumeBasicShapeShape):
(WebCore::CSSPropertyParserHelpers::consumeBasicShape):
* Source/WebCore/rendering/style/BasicShapes.cpp:
(WebCore::operator<<):
* Source/WebCore/rendering/style/BasicShapes.h:
* Source/WebCore/rendering/style/BasicShapesShape.cpp: Added.
(WebCore::BasicShapeShape::create):
(WebCore::BasicShapeShape::BasicShapeShape):
(WebCore::BasicShapeShape::clone const):
(WebCore::BasicShapeShape::path const):
(WebCore::BasicShapeShape::canBlend const):
(WebCore::BasicShapeShape::blend const):
(WebCore::BasicShapeShape::operator== const):
(WebCore::BasicShapeShape::dump const):
(WebCore::operator<<):
* Source/WebCore/rendering/style/BasicShapesShape.h: Added.
(WebCore::ShapeSegmentBase::ShapeSegmentBase):
(WebCore::ShapeSegmentBase::affinity const):
  • Loading branch information
smfr committed Aug 2, 2024
1 parent 8d191d0 commit 22aced7
Show file tree
Hide file tree
Showing 18 changed files with 1,094 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Shapes Module Level 2: computed values for the shape() function</title>
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#shape-function">
<meta name="assert" content="Tests parsing of the circle() function">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/computed-testcommon.js"></script>
</head>
<body>
<div id="target"></div>
<script>
test_computed_value("clip-path", "shape(from 20px 40px, line to 20px 30px)");
test_computed_value("clip-path", "shape(from 20px 40px, line to 20px 30px )", "shape(from 20px 40px, line to 20px 30px)");
test_computed_value("clip-path", "shape(from 0 0, line to 100% 100%)", "shape(from 0px 0px, line to 100% 100%)");

test_computed_value("clip-path", "shape(from 20px 40px, move to 20px 30px, line by 20px 30px)");
test_computed_value("clip-path", "shape(from 20px 40px, move to 20px 30px, hline to 100px)");
test_computed_value("clip-path", "shape(from 20px 40px, move to 20px 30px, hline by 100%)");
test_computed_value("clip-path", "shape(from 20px 40px, move to 20px 30px, vline to 100px)");
test_computed_value("clip-path", "shape(from 20px 40px, move to 20px 30px, vline by 100%)");

test_computed_value("clip-path", "shape(from 20px 40px, curve by 20px 20px using 10px 30px)");
test_computed_value("clip-path", "shape(from 20px 40px, curve by 20px 20px using 10px 30px 12px 32px)");

test_computed_value("clip-path", "shape(from 20px 40px, smooth by 20px 20px)");
test_computed_value("clip-path", "shape(from 20px 40px, smooth by 20px 20px using 12px 32px)");

test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10%)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 0)", "shape(from 20px 40px, arc by 20px 20px of 0px)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 0)", "shape(from 20px 40px, arc by 20px 20px of 10% 0px)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% rotate 0deg)", "shape(from 20px 40px, arc by 20px 20px of 10%)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20%)");

test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% large)");

test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of -10% -20% large)");

test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% rotate 1deg)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw rotate 12deg)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw rotate 3.14159265rad)", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw rotate 180deg)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% large rotate 12deg)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw large)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% large cw)", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw large)");
test_computed_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% rotate 12deg large)", "shape(from 20px 40px, arc by 20px 20px of 10% 20% large rotate 12deg)");

document.getElementById('target').remove();
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Shapes Module Level 1: parsing the shape() function</title>
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#shape-function">
<meta name="assert" content="Tests parsing of the circle() function">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_invalid_value("clip-path", "shape(from 20px 40px line to 20px 30px)");
test_invalid_value("clip-path", "shape(from 20px 40px line to 20px 30px,)");
test_invalid_value("clip-path", "shape(from 20px, 40px, line to 20px, 30px)");

test_invalid_value("clip-path", "shape(from 20px 40px, curve by 20px 20px, using 10px 30px 12px 32px)");
test_invalid_value("clip-path", "shape(from 20px 40px, curve by 20px 20px using 10px 30px, 12px 32px)");
test_invalid_value("clip-path", "shape(from 20px 40px, smooth by 20px 20px using 10px 30px 12px 32px)");
test_invalid_value("clip-path", "shape(from 20px 40px, curve by 20px 20px via 10px 30px 12px 32px)");

test_invalid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% 12deg)");
test_invalid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% rotate 12deg rotate 13deg)");
test_invalid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw large 12deg)");
test_invalid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% small large)");
test_invalid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw ccw)");
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Shapes Module Level 2: parsing the shape() function</title>
<link rel="help" href="https://drafts.csswg.org/css-shapes-2/#shape-function">
<meta name="assert" content="Tests parsing of the circle() function">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<style>
#target {
width: 200px;
height: 100px;
}
</style>
</head>
<body>
<div id="target"></div>
<script>
test_valid_value("clip-path", "shape(from 20px 40px, line to 20px 30px)");
test_valid_value("clip-path", "shape(from 20px 40px, line to 20px 30px )", "shape(from 20px 40px, line to 20px 30px)");
test_valid_value("clip-path", "shape(from 0 0, line to 100% 100%)", "shape(from 0px 0px, line to 100% 100%)");

test_valid_value("clip-path", "shape(from 20px 40px, move to 20px 30px, line by 20px 30px)");
test_valid_value("clip-path", "shape(from 20px 40px, move to 20px 30px, hline to 100px)");
test_valid_value("clip-path", "shape(from 20px 40px, move to 20px 30px, hline by 100%)");
test_valid_value("clip-path", "shape(from 20px 40px, move to 20px 30px, vline to 100px)");
test_valid_value("clip-path", "shape(from 20px 40px, move to 20px 30px, vline by 100%)");

test_valid_value("clip-path", "shape(from 20px 40px, curve by 20px 20px using 10px 30px)");
test_valid_value("clip-path", "shape(from 20px 40px, curve by 20px 20px using 10px 30px 12px 32px)");

test_valid_value("clip-path", "shape(from 20px 40px, smooth by 20px 20px)");
test_valid_value("clip-path", "shape(from 20px 40px, smooth by 20px 20px using 12px 32px)");

test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10%)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 0)", "shape(from 20px 40px, arc by 20px 20px of 0px)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 0)", "shape(from 20px 40px, arc by 20px 20px of 10% 0px)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% rotate 0deg)", "shape(from 20px 40px, arc by 20px 20px of 10%)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20%)");

test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% large)");

test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of -10% -20% large)");

test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% rotate 1deg)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw rotate 12deg)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw rotate 0.52rad)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% large rotate 12deg)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw large)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% large cw)", "shape(from 20px 40px, arc by 20px 20px of 10% 20% cw large)");
test_valid_value("clip-path", "shape(from 20px 40px, arc by 20px 20px of 10% 20% rotate 12deg large)", "shape(from 20px 40px, arc by 20px 20px of 10% 20% large rotate 12deg)");
document.getElementById('target').remove();
</script>
</body>
</html>
2 changes: 2 additions & 0 deletions Source/WebCore/Sources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,7 @@ crypto/keys/CryptoKeyRSA.cpp
crypto/keys/CryptoKeyRSAComponents.cpp
crypto/keys/CryptoKeyRaw.cpp
css/BasicShapeConversion.cpp
css/BasicShapesShapeSegmentConversion.cpp
css/CSSAnchorValue.cpp
css/CSSAspectRatioValue.cpp
css/CSSBackgroundRepeatValue.cpp
Expand Down Expand Up @@ -2801,6 +2802,7 @@ rendering/shapes/RectangleShape.cpp
rendering/shapes/Shape.cpp
rendering/shapes/ShapeOutsideInfo.cpp
rendering/style/BasicShapes.cpp
rendering/style/BasicShapesShape.cpp
rendering/style/BorderData.cpp
rendering/style/BorderValue.cpp
rendering/style/ContentData.cpp
Expand Down
8 changes: 8 additions & 0 deletions Source/WebCore/WebCore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7305,6 +7305,10 @@
0FCF33230F2B9715004B6795 /* ColorCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColorCG.cpp; sourceTree = "<group>"; };
0FCF332A0F2B9A25004B6795 /* WebLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebLayer.mm; sourceTree = "<group>"; };
0FCF332B0F2B9A25004B6795 /* WebLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebLayer.h; sourceTree = "<group>"; };
0FD2C6A12C58485E00ED7278 /* BasicShapesShapeSegmentConversion.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BasicShapesShapeSegmentConversion.cpp; sourceTree = "<group>"; };
0FD2C6A22C58485E00ED7278 /* BasicShapesShapeSegmentConversion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BasicShapesShapeSegmentConversion.h; sourceTree = "<group>"; };
0FD2C6A32C5848A900ED7278 /* BasicShapesShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BasicShapesShape.h; sourceTree = "<group>"; };
0FD2C6A42C5848A900ED7278 /* BasicShapesShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BasicShapesShape.cpp; sourceTree = "<group>"; };
0FD3080C117CF7E700A791F7 /* RenderFrameBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderFrameBase.cpp; sourceTree = "<group>"; };
0FD3080D117CF7E700A791F7 /* RenderFrameBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderFrameBase.h; sourceTree = "<group>"; };
0FD308D3117D168400A791F7 /* RenderIFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderIFrame.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -33496,6 +33500,8 @@
children = (
FBD6AF8215EF21A3008B7110 /* BasicShapes.cpp */,
FBD6AF8315EF21A3008B7110 /* BasicShapes.h */,
0FD2C6A42C5848A900ED7278 /* BasicShapesShape.cpp */,
0FD2C6A32C5848A900ED7278 /* BasicShapesShape.h */,
0F283A9123563126004794CA /* BorderData.cpp */,
BC5EB5E00E81BE8700B25965 /* BorderData.h */,
BCD34EEC28ECB6D800472470 /* BorderValue.cpp */,
Expand Down Expand Up @@ -35973,6 +35979,8 @@
4BAFD0DA21921EAD00C0AB64 /* typedom */,
FBD6AF8415EF21D4008B7110 /* BasicShapeConversion.cpp */,
FBD6AF8515EF21D4008B7110 /* BasicShapeConversion.h */,
0FD2C6A12C58485E00ED7278 /* BasicShapesShapeSegmentConversion.cpp */,
0FD2C6A22C58485E00ED7278 /* BasicShapesShapeSegmentConversion.h */,
713785EE28D9F4C50092D9F2 /* ComputedStyleExtractor.cpp */,
713785EF28D9F4C50092D9F2 /* ComputedStyleExtractor.h */,
A80E6CDA0A1989CA007FB8C5 /* Counter.h */,
Expand Down
66 changes: 59 additions & 7 deletions Source/WebCore/css/BasicShapeConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@
#include "BasicShapeConversion.h"

#include "BasicShapes.h"
#include "BasicShapesShape.h"
#include "BasicShapesShapeSegmentConversion.h"
#include "CSSBasicShapes.h"
#include "CSSCalcNegateNode.h"
#include "CSSCalcOperationNode.h"
#include "CSSCalcPrimitiveValueNode.h"
#include "CSSPrimitiveValueMappings.h"
#include "CSSShapeSegmentValue.h"
#include "CSSValuePair.h"
#include "CSSValuePool.h"
#include "CalculationValue.h"
Expand Down Expand Up @@ -94,6 +97,9 @@ Ref<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicShape& bas
auto createPair = [&](const LengthSize& size) {
return CSSValuePair::create(createValue(size.width), createValue(size.height));
};
auto createCoordinatePair = [&](const LengthPoint& point) {
return CSSValuePair::createNoncoalescing(createValue(point.x()), createValue(point.y()));
};
auto createReflectedSumValue = [&](const Length& a, const Length& b) {
auto reflected = convertTo100PercentMinusLengthSum(a, b);
return CSSPrimitiveValue::create(reflected, style);
Expand Down Expand Up @@ -160,6 +166,18 @@ Ref<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicShape& bas
createPair(rect.topLeftRadius()), createPair(rect.topRightRadius()),
createPair(rect.bottomRightRadius()), createPair(rect.bottomLeftRadius()));
}
case BasicShape::Type::Shape: {
auto& shape = uncheckedDowncast<BasicShapeShape>(basicShape);

CSSValueListBuilder segments;

for (auto& segment : shape.segments()) {
Ref value = toCSSShapeSegmentValue(style, segment);
segments.append(WTFMove(value));
}

return CSSShapeValue::create(shape.windRule(), createCoordinatePair(shape.startPoint()), WTFMove(segments));
}
}
RELEASE_ASSERT_NOT_REACHED();
}
Expand All @@ -182,6 +200,15 @@ static LengthSize convertToLengthSize(const CSSToLengthConversionData& conversio
return { convertToLength(conversionData, value->protectedFirst()), convertToLength(conversionData, value->protectedSecond()) };
}

static LengthPoint convertToLengthPoint(const CSSToLengthConversionData& conversionData, const CSSValue& value)
{
RefPtr pairValue = dynamicDowncast<CSSValuePair>(value);
if (!pairValue)
return { };

return { convertToLength(conversionData, pairValue->first()), convertToLength(conversionData, pairValue->second()) };
}

static BasicShapeCenterCoordinate convertToCenterCoordinate(const CSSToLengthConversionData& conversionData, const CSSValue* value)
{
CSSValueID keyword = CSSValueTop;
Expand Down Expand Up @@ -241,15 +268,16 @@ static BasicShapeRadius cssValueToBasicShapeRadius(const CSSToLengthConversionDa

Ref<BasicShape> basicShapeForValue(const CSSToLengthConversionData& conversionData, const CSSValue& value, float zoom)
{
if (auto* circleValue = dynamicDowncast<CSSCircleValue>(value)) {
if (RefPtr circleValue = dynamicDowncast<CSSCircleValue>(value)) {
auto circle = BasicShapeCircle::create();
circle->setRadius(cssValueToBasicShapeRadius(conversionData, circleValue->protectedRadius().get()));
circle->setCenterX(convertToCenterCoordinate(conversionData, circleValue->protectedCenterX().get()));
circle->setCenterY(convertToCenterCoordinate(conversionData, circleValue->protectedCenterY().get()));
circle->setPositionWasOmitted(!circleValue->centerX() && !circleValue->centerY());
return circle;
}
if (auto* ellipseValue = dynamicDowncast<CSSEllipseValue>(value)) {

if (RefPtr ellipseValue = dynamicDowncast<CSSEllipseValue>(value)) {
auto ellipse = BasicShapeEllipse::create();
ellipse->setRadiusX(cssValueToBasicShapeRadius(conversionData, ellipseValue->protectedRadiusX().get()));
ellipse->setRadiusY(cssValueToBasicShapeRadius(conversionData, ellipseValue->protectedRadiusY().get()));
Expand All @@ -258,14 +286,16 @@ Ref<BasicShape> basicShapeForValue(const CSSToLengthConversionData& conversionDa
ellipse->setPositionWasOmitted(!ellipseValue->centerX() && !ellipseValue->centerY());
return ellipse;
}
if (auto* polygonValue = dynamicDowncast<CSSPolygonValue>(value)) {

if (RefPtr polygonValue = dynamicDowncast<CSSPolygonValue>(value)) {
auto polygon = BasicShapePolygon::create();
polygon->setWindRule(polygonValue->windRule());
for (unsigned i = 0; i < polygonValue->size(); i += 2)
polygon->appendPoint(convertToLength(conversionData, *polygonValue->protectedItem(i)), convertToLength(conversionData, *polygonValue->protectedItem(i + 1)));
return polygon;
}
if (auto* rectValue = dynamicDowncast<CSSInsetShapeValue>(value)) {

if (RefPtr rectValue = dynamicDowncast<CSSInsetShapeValue>(value)) {
auto rect = BasicShapeInset::create();
rect->setTop(convertToLength(conversionData, rectValue->protectedTop()));
rect->setRight(convertToLength(conversionData, rectValue->protectedRight()));
Expand All @@ -277,7 +307,8 @@ Ref<BasicShape> basicShapeForValue(const CSSToLengthConversionData& conversionDa
rect->setBottomLeftRadius(convertToLengthSize(conversionData, rectValue->protectedBottomLeftRadius().get()));
return rect;
}
if (auto* rectValue = dynamicDowncast<CSSXywhValue>(value)) {

if (RefPtr rectValue = dynamicDowncast<CSSXywhValue>(value)) {
auto rect = BasicShapeXywh::create();
rect->setInsetX(convertToLength(conversionData, rectValue->protectedInsetX().get()));
rect->setInsetY(convertToLength(conversionData, rectValue->protectedInsetY().get()));
Expand All @@ -290,7 +321,8 @@ Ref<BasicShape> basicShapeForValue(const CSSToLengthConversionData& conversionDa
rect->setBottomLeftRadius(convertToLengthSize(conversionData, rectValue->protectedBottomLeftRadius().get()));
return rect;
}
if (auto* rectValue = dynamicDowncast<CSSRectShapeValue>(value)) {

if (RefPtr rectValue = dynamicDowncast<CSSRectShapeValue>(value)) {
auto rect = BasicShapeRect::create();
rect->setTop(convertToLengthOrAuto(conversionData, rectValue->protectedTop()));
rect->setRight(convertToLengthOrAuto(conversionData, rectValue->protectedRight()));
Expand All @@ -304,9 +336,12 @@ Ref<BasicShape> basicShapeForValue(const CSSToLengthConversionData& conversionDa
return rect;
}

if (auto* pathValue = dynamicDowncast<CSSPathValue>(value))
if (RefPtr pathValue = dynamicDowncast<CSSPathValue>(value))
return basicShapePathForValue(*pathValue, zoom);

if (RefPtr shapeValue = dynamicDowncast<CSSShapeValue>(value))
return basicShapeShapeForValue(*shapeValue, conversionData);

RELEASE_ASSERT_NOT_REACHED();
}

Expand All @@ -318,6 +353,23 @@ Ref<BasicShapePath> basicShapePathForValue(const CSSPathValue& value, float zoom
return path;
}

Ref<BasicShapeShape> basicShapeShapeForValue(const CSSShapeValue& shapeValue, const CSSToLengthConversionData& conversionData)
{
Vector<BasicShapeShape::ShapeSegment> segments;
segments.reserveInitialCapacity(shapeValue.length());

for (auto& segment : shapeValue) {
RefPtr shapeSegment = dynamicDowncast<CSSShapeSegmentValue>(segment);
if (!shapeSegment) {
ASSERT_NOT_REACHED();
continue;
}
segments.append(fromCSSShapeSegmentValue(conversionData, *shapeSegment));
}

return BasicShapeShape::create(shapeValue.windRule(), convertToLengthPoint(conversionData, shapeValue.protectedFromCoordinates().get()), WTFMove(segments));
}

float floatValueForCenterCoordinate(const BasicShapeCenterCoordinate& center, float boxDimension)
{
float offset = floatValueForLength(center.length(), boxDimension);
Expand Down
Loading

0 comments on commit 22aced7

Please sign in to comment.