Source/WebCore/ChangeLog

 12022-03-09 Nikolas Zimmermann <nzimmermann@igalia.com>
 2
 3 Extract transform-origin handling out of RenderStyle::applyTransform()
 4 https://bugs.webkit.org/show_bug.cgi?id=237590
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 RenderStyle::applyTransform() implements the algorithm given in
 9 CSS Transforms Module Level 2 (https://www.w3.org/TR/css-transforms-2/#ctm)
 10 that yields the "current transformation matrix". It is used e.g. in
 11 RenderLayer::updateTransform() to compute the layer transformation
 12 matrix, that's used for rendering.
 13
 14 LBSE wants to re-use the same algorithm, interchanging the individual
 15 CSS transform properties / the CSS transform property with an external
 16 AffineTransform, representing the SVG 2D transform.
 17
 18 Therefore Split RenderStyle::applyTransform() into three methods:
 19 applyTransformOrigin / applyCSSTransform / unapplyTransformOrigin.
 20
 21 LBSE can call applyTransformOrigin(), multiply the TransformationMatrix
 22 with the given SVG 2D AffineTransform and call unapplyTransformOrigin().
 23 The rest of the codebase remaings unchanged, since applyTransform() is kept as-is.
 24
 25 Covered by existing tests, no change in behaviour.
 26
 27 * platform/graphics/transforms/TransformationMatrix.cpp:
 28 (WebCore::TransformationMatrix::multiplyAffineTransform):
 29 * platform/graphics/transforms/TransformationMatrix.h:
 30 * rendering/style/RenderStyle.cpp:
 31 (WebCore::RenderStyle::applyTransformOrigin const):
 32 (WebCore::RenderStyle::unapplyTransformOrigin):
 33 (WebCore::RenderStyle::applyTransform const):
 34 (WebCore::RenderStyle::applyCSSTransform const):
 35 * rendering/style/RenderStyle.h:
 36
1372022-03-09 Nikolas Zimmermann <nzimmermann@igalia.com>
238
339 Unify 'transform-box' reference box computation

Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp

@@TransformationMatrix& TransformationMatrix::multiply(const TransformationMatrix&
15331533 return *this;
15341534}
15351535
 1536TransformationMatrix& TransformationMatrix::multiplyAffineTransform(const AffineTransform& mat)
 1537{
 1538 if (mat.isIdentity())
 1539 return *this;
 1540
 1541 if (mat.isIdentityOrTranslation())
 1542 return translate(mat.e(), mat.f());
 1543
 1544 return multiply(mat.toTransformationMatrix());
 1545}
 1546
15361547void TransformationMatrix::multVecMatrix(double x, double y, double& resultX, double& resultY) const
15371548{
15381549 resultX = m_matrix[3][0] + x * m_matrix[0][0] + y * m_matrix[1][0];

Source/WebCore/platform/graphics/transforms/TransformationMatrix.h

@@public:
249249
250250 // this = mat * this.
251251 WEBCORE_EXPORT TransformationMatrix& multiply(const TransformationMatrix&);
 252 // Identical to multiply(TransformationMatrix&), but saving a AffineTransform -> TransformationMatrix roundtrip for identity or translation matrices.
 253 TransformationMatrix& multiplyAffineTransform(const AffineTransform&);
252254
253255 WEBCORE_EXPORT TransformationMatrix& scale(double);
254256 WEBCORE_EXPORT TransformationMatrix& scaleNonUniform(double sx, double sy);

Source/WebCore/rendering/style/RenderStyle.cpp

@@void RenderStyle::setHasAttrContent()
14211421 SET_VAR(m_rareNonInheritedData, hasAttrContent, true);
14221422}
14231423
1424 void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> options) const
 1424FloatPoint3D RenderStyle::applyTransformOrigin(TransformationMatrix& transform, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> options) const
14251425{
1426  // https://www.w3.org/TR/css-transforms-2/#ctm
1427  // The transformation matrix is computed from the transform, transform-origin, translate, rotate, scale, and offset properties as follows:
1428  // 1. Start with the identity matrix.
1429 
14301426 auto& transformOperations = m_rareNonInheritedData->transform->operations;
14311427 bool applyTransformOrigin = options.contains(RenderStyle::TransformOperationOption::TransformOrigin)
14321428 && ((m_rareNonInheritedData->rotate && !m_rareNonInheritedData->rotate->isIdentity())
14331429 || (m_rareNonInheritedData->scale && !m_rareNonInheritedData->scale->isIdentity())
14341430 || transformOperations.affectedByTransformOrigin()
14351431 || offsetPath());
 1432 if (!applyTransformOrigin)
 1433 return { };
14361434
 1435 // https://www.w3.org/TR/css-transforms-2/#ctm
14371436 // 2. Translate by the computed X, Y, and Z values of transform-origin.
14381437 FloatPoint3D originTranslate;
1439  if (applyTransformOrigin) {
1440  originTranslate.setXY(boundingBox.location() + floatPointForLengthPoint(transformOriginXY(), boundingBox.size()));
1441  originTranslate.setZ(transformOriginZ());
 1438 originTranslate.setXY(boundingBox.location() + floatPointForLengthPoint(transformOriginXY(), boundingBox.size()));
 1439 originTranslate.setZ(transformOriginZ());
 1440 if (!originTranslate.isZero())
14421441 transform.translate3d(originTranslate.x(), originTranslate.y(), originTranslate.z());
1443  }
 1442 return originTranslate;
 1443}
 1444
 1445void RenderStyle::unapplyTransformOrigin(TransformationMatrix& transform, const FloatPoint3D& originTranslate) const
 1446{
 1447 // https://www.w3.org/TR/css-transforms-2/#ctm
 1448 // 8. Translate by the negated computed X, Y and Z values of transform-origin.
 1449 if (!originTranslate.isZero())
 1450 transform.translate3d(-originTranslate.x(), -originTranslate.y(), -originTranslate.z());
 1451}
 1452
 1453void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> options) const
 1454{
 1455 auto originTranslate = applyTransformOrigin(transform, boundingBox, options);
 1456 applyCSSTransform(transform, boundingBox, options);
 1457 unapplyTransformOrigin(transform, originTranslate);
 1458}
 1459
 1460void RenderStyle::applyCSSTransform(TransformationMatrix& transform, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> options) const
 1461{
 1462 // https://www.w3.org/TR/css-transforms-2/#ctm
 1463 // The transformation matrix is computed from the transform, transform-origin, translate, rotate, scale, and offset properties as follows:
 1464 // 1. Start with the identity matrix.
 1465 // 2. Translate by the computed X, Y, and Z values of transform-origin. (see applyTransformOrigin)
14441466
14451467 // 3. Translate by the computed X, Y, and Z values of translate.
14461468 if (options.contains(RenderStyle::TransformOperationOption::Translate)) {

@@void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRec
14651487 applyMotionPathTransform(transform, boundingBox);
14661488
14671489 // 7. Multiply by each of the transform functions in transform from left to right.
 1490 auto& transformOperations = m_rareNonInheritedData->transform->operations;
14681491 for (auto& operation : transformOperations.operations())
14691492 operation->apply(transform, boundingBox.size());
14701493
1471  // 8. Translate by the negated computed X, Y and Z values of transform-origin.
1472  if (applyTransformOrigin)
1473  transform.translate3d(-originTranslate.x(), -originTranslate.y(), -originTranslate.z());
 1494 // 8. Translate by the negated computed X, Y and Z values of transform-origin. (see unapplyTransformOrigin)
14741495}
14751496
14761497static std::optional<Path> getPathFromPathOperation(const FloatRect& box, const PathOperation& operation)

Source/WebCore/rendering/style/RenderStyle.h

@@public:
697697
698698 static constexpr OptionSet<TransformOperationOption> allTransformOperations = { TransformOperationOption::TransformOrigin, TransformOperationOption::Translate, TransformOperationOption::Rotate, TransformOperationOption::Scale , TransformOperationOption::Offset };
699699 static constexpr OptionSet<TransformOperationOption> individualTransformOperations = { TransformOperationOption::Translate, TransformOperationOption::Rotate, TransformOperationOption::Scale, TransformOperationOption::Offset };
 700
 701 FloatPoint3D applyTransformOrigin(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<TransformOperationOption> = allTransformOperations) const;
 702 void unapplyTransformOrigin(TransformationMatrix&, const FloatPoint3D& originTranslate) const;
 703 // applyTransform calls applyTransformOrigin(), then applyCSSTransform(), followed by unapplyTransformOrigin().
700704 void applyTransform(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<TransformOperationOption> = allTransformOperations) const;
 705 void applyCSSTransform(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<TransformOperationOption> = allTransformOperations) const;
701706 void applyMotionPathTransform(TransformationMatrix&, const FloatRect& boundingBox) const;
702707 void setPageScaleTransform(float);
703708