diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/graphics/transforms | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/platform/graphics/transforms')
25 files changed, 791 insertions, 331 deletions
diff --git a/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp b/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp index 62a7639ba..8ebdd98f1 100644 --- a/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp +++ b/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2005, 2006 Apple Inc. All rights reserved. * 2010 Dirk Schulze <krit@webkit.org> * * Redistribution and use in source and binary forms, with or without @@ -11,10 +11,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -31,21 +31,34 @@ #include "FloatQuad.h" #include "FloatRect.h" #include "IntRect.h" +#include "TextStream.h" #include "TransformationMatrix.h" #include <wtf/MathExtras.h> namespace WebCore { +#if COMPILER(MSVC) AffineTransform::AffineTransform() { - setMatrix(1, 0, 0, 1, 0, 0); + m_transform = { 1, 0, 0, 1, 0, 0 }; +} + +AffineTransform::AffineTransform(double a, double b, double c, double d, double e, double f) +{ + m_transform = { a, b, c, d, e, f }; +} +#else +AffineTransform::AffineTransform() + : m_transform { { 1, 0, 0, 1, 0, 0 } } +{ } AffineTransform::AffineTransform(double a, double b, double c, double d, double e, double f) + : m_transform{ { a, b, c, d, e, f } } { - setMatrix(a, b, c, d, e, f); } +#endif void AffineTransform::makeIdentity() { @@ -79,21 +92,23 @@ double AffineTransform::yScale() const return sqrt(m_transform[2] * m_transform[2] + m_transform[3] * m_transform[3]); } -double AffineTransform::det() const +static double det(const std::array<double, 6>& transform) { - return m_transform[0] * m_transform[3] - m_transform[1] * m_transform[2]; + return transform[0] * transform[3] - transform[1] * transform[2]; } bool AffineTransform::isInvertible() const { - return det() != 0.0; + double determinant = det(m_transform); + + return std::isfinite(determinant) && determinant != 0; } -AffineTransform AffineTransform::inverse() const +std::optional<AffineTransform> AffineTransform::inverse() const { - double determinant = det(); - if (determinant == 0.0) - return AffineTransform(); + double determinant = det(m_transform); + if (!std::isfinite(determinant) || determinant == 0) + return std::nullopt; AffineTransform result; if (isIdentityOrTranslation()) { @@ -128,7 +143,7 @@ AffineTransform& AffineTransform::multiply(const AffineTransform& other) trans.m_transform[4] = other.m_transform[4] * m_transform[0] + other.m_transform[5] * m_transform[2] + m_transform[4]; trans.m_transform[5] = other.m_transform[4] * m_transform[1] + other.m_transform[5] * m_transform[3] + m_transform[5]; - setMatrix(trans.m_transform); + *this = trans; return *this; } @@ -158,6 +173,16 @@ AffineTransform& AffineTransform::scale(double sx, double sy) return *this; } +AffineTransform& AffineTransform::scaleNonUniform(double sx, double sy) +{ + return scale(sx, sy); +} + +AffineTransform& AffineTransform::scale(const FloatSize& s) +{ + return scale(s.width(), s.height()); +} + // *this = *this * translation AffineTransform& AffineTransform::translate(double tx, double ty) { @@ -172,9 +197,9 @@ AffineTransform& AffineTransform::translate(double tx, double ty) return *this; } -AffineTransform& AffineTransform::scaleNonUniform(double sx, double sy) +AffineTransform& AffineTransform::translate(const FloatPoint& t) { - return scale(sx, sy); + return translate(t.x(), t.y()); } AffineTransform& AffineTransform::rotateFromVector(double x, double y) @@ -401,4 +426,20 @@ void AffineTransform::recompose(const DecomposedType& decomp) this->scale(decomp.scaleX, decomp.scaleY); } +TextStream& operator<<(TextStream& ts, const AffineTransform& transform) +{ + if (transform.isIdentity()) + ts << "identity"; + else + ts << "{m=((" + << transform.a() << "," << transform.b() + << ")(" + << transform.c() << "," << transform.d() + << ")) t=(" + << transform.e() << "," << transform.f() + << ")}"; + + return ts; +} + } diff --git a/Source/WebCore/platform/graphics/transforms/AffineTransform.h b/Source/WebCore/platform/graphics/transforms/AffineTransform.h index 0a5b45732..a0b1f7bd3 100644 --- a/Source/WebCore/platform/graphics/transforms/AffineTransform.h +++ b/Source/WebCore/platform/graphics/transforms/AffineTransform.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2005-2016 Apple Inc. All rights reserved. * 2010 Dirk Schulze <krit@webkit.org> * * Redistribution and use in source and binary forms, with or without @@ -11,10 +11,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -27,8 +27,10 @@ #ifndef AffineTransform_h #define AffineTransform_h -#include <string.h> // for memcpy +#include "PlatformExportMacros.h" +#include <array> #include <wtf/FastMalloc.h> +#include <wtf/Optional.h> #if USE(CG) typedef struct CGAffineTransform CGAffineTransform; @@ -36,6 +38,11 @@ typedef struct CGAffineTransform CGAffineTransform; #include <cairo.h> #endif +#if PLATFORM(WIN) +struct D2D_MATRIX_3X2_F; +typedef D2D_MATRIX_3X2_F D2D1_MATRIX_3X2_F; +#endif + namespace WebCore { class FloatPoint; @@ -45,18 +52,21 @@ class FloatSize; class IntPoint; class IntSize; class IntRect; +class TextStream; class TransformationMatrix; class AffineTransform { WTF_MAKE_FAST_ALLOCATED; public: - typedef double Transform[6]; - - AffineTransform(); - AffineTransform(double a, double b, double c, double d, double e, double f); + WEBCORE_EXPORT AffineTransform(); + WEBCORE_EXPORT AffineTransform(double a, double b, double c, double d, double e, double f); #if USE(CG) - AffineTransform(const CGAffineTransform&); + WEBCORE_EXPORT AffineTransform(const CGAffineTransform&); +#endif + +#if PLATFORM(WIN) + AffineTransform(const D2D1_MATRIX_3X2_F&); #endif void setMatrix(double a, double b, double c, double d, double e, double f); @@ -64,22 +74,22 @@ public: void map(double x, double y, double& x2, double& y2) const; // Rounds the mapped point to the nearest integer value. - IntPoint mapPoint(const IntPoint&) const; + WEBCORE_EXPORT IntPoint mapPoint(const IntPoint&) const; - FloatPoint mapPoint(const FloatPoint&) const; + WEBCORE_EXPORT FloatPoint mapPoint(const FloatPoint&) const; - IntSize mapSize(const IntSize&) const; + WEBCORE_EXPORT IntSize mapSize(const IntSize&) const; - FloatSize mapSize(const FloatSize&) const; + WEBCORE_EXPORT FloatSize mapSize(const FloatSize&) const; // Rounds the resulting mapped rectangle out. This is helpful for bounding // box computations but may not be what is wanted in other contexts. - IntRect mapRect(const IntRect&) const; + WEBCORE_EXPORT IntRect mapRect(const IntRect&) const; - FloatRect mapRect(const FloatRect&) const; - FloatQuad mapQuad(const FloatQuad&) const; + WEBCORE_EXPORT FloatRect mapRect(const FloatRect&) const; + WEBCORE_EXPORT FloatQuad mapQuad(const FloatQuad&) const; - bool isIdentity() const; + WEBCORE_EXPORT bool isIdentity() const; double a() const { return m_transform[0]; } void setA(double a) { m_transform[0] = a; } @@ -94,34 +104,35 @@ public: double f() const { return m_transform[5]; } void setF(double f) { m_transform[5] = f; } - void makeIdentity(); + WEBCORE_EXPORT void makeIdentity(); - AffineTransform& multiply(const AffineTransform& other); - AffineTransform& scale(double); + WEBCORE_EXPORT AffineTransform& multiply(const AffineTransform& other); + WEBCORE_EXPORT AffineTransform& scale(double); AffineTransform& scale(double sx, double sy); - AffineTransform& scaleNonUniform(double sx, double sy); - AffineTransform& rotate(double d); + WEBCORE_EXPORT AffineTransform& scaleNonUniform(double sx, double sy); + WEBCORE_EXPORT AffineTransform& scale(const FloatSize&); + WEBCORE_EXPORT AffineTransform& rotate(double); AffineTransform& rotateFromVector(double x, double y); - AffineTransform& translate(double tx, double ty); - AffineTransform& shear(double sx, double sy); - AffineTransform& flipX(); - AffineTransform& flipY(); - AffineTransform& skew(double angleX, double angleY); + WEBCORE_EXPORT AffineTransform& translate(double tx, double ty); + WEBCORE_EXPORT AffineTransform& translate(const FloatPoint&); + WEBCORE_EXPORT AffineTransform& shear(double sx, double sy); + WEBCORE_EXPORT AffineTransform& flipX(); + WEBCORE_EXPORT AffineTransform& flipY(); + WEBCORE_EXPORT AffineTransform& skew(double angleX, double angleY); AffineTransform& skewX(double angle); AffineTransform& skewY(double angle); // These functions get the length of an axis-aligned unit vector // once it has been mapped through the transform - double xScale() const; - double yScale() const; + WEBCORE_EXPORT double xScale() const; + WEBCORE_EXPORT double yScale() const; - double det() const; - bool isInvertible() const; - AffineTransform inverse() const; + bool isInvertible() const; // If you call this this, you're probably doing it wrong. + WEBCORE_EXPORT std::optional<AffineTransform> inverse() const; - void blend(const AffineTransform& from, double progress); + WEBCORE_EXPORT void blend(const AffineTransform& from, double progress); - TransformationMatrix toTransformationMatrix() const; + WEBCORE_EXPORT TransformationMatrix toTransformationMatrix() const; bool isIdentityOrTranslation() const { @@ -165,16 +176,20 @@ public: } #if USE(CG) - operator CGAffineTransform() const; + WEBCORE_EXPORT operator CGAffineTransform() const; #elif USE(CAIRO) operator cairo_matrix_t() const; #endif +#if PLATFORM(WIN) + operator D2D1_MATRIX_3X2_F() const; +#endif + static AffineTransform translation(double x, double y) { return AffineTransform(1, 0, 0, 1, x, y); } - + // decompose the matrix into its component parts typedef struct { double scaleX, scaleY; @@ -187,16 +202,12 @@ public: void recompose(const DecomposedType&); private: - void setMatrix(const Transform m) - { - if (m && m != m_transform) - memcpy(m_transform, m, sizeof(Transform)); - } - - Transform m_transform; + std::array<double, 6> m_transform; }; -AffineTransform makeMapBetweenRects(const FloatRect& source, const FloatRect& dest); +WEBCORE_EXPORT AffineTransform makeMapBetweenRects(const FloatRect& source, const FloatRect& dest); + +WEBCORE_EXPORT TextStream& operator<<(TextStream&, const AffineTransform&); } diff --git a/Source/WebCore/platform/graphics/transforms/IdentityTransformOperation.h b/Source/WebCore/platform/graphics/transforms/IdentityTransformOperation.h index c1f7f4512..eed4c847b 100644 --- a/Source/WebCore/platform/graphics/transforms/IdentityTransformOperation.h +++ b/Source/WebCore/platform/graphics/transforms/IdentityTransformOperation.h @@ -26,36 +26,44 @@ #define IdentityTransformOperation_h #include "TransformOperation.h" +#include <wtf/Ref.h> namespace WebCore { -class IdentityTransformOperation : public TransformOperation { +class IdentityTransformOperation final : public TransformOperation { public: - static PassRefPtr<IdentityTransformOperation> create() + static Ref<IdentityTransformOperation> create() { - return adoptRef(new IdentityTransformOperation()); + return adoptRef(*new IdentityTransformOperation()); } - + + Ref<TransformOperation> clone() const override + { + return create(); + } + private: - virtual bool isIdentity() const { return true; } - virtual OperationType type() const { return IDENTITY; } - virtual bool isSameType(const TransformOperation& o) const { return o.type() == IDENTITY; } + bool isIdentity() const override { return true; } + OperationType type() const override { return IDENTITY; } + bool isSameType(const TransformOperation& o) const override { return o.type() == IDENTITY; } - virtual bool operator==(const TransformOperation& o) const + bool operator==(const TransformOperation& o) const override { return isSameType(o); } - virtual bool apply(TransformationMatrix&, const FloatSize&) const + bool apply(TransformationMatrix&, const FloatSize&) const override { return false; } - virtual PassRefPtr<TransformOperation> blend(const TransformOperation*, double, bool = false) + Ref<TransformOperation> blend(const TransformOperation*, double, bool = false) override { - return this; + return *this; } + void dump(TextStream&) const final; + IdentityTransformOperation() { } @@ -64,4 +72,6 @@ private: } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_TRANSFORMOPERATION(WebCore::IdentityTransformOperation, type() == WebCore::TransformOperation::IDENTITY) + #endif // IdentityTransformOperation_h diff --git a/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.cpp b/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.cpp index 443816f9e..c710f3981 100644 --- a/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.cpp +++ b/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.cpp @@ -13,7 +13,7 @@ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -26,14 +26,26 @@ #include "config.h" #include "Matrix3DTransformOperation.h" +#include "TextStream.h" #include <algorithm> namespace WebCore { -PassRefPtr<TransformOperation> Matrix3DTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) +bool Matrix3DTransformOperation::operator==(const TransformOperation& other) const +{ + return isSameType(other) && m_matrix == downcast<Matrix3DTransformOperation>(other).m_matrix; +} + +static Ref<TransformOperation> createOperation(TransformationMatrix& to, TransformationMatrix& from, double progress) +{ + to.blend(from, progress); + return Matrix3DTransformOperation::create(to); +} + +Ref<TransformOperation> Matrix3DTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) { if (from && !from->isSameType(*this)) - return this; + return *this; // Convert the TransformOperations into matrices FloatSize size; @@ -45,10 +57,13 @@ PassRefPtr<TransformOperation> Matrix3DTransformOperation::blend(const Transform apply(toT, size); if (blendToIdentity) - std::swap(fromT, toT); + return createOperation(fromT, toT, progress); + return createOperation(toT, fromT, progress); +} - toT.blend(fromT, progress); - return Matrix3DTransformOperation::create(toT); +void Matrix3DTransformOperation::dump(TextStream& ts) const +{ + ts << type() << "(" << m_matrix << ")"; } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h b/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h index 889c2b732..a30b0aa59 100644 --- a/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h +++ b/Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h @@ -13,7 +13,7 @@ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -27,40 +27,43 @@ #define Matrix3DTransformOperation_h #include "TransformOperation.h" +#include <wtf/Ref.h> namespace WebCore { -class Matrix3DTransformOperation : public TransformOperation { +class Matrix3DTransformOperation final : public TransformOperation { public: - static PassRefPtr<Matrix3DTransformOperation> create(const TransformationMatrix& matrix) + static Ref<Matrix3DTransformOperation> create(const TransformationMatrix& matrix) { - return adoptRef(new Matrix3DTransformOperation(matrix)); + return adoptRef(*new Matrix3DTransformOperation(matrix)); + } + + Ref<TransformOperation> clone() const override + { + return adoptRef(*new Matrix3DTransformOperation(m_matrix)); } TransformationMatrix matrix() const {return m_matrix; } private: - virtual bool isIdentity() const { return m_matrix.isIdentity(); } + bool isIdentity() const override { return m_matrix.isIdentity(); } + bool isAffectedByTransformOrigin() const override { return !isIdentity(); } - virtual OperationType type() const { return MATRIX_3D; } - virtual bool isSameType(const TransformOperation& o) const { return o.type() == MATRIX_3D; } + OperationType type() const override { return MATRIX_3D; } + bool isSameType(const TransformOperation& o) const override { return o.type() == MATRIX_3D; } - virtual bool operator==(const TransformOperation& o) const - { - if (!isSameType(o)) - return false; - const Matrix3DTransformOperation* m = static_cast<const Matrix3DTransformOperation*>(&o); - return m_matrix == m->m_matrix; - } + bool operator==(const TransformOperation&) const override; - virtual bool apply(TransformationMatrix& transform, const FloatSize&) const + bool apply(TransformationMatrix& transform, const FloatSize&) const override { - transform.multiply(TransformationMatrix(m_matrix)); + transform.multiply(m_matrix); return false; } - virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false); + Ref<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override; + void dump(TextStream&) const final; + Matrix3DTransformOperation(const TransformationMatrix& mat) { m_matrix = mat; @@ -71,4 +74,6 @@ private: } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_TRANSFORMOPERATION(WebCore::Matrix3DTransformOperation, type() == WebCore::TransformOperation::MATRIX_3D) + #endif // Matrix3DTransformOperation_h diff --git a/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp b/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp index a3658a91d..17860e4e1 100644 --- a/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp +++ b/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp @@ -22,29 +22,52 @@ #include "config.h" #include "MatrixTransformOperation.h" +#include "TextStream.h" #include <algorithm> namespace WebCore { -PassRefPtr<TransformOperation> MatrixTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) +bool MatrixTransformOperation::operator==(const TransformOperation& other) const +{ + if (!isSameType(other)) + return false; + const MatrixTransformOperation& m = downcast<MatrixTransformOperation>(other); + return m_a == m.m_a && m_b == m.m_b && m_c == m.m_c && m_d == m.m_d && m_e == m.m_e && m_f == m.m_f; +} + +static Ref<TransformOperation> createOperation(TransformationMatrix& to, TransformationMatrix& from, double progress) +{ + to.blend(from, progress); + return MatrixTransformOperation::create(to); +} + +Ref<TransformOperation> MatrixTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) { if (from && !from->isSameType(*this)) - return this; + return *this; // convert the TransformOperations into matrices - FloatSize size; TransformationMatrix fromT; TransformationMatrix toT(m_a, m_b, m_c, m_d, m_e, m_f); if (from) { - const MatrixTransformOperation* m = static_cast<const MatrixTransformOperation*>(from); - fromT.setMatrix(m->m_a, m->m_b, m->m_c, m->m_d, m->m_e, m->m_f); + const MatrixTransformOperation& m = downcast<MatrixTransformOperation>(*from); + fromT.setMatrix(m.m_a, m.m_b, m.m_c, m.m_d, m.m_e, m.m_f); } - + if (blendToIdentity) - std::swap(fromT, toT); + return createOperation(fromT, toT, progress); + return createOperation(toT, fromT, progress); +} - toT.blend(fromT, progress); - return MatrixTransformOperation::create(toT.a(), toT.b(), toT.c(), toT.d(), toT.e(), toT.f()); +void MatrixTransformOperation::dump(TextStream& ts) const +{ + ts << "(" + << TextStream::FormatNumberRespectingIntegers(m_a) << ", " + << TextStream::FormatNumberRespectingIntegers(m_b) << ", " + << TextStream::FormatNumberRespectingIntegers(m_c) << ", " + << TextStream::FormatNumberRespectingIntegers(m_d) << ", " + << TextStream::FormatNumberRespectingIntegers(m_e) << ", " + << TextStream::FormatNumberRespectingIntegers(m_f) << ")"; } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.h b/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.h index 76c5dffcd..3e88a9954 100644 --- a/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.h +++ b/Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.h @@ -27,47 +27,49 @@ #include "TransformOperation.h" #include "TransformationMatrix.h" +#include <wtf/Ref.h> namespace WebCore { -class MatrixTransformOperation : public TransformOperation { +class MatrixTransformOperation final : public TransformOperation { public: - static PassRefPtr<MatrixTransformOperation> create(double a, double b, double c, double d, double e, double f) + static Ref<MatrixTransformOperation> create(double a, double b, double c, double d, double e, double f) { - return adoptRef(new MatrixTransformOperation(a, b, c, d, e, f)); + return adoptRef(*new MatrixTransformOperation(a, b, c, d, e, f)); } - static PassRefPtr<MatrixTransformOperation> create(const TransformationMatrix& t) + static Ref<MatrixTransformOperation> create(const TransformationMatrix& t) { - return adoptRef(new MatrixTransformOperation(t)); + return adoptRef(*new MatrixTransformOperation(t)); + } + + Ref<TransformOperation> clone() const override + { + return adoptRef(*new MatrixTransformOperation(matrix())); } TransformationMatrix matrix() const { return TransformationMatrix(m_a, m_b, m_c, m_d, m_e, m_f); } private: - virtual bool isIdentity() const { return m_a == 1 && m_b == 0 && m_c == 0 && m_d == 1 && m_e == 0 && m_f == 0; } + bool isIdentity() const override { return m_a == 1 && m_b == 0 && m_c == 0 && m_d == 1 && m_e == 0 && m_f == 0; } + bool isAffectedByTransformOrigin() const override { return !isIdentity(); } - virtual OperationType type() const { return MATRIX; } - virtual bool isSameType(const TransformOperation& o) const { return o.type() == MATRIX; } - - virtual bool operator==(const TransformOperation& o) const - { - if (!isSameType(o)) - return false; + OperationType type() const override { return MATRIX; } + bool isSameType(const TransformOperation& o) const override { return o.type() == MATRIX; } - const MatrixTransformOperation* m = static_cast<const MatrixTransformOperation*>(&o); - return m_a == m->m_a && m_b == m->m_b && m_c == m->m_c && m_d == m->m_d && m_e == m->m_e && m_f == m->m_f; - } + bool operator==(const TransformOperation&) const override; - virtual bool apply(TransformationMatrix& transform, const FloatSize&) const + bool apply(TransformationMatrix& transform, const FloatSize&) const override { TransformationMatrix matrix(m_a, m_b, m_c, m_d, m_e, m_f); transform.multiply(matrix); return false; } - virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false); - + Ref<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override; + + void dump(TextStream&) const final; + MatrixTransformOperation(double a, double b, double c, double d, double e, double f) : m_a(a) , m_b(b) @@ -98,4 +100,6 @@ private: } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_TRANSFORMOPERATION(WebCore::MatrixTransformOperation, type() == WebCore::TransformOperation::MATRIX) + #endif // MatrixTransformOperation_h diff --git a/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp b/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp index a3ffb664c..a612aed6e 100644 --- a/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp +++ b/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp @@ -13,7 +13,7 @@ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -27,14 +27,22 @@ #include "PerspectiveTransformOperation.h" #include "AnimationUtilities.h" +#include "TextStream.h" #include <wtf/MathExtras.h> namespace WebCore { -PassRefPtr<TransformOperation> PerspectiveTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) +bool PerspectiveTransformOperation::operator==(const TransformOperation& other) const +{ + if (!isSameType(other)) + return false; + return m_p == downcast<PerspectiveTransformOperation>(other).m_p; +} + +Ref<TransformOperation> PerspectiveTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) { if (from && !from->isSameType(*this)) - return this; + return *this; if (blendToIdentity) { double p = floatValueForLength(m_p, 1); @@ -42,7 +50,7 @@ PassRefPtr<TransformOperation> PerspectiveTransformOperation::blend(const Transf return PerspectiveTransformOperation::create(Length(clampToPositiveInteger(p), Fixed)); } - const PerspectiveTransformOperation* fromOp = static_cast<const PerspectiveTransformOperation*>(from); + const PerspectiveTransformOperation* fromOp = downcast<PerspectiveTransformOperation>(from); Length fromP = fromOp ? fromOp->m_p : Length(m_p.type()); Length toP = m_p; @@ -61,4 +69,9 @@ PassRefPtr<TransformOperation> PerspectiveTransformOperation::blend(const Transf return PerspectiveTransformOperation::create(Length(0, Fixed)); } +void PerspectiveTransformOperation::dump(TextStream& ts) const +{ + ts << type() << "(" << m_p << ")"; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h b/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h index 73aa680ad..d9b20a561 100644 --- a/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h +++ b/Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h @@ -13,7 +13,7 @@ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -29,38 +29,42 @@ #include "Length.h" #include "LengthFunctions.h" #include "TransformOperation.h" +#include <wtf/Ref.h> namespace WebCore { -class PerspectiveTransformOperation : public TransformOperation { +class PerspectiveTransformOperation final : public TransformOperation { public: - static PassRefPtr<PerspectiveTransformOperation> create(const Length& p) + static Ref<PerspectiveTransformOperation> create(const Length& p) { - return adoptRef(new PerspectiveTransformOperation(p)); + return adoptRef(*new PerspectiveTransformOperation(p)); + } + + Ref<TransformOperation> clone() const override + { + return adoptRef(*new PerspectiveTransformOperation(m_p)); } Length perspective() const { return m_p; } private: - virtual bool isIdentity() const { return !floatValueForLength(m_p, 1); } - virtual OperationType type() const { return PERSPECTIVE; } - virtual bool isSameType(const TransformOperation& o) const { return o.type() == PERSPECTIVE; } + bool isIdentity() const override { return !floatValueForLength(m_p, 1); } + bool isAffectedByTransformOrigin() const override { return !isIdentity(); } - virtual bool operator==(const TransformOperation& o) const - { - if (!isSameType(o)) - return false; - const PerspectiveTransformOperation* p = static_cast<const PerspectiveTransformOperation*>(&o); - return m_p == p->m_p; - } + OperationType type() const override { return PERSPECTIVE; } + bool isSameType(const TransformOperation& o) const override { return o.type() == PERSPECTIVE; } + + bool operator==(const TransformOperation&) const override; - virtual bool apply(TransformationMatrix& transform, const FloatSize&) const + bool apply(TransformationMatrix& transform, const FloatSize&) const override { transform.applyPerspective(floatValueForLength(m_p, 1)); return false; } - virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false); + Ref<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override; + + void dump(TextStream&) const final; PerspectiveTransformOperation(const Length& p) : m_p(p) @@ -73,4 +77,6 @@ private: } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_TRANSFORMOPERATION(WebCore::PerspectiveTransformOperation, type() == WebCore::TransformOperation::PERSPECTIVE) + #endif // PerspectiveTransformOperation_h diff --git a/Source/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp b/Source/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp index 32b4c6e1c..52c3dbcc5 100644 --- a/Source/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp +++ b/Source/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp @@ -23,20 +23,29 @@ #include "RotateTransformOperation.h" #include "AnimationUtilities.h" +#include "TextStream.h" #include <algorithm> #include <wtf/MathExtras.h> namespace WebCore { -PassRefPtr<TransformOperation> RotateTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) +bool RotateTransformOperation::operator==(const TransformOperation& other) const +{ + if (!isSameType(other)) + return false; + const RotateTransformOperation& r = downcast<RotateTransformOperation>(other); + return m_x == r.m_x && m_y == r.m_y && m_z == r.m_z && m_angle == r.m_angle; +} + +Ref<TransformOperation> RotateTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) { if (from && !from->isSameType(*this)) - return this; + return *this; if (blendToIdentity) return RotateTransformOperation::create(m_x, m_y, m_z, m_angle - m_angle * progress, m_type); - const RotateTransformOperation* fromOp = static_cast<const RotateTransformOperation*>(from); + const RotateTransformOperation* fromOp = downcast<RotateTransformOperation>(from); // Optimize for single axis rotation if (!fromOp || (fromOp->m_x == 0 && fromOp->m_y == 0 && fromOp->m_z == 1) || @@ -91,4 +100,9 @@ PassRefPtr<TransformOperation> RotateTransformOperation::blend(const TransformOp return RotateTransformOperation::create(x, y, z, angle, ROTATE_3D); } +void RotateTransformOperation::dump(TextStream& ts) const +{ + ts << type() << "(" << TextStream::FormatNumberRespectingIntegers(m_x) << ", " << TextStream::FormatNumberRespectingIntegers(m_y) << ", " << TextStream::FormatNumberRespectingIntegers(m_z) << ", " << TextStream::FormatNumberRespectingIntegers(m_angle) << "deg)"; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/transforms/RotateTransformOperation.h b/Source/WebCore/platform/graphics/transforms/RotateTransformOperation.h index f47a51e17..be8c6e2f3 100644 --- a/Source/WebCore/platform/graphics/transforms/RotateTransformOperation.h +++ b/Source/WebCore/platform/graphics/transforms/RotateTransformOperation.h @@ -26,19 +26,25 @@ #define RotateTransformOperation_h #include "TransformOperation.h" +#include <wtf/Ref.h> namespace WebCore { -class RotateTransformOperation : public TransformOperation { +class RotateTransformOperation final : public TransformOperation { public: - static PassRefPtr<RotateTransformOperation> create(double angle, OperationType type) + static Ref<RotateTransformOperation> create(double angle, OperationType type) { - return adoptRef(new RotateTransformOperation(0, 0, 1, angle, type)); + return adoptRef(*new RotateTransformOperation(0, 0, 1, angle, type)); } - static PassRefPtr<RotateTransformOperation> create(double x, double y, double z, double angle, OperationType type) + static Ref<RotateTransformOperation> create(double x, double y, double z, double angle, OperationType type) { - return adoptRef(new RotateTransformOperation(x, y, z, angle, type)); + return adoptRef(*new RotateTransformOperation(x, y, z, angle, type)); + } + + Ref<TransformOperation> clone() const override + { + return adoptRef(*new RotateTransformOperation(m_x, m_y, m_z, m_angle, m_type)); } double x() const { return m_x; } @@ -47,26 +53,23 @@ public: double angle() const { return m_angle; } private: - virtual bool isIdentity() const { return m_angle == 0; } + bool isIdentity() const override { return m_angle == 0; } + bool isAffectedByTransformOrigin() const override { return !isIdentity(); } - virtual OperationType type() const { return m_type; } - virtual bool isSameType(const TransformOperation& o) const { return o.type() == m_type; } + OperationType type() const override { return m_type; } + bool isSameType(const TransformOperation& o) const override { return o.type() == m_type; } - virtual bool operator==(const TransformOperation& o) const - { - if (!isSameType(o)) - return false; - const RotateTransformOperation* r = static_cast<const RotateTransformOperation*>(&o); - return m_x == r->m_x && m_y == r->m_y && m_z == r->m_z && m_angle == r->m_angle; - } + bool operator==(const TransformOperation&) const override; - virtual bool apply(TransformationMatrix& transform, const FloatSize& /*borderBoxSize*/) const + bool apply(TransformationMatrix& transform, const FloatSize& /*borderBoxSize*/) const override { transform.rotate3d(m_x, m_y, m_z, m_angle); return false; } - virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false); + Ref<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override; + + void dump(TextStream&) const final; RotateTransformOperation(double x, double y, double z, double angle, OperationType type) : m_x(x) @@ -75,7 +78,7 @@ private: , m_angle(angle) , m_type(type) { - ASSERT(type == ROTATE_X || type == ROTATE_Y || type == ROTATE_Z || type == ROTATE_3D); + ASSERT(isRotateTransformOperationType()); } double m_x; @@ -87,4 +90,6 @@ private: } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_TRANSFORMOPERATION(WebCore::RotateTransformOperation, isRotateTransformOperationType()) + #endif // RotateTransformOperation_h diff --git a/Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp b/Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp index e8806f203..862eafe15 100644 --- a/Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp +++ b/Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp @@ -23,20 +23,29 @@ #include "ScaleTransformOperation.h" #include "AnimationUtilities.h" +#include "TextStream.h" namespace WebCore { -PassRefPtr<TransformOperation> ScaleTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) +bool ScaleTransformOperation::operator==(const TransformOperation& other) const +{ + if (!isSameType(other)) + return false; + const ScaleTransformOperation& s = downcast<ScaleTransformOperation>(other); + return m_x == s.m_x && m_y == s.m_y && m_z == s.m_z; +} + +Ref<TransformOperation> ScaleTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) { if (from && !from->isSameType(*this)) - return this; + return *this; if (blendToIdentity) return ScaleTransformOperation::create(WebCore::blend(m_x, 1.0, progress), WebCore::blend(m_y, 1.0, progress), WebCore::blend(m_z, 1.0, progress), m_type); - const ScaleTransformOperation* fromOp = static_cast<const ScaleTransformOperation*>(from); + const ScaleTransformOperation* fromOp = downcast<ScaleTransformOperation>(from); double fromX = fromOp ? fromOp->m_x : 1.0; double fromY = fromOp ? fromOp->m_y : 1.0; double fromZ = fromOp ? fromOp->m_z : 1.0; @@ -45,4 +54,9 @@ PassRefPtr<TransformOperation> ScaleTransformOperation::blend(const TransformOpe WebCore::blend(fromZ, m_z, progress), m_type); } +void ScaleTransformOperation::dump(TextStream& ts) const +{ + ts << type() << "(" << TextStream::FormatNumberRespectingIntegers(m_x) << ", " << TextStream::FormatNumberRespectingIntegers(m_y) << ", " << TextStream::FormatNumberRespectingIntegers(m_z) << ")"; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.h b/Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.h index 62beb23ce..ae8a55556 100644 --- a/Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.h +++ b/Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.h @@ -26,19 +26,25 @@ #define ScaleTransformOperation_h #include "TransformOperation.h" +#include <wtf/Ref.h> namespace WebCore { -class ScaleTransformOperation : public TransformOperation { +class ScaleTransformOperation final : public TransformOperation { public: - static PassRefPtr<ScaleTransformOperation> create(double sx, double sy, OperationType type) + static Ref<ScaleTransformOperation> create(double sx, double sy, OperationType type) { - return adoptRef(new ScaleTransformOperation(sx, sy, 1, type)); + return adoptRef(*new ScaleTransformOperation(sx, sy, 1, type)); } - static PassRefPtr<ScaleTransformOperation> create(double sx, double sy, double sz, OperationType type) + static Ref<ScaleTransformOperation> create(double sx, double sy, double sz, OperationType type) { - return adoptRef(new ScaleTransformOperation(sx, sy, sz, type)); + return adoptRef(*new ScaleTransformOperation(sx, sy, sz, type)); + } + + Ref<TransformOperation> clone() const override + { + return adoptRef(*new ScaleTransformOperation(m_x, m_y, m_z, m_type)); } double x() const { return m_x; } @@ -46,26 +52,23 @@ public: double z() const { return m_z; } private: - virtual bool isIdentity() const { return m_x == 1 && m_y == 1 && m_z == 1; } + bool isIdentity() const override { return m_x == 1 && m_y == 1 && m_z == 1; } + bool isAffectedByTransformOrigin() const override { return !isIdentity(); } - virtual OperationType type() const { return m_type; } - virtual bool isSameType(const TransformOperation& o) const { return o.type() == m_type; } + OperationType type() const override { return m_type; } + bool isSameType(const TransformOperation& o) const override { return o.type() == m_type; } - virtual bool operator==(const TransformOperation& o) const - { - if (!isSameType(o)) - return false; - const ScaleTransformOperation* s = static_cast<const ScaleTransformOperation*>(&o); - return m_x == s->m_x && m_y == s->m_y && m_z == s->m_z; - } + bool operator==(const TransformOperation&) const override; - virtual bool apply(TransformationMatrix& transform, const FloatSize&) const + bool apply(TransformationMatrix& transform, const FloatSize&) const override { transform.scale3d(m_x, m_y, m_z); return false; } - virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false); + Ref<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override; + + void dump(TextStream&) const final; ScaleTransformOperation(double sx, double sy, double sz, OperationType type) : m_x(sx) @@ -73,7 +76,7 @@ private: , m_z(sz) , m_type(type) { - ASSERT(type == SCALE_X || type == SCALE_Y || type == SCALE_Z || type == SCALE || type == SCALE_3D); + ASSERT(isScaleTransformOperationType()); } double m_x; @@ -84,4 +87,6 @@ private: } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_TRANSFORMOPERATION(WebCore::ScaleTransformOperation, isScaleTransformOperationType()) + #endif // ScaleTransformOperation_h diff --git a/Source/WebCore/platform/graphics/transforms/SkewTransformOperation.cpp b/Source/WebCore/platform/graphics/transforms/SkewTransformOperation.cpp index d92d895ce..ec52112ef 100644 --- a/Source/WebCore/platform/graphics/transforms/SkewTransformOperation.cpp +++ b/Source/WebCore/platform/graphics/transforms/SkewTransformOperation.cpp @@ -23,21 +23,35 @@ #include "SkewTransformOperation.h" #include "AnimationUtilities.h" +#include "TextStream.h" namespace WebCore { -PassRefPtr<TransformOperation> SkewTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) +bool SkewTransformOperation::operator==(const TransformOperation& other) const +{ + if (!isSameType(other)) + return false; + const SkewTransformOperation& s = downcast<SkewTransformOperation>(other); + return m_angleX == s.m_angleX && m_angleY == s.m_angleY; +} + +Ref<TransformOperation> SkewTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) { if (from && !from->isSameType(*this)) - return this; + return *this; if (blendToIdentity) return SkewTransformOperation::create(WebCore::blend(m_angleX, 0.0, progress), WebCore::blend(m_angleY, 0.0, progress), m_type); - const SkewTransformOperation* fromOp = static_cast<const SkewTransformOperation*>(from); + const SkewTransformOperation* fromOp = downcast<SkewTransformOperation>(from); double fromAngleX = fromOp ? fromOp->m_angleX : 0; double fromAngleY = fromOp ? fromOp->m_angleY : 0; return SkewTransformOperation::create(WebCore::blend(fromAngleX, m_angleX, progress), WebCore::blend(fromAngleY, m_angleY, progress), m_type); } +void SkewTransformOperation::dump(TextStream& ts) const +{ + ts << type() << "(" << TextStream::FormatNumberRespectingIntegers(m_angleX) << "deg, " << TextStream::FormatNumberRespectingIntegers(m_angleY) << "deg)"; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/transforms/SkewTransformOperation.h b/Source/WebCore/platform/graphics/transforms/SkewTransformOperation.h index e9f0c819b..422d14b6a 100644 --- a/Source/WebCore/platform/graphics/transforms/SkewTransformOperation.h +++ b/Source/WebCore/platform/graphics/transforms/SkewTransformOperation.h @@ -26,45 +26,50 @@ #define SkewTransformOperation_h #include "TransformOperation.h" +#include <wtf/Ref.h> namespace WebCore { -class SkewTransformOperation : public TransformOperation { +class SkewTransformOperation final : public TransformOperation { public: - static PassRefPtr<SkewTransformOperation> create(double angleX, double angleY, OperationType type) + static Ref<SkewTransformOperation> create(double angleX, double angleY, OperationType type) { - return adoptRef(new SkewTransformOperation(angleX, angleY, type)); + return adoptRef(*new SkewTransformOperation(angleX, angleY, type)); + } + + Ref<TransformOperation> clone() const override + { + return adoptRef(*new SkewTransformOperation(m_angleX, m_angleY, m_type)); } double angleX() const { return m_angleX; } double angleY() const { return m_angleY; } private: - virtual bool isIdentity() const { return m_angleX == 0 && m_angleY == 0; } - virtual OperationType type() const { return m_type; } - virtual bool isSameType(const TransformOperation& o) const { return o.type() == m_type; } + bool isIdentity() const override { return m_angleX == 0 && m_angleY == 0; } + bool isAffectedByTransformOrigin() const override { return !isIdentity(); } - virtual bool operator==(const TransformOperation& o) const - { - if (!isSameType(o)) - return false; - const SkewTransformOperation* s = static_cast<const SkewTransformOperation*>(&o); - return m_angleX == s->m_angleX && m_angleY == s->m_angleY; - } + OperationType type() const override { return m_type; } + bool isSameType(const TransformOperation& o) const override { return o.type() == m_type; } + + bool operator==(const TransformOperation&) const override; - virtual bool apply(TransformationMatrix& transform, const FloatSize&) const + bool apply(TransformationMatrix& transform, const FloatSize&) const override { transform.skew(m_angleX, m_angleY); return false; } - virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false); + Ref<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override; + + void dump(TextStream&) const final; SkewTransformOperation(double angleX, double angleY, OperationType type) : m_angleX(angleX) , m_angleY(angleY) , m_type(type) { + ASSERT(isSkewTransformOperationType()); } double m_angleX; @@ -74,4 +79,6 @@ private: } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_TRANSFORMOPERATION(WebCore::SkewTransformOperation, isSkewTransformOperationType()) + #endif // SkewTransformOperation_h diff --git a/Source/WebCore/platform/graphics/transforms/TransformOperation.cpp b/Source/WebCore/platform/graphics/transforms/TransformOperation.cpp new file mode 100644 index 000000000..2ec90c12a --- /dev/null +++ b/Source/WebCore/platform/graphics/transforms/TransformOperation.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "TransformOperation.h" + +#include "IdentityTransformOperation.h" +#include "TextStream.h" + +namespace WebCore { + +void IdentityTransformOperation::dump(TextStream& ts) const +{ + ts << type(); +} + +TextStream& operator<<(TextStream& ts, TransformOperation::OperationType type) +{ + switch (type) { + case TransformOperation::SCALE_X: ts << "scaleX"; break; + case TransformOperation::SCALE_Y: ts << "scaleY"; break; + case TransformOperation::SCALE: ts << "scale"; break; + case TransformOperation::TRANSLATE_X: ts << "translateX"; break; + case TransformOperation::TRANSLATE_Y: ts << "translateY"; break; + case TransformOperation::TRANSLATE: ts << "translate"; break; + case TransformOperation::ROTATE: ts << "rotate"; break; + case TransformOperation::SKEW_X: ts << "skewX"; break; + case TransformOperation::SKEW_Y: ts << "skewY"; break; + case TransformOperation::SKEW: ts << "skew"; break; + case TransformOperation::MATRIX: ts << "matrix"; break; + case TransformOperation::SCALE_Z: ts << "scaleX"; break; + case TransformOperation::SCALE_3D: ts << "scale3d"; break; + case TransformOperation::TRANSLATE_Z: ts << "translateZ"; break; + case TransformOperation::TRANSLATE_3D: ts << "translate3d"; break; + case TransformOperation::ROTATE_X: ts << "rotateX"; break; + case TransformOperation::ROTATE_Y: ts << "rotateY"; break; + case TransformOperation::ROTATE_3D: ts << "rotate3d"; break; + case TransformOperation::MATRIX_3D: ts << "matrix3d"; break; + case TransformOperation::PERSPECTIVE: ts << "perspective"; break; + case TransformOperation::IDENTITY: ts << "identity"; break; + case TransformOperation::NONE: ts << "none"; break; + } + + return ts; +} + +TextStream& operator<<(TextStream& ts, const TransformOperation& operation) +{ + operation.dump(ts); + return ts; +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/transforms/TransformOperation.h b/Source/WebCore/platform/graphics/transforms/TransformOperation.h index f9f975fa4..4f6aa88da 100644 --- a/Source/WebCore/platform/graphics/transforms/TransformOperation.h +++ b/Source/WebCore/platform/graphics/transforms/TransformOperation.h @@ -27,8 +27,9 @@ #include "FloatSize.h" #include "TransformationMatrix.h" -#include <wtf/PassRefPtr.h> +#include <wtf/Forward.h> #include <wtf/RefCounted.h> +#include <wtf/TypeCasts.h> namespace WebCore { @@ -53,6 +54,8 @@ public: virtual ~TransformOperation() { } + virtual Ref<TransformOperation> clone() const = 0; + virtual bool operator==(const TransformOperation&) const = 0; bool operator!=(const TransformOperation& o) const { return !(*this == o); } @@ -61,10 +64,12 @@ public: // Return true if the borderBoxSize was used in the computation, false otherwise. virtual bool apply(TransformationMatrix&, const FloatSize& borderBoxSize) const = 0; - virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) = 0; + virtual Ref<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) = 0; virtual OperationType type() const = 0; virtual bool isSameType(const TransformOperation&) const { return false; } + + virtual bool isAffectedByTransformOrigin() const { return false; } bool is3DOperation() const { @@ -79,8 +84,38 @@ public: opType == MATRIX_3D || opType == PERSPECTIVE; } + + bool isRotateTransformOperationType() const + { + return type() == ROTATE_X || type() == ROTATE_Y || type() == ROTATE_Z || type() == ROTATE || type() == ROTATE_3D; + } + + bool isScaleTransformOperationType() const + { + return type() == SCALE_X || type() == SCALE_Y || type() == SCALE_Z || type() == SCALE || type() == SCALE_3D; + } + + bool isSkewTransformOperationType() const + { + return type() == SKEW_X || type() == SKEW_Y || type() == SKEW; + } + + bool isTranslateTransformOperationType() const + { + return type() == TRANSLATE_X || type() == TRANSLATE_Y || type() == TRANSLATE_Z || type() == TRANSLATE || type() == TRANSLATE_3D; + } + + virtual void dump(TextStream&) const = 0; }; +TextStream& operator<<(TextStream&, TransformOperation::OperationType); +TextStream& operator<<(TextStream&, const TransformOperation&); + } // namespace WebCore +#define SPECIALIZE_TYPE_TRAITS_TRANSFORMOPERATION(ToValueTypeName, predicate) \ +SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \ + static bool isType(const WebCore::TransformOperation& operation) { return operation.predicate; } \ +SPECIALIZE_TYPE_TRAITS_END() + #endif // TransformOperation_h diff --git a/Source/WebCore/platform/graphics/transforms/TransformOperations.cpp b/Source/WebCore/platform/graphics/transforms/TransformOperations.cpp index a71de471a..9b156bd3d 100644 --- a/Source/WebCore/platform/graphics/transforms/TransformOperations.cpp +++ b/Source/WebCore/platform/graphics/transforms/TransformOperations.cpp @@ -24,6 +24,7 @@ #include "IdentityTransformOperation.h" #include "Matrix3DTransformOperation.h" +#include "TextStream.h" #include <algorithm> namespace WebCore { @@ -63,6 +64,15 @@ bool TransformOperations::operationsMatch(const TransformOperations& other) cons return true; } +bool TransformOperations::affectedByTransformOrigin() const +{ + for (const auto& operation : m_operations) { + if (operation->isAffectedByTransformOrigin()) + return true; + } + return false; +} + TransformOperations TransformOperations::blendByMatchingOperations(const TransformOperations& from, const double& progress) const { TransformOperations result; @@ -71,9 +81,9 @@ TransformOperations TransformOperations::blendByMatchingOperations(const Transfo unsigned toSize = operations().size(); unsigned size = std::max(fromSize, toSize); for (unsigned i = 0; i < size; i++) { - RefPtr<TransformOperation> fromOperation = (i < fromSize) ? from.operations()[i].get() : 0; - RefPtr<TransformOperation> toOperation = (i < toSize) ? operations()[i].get() : 0; - RefPtr<TransformOperation> blendedOperation = toOperation ? toOperation->blend(fromOperation.get(), progress) : (fromOperation ? fromOperation->blend(0, progress, true) : 0); + RefPtr<TransformOperation> fromOperation = (i < fromSize) ? from.operations()[i].get() : nullptr; + RefPtr<TransformOperation> toOperation = (i < toSize) ? operations()[i].get() : nullptr; + RefPtr<TransformOperation> blendedOperation = toOperation ? toOperation->blend(fromOperation.get(), progress) : (fromOperation ? RefPtr<TransformOperation>(fromOperation->blend(nullptr, progress, true)) : nullptr); if (blendedOperation) result.operations().append(blendedOperation); else { @@ -117,4 +127,11 @@ TransformOperations TransformOperations::blend(const TransformOperations& from, return blendByUsingMatrixInterpolation(from, progress, size); } +TextStream& operator<<(TextStream& ts, const TransformOperations& ops) +{ + for (const auto& operation : ops.operations()) + ts << *operation; + return ts; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/transforms/TransformOperations.h b/Source/WebCore/platform/graphics/transforms/TransformOperations.h index 96045d3f9..3e1d08e0e 100644 --- a/Source/WebCore/platform/graphics/transforms/TransformOperations.h +++ b/Source/WebCore/platform/graphics/transforms/TransformOperations.h @@ -65,6 +65,8 @@ public: { m_operations.clear(); } + + bool affectedByTransformOrigin() const; Vector<RefPtr<TransformOperation>>& operations() { return m_operations; } const Vector<RefPtr<TransformOperation>>& operations() const { return m_operations; } @@ -80,6 +82,8 @@ private: Vector<RefPtr<TransformOperation>> m_operations; }; +TextStream& operator<<(TextStream&, const TransformOperations&); + } // namespace WebCore #endif // TransformOperations_h diff --git a/Source/WebCore/platform/graphics/transforms/TransformState.cpp b/Source/WebCore/platform/graphics/transforms/TransformState.cpp index 541b1c648..5ef0e5bf4 100644 --- a/Source/WebCore/platform/graphics/transforms/TransformState.cpp +++ b/Source/WebCore/platform/graphics/transforms/TransformState.cpp @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -26,8 +26,6 @@ #include "config.h" #include "TransformState.h" -#include <wtf/PassOwnPtr.h> - namespace WebCore { TransformState& TransformState::operator=(const TransformState& other) @@ -37,15 +35,20 @@ TransformState& TransformState::operator=(const TransformState& other) m_mapQuad = other.m_mapQuad; if (m_mapPoint) m_lastPlanarPoint = other.m_lastPlanarPoint; - if (m_mapQuad) + if (m_mapQuad) { m_lastPlanarQuad = other.m_lastPlanarQuad; + if (other.m_lastPlanarSecondaryQuad) + m_lastPlanarSecondaryQuad = std::make_unique<FloatQuad>(*other.m_lastPlanarSecondaryQuad); + else + m_lastPlanarSecondaryQuad = nullptr; + } m_accumulatingTransform = other.m_accumulatingTransform; m_direction = other.m_direction; - m_accumulatedTransform.clear(); + m_accumulatedTransform = nullptr; if (other.m_accumulatedTransform) - m_accumulatedTransform = adoptPtr(new TransformationMatrix(*other.m_accumulatedTransform)); + m_accumulatedTransform = std::make_unique<TransformationMatrix>(*other.m_accumulatedTransform); return *this; } @@ -63,8 +66,11 @@ void TransformState::translateMappedCoordinates(const LayoutSize& offset) LayoutSize adjustedOffset = (m_direction == ApplyTransformDirection) ? offset : -offset; if (m_mapPoint) m_lastPlanarPoint.move(adjustedOffset); - if (m_mapQuad) + if (m_mapQuad) { m_lastPlanarQuad.move(adjustedOffset); + if (m_lastPlanarSecondaryQuad) + m_lastPlanarSecondaryQuad->move(adjustedOffset); + } } void TransformState::move(const LayoutSize& offset, TransformAccumulation accumulate) @@ -121,12 +127,12 @@ void TransformState::applyTransform(const TransformationMatrix& transformFromCon // If we have an accumulated transform from last time, multiply in this transform if (m_accumulatedTransform) { if (m_direction == ApplyTransformDirection) - m_accumulatedTransform = adoptPtr(new TransformationMatrix(transformFromContainer * *m_accumulatedTransform)); + m_accumulatedTransform = std::make_unique<TransformationMatrix>(transformFromContainer * *m_accumulatedTransform); else m_accumulatedTransform->multiply(transformFromContainer); } else if (accumulate == AccumulateTransform) { // Make one if we started to accumulate - m_accumulatedTransform = adoptPtr(new TransformationMatrix(transformFromContainer)); + m_accumulatedTransform = std::make_unique<TransformationMatrix>(transformFromContainer); } if (accumulate == FlattenTransform) { @@ -164,7 +170,7 @@ FloatPoint TransformState::mappedPoint(bool* wasClamped) const if (m_direction == ApplyTransformDirection) return m_accumulatedTransform->mapPoint(point); - return m_accumulatedTransform->inverse().projectPoint(point, wasClamped); + return m_accumulatedTransform->inverse().value_or(TransformationMatrix()).projectPoint(point, wasClamped); } FloatQuad TransformState::mappedQuad(bool* wasClamped) const @@ -173,14 +179,46 @@ FloatQuad TransformState::mappedQuad(bool* wasClamped) const *wasClamped = false; FloatQuad quad = m_lastPlanarQuad; - quad.move((m_direction == ApplyTransformDirection) ? m_accumulatedOffset : -m_accumulatedOffset); + mapQuad(quad, m_direction, wasClamped); + return quad; +} + +std::optional<FloatQuad> TransformState::mappedSecondaryQuad(bool* wasClamped) const +{ + if (wasClamped) + *wasClamped = false; + + if (!m_lastPlanarSecondaryQuad) + return std::optional<FloatQuad>(); + + FloatQuad quad = *m_lastPlanarSecondaryQuad; + mapQuad(quad, m_direction, wasClamped); + return quad; +} + +void TransformState::setLastPlanarSecondaryQuad(const FloatQuad* quad) +{ + if (!quad) { + m_lastPlanarSecondaryQuad = nullptr; + return; + } + + // Map the quad back through any transform or offset back into the last flattening coordinate space. + FloatQuad backMappedQuad(*quad); + mapQuad(backMappedQuad, inverseDirection()); + m_lastPlanarSecondaryQuad = std::make_unique<FloatQuad>(backMappedQuad); +} + +void TransformState::mapQuad(FloatQuad& quad, TransformDirection direction, bool* wasClamped) const +{ + quad.move((direction == ApplyTransformDirection) ? m_accumulatedOffset : -m_accumulatedOffset); if (!m_accumulatedTransform) - return quad; + return; - if (m_direction == ApplyTransformDirection) - return m_accumulatedTransform->mapQuad(quad); + if (direction == ApplyTransformDirection) + quad = m_accumulatedTransform->mapQuad(quad); - return m_accumulatedTransform->inverse().projectQuad(quad, wasClamped); + quad = m_accumulatedTransform->inverse().value_or(TransformationMatrix()).projectQuad(quad, wasClamped); } void TransformState::flattenWithTransform(const TransformationMatrix& t, bool* wasClamped) @@ -188,14 +226,21 @@ void TransformState::flattenWithTransform(const TransformationMatrix& t, bool* w if (m_direction == ApplyTransformDirection) { if (m_mapPoint) m_lastPlanarPoint = t.mapPoint(m_lastPlanarPoint); - if (m_mapQuad) + if (m_mapQuad) { m_lastPlanarQuad = t.mapQuad(m_lastPlanarQuad); + if (m_lastPlanarSecondaryQuad) + *m_lastPlanarSecondaryQuad = t.mapQuad(*m_lastPlanarSecondaryQuad); + } + } else { - TransformationMatrix inverseTransform = t.inverse(); + TransformationMatrix inverseTransform = t.inverse().value_or(TransformationMatrix()); if (m_mapPoint) m_lastPlanarPoint = inverseTransform.projectPoint(m_lastPlanarPoint); - if (m_mapQuad) + if (m_mapQuad) { m_lastPlanarQuad = inverseTransform.projectQuad(m_lastPlanarQuad, wasClamped); + if (m_lastPlanarSecondaryQuad) + *m_lastPlanarSecondaryQuad = inverseTransform.projectQuad(*m_lastPlanarSecondaryQuad, wasClamped); + } } // We could throw away m_accumulatedTransform if we wanted to here, but that diff --git a/Source/WebCore/platform/graphics/transforms/TransformState.h b/Source/WebCore/platform/graphics/transforms/TransformState.h index 874177b5d..cd955abf4 100644 --- a/Source/WebCore/platform/graphics/transforms/TransformState.h +++ b/Source/WebCore/platform/graphics/transforms/TransformState.h @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -32,7 +32,7 @@ #include "IntSize.h" #include "LayoutSize.h" #include "TransformationMatrix.h" -#include <wtf/OwnPtr.h> +#include <wtf/Optional.h> namespace WebCore { @@ -75,30 +75,45 @@ public: void setQuad(const FloatQuad& quad) { - // FIXME: this assumes that the quad being added is in the coordinate system of the current state. - // This breaks if we're simultaneously mapping a point. https://bugs.webkit.org/show_bug.cgi?id=106680 - ASSERT(!m_mapPoint); - m_accumulatedOffset = LayoutSize(); + // We must be in a flattened state (no accumulated offset) when setting this quad. + ASSERT(m_accumulatedOffset == LayoutSize()); m_lastPlanarQuad = quad; } + // FIXME: webkit.org/b/144226 use std::optional<FloatQuad>. + void setSecondaryQuad(const FloatQuad* quad) + { + // We must be in a flattened state (no accumulated offset) when setting this secondary quad. + ASSERT(m_accumulatedOffset == LayoutSize()); + if (quad) + m_lastPlanarSecondaryQuad = std::make_unique<FloatQuad>(*quad); + else + m_lastPlanarSecondaryQuad = nullptr; + } + + // FIXME: webkit.org/b/144226 use std::optional<FloatQuad>. + void setLastPlanarSecondaryQuad(const FloatQuad*); + void move(LayoutUnit x, LayoutUnit y, TransformAccumulation accumulate = FlattenTransform) { move(LayoutSize(x, y), accumulate); } void move(const LayoutSize&, TransformAccumulation = FlattenTransform); - void applyTransform(const AffineTransform& transformFromContainer, TransformAccumulation = FlattenTransform, bool* wasClamped = 0); - void applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation = FlattenTransform, bool* wasClamped = 0); - void flatten(bool* wasClamped = 0); + void applyTransform(const AffineTransform& transformFromContainer, TransformAccumulation = FlattenTransform, bool* wasClamped = nullptr); + void applyTransform(const TransformationMatrix& transformFromContainer, TransformAccumulation = FlattenTransform, bool* wasClamped = nullptr); + void flatten(bool* wasClamped = nullptr); // Return the coords of the point or quad in the last flattened layer FloatPoint lastPlanarPoint() const { return m_lastPlanarPoint; } FloatQuad lastPlanarQuad() const { return m_lastPlanarQuad; } + FloatQuad* lastPlanarSecondaryQuad() const { return m_lastPlanarSecondaryQuad.get(); } + bool isMappingSecondaryQuad() const { return m_lastPlanarSecondaryQuad.get(); } // Return the point or quad mapped through the current transform - FloatPoint mappedPoint(bool* wasClamped = 0) const; - FloatQuad mappedQuad(bool* wasClamped = 0) const; + FloatPoint mappedPoint(bool* wasClamped = nullptr) const; + FloatQuad mappedQuad(bool* wasClamped = nullptr) const; + std::optional<FloatQuad> mappedSecondaryQuad(bool* wasClamped = nullptr) const; private: void translateTransform(const LayoutSize&); @@ -106,17 +121,29 @@ private: void flattenWithTransform(const TransformationMatrix&, bool* wasClamped); void applyAccumulatedOffset(); + TransformDirection direction() const { return m_direction; } + TransformDirection inverseDirection() const; + + void mapQuad(FloatQuad&, TransformDirection, bool* clamped = nullptr) const; + FloatPoint m_lastPlanarPoint; FloatQuad m_lastPlanarQuad; + std::unique_ptr<FloatQuad> m_lastPlanarSecondaryQuad; // Optional second quad to map. // We only allocate the transform if we need to - OwnPtr<TransformationMatrix> m_accumulatedTransform; + std::unique_ptr<TransformationMatrix> m_accumulatedTransform; LayoutSize m_accumulatedOffset; bool m_accumulatingTransform; - bool m_mapPoint, m_mapQuad; + bool m_mapPoint; + bool m_mapQuad; TransformDirection m_direction; }; +inline TransformState::TransformDirection TransformState::inverseDirection() const +{ + return m_direction == ApplyTransformDirection ? UnapplyInverseTransformDirection : ApplyTransformDirection; +} + } // namespace WebCore #endif // TransformState_h diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp index c5066668d..2427b01c1 100644 --- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp +++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006, 2013 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2013 Apple Inc. All rights reserved. * Copyright (C) 2009 Torch Mobile, Inc. * * Redistribution and use in source and binary forms, with or without @@ -11,10 +11,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -32,7 +32,7 @@ #include "FloatQuad.h" #include "IntRect.h" #include "LayoutRect.h" - +#include "TextStream.h" #include <wtf/Assertions.h> #include <wtf/MathExtras.h> @@ -1445,7 +1445,7 @@ bool TransformationMatrix::isInvertible() const return true; } -TransformationMatrix TransformationMatrix::inverse() const +std::optional<TransformationMatrix> TransformationMatrix::inverse() const { if (isIdentityOrTranslation()) { // identity matrix @@ -1460,9 +1460,10 @@ TransformationMatrix TransformationMatrix::inverse() const } TransformationMatrix invMat; - bool inverted = WebCore::inverse(m_matrix, invMat.m_matrix); - if (!inverted) - return TransformationMatrix(); + // FIXME: Use LU decomposition to apply the inverse instead of calculating the inverse explicitly. + // Calculating the inverse of a 4x4 matrix using cofactors is numerically unstable and unnecessary to apply the inverse transformation to a point. + if (!WebCore::inverse(m_matrix, invMat.m_matrix)) + return std::nullopt; return invMat; } @@ -1500,8 +1501,11 @@ void TransformationMatrix::blend2(const TransformationMatrix& from, double progr { Decomposed2Type fromDecomp; Decomposed2Type toDecomp; - from.decompose2(fromDecomp); - decompose2(toDecomp); + if (!from.decompose2(fromDecomp) || !decompose2(toDecomp)) { + if (progress < 0.5) + *this = from; + return; + } // If x-axis of one is flipped, and y-axis of the other, convert to an unflipped rotation. if ((fromDecomp.scaleX < 0 && toDecomp.scaleY < 0) || (fromDecomp.scaleY < 0 && toDecomp.scaleX < 0)) { @@ -1540,8 +1544,11 @@ void TransformationMatrix::blend4(const TransformationMatrix& from, double progr { Decomposed4Type fromDecomp; Decomposed4Type toDecomp; - from.decompose4(fromDecomp); - decompose4(toDecomp); + if (!from.decompose4(fromDecomp) || !decompose4(toDecomp)) { + if (progress < 0.5) + *this = from; + return; + } blendFloat(fromDecomp.scaleX, toDecomp.scaleX, progress); blendFloat(fromDecomp.scaleY, toDecomp.scaleY, progress); @@ -1579,6 +1586,9 @@ bool TransformationMatrix::decompose2(Decomposed2Type& decomp) const memset(&decomp, 0, sizeof(decomp)); decomp.scaleX = 1; decomp.scaleY = 1; + decomp.m11 = 1; + decomp.m22 = 1; + return true; } return WebCore::decompose2(m_matrix, decomp); @@ -1592,6 +1602,7 @@ bool TransformationMatrix::decompose4(Decomposed4Type& decomp) const decomp.scaleX = 1; decomp.scaleY = 1; decomp.scaleZ = 1; + return true; } return WebCore::decompose4(m_matrix, decomp); @@ -1738,4 +1749,20 @@ bool TransformationMatrix::isBackFaceVisible() const return zComponentOfTransformedNormal < 0; } +TextStream& operator<<(TextStream& ts, const TransformationMatrix& transform) +{ + ts << "\n"; + ts.increaseIndent(); + ts.writeIndent(); + ts << "[" << transform.m11() << " " << transform.m12() << " " << transform.m13() << " " << transform.m14() << "]\n"; + ts.writeIndent(); + ts << "[" << transform.m21() << " " << transform.m22() << " " << transform.m23() << " " << transform.m24() << "]\n"; + ts.writeIndent(); + ts << "[" << transform.m31() << " " << transform.m32() << " " << transform.m33() << " " << transform.m34() << "]\n"; + ts.writeIndent(); + ts << "[" << transform.m41() << " " << transform.m42() << " " << transform.m43() << " " << transform.m44() << "]"; + ts.decreaseIndent(); + return ts; +} + } diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h index 011cd87b5..5db0c002a 100644 --- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h +++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2005-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -31,6 +31,7 @@ #include "IntPoint.h" #include <string.h> //for memcpy #include <wtf/FastMalloc.h> +#include <wtf/Optional.h> #if USE(CA) typedef struct CATransform3D CATransform3D; @@ -49,6 +50,11 @@ typedef struct tagXFORM XFORM; #endif #endif +#if PLATFORM(WIN) +struct D2D_MATRIX_3X2_F; +typedef D2D_MATRIX_3X2_F D2D1_MATRIX_3X2_F; +#endif + namespace WebCore { class AffineTransform; @@ -56,6 +62,7 @@ class IntRect; class LayoutRect; class FloatRect; class FloatQuad; +class TextStream; #if CPU(X86_64) #define TRANSFORMATION_MATRIX_USE_X86_64_SSE2 @@ -65,7 +72,7 @@ class TransformationMatrix { WTF_MAKE_FAST_ALLOCATED; public: -#if CPU(APPLE_ARMV7S) || defined(TRANSFORMATION_MATRIX_USE_X86_64_SSE2) +#if (PLATFORM(IOS) && CPU(ARM_THUMB2)) || defined(TRANSFORMATION_MATRIX_USE_X86_64_SSE2) #if COMPILER(MSVC) __declspec(align(16)) typedef double Matrix4[4][4]; #else @@ -76,7 +83,7 @@ public: #endif TransformationMatrix() { makeIdentity(); } - TransformationMatrix(const AffineTransform& t); + WEBCORE_EXPORT TransformationMatrix(const AffineTransform&); TransformationMatrix(const TransformationMatrix& t) { *this = t; } TransformationMatrix(double a, double b, double c, double d, double e, double f) { setMatrix(a, b, c, d, e, f); } TransformationMatrix(double m11, double m12, double m13, double m14, @@ -126,15 +133,15 @@ public: m_matrix[3][0] == 0 && m_matrix[3][1] == 0 && m_matrix[3][2] == 0 && m_matrix[3][3] == 1; } - // This form preserves the double math from input to output + // This form preserves the double math from input to output. void map(double x, double y, double& x2, double& y2) const { multVecMatrix(x, y, x2, y2); } - // Map a 3D point through the transform, returning a 3D point. + // Maps a 3D point through the transform, returning a 3D point. FloatPoint3D mapPoint(const FloatPoint3D&) const; - // Map a 2D point through the transform, returning a 2D point. + // Maps a 2D point through the transform, returning a 2D point. // Note that this ignores the z component, effectively projecting the point into the z=0 plane. - FloatPoint mapPoint(const FloatPoint&) const; + WEBCORE_EXPORT FloatPoint mapPoint(const FloatPoint&) const; // Like the version above, except that it rounds the mapped point to the nearest integer value. IntPoint mapPoint(const IntPoint& p) const @@ -143,25 +150,23 @@ public: } // If the matrix has 3D components, the z component of the result is - // dropped, effectively projecting the rect into the z=0 plane - FloatRect mapRect(const FloatRect&) const; + // dropped, effectively projecting the rect into the z=0 plane. + WEBCORE_EXPORT FloatRect mapRect(const FloatRect&) const; // Rounds the resulting mapped rectangle out. This is helpful for bounding // box computations but may not be what is wanted in other contexts. - IntRect mapRect(const IntRect&) const; + WEBCORE_EXPORT IntRect mapRect(const IntRect&) const; LayoutRect mapRect(const LayoutRect&) const; // If the matrix has 3D components, the z component of the result is - // dropped, effectively projecting the quad into the z=0 plane - FloatQuad mapQuad(const FloatQuad&) const; - - // Map a point on the z=0 plane into a point on - // the plane with with the transform applied, by extending - // a ray perpendicular to the source plane and computing - // the local x,y position of the point where that ray intersects - // with the destination plane. + // dropped, effectively projecting the quad into the z=0 plane. + WEBCORE_EXPORT FloatQuad mapQuad(const FloatQuad&) const; + + // Maps a point on the z=0 plane into a point on the plane with with the transform applied, by + // extending a ray perpendicular to the source plane and computing the local x,y position of + // the point where that ray intersects with the destination plane. FloatPoint projectPoint(const FloatPoint&, bool* clamped = 0) const; - // Projects the four corners of the quad + // Projects the four corners of the quad. FloatQuad projectQuad(const FloatQuad&, bool* clamped = 0) const; // Projects the four corners of the quad and takes a bounding box, // while sanitizing values created when the w component is negative. @@ -219,61 +224,74 @@ public: void setF(double f) { m_matrix[3][1] = f; } // this = mat * this. - TransformationMatrix& multiply(const TransformationMatrix&); + WEBCORE_EXPORT TransformationMatrix& multiply(const TransformationMatrix&); - TransformationMatrix& scale(double); - TransformationMatrix& scaleNonUniform(double sx, double sy); + WEBCORE_EXPORT TransformationMatrix& scale(double); + WEBCORE_EXPORT TransformationMatrix& scaleNonUniform(double sx, double sy); TransformationMatrix& scale3d(double sx, double sy, double sz); // Angle is in degrees. TransformationMatrix& rotate(double d) { return rotate3d(0, 0, d); } TransformationMatrix& rotateFromVector(double x, double y); - TransformationMatrix& rotate3d(double rx, double ry, double rz); + WEBCORE_EXPORT TransformationMatrix& rotate3d(double rx, double ry, double rz); - // The vector (x,y,z) is normalized if it's not already. A vector of - // (0,0,0) uses a vector of (0,0,1). + // The vector (x,y,z) is normalized if it's not already. A vector of (0,0,0) uses a vector of (0,0,1). TransformationMatrix& rotate3d(double x, double y, double z, double angle); - TransformationMatrix& translate(double tx, double ty); + WEBCORE_EXPORT TransformationMatrix& translate(double tx, double ty); TransformationMatrix& translate3d(double tx, double ty, double tz); // translation added with a post-multiply TransformationMatrix& translateRight(double tx, double ty); TransformationMatrix& translateRight3d(double tx, double ty, double tz); - TransformationMatrix& flipX(); - TransformationMatrix& flipY(); - TransformationMatrix& skew(double angleX, double angleY); + WEBCORE_EXPORT TransformationMatrix& flipX(); + WEBCORE_EXPORT TransformationMatrix& flipY(); + WEBCORE_EXPORT TransformationMatrix& skew(double angleX, double angleY); TransformationMatrix& skewX(double angle) { return skew(angle, 0); } TransformationMatrix& skewY(double angle) { return skew(0, angle); } TransformationMatrix& applyPerspective(double p); bool hasPerspective() const { return m_matrix[2][3] != 0.0f; } - // returns a transformation that maps a rect to a rect - static TransformationMatrix rectToRect(const FloatRect&, const FloatRect&); + // Returns a transformation that maps a rect to a rect. + WEBCORE_EXPORT static TransformationMatrix rectToRect(const FloatRect&, const FloatRect&); - bool isInvertible() const; + bool isInvertible() const; // If you call this this, you're probably doing it wrong. + WEBCORE_EXPORT std::optional<TransformationMatrix> inverse() const; - // This method returns the identity matrix if it is not invertible. - // Use isInvertible() before calling this if you need to know. - TransformationMatrix inverse() const; - - // decompose the matrix into its component parts - typedef struct { + // Decompose the matrix into its component parts. + struct Decomposed2Type { double scaleX, scaleY; double translateX, translateY; double angle; double m11, m12, m21, m22; - } Decomposed2Type; - - typedef struct { + + bool operator==(const Decomposed2Type& other) const + { + return scaleX == other.scaleX && scaleY == other.scaleY + && translateX == other.translateX && translateY == other.translateY + && angle == other.angle + && m11 == other.m11 && m12 == other.m12 && m21 == other.m21 && m22 == other.m22; + } + }; + + struct Decomposed4Type { double scaleX, scaleY, scaleZ; double skewXY, skewXZ, skewYZ; double quaternionX, quaternionY, quaternionZ, quaternionW; double translateX, translateY, translateZ; double perspectiveX, perspectiveY, perspectiveZ, perspectiveW; - } Decomposed4Type; + + bool operator==(const Decomposed4Type& other) const + { + return scaleX == other.scaleX && scaleY == other.scaleY && scaleZ == other.scaleZ + && skewXY == other.skewXY && skewXZ == other.skewXZ && skewYZ == other.skewYZ + && quaternionX == other.quaternionX && quaternionY == other.quaternionY && quaternionZ == other.quaternionZ && quaternionW == other.quaternionW + && translateX == other.translateX && translateY == other.translateY && translateZ == other.translateZ + && perspectiveX == other.perspectiveX && perspectiveY == other.perspectiveY && perspectiveZ == other.perspectiveZ && perspectiveW == other.perspectiveW; + } + }; bool decompose2(Decomposed2Type&) const; void recompose2(const Decomposed2Type&); @@ -281,9 +299,9 @@ public: bool decompose4(Decomposed4Type&) const; void recompose4(const Decomposed4Type&); - void blend(const TransformationMatrix& from, double progress); - void blend2(const TransformationMatrix& from, double progress); - void blend4(const TransformationMatrix& from, double progress); + WEBCORE_EXPORT void blend(const TransformationMatrix& from, double progress); + WEBCORE_EXPORT void blend2(const TransformationMatrix& from, double progress); + WEBCORE_EXPORT void blend4(const TransformationMatrix& from, double progress); bool isAffine() const { @@ -291,10 +309,10 @@ public: m31() == 0 && m32() == 0 && m33() == 1 && m34() == 0 && m43() == 0 && m44() == 1); } - // Throw away the non-affine parts of the matrix (lossy!) - void makeAffine(); + // Throw away the non-affine parts of the matrix (lossy!). + WEBCORE_EXPORT void makeAffine(); - AffineTransform toAffineTransform() const; + WEBCORE_EXPORT AffineTransform toAffineTransform() const; bool operator==(const TransformationMatrix& m2) const { @@ -333,12 +351,12 @@ public: } #if USE(CA) - TransformationMatrix(const CATransform3D&); - operator CATransform3D() const; + WEBCORE_EXPORT TransformationMatrix(const CATransform3D&); + WEBCORE_EXPORT operator CATransform3D() const; #endif #if USE(CG) - TransformationMatrix(const CGAffineTransform&); - operator CGAffineTransform() const; + WEBCORE_EXPORT TransformationMatrix(const CGAffineTransform&); + WEBCORE_EXPORT operator CGAffineTransform() const; #elif USE(CAIRO) operator cairo_matrix_t() const; #endif @@ -347,6 +365,11 @@ public: operator XFORM() const; #endif +#if PLATFORM(WIN) + TransformationMatrix(const D2D1_MATRIX_3X2_F&); + operator D2D1_MATRIX_3X2_F() const; +#endif + bool isIdentityOrTranslation() const { return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0 @@ -357,7 +380,7 @@ public: bool isIntegerTranslation() const; - // This method returns the matrix without 3D components. + // Returns the matrix without 3D components. TransformationMatrix to2dTransform() const; typedef float FloatMatrix4[16]; @@ -380,7 +403,6 @@ private: return FloatPoint(static_cast<float>(resultX), static_cast<float>(resultY)); } - // multiply passed 3D point by matrix void multVecMatrix(double x, double y, double z, double& dstX, double& dstY, double& dstZ) const; FloatPoint3D internalMapPoint(const FloatPoint3D& sourcePoint) const { @@ -400,6 +422,8 @@ private: Matrix4 m_matrix; }; +WEBCORE_EXPORT TextStream& operator<<(TextStream&, const TransformationMatrix&); + } // namespace WebCore #endif // TransformationMatrix_h diff --git a/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp b/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp index f140c5081..02880849e 100644 --- a/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp +++ b/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp @@ -21,24 +21,39 @@ #include "config.h" #include "TranslateTransformOperation.h" + #include "FloatConversion.h" +#include "TextStream.h" namespace WebCore { -PassRefPtr<TransformOperation> TranslateTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) +bool TranslateTransformOperation::operator==(const TransformOperation& other) const +{ + if (!isSameType(other)) + return false; + const TranslateTransformOperation& t = downcast<TranslateTransformOperation>(other); + return m_x == t.m_x && m_y == t.m_y && m_z == t.m_z; +} + +Ref<TransformOperation> TranslateTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity) { if (from && !from->isSameType(*this)) - return this; + return *this; Length zeroLength(0, Fixed); if (blendToIdentity) - return TranslateTransformOperation::create(zeroLength.blend(m_x, progress), zeroLength.blend(m_y, progress), zeroLength.blend(m_z, progress), m_type); + return TranslateTransformOperation::create(WebCore::blend(m_x, zeroLength, progress), WebCore::blend(m_y, zeroLength, progress), WebCore::blend(m_z, zeroLength, progress), m_type); - const TranslateTransformOperation* fromOp = static_cast<const TranslateTransformOperation*>(from); + const TranslateTransformOperation* fromOp = downcast<TranslateTransformOperation>(from); Length fromX = fromOp ? fromOp->m_x : zeroLength; Length fromY = fromOp ? fromOp->m_y : zeroLength; Length fromZ = fromOp ? fromOp->m_z : zeroLength; - return TranslateTransformOperation::create(m_x.blend(fromX, progress), m_y.blend(fromY, progress), m_z.blend(fromZ, progress), m_type); + return TranslateTransformOperation::create(WebCore::blend(fromX, x(), progress), WebCore::blend(fromY, y(), progress), WebCore::blend(fromZ, z(), progress), m_type); +} + +void TranslateTransformOperation::dump(TextStream& ts) const +{ + ts << type() << "(" << m_x << ", " << m_y << ", " << m_z << ")"; } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.h b/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.h index 63cf587b2..e9f687541 100644 --- a/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.h +++ b/Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.h @@ -28,19 +28,25 @@ #include "Length.h" #include "LengthFunctions.h" #include "TransformOperation.h" +#include <wtf/Ref.h> namespace WebCore { -class TranslateTransformOperation : public TransformOperation { +class TranslateTransformOperation final : public TransformOperation { public: - static PassRefPtr<TranslateTransformOperation> create(const Length& tx, const Length& ty, OperationType type) + static Ref<TranslateTransformOperation> create(const Length& tx, const Length& ty, OperationType type) { - return adoptRef(new TranslateTransformOperation(tx, ty, Length(0, Fixed), type)); + return adoptRef(*new TranslateTransformOperation(tx, ty, Length(0, Fixed), type)); } - static PassRefPtr<TranslateTransformOperation> create(const Length& tx, const Length& ty, const Length& tz, OperationType type) + static Ref<TranslateTransformOperation> create(const Length& tx, const Length& ty, const Length& tz, OperationType type) { - return adoptRef(new TranslateTransformOperation(tx, ty, tz, type)); + return adoptRef(*new TranslateTransformOperation(tx, ty, tz, type)); + } + + Ref<TransformOperation> clone() const override + { + return adoptRef(*new TranslateTransformOperation(m_x, m_y, m_z, m_type)); } double x(const FloatSize& borderBoxSize) const { return floatValueForLength(m_x, borderBoxSize.width()); } @@ -52,26 +58,22 @@ public: Length z() const { return m_z; } private: - virtual bool isIdentity() const { return !floatValueForLength(m_x, 1) && !floatValueForLength(m_y, 1) && !floatValueForLength(m_z, 1); } + bool isIdentity() const override { return !floatValueForLength(m_x, 1) && !floatValueForLength(m_y, 1) && !floatValueForLength(m_z, 1); } - virtual OperationType type() const { return m_type; } - virtual bool isSameType(const TransformOperation& o) const { return o.type() == m_type; } + OperationType type() const override { return m_type; } + bool isSameType(const TransformOperation& o) const override { return o.type() == m_type; } - virtual bool operator==(const TransformOperation& o) const - { - if (!isSameType(o)) - return false; - const TranslateTransformOperation* t = static_cast<const TranslateTransformOperation*>(&o); - return m_x == t->m_x && m_y == t->m_y && m_z == t->m_z; - } + bool operator==(const TransformOperation&) const override; - virtual bool apply(TransformationMatrix& transform, const FloatSize& borderBoxSize) const + bool apply(TransformationMatrix& transform, const FloatSize& borderBoxSize) const override { transform.translate3d(x(borderBoxSize), y(borderBoxSize), z(borderBoxSize)); - return m_x.type() == Percent || m_y.type() == Percent; + return m_x.isPercent() || m_y.isPercent(); } - virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false); + Ref<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override; + + void dump(TextStream&) const final; TranslateTransformOperation(const Length& tx, const Length& ty, const Length& tz, OperationType type) : m_x(tx) @@ -79,7 +81,7 @@ private: , m_z(tz) , m_type(type) { - ASSERT(type == TRANSLATE_X || type == TRANSLATE_Y || type == TRANSLATE_Z || type == TRANSLATE || type == TRANSLATE_3D); + ASSERT(isTranslateTransformOperationType()); } Length m_x; @@ -90,4 +92,6 @@ private: } // namespace WebCore +SPECIALIZE_TYPE_TRAITS_TRANSFORMOPERATION(WebCore::TranslateTransformOperation, isTranslateTransformOperationType()) + #endif // TranslateTransformOperation_h |