- Revision
- 286085
- Author
- commit-qu...@webkit.org
- Date
- 2021-11-19 16:49:21 -0800 (Fri, 19 Nov 2021)
Log Message
Integrate motion path transforms in transformation pipeline
https://bugs.webkit.org/show_bug.cgi?id=233144
Patch by Kiet Ho <th...@apple.com> on 2021-11-19
Reviewed by Dean Jackson.
Source/WebCore:
This patch ties everything together and renders CSS Motion Path out onto the screen.
Motion path properties are desugared into two transformations: one translate to move
the element to the specified location on the path, and one rotate to rotate the element
to the correct orientation specified by offset-rotate. The two transformations are applied
after scale() and before the individual transform functions, as specified in the CSS
Transforms spec.
Tests: imported/w3c/web-platform-tests/css/motion/animation/reftests/offset-path-with-transforms-001.html
imported/w3c/web-platform-tests/css/motion/offset-distance-001.html
imported/w3c/web-platform-tests/css/motion/offset-distance-002.html
imported/w3c/web-platform-tests/css/motion/offset-distance-003.html
imported/w3c/web-platform-tests/css/motion/offset-distance-004.html
imported/w3c/web-platform-tests/css/motion/offset-distance-005.html
imported/w3c/web-platform-tests/css/motion/offset-distance-006.html
imported/w3c/web-platform-tests/css/motion/offset-distance-007.html
imported/w3c/web-platform-tests/css/motion/offset-distance-008.html
imported/w3c/web-platform-tests/css/motion/offset-distance-009.html
imported/w3c/web-platform-tests/css/motion/offset-path-string-001.html
imported/w3c/web-platform-tests/css/motion/offset-path-string-002.html
imported/w3c/web-platform-tests/css/motion/offset-rotate-003.html
imported/w3c/web-platform-tests/css/motion/offset-rotate-004.html
imported/w3c/web-platform-tests/css/motion/offset-rotate-005.html
* platform/graphics/Path.cpp:
(WebCore::Path::isClosed const): Added method to determine if a Path is closed (i.e,
the last draw command is CloseSubpath). This is required because offset-distance is
handled differently depending on if the Path is closed or not.
* platform/graphics/Path.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::recompositeChangeRequiresGeometryUpdate): Account in changes in motion path properties.
* rendering/RenderObject.h:
(WebCore::RenderObject::hasTransform const): Account in motion path properties.
* rendering/style/RenderStyle.cpp:
(WebCore::rareNonInheritedDataChangeRequiresLayout):
(WebCore::RenderStyle::applyTransform const): Add an additional step to apply motion path transforms.
(WebCore::getPathFromPathOperation):
(WebCore::getTraversalStateAtDistance):
(WebCore::RenderStyle::applyMotionPathTransform const): Added method to apply motion path transforms.
* rendering/style/RenderStyle.h:
(WebCore::RenderStyle::hasTransform const): Account for motion path properties.
LayoutTests:
Removed ImageOnlyFailure expectations for tests that should now pass.
* TestExpectations:
Modified Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (286084 => 286085)
--- trunk/LayoutTests/ChangeLog 2021-11-19 23:52:41 UTC (rev 286084)
+++ trunk/LayoutTests/ChangeLog 2021-11-20 00:49:21 UTC (rev 286085)
@@ -1,3 +1,14 @@
+2021-11-19 Kiet Ho <th...@apple.com>
+
+ Integrate motion path transforms in transformation pipeline
+ https://bugs.webkit.org/show_bug.cgi?id=233144
+
+ Reviewed by Dean Jackson.
+
+ Removed ImageOnlyFailure expectations for tests that should now pass.
+
+ * TestExpectations:
+
2021-11-19 Antti Koivisto <an...@apple.com>
[CSS Cascade Layers] [Debug] ASSERTION FAILED: m_childRules.isEmpty() when using @import with layer name
Modified: trunk/LayoutTests/TestExpectations (286084 => 286085)
--- trunk/LayoutTests/TestExpectations 2021-11-19 23:52:41 UTC (rev 286084)
+++ trunk/LayoutTests/TestExpectations 2021-11-20 00:49:21 UTC (rev 286085)
@@ -5089,42 +5089,29 @@
# import-w3c-tests copies -notref.html to -expected.html, so expected image failure here.
imported/w3c/web-platform-tests/html/semantics/forms/the-textarea-element/placeholder-white-space.tentative.html [ ImageOnlyFailure ]
-# CSS motion path tests, currently failing.
-imported/w3c/web-platform-tests/css/motion/animation/reftests/offset-path-with-transforms-001.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-anchor-transform-box-fill-box-001.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-anchor-transform-box-fill-box-002.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-anchor-transform-box-fill-box-003.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-distance-001.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-distance-002.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-distance-003.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-distance-004.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-distance-005.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-distance-006.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-distance-007.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-distance-008.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-distance-009.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-001.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-002.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-003.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-004.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-005.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-006.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-007.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-008.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-009.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-contain-001.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-contain-002.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-contain-003.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-contain-004.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-ray-contain-005.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-string-001.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-path-string-002.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-rotate-001.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-rotate-002.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-rotate-003.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-rotate-004.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/motion/offset-rotate-005.html [ ImageOnlyFailure ]
+# CSS motion path tests failing for unknown reasons, needs investigation.
+webkit.org/b/233340 imported/w3c/web-platform-tests/css/motion/offset-anchor-transform-box-fill-box-001.html [ ImageOnlyFailure ]
+webkit.org/b/233340 imported/w3c/web-platform-tests/css/motion/offset-anchor-transform-box-fill-box-002.html [ ImageOnlyFailure ]
+webkit.org/b/233340 imported/w3c/web-platform-tests/css/motion/offset-anchor-transform-box-fill-box-003.html [ ImageOnlyFailure ]
+# CSS motion path that depends on ray(), currently not implemented.
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-001.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-002.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-003.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-004.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-005.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-006.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-007.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-008.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-009.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-contain-001.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-contain-002.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-contain-003.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-contain-004.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-path-ray-contain-005.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-rotate-001.html [ ImageOnlyFailure ]
+webkit.org/b/233344 imported/w3c/web-platform-tests/css/motion/offset-rotate-002.html [ ImageOnlyFailure ]
+
# IPC test failing in Debug mode due to assert.
[ Debug ] ipc/send-invalid-message.html [ Skip ]
Modified: trunk/Source/WebCore/ChangeLog (286084 => 286085)
--- trunk/Source/WebCore/ChangeLog 2021-11-19 23:52:41 UTC (rev 286084)
+++ trunk/Source/WebCore/ChangeLog 2021-11-20 00:49:21 UTC (rev 286085)
@@ -1,3 +1,51 @@
+2021-11-19 Kiet Ho <th...@apple.com>
+
+ Integrate motion path transforms in transformation pipeline
+ https://bugs.webkit.org/show_bug.cgi?id=233144
+
+ Reviewed by Dean Jackson.
+
+ This patch ties everything together and renders CSS Motion Path out onto the screen.
+ Motion path properties are desugared into two transformations: one translate to move
+ the element to the specified location on the path, and one rotate to rotate the element
+ to the correct orientation specified by offset-rotate. The two transformations are applied
+ after scale() and before the individual transform functions, as specified in the CSS
+ Transforms spec.
+
+ Tests: imported/w3c/web-platform-tests/css/motion/animation/reftests/offset-path-with-transforms-001.html
+ imported/w3c/web-platform-tests/css/motion/offset-distance-001.html
+ imported/w3c/web-platform-tests/css/motion/offset-distance-002.html
+ imported/w3c/web-platform-tests/css/motion/offset-distance-003.html
+ imported/w3c/web-platform-tests/css/motion/offset-distance-004.html
+ imported/w3c/web-platform-tests/css/motion/offset-distance-005.html
+ imported/w3c/web-platform-tests/css/motion/offset-distance-006.html
+ imported/w3c/web-platform-tests/css/motion/offset-distance-007.html
+ imported/w3c/web-platform-tests/css/motion/offset-distance-008.html
+ imported/w3c/web-platform-tests/css/motion/offset-distance-009.html
+ imported/w3c/web-platform-tests/css/motion/offset-path-string-001.html
+ imported/w3c/web-platform-tests/css/motion/offset-path-string-002.html
+ imported/w3c/web-platform-tests/css/motion/offset-rotate-003.html
+ imported/w3c/web-platform-tests/css/motion/offset-rotate-004.html
+ imported/w3c/web-platform-tests/css/motion/offset-rotate-005.html
+
+ * platform/graphics/Path.cpp:
+ (WebCore::Path::isClosed const): Added method to determine if a Path is closed (i.e,
+ the last draw command is CloseSubpath). This is required because offset-distance is
+ handled differently depending on if the Path is closed or not.
+ * platform/graphics/Path.h:
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::recompositeChangeRequiresGeometryUpdate): Account in changes in motion path properties.
+ * rendering/RenderObject.h:
+ (WebCore::RenderObject::hasTransform const): Account in motion path properties.
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::rareNonInheritedDataChangeRequiresLayout):
+ (WebCore::RenderStyle::applyTransform const): Add an additional step to apply motion path transforms.
+ (WebCore::getPathFromPathOperation):
+ (WebCore::getTraversalStateAtDistance):
+ (WebCore::RenderStyle::applyMotionPathTransform const): Added method to apply motion path transforms.
+ * rendering/style/RenderStyle.h:
+ (WebCore::RenderStyle::hasTransform const): Account for motion path properties.
+
2021-11-19 Alex Christensen <achristen...@webkit.org>
Implement extension-path variant of redirect action in WKContentRuleList
Modified: trunk/Source/WebCore/platform/graphics/Path.cpp (286084 => 286085)
--- trunk/Source/WebCore/platform/graphics/Path.cpp 2021-11-19 23:52:41 UTC (rev 286084)
+++ trunk/Source/WebCore/platform/graphics/Path.cpp 2021-11-20 00:49:21 UTC (rev 286085)
@@ -275,6 +275,26 @@
return currentPointSlowCase();
}
+bool Path::isClosed() const
+{
+ bool lastElementIsClosed = false;
+
+ // The path is closed if the type of the last PathElement is CloseSubpath. Unfortunately,
+ // the only way to access PathElements is sequentially through apply(), there's no random
+ // access as if they're in a vector.
+ // The lambda below sets lastElementIsClosed if the last PathElement is CloseSubpath.
+ // Because lastElementIsClosed is overridden if there are any remaining PathElements
+ // to be iterated, its final value is the value of the last iteration.
+ // (i.e the last PathElement).
+ // FIXME: find a more efficient way to implement this, that does not require iterating
+ // through all PathElements.
+ apply([&lastElementIsClosed](const WebCore::PathElement& element) {
+ lastElementIsClosed = (element.type == PathElement::Type::CloseSubpath);
+ });
+
+ return lastElementIsClosed;
+}
+
size_t Path::elementCount() const
{
#if ENABLE(INLINE_PATH_DATA)
Modified: trunk/Source/WebCore/platform/graphics/Path.h (286084 => 286085)
--- trunk/Source/WebCore/platform/graphics/Path.h 2021-11-19 23:52:41 UTC (rev 286084)
+++ trunk/Source/WebCore/platform/graphics/Path.h 2021-11-20 00:49:21 UTC (rev 286085)
@@ -160,6 +160,8 @@
bool hasCurrentPoint() const;
FloatPoint currentPoint() const;
+ bool isClosed() const;
+
WEBCORE_EXPORT void moveTo(const FloatPoint&);
WEBCORE_EXPORT void addLineTo(const FloatPoint&);
WEBCORE_EXPORT void addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& endPoint);
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (286084 => 286085)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2021-11-19 23:52:41 UTC (rev 286084)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2021-11-20 00:49:21 UTC (rev 286085)
@@ -1647,6 +1647,11 @@
|| oldStyle.perspectiveOriginX() != newStyle.perspectiveOriginX()
|| oldStyle.perspectiveOriginY() != newStyle.perspectiveOriginY()
|| oldStyle.backfaceVisibility() != newStyle.backfaceVisibility()
+ || !arePointingToEqualData(oldStyle.offsetPath(), newStyle.offsetPath())
+ || oldStyle.offsetAnchor() != newStyle.offsetAnchor()
+ || oldStyle.offsetPosition() != newStyle.offsetPosition()
+ || oldStyle.offsetDistance() != newStyle.offsetDistance()
+ || oldStyle.offsetRotate() != newStyle.offsetRotate()
|| !arePointingToEqualData(oldStyle.clipPath(), newStyle.clipPath());
}
Modified: trunk/Source/WebCore/rendering/RenderObject.h (286084 => 286085)
--- trunk/Source/WebCore/rendering/RenderObject.h 2021-11-19 23:52:41 UTC (rev 286084)
+++ trunk/Source/WebCore/rendering/RenderObject.h 2021-11-20 00:49:21 UTC (rev 286085)
@@ -444,7 +444,7 @@
bool hasPotentiallyScrollableOverflow() const;
bool hasTransformRelatedProperty() const { return m_bitfields.hasTransformRelatedProperty(); } // Transform, perspective or transform-style: preserve-3d.
- bool hasTransform() const { return hasTransformRelatedProperty() && (style().hasTransform() || style().translate() || style().scale() || style().rotate()); }
+ bool hasTransform() const { return hasTransformRelatedProperty() && (style().hasTransform() || style().translate() || style().scale() || style().rotate() || style().offsetPath()); }
inline bool preservesNewline() const;
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (286084 => 286085)
--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2021-11-19 23:52:41 UTC (rev 286084)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2021-11-20 00:49:21 UTC (rev 286085)
@@ -36,6 +36,7 @@
#include "InlineIteratorTextBox.h"
#include "InlineTextBoxStyle.h"
#include "Pagination.h"
+#include "PathTraversalState.h"
#include "QuotesData.h"
#include "RenderBlock.h"
#include "RenderObject.h"
@@ -698,6 +699,13 @@
|| !arePointingToEqualData(first.translate, second.translate))
changedContextSensitiveProperties.add(StyleDifferenceContextSensitiveProperty::Transform);
+ if (!arePointingToEqualData(first.offsetPath, second.offsetPath)
+ || first.offsetPosition != second.offsetPosition
+ || first.offsetDistance != second.offsetDistance
+ || first.offsetAnchor != second.offsetAnchor
+ || first.offsetRotate != second.offsetRotate)
+ changedContextSensitiveProperties.add(StyleDifferenceContextSensitiveProperty::Transform);
+
if (first.grid != second.grid
|| first.gridItem != second.gridItem)
return true;
@@ -1407,7 +1415,11 @@
// 1. Start with the identity matrix.
auto& transformOperations = m_rareNonInheritedData->transform->operations;
- bool applyTransformOrigin = options.contains(RenderStyle::TransformOperationOption::TransformOrigin) && ((m_rareNonInheritedData->rotate && !m_rareNonInheritedData->rotate->isIdentity()) || (m_rareNonInheritedData->scale && !m_rareNonInheritedData->scale->isIdentity()) || transformOperations.affectedByTransformOrigin());
+ bool applyTransformOrigin = options.contains(RenderStyle::TransformOperationOption::TransformOrigin)
+ && ((m_rareNonInheritedData->rotate && !m_rareNonInheritedData->rotate->isIdentity())
+ || (m_rareNonInheritedData->scale && !m_rareNonInheritedData->scale->isIdentity())
+ || transformOperations.affectedByTransformOrigin()
+ || offsetPath());
// 2. Translate by the computed X, Y, and Z values of transform-origin.
FloatPoint3D originTranslate;
@@ -1435,7 +1447,9 @@
scale->apply(transform, boundingBox.size());
}
- // 6. Translate and rotate by the transform specified by offset. (FIXME: we don't support the offset property)
+ // 6. Translate and rotate by the transform specified by offset.
+ if (options.contains(RenderStyle::TransformOperationOption::Offset))
+ applyMotionPathTransform(transform, boundingBox);
// 7. Multiply by each of the transform functions in transform from left to right.
for (auto& operation : transformOperations.operations())
@@ -1446,6 +1460,67 @@
transform.translate3d(-originTranslate.x(), -originTranslate.y(), -originTranslate.z());
}
+static std::optional<Path> getPathFromPathOperation(const FloatRect& box, const PathOperation& operation)
+{
+ if (operation.type() == PathOperation::Shape)
+ return downcast<ShapePathOperation>(operation).pathForReferenceRect(box);
+
+ // FIXME: support Reference and Box type.
+ // https://bugs.webkit.org/show_bug.cgi?id=233382
+ return std::nullopt;
+}
+
+static PathTraversalState getTraversalStateAtDistance(const Path& path, const Length& distance)
+{
+ auto pathLength = path.length();
+ auto distanceValue = floatValueForLength(distance, pathLength);
+
+ float resolvedLength = 0;
+ if (path.isClosed()) {
+ if (pathLength) {
+ resolvedLength = fmod(distanceValue, pathLength);
+ if (resolvedLength < 0)
+ resolvedLength += pathLength;
+ }
+ } else
+ resolvedLength = clampTo<float>(distanceValue, 0, pathLength);
+
+ ASSERT(resolvedLength >= 0);
+ return path.traversalStateAtLength(resolvedLength);
+}
+
+void RenderStyle::applyMotionPathTransform(TransformationMatrix& transform, const FloatRect& boundingBox) const
+{
+ if (!offsetPath())
+ return;
+
+ // Shift element to the point on path specified by offset-path and offset-distance.
+ auto path = getPathFromPathOperation(boundingBox, *offsetPath());
+ if (!path)
+ return;
+ auto traversalState = getTraversalStateAtDistance(*path, offsetDistance());
+ transform.translate(traversalState.current().x(), traversalState.current().y());
+
+ // Shift element to the anchor specified by offset-anchor.
+ auto transformOrigin = floatPointForLengthPoint(transformOriginXY(), boundingBox.size()) + boundingBox.location();
+ auto anchor = transformOrigin;
+ if (!offsetAnchor().x().isAuto())
+ anchor = floatPointForLengthPoint(offsetAnchor(), boundingBox.size()) + boundingBox.location();
+ transform.translate(-anchor.x(), -anchor.y());
+
+ auto shiftToOrigin = anchor - transformOrigin;
+ transform.translate(shiftToOrigin.width(), shiftToOrigin.height());
+
+ // Apply rotation.
+ auto rotation = offsetRotate();
+ if (rotation.hasAuto())
+ transform.rotate(traversalState.normalAngle() + rotation.angle());
+ else
+ transform.rotate(rotation.angle());
+
+ transform.translate(-shiftToOrigin.width(), -shiftToOrigin.height());
+}
+
void RenderStyle::setPageScaleTransform(float scale)
{
if (scale == 1)
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (286084 => 286085)
--- trunk/Source/WebCore/rendering/style/RenderStyle.h 2021-11-19 23:52:41 UTC (rev 286084)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h 2021-11-20 00:49:21 UTC (rev 286085)
@@ -645,7 +645,7 @@
ColumnSpan columnSpan() const { return static_cast<ColumnSpan>(m_rareNonInheritedData->multiCol->columnSpan); }
const TransformOperations& transform() const { return m_rareNonInheritedData->transform->operations; }
- bool hasTransform() const { return !m_rareNonInheritedData->transform->operations.operations().isEmpty(); }
+ bool hasTransform() const { return !m_rareNonInheritedData->transform->operations.operations().isEmpty() || offsetPath(); }
const Length& transformOriginX() const { return m_rareNonInheritedData->transform->x; }
const Length& transformOriginY() const { return m_rareNonInheritedData->transform->y; }
float transformOriginZ() const { return m_rareNonInheritedData->transform->z; }
@@ -684,12 +684,14 @@
TransformOrigin = 1 << 0,
Translate = 1 << 1,
Rotate = 1 << 2,
- Scale = 1 << 3
+ Scale = 1 << 3,
+ Offset = 1 << 4
};
- static constexpr OptionSet<TransformOperationOption> allTransformOperations = { TransformOperationOption::TransformOrigin, TransformOperationOption::Translate, TransformOperationOption::Rotate, TransformOperationOption::Scale };
- static constexpr OptionSet<TransformOperationOption> individualTransformOperations = { TransformOperationOption::Translate, TransformOperationOption::Rotate, TransformOperationOption::Scale };
+ static constexpr OptionSet<TransformOperationOption> allTransformOperations = { TransformOperationOption::TransformOrigin, TransformOperationOption::Translate, TransformOperationOption::Rotate, TransformOperationOption::Scale , TransformOperationOption::Offset };
+ static constexpr OptionSet<TransformOperationOption> individualTransformOperations = { TransformOperationOption::Translate, TransformOperationOption::Rotate, TransformOperationOption::Scale, TransformOperationOption::Offset };
void applyTransform(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<TransformOperationOption> = allTransformOperations) const;
+ void applyMotionPathTransform(TransformationMatrix&, const FloatRect& boundingBox) const;
void setPageScaleTransform(float);
bool hasMask() const { return m_rareNonInheritedData->mask->hasImage() || m_rareNonInheritedData->maskBoxImage.hasImage(); }