Add type-checked casts for TransformOperations
authorddkilzer@apple.com <ddkilzer@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 25 May 2014 18:09:16 +0000 (18:09 +0000)
committerddkilzer@apple.com <ddkilzer@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 25 May 2014 18:09:16 +0000 (18:09 +0000)
<http://webkit.org/b/133217>

Reviewed by Simon Fraser.

Source/WebCore:

* platform/graphics/GraphicsLayer.cpp:
(WebCore::GraphicsLayer::validateTransformOperations):
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::getTransformFunctionValue):
- Switch to type-checked casts.

* platform/graphics/transforms/IdentityTransformOperation.h:
* platform/graphics/transforms/Matrix3DTransformOperation.h:
* platform/graphics/transforms/MatrixTransformOperation.h:
* platform/graphics/transforms/PerspectiveTransformOperation.h:
* platform/graphics/transforms/RotateTransformOperation.h:
* platform/graphics/transforms/ScaleTransformOperation.h:
* platform/graphics/transforms/SkewTransformOperation.h:
* platform/graphics/transforms/TranslateTransformOperation.h:
- Add 'final' to class declaration.
- Add 'override' to overridden methods.
- Add type-checked cast via TRANSFORMOPERATION_TYPE_CASTS macro.
- Move implementation of operator==(const TransformOperation&)
  from header to source file so it is able to use a type-checked
  cast, and switch back to using a reference instead of a
  pointer.
- Add or update ASSERT in private constructor to check for
  correct OperationType in classes that represent multiple
  types.

* platform/graphics/transforms/Matrix3DTransformOperation.cpp:
(WebCore::Matrix3DTransformOperation::operator==): Added.

* platform/graphics/transforms/MatrixTransformOperation.cpp:
(WebCore::Matrix3DTransformOperation::operator==): Added.
(WebCore::MatrixTransformOperation::blend):
- Switch to type-checked casts and use a reference.

* platform/graphics/transforms/PerspectiveTransformOperation.cpp:
(WebCore::Matrix3DTransformOperation::operator==): Added.
(WebCore::PerspectiveTransformOperation::blend):
* platform/graphics/transforms/RotateTransformOperation.cpp:
(WebCore::Matrix3DTransformOperation::operator==): Added.
(WebCore::RotateTransformOperation::blend):
* platform/graphics/transforms/ScaleTransformOperation.cpp:
(WebCore::Matrix3DTransformOperation::operator==): Added.
(WebCore::ScaleTransformOperation::blend):
* platform/graphics/transforms/SkewTransformOperation.cpp:
(WebCore::Matrix3DTransformOperation::operator==): Added.
(WebCore::SkewTransformOperation::blend):
* platform/graphics/transforms/TranslateTransformOperation.cpp:
(WebCore::Matrix3DTransformOperation::operator==): Added.
(WebCore::TranslateTransformOperation::blend):
- Switch to type-checked casts.

* platform/graphics/transforms/TransformOperation.h:
(WebCore::TransformOperation::isRotateTransformOperationType):
(WebCore::TransformOperation::isScaleTransformOperationType):
(WebCore::TransformOperation::isSkewTransformOperationType):
(WebCore::TransformOperation::isTranslateTransformOperationType):
- Add type-checking methods used in constructors and type-checked
  casts.
- Define TRANSFORMOPERATION_TYPE_CASTS macro used by subclasses.

Source/WebKit2:

* Shared/CoordinatedGraphics/CoordinatedGraphicsArgumentCoders.cpp:
(IPC::ArgumentCoder<TransformOperations>::encode):
- Switch to type-checked casts.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@169320 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/GraphicsLayer.cpp
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
Source/WebCore/platform/graphics/transforms/IdentityTransformOperation.h
Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.cpp
Source/WebCore/platform/graphics/transforms/Matrix3DTransformOperation.h
Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.cpp
Source/WebCore/platform/graphics/transforms/MatrixTransformOperation.h
Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.cpp
Source/WebCore/platform/graphics/transforms/PerspectiveTransformOperation.h
Source/WebCore/platform/graphics/transforms/RotateTransformOperation.cpp
Source/WebCore/platform/graphics/transforms/RotateTransformOperation.h
Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.cpp
Source/WebCore/platform/graphics/transforms/ScaleTransformOperation.h
Source/WebCore/platform/graphics/transforms/SkewTransformOperation.cpp
Source/WebCore/platform/graphics/transforms/SkewTransformOperation.h
Source/WebCore/platform/graphics/transforms/TransformOperation.h
Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.cpp
Source/WebCore/platform/graphics/transforms/TranslateTransformOperation.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/CoordinatedGraphics/CoordinatedGraphicsArgumentCoders.cpp

index 82d59dcefac145dc67b54da8fb7f8be15712052b..cc778b5eae1354037d7f1bbe2182ac8081cd4d56 100644 (file)
@@ -1,3 +1,69 @@
+2014-05-25  David Kilzer  <ddkilzer@apple.com>
+
+        Add type-checked casts for TransformOperations
+        <http://webkit.org/b/133217>
+
+        Reviewed by Simon Fraser.
+
+        * platform/graphics/GraphicsLayer.cpp:
+        (WebCore::GraphicsLayer::validateTransformOperations):
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::getTransformFunctionValue):
+        - Switch to type-checked casts.
+
+        * platform/graphics/transforms/IdentityTransformOperation.h:
+        * platform/graphics/transforms/Matrix3DTransformOperation.h:
+        * platform/graphics/transforms/MatrixTransformOperation.h:
+        * platform/graphics/transforms/PerspectiveTransformOperation.h:
+        * platform/graphics/transforms/RotateTransformOperation.h:
+        * platform/graphics/transforms/ScaleTransformOperation.h:
+        * platform/graphics/transforms/SkewTransformOperation.h:
+        * platform/graphics/transforms/TranslateTransformOperation.h:
+        - Add 'final' to class declaration.
+        - Add 'override' to overridden methods.
+        - Add type-checked cast via TRANSFORMOPERATION_TYPE_CASTS macro.
+        - Move implementation of operator==(const TransformOperation&)
+          from header to source file so it is able to use a type-checked
+          cast, and switch back to using a reference instead of a
+          pointer.
+        - Add or update ASSERT in private constructor to check for
+          correct OperationType in classes that represent multiple
+          types.
+
+        * platform/graphics/transforms/Matrix3DTransformOperation.cpp:
+        (WebCore::Matrix3DTransformOperation::operator==): Added.
+
+        * platform/graphics/transforms/MatrixTransformOperation.cpp:
+        (WebCore::Matrix3DTransformOperation::operator==): Added.
+        (WebCore::MatrixTransformOperation::blend):
+        - Switch to type-checked casts and use a reference.
+
+        * platform/graphics/transforms/PerspectiveTransformOperation.cpp:
+        (WebCore::Matrix3DTransformOperation::operator==): Added.
+        (WebCore::PerspectiveTransformOperation::blend):
+        * platform/graphics/transforms/RotateTransformOperation.cpp:
+        (WebCore::Matrix3DTransformOperation::operator==): Added.
+        (WebCore::RotateTransformOperation::blend):
+        * platform/graphics/transforms/ScaleTransformOperation.cpp:
+        (WebCore::Matrix3DTransformOperation::operator==): Added.
+        (WebCore::ScaleTransformOperation::blend):
+        * platform/graphics/transforms/SkewTransformOperation.cpp:
+        (WebCore::Matrix3DTransformOperation::operator==): Added.
+        (WebCore::SkewTransformOperation::blend):
+        * platform/graphics/transforms/TranslateTransformOperation.cpp:
+        (WebCore::Matrix3DTransformOperation::operator==): Added.
+        (WebCore::TranslateTransformOperation::blend):
+        - Switch to type-checked casts.
+
+        * platform/graphics/transforms/TransformOperation.h:
+        (WebCore::TransformOperation::isRotateTransformOperationType):
+        (WebCore::TransformOperation::isScaleTransformOperationType):
+        (WebCore::TransformOperation::isSkewTransformOperationType):
+        (WebCore::TransformOperation::isTranslateTransformOperationType):
+        - Add type-checking methods used in constructors and type-checked
+          casts.
+        - Define TRANSFORMOPERATION_TYPE_CASTS macro used by subclasses.
+
 2014-05-25  David Kilzer  <ddkilzer@apple.com>
 
         Crash in WebCore::TextResourceDecoder::checkForCSSCharset
index 869ae1457f2ad12032f87e81a186781ccf6a5d8a..9d54001fca232d9bb0d85f9ca43059cb664c8bdb 100644 (file)
@@ -516,14 +516,14 @@ int GraphicsLayer::validateTransformOperations(const KeyframeValueList& valueLis
             type == TransformOperation::ROTATE_Y ||
             type == TransformOperation::ROTATE_Z ||
             type == TransformOperation::ROTATE_3D) {
-            lastRotAngle = static_cast<RotateTransformOperation*>(firstVal.operations().at(j).get())->angle();
+            lastRotAngle = toRotateTransformOperation(firstVal.operations().at(j).get())->angle();
             
             if (maxRotAngle < 0)
                 maxRotAngle = fabs(lastRotAngle);
             
             for (size_t i = firstIndex + 1; i < valueList.size(); ++i) {
                 const TransformOperations& val = operationsAt(valueList, i);
-                double rotAngle = val.operations().isEmpty() ? 0 : (static_cast<RotateTransformOperation*>(val.operations().at(j).get())->angle());
+                double rotAngle = val.operations().isEmpty() ? 0 : (toRotateTransformOperation(val.operations().at(j).get())->angle());
                 double diffAngle = fabs(rotAngle - lastRotAngle);
                 if (diffAngle > maxRotAngle)
                     maxRotAngle = diffAngle;
index e1f5719981284f6a779304ae0405c065617e2a6c..47a6840a54ca7c196fba118862857829204c8a97 100644 (file)
@@ -129,25 +129,25 @@ static void getTransformFunctionValue(const TransformOperation* transformOp, Tra
     case TransformOperation::ROTATE:
     case TransformOperation::ROTATE_X:
     case TransformOperation::ROTATE_Y:
-        value = transformOp ? narrowPrecisionToFloat(deg2rad(static_cast<const RotateTransformOperation*>(transformOp)->angle())) : 0;
+        value = transformOp ? narrowPrecisionToFloat(deg2rad(toRotateTransformOperation(transformOp)->angle())) : 0;
         break;
     case TransformOperation::SCALE_X:
-        value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1;
+        value = transformOp ? narrowPrecisionToFloat(toScaleTransformOperation(transformOp)->x()) : 1;
         break;
     case TransformOperation::SCALE_Y:
-        value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1;
+        value = transformOp ? narrowPrecisionToFloat(toScaleTransformOperation(transformOp)->y()) : 1;
         break;
     case TransformOperation::SCALE_Z:
-        value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1;
+        value = transformOp ? narrowPrecisionToFloat(toScaleTransformOperation(transformOp)->z()) : 1;
         break;
     case TransformOperation::TRANSLATE_X:
-        value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0;
+        value = transformOp ? narrowPrecisionToFloat(toTranslateTransformOperation(transformOp)->x(size)) : 0;
         break;
     case TransformOperation::TRANSLATE_Y:
-        value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0;
+        value = transformOp ? narrowPrecisionToFloat(toTranslateTransformOperation(transformOp)->y(size)) : 0;
         break;
     case TransformOperation::TRANSLATE_Z:
-        value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0;
+        value = transformOp ? narrowPrecisionToFloat(toTranslateTransformOperation(transformOp)->z(size)) : 0;
         break;
     default:
         break;
@@ -158,17 +158,21 @@ static void getTransformFunctionValue(const TransformOperation* transformOp, Tra
 {
     switch (transformType) {
     case TransformOperation::SCALE:
-    case TransformOperation::SCALE_3D:
-        value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1);
-        value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1);
-        value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1);
+    case TransformOperation::SCALE_3D: {
+        const ScaleTransformOperation* scaleTransformOp = toScaleTransformOperation(transformOp);
+        value.setX(scaleTransformOp ? narrowPrecisionToFloat(scaleTransformOp->x()) : 1);
+        value.setY(scaleTransformOp ? narrowPrecisionToFloat(scaleTransformOp->y()) : 1);
+        value.setZ(scaleTransformOp ? narrowPrecisionToFloat(scaleTransformOp->z()) : 1);
         break;
+    }
     case TransformOperation::TRANSLATE:
-    case TransformOperation::TRANSLATE_3D:
-        value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0);
-        value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0);
-        value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0);
+    case TransformOperation::TRANSLATE_3D: {
+        const TranslateTransformOperation* translateTransformOp = toTranslateTransformOperation(transformOp);
+        value.setX(translateTransformOp ? narrowPrecisionToFloat(translateTransformOp->x(size)) : 0);
+        value.setY(translateTransformOp ? narrowPrecisionToFloat(translateTransformOp->y(size)) : 0);
+        value.setZ(translateTransformOp ? narrowPrecisionToFloat(translateTransformOp->z(size)) : 0);
         break;
+    }
     default:
         break;
     }
index c1f7f451259bb5ad76020d42f3b1a3976f123240..27f5058621efc458829be02554be38ec4ed2b94d 100644 (file)
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-class IdentityTransformOperation : public TransformOperation {
+class IdentityTransformOperation final : public TransformOperation {
 public:
     static PassRefPtr<IdentityTransformOperation> create()
     {
@@ -37,21 +37,21 @@ public:
     }
         
 private:
-    virtual bool isIdentity() const { return true; }
-    virtual OperationType type() const { return IDENTITY; }
-    virtual bool isSameType(const TransformOperation& o) const { return o.type() == IDENTITY; }
+    virtual bool isIdentity() const override { return true; }
+    virtual OperationType type() const override { return IDENTITY; }
+    virtual bool isSameType(const TransformOperation& o) const override { return o.type() == IDENTITY; }
 
-    virtual bool operator==(const TransformOperation& o) const
+    virtual bool operator==(const TransformOperation& o) const override
     {
         return isSameType(o);
     }
 
-    virtual bool apply(TransformationMatrix&, const FloatSize&) const
+    virtual bool apply(TransformationMatrix&, const FloatSize&) const override
     {
         return false;
     }
 
-    virtual PassRefPtr<TransformOperation> blend(const TransformOperation*, double, bool = false)
+    virtual PassRefPtr<TransformOperation> blend(const TransformOperation*, double, bool = false) override
     {
         return this;
     }
@@ -62,6 +62,8 @@ private:
 
 };
 
+TRANSFORMOPERATION_TYPE_CASTS(IdentityTransformOperation, type() == TransformOperation::IDENTITY);
+
 } // namespace WebCore
 
 #endif // IdentityTransformOperation_h
index 79ee43ec6a0d86945a2ab07daaeb91e4f244036a..529f750b6470f679d0a173567b1ff2f8dbeeb1ef 100644 (file)
 
 namespace WebCore {
 
+bool Matrix3DTransformOperation::operator==(const TransformOperation& o) const
+{
+    if (!isSameType(o))
+        return false;
+    const Matrix3DTransformOperation& m = toMatrix3DTransformOperation(o);
+    return m_matrix == m.m_matrix;
+}
+
 PassRefPtr<TransformOperation> Matrix3DTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
 {
     if (from && !from->isSameType(*this))
index ada42ec5d8431c19a160c4f4c65b437b63c71963..21d39fe62342f92bbaf36e73ae8e7d224810bd63 100644 (file)
@@ -30,7 +30,7 @@
 
 namespace WebCore {
 
-class Matrix3DTransformOperation : public TransformOperation {
+class Matrix3DTransformOperation final : public TransformOperation {
 public:
     static PassRefPtr<Matrix3DTransformOperation> create(const TransformationMatrix& matrix)
     {
@@ -40,26 +40,20 @@ public:
     TransformationMatrix matrix() const {return m_matrix; }
 
 private:    
-    virtual bool isIdentity() const { return m_matrix.isIdentity(); }
+    virtual bool isIdentity() const override { return m_matrix.isIdentity(); }
 
-    virtual OperationType type() const { return MATRIX_3D; }
-    virtual bool isSameType(const TransformOperation& o) const { return o.type() == MATRIX_3D; }
+    virtual OperationType type() const override { return MATRIX_3D; }
+    virtual 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;
-    }
+    virtual bool operator==(const TransformOperation&) const override;
 
-    virtual bool apply(TransformationMatrix& transform, const FloatSize&) const
+    virtual bool apply(TransformationMatrix& transform, const FloatSize&) const override
     {
         transform.multiply(TransformationMatrix(m_matrix));
         return false;
     }
 
-    virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false);
+    virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override;
     
     Matrix3DTransformOperation(const TransformationMatrix& mat)
     {
@@ -69,6 +63,8 @@ private:
     TransformationMatrix m_matrix;
 };
 
+TRANSFORMOPERATION_TYPE_CASTS(Matrix3DTransformOperation, type() == TransformOperation::MATRIX_3D);
+
 } // namespace WebCore
 
 #endif // Matrix3DTransformOperation_h
index a3658a91dafea419ac05284d015919222ab28b43..b060b9ef207fdd3da2cee8d9c9ee8afd8a4d1307 100644 (file)
 
 namespace WebCore {
 
+bool MatrixTransformOperation::operator==(const TransformOperation& o) const
+{
+    if (!isSameType(o))
+        return false;
+    const MatrixTransformOperation& m = toMatrixTransformOperation(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;
+}
+
 PassRefPtr<TransformOperation> MatrixTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
 {
     if (from && !from->isSameType(*this))
@@ -36,8 +44,8 @@ PassRefPtr<TransformOperation> MatrixTransformOperation::blend(const TransformOp
     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 = toMatrixTransformOperation(*from);
+        fromT.setMatrix(m.m_a, m.m_b, m.m_c, m.m_d, m.m_e, m.m_f);
     }
     
     if (blendToIdentity)
index 76c5dffcd4da1dc54fa070ac80e03a7497b86ea5..5d552647cafc3e7d830d4859c94290b104f45346 100644 (file)
@@ -30,7 +30,7 @@
 
 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)
     {
@@ -45,28 +45,21 @@ public:
     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; }
+    virtual bool isIdentity() const override { return m_a == 1 && m_b == 0 && m_c == 0 && m_d == 1 && m_e == 0 && m_f == 0; }
 
-    virtual OperationType type() const { return MATRIX; }
-    virtual bool isSameType(const TransformOperation& o) const { return o.type() == MATRIX; }
+    virtual OperationType type() const override { return MATRIX; }
+    virtual bool isSameType(const TransformOperation& o) const override { return o.type() == MATRIX; }
 
-    virtual bool operator==(const TransformOperation& o) const
-    {
-        if (!isSameType(o))
-            return false;
-
-        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;
-    }
+    virtual bool operator==(const TransformOperation&) const override;
 
-    virtual bool apply(TransformationMatrix& transform, const FloatSize&) const
+    virtual 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);
+    virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override;
     
     MatrixTransformOperation(double a, double b, double c, double d, double e, double f)
         : m_a(a)
@@ -96,6 +89,8 @@ private:
     double m_f;
 };
 
+TRANSFORMOPERATION_TYPE_CASTS(MatrixTransformOperation, type() == TransformOperation::MATRIX);
+
 } // namespace WebCore
 
 #endif // MatrixTransformOperation_h
index f58ad642c303047761aa31b3b8f8a29e23c12f01..b771e0b09e8cbe6d096bc13532cddf01f9f28c44 100644 (file)
 
 namespace WebCore {
 
+bool PerspectiveTransformOperation::operator==(const TransformOperation& o) const
+{
+    if (!isSameType(o))
+        return false;
+    const PerspectiveTransformOperation& p = toPerspectiveTransformOperation(o);
+    return m_p == p.m_p;
+}
+
 PassRefPtr<TransformOperation> PerspectiveTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
 {
     if (from && !from->isSameType(*this))
@@ -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 = toPerspectiveTransformOperation(from);
     Length fromP = fromOp ? fromOp->m_p : Length(m_p.type());
     Length toP = m_p;
 
index 0856becc8475547ff48680309dfd4fc6d4bc8b62..1f162cf5633ce12a3360a079fe5cbb8c89e5825e 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace WebCore {
 
-class PerspectiveTransformOperation : public TransformOperation {
+class PerspectiveTransformOperation final : public TransformOperation {
 public:
     static PassRefPtr<PerspectiveTransformOperation> create(const Length& p)
     {
@@ -42,25 +42,19 @@ public:
     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; }
+    virtual bool isIdentity() const override { return !floatValueForLength(m_p, 1); }
+    virtual OperationType type() const override { return PERSPECTIVE; }
+    virtual bool isSameType(const TransformOperation& o) const override { return o.type() == PERSPECTIVE; }
 
-    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;
-    }
+    virtual bool operator==(const TransformOperation&) const override;
 
-    virtual bool apply(TransformationMatrix& transform, const FloatSize&) const
+    virtual 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);
+    virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override;
 
     PerspectiveTransformOperation(const Length& p)
         : m_p(p)
@@ -71,6 +65,8 @@ private:
     Length m_p;
 };
 
+TRANSFORMOPERATION_TYPE_CASTS(PerspectiveTransformOperation, type() == TransformOperation::PERSPECTIVE);
+
 } // namespace WebCore
 
 #endif // PerspectiveTransformOperation_h
index 32b4c6e1c76ddf4d730bb00425bf85c8a3c09905..b6a87b59468449f95a6df20c94b6202f65bc781d 100644 (file)
 
 namespace WebCore {
 
+bool RotateTransformOperation::operator==(const TransformOperation& o) const
+{
+    if (!isSameType(o))
+        return false;
+    const RotateTransformOperation& r = toRotateTransformOperation(o);
+    return m_x == r.m_x && m_y == r.m_y && m_z == r.m_z && m_angle == r.m_angle;
+}
+
 PassRefPtr<TransformOperation> RotateTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
 {
     if (from && !from->isSameType(*this))
@@ -36,7 +44,7 @@ PassRefPtr<TransformOperation> RotateTransformOperation::blend(const TransformOp
     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 = toRotateTransformOperation(from);
     
     // Optimize for single axis rotation
     if (!fromOp || (fromOp->m_x == 0 && fromOp->m_y == 0 && fromOp->m_z == 1) || 
index f47a51e170eb1bce9a56f0d6d92138be932b9fae..67c9bd572159437204bfd30277cc8ab14cbe9ceb 100644 (file)
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-class RotateTransformOperation : public TransformOperation {
+class RotateTransformOperation final : public TransformOperation {
 public:
     static PassRefPtr<RotateTransformOperation> create(double angle, OperationType type)
     {
@@ -47,26 +47,20 @@ public:
     double angle() const { return m_angle; }
 
 private:
-    virtual bool isIdentity() const { return m_angle == 0; }
+    virtual bool isIdentity() const override { return m_angle == 0; }
 
-    virtual OperationType type() const { return m_type; }
-    virtual bool isSameType(const TransformOperation& o) const { return o.type() == m_type; }
+    virtual OperationType type() const override { return m_type; }
+    virtual 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;
-    }
+    virtual bool operator==(const TransformOperation&) const override;
 
-    virtual bool apply(TransformationMatrix& transform, const FloatSize& /*borderBoxSize*/) const
+    virtual 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);
+    virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override;
 
     RotateTransformOperation(double x, double y, double z, double angle, OperationType type)
         : m_x(x)
@@ -75,7 +69,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;
@@ -85,6 +79,8 @@ private:
     OperationType m_type;
 };
 
+TRANSFORMOPERATION_TYPE_CASTS(RotateTransformOperation, isRotateTransformOperationType());
+
 } // namespace WebCore
 
 #endif // RotateTransformOperation_h
index e8806f20308f7f3807de271a47489b9318a14e67..56a6d0f61972a3be41e6b083d8a8991b88917923 100644 (file)
 
 namespace WebCore {
 
+bool ScaleTransformOperation::operator==(const TransformOperation& o) const
+{
+    if (!isSameType(o))
+        return false;
+    const ScaleTransformOperation& s = toScaleTransformOperation(o);
+    return m_x == s.m_x && m_y == s.m_y && m_z == s.m_z;
+}
+
 PassRefPtr<TransformOperation> ScaleTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
 {
     if (from && !from->isSameType(*this))
@@ -36,7 +44,7 @@ PassRefPtr<TransformOperation> ScaleTransformOperation::blend(const TransformOpe
                                                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 = toScaleTransformOperation(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;
index 62beb23ce060c8997642495c1510e52317a30fc6..02f0c3640fd3f471ec9ec91fe51548b92fd44602 100644 (file)
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-class ScaleTransformOperation : public TransformOperation {
+class ScaleTransformOperation final : public TransformOperation {
 public:
     static PassRefPtr<ScaleTransformOperation> create(double sx, double sy, OperationType type)
     {
@@ -46,26 +46,20 @@ public:
     double z() const { return m_z; }
 
 private:
-    virtual bool isIdentity() const { return m_x == 1 &&  m_y == 1 &&  m_z == 1; }
+    virtual bool isIdentity() const override { return m_x == 1 &&  m_y == 1 &&  m_z == 1; }
 
-    virtual OperationType type() const { return m_type; }
-    virtual bool isSameType(const TransformOperation& o) const { return o.type() == m_type; }
+    virtual OperationType type() const override { return m_type; }
+    virtual 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;
-    }
+    virtual bool operator==(const TransformOperation&) const override;
 
-    virtual bool apply(TransformationMatrix& transform, const FloatSize&) const
+    virtual 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);
+    virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override;
 
     ScaleTransformOperation(double sx, double sy, double sz, OperationType type)
         : m_x(sx)
@@ -73,7 +67,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;
@@ -82,6 +76,8 @@ private:
     OperationType m_type;
 };
 
+TRANSFORMOPERATION_TYPE_CASTS(ScaleTransformOperation, isScaleTransformOperationType());
+
 } // namespace WebCore
 
 #endif // ScaleTransformOperation_h
index d92d895ceb68760fff740c1746b6dc3542f2a7f2..f59db9ed97dcd08a616519682ce42a26f2f9ed32 100644 (file)
 
 namespace WebCore {
 
+bool SkewTransformOperation::operator==(const TransformOperation& o) const
+{
+    if (!isSameType(o))
+        return false;
+    const SkewTransformOperation& s = toSkewTransformOperation(o);
+    return m_angleX == s.m_angleX && m_angleY == s.m_angleY;
+}
+
 PassRefPtr<TransformOperation> SkewTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
 {
     if (from && !from->isSameType(*this))
@@ -34,7 +42,7 @@ PassRefPtr<TransformOperation> SkewTransformOperation::blend(const TransformOper
     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 = toSkewTransformOperation(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);
index e9f0c819b0605d5d48cd4f51fac3677bc79b0a26..c03edbd2b24cc25f61f1a5c147ec51f97e200b5a 100644 (file)
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-class SkewTransformOperation : public TransformOperation {
+class SkewTransformOperation final : public TransformOperation {
 public:
     static PassRefPtr<SkewTransformOperation> create(double angleX, double angleY, OperationType type)
     {
@@ -40,31 +40,26 @@ public:
     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; }
+    virtual bool isIdentity() const override { return m_angleX == 0 && m_angleY == 0; }
+    virtual OperationType type() const override { return m_type; }
+    virtual 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 SkewTransformOperation* s = static_cast<const SkewTransformOperation*>(&o);
-        return m_angleX == s->m_angleX && m_angleY == s->m_angleY;
-    }
+    virtual bool operator==(const TransformOperation&) const override;
 
-    virtual bool apply(TransformationMatrix& transform, const FloatSize&) const
+    virtual 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);
+    virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override;
     
     SkewTransformOperation(double angleX, double angleY, OperationType type)
         : m_angleX(angleX)
         , m_angleY(angleY)
         , m_type(type)
     {
+        ASSERT(isSkewTransformOperationType());
     }
     
     double m_angleX;
@@ -72,6 +67,8 @@ private:
     OperationType m_type;
 };
 
+TRANSFORMOPERATION_TYPE_CASTS(SkewTransformOperation, isSkewTransformOperationType());
+
 } // namespace WebCore
 
 #endif // SkewTransformOperation_h
index f9f975fa4ad7f7808360a16e57016f0b0690a184..687999d419191e3300d8d320400203497b574fee 100644 (file)
@@ -79,8 +79,31 @@ 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;
+    }
 };
 
+#define TRANSFORMOPERATION_TYPE_CASTS(ToValueTypeName, predicate) \
+    TYPE_CASTS_BASE(ToValueTypeName, WebCore::TransformOperation, value, value->predicate, value.predicate)
+
 } // namespace WebCore
 
 #endif // TransformOperation_h
index f140c5081b9a1e773895e63503d82f24f048416a..2e60fb54bdddce68491fbbe3e7c62fb59870f8ef 100644 (file)
 
 namespace WebCore {
 
+bool TranslateTransformOperation::operator==(const TransformOperation& o) const
+{
+    if (!isSameType(o))
+        return false;
+    const TranslateTransformOperation& t = toTranslateTransformOperation(o);
+    return m_x == t.m_x && m_y == t.m_y && m_z == t.m_z;
+}
+
 PassRefPtr<TransformOperation> TranslateTransformOperation::blend(const TransformOperation* from, double progress, bool blendToIdentity)
 {
     if (from && !from->isSameType(*this))
@@ -34,7 +42,7 @@ PassRefPtr<TransformOperation> TranslateTransformOperation::blend(const Transfor
     if (blendToIdentity)
         return TranslateTransformOperation::create(zeroLength.blend(m_x, progress), zeroLength.blend(m_y, progress), zeroLength.blend(m_z, progress), m_type);
 
-    const TranslateTransformOperation* fromOp = static_cast<const TranslateTransformOperation*>(from);
+    const TranslateTransformOperation* fromOp = toTranslateTransformOperation(from);
     Length fromX = fromOp ? fromOp->m_x : zeroLength;
     Length fromY = fromOp ? fromOp->m_y : zeroLength;
     Length fromZ = fromOp ? fromOp->m_z : zeroLength;
index 69e5d8525a11640411ace1b4b6c6e3f87b7aaa4c..f14e4658e065e8ca126b37470e9b0928f881c9fd 100644 (file)
@@ -31,7 +31,7 @@
 
 namespace WebCore {
 
-class TranslateTransformOperation : public TransformOperation {
+class TranslateTransformOperation final : public TransformOperation {
 public:
     static PassRefPtr<TranslateTransformOperation> create(const Length& tx, const Length& ty, OperationType type)
     {
@@ -52,26 +52,20 @@ 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); }
+    virtual 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; }
+    virtual OperationType type() const override { return m_type; }
+    virtual 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;
-    }
+    virtual bool operator==(const TransformOperation&) const override;
 
-    virtual bool apply(TransformationMatrix& transform, const FloatSize& borderBoxSize) const
+    virtual bool apply(TransformationMatrix& transform, const FloatSize& borderBoxSize) const override
     {
         transform.translate3d(x(borderBoxSize), y(borderBoxSize), z(borderBoxSize));
         return m_x.isPercentNotCalculated() || m_y.isPercentNotCalculated();
     }
 
-    virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false);
+    virtual PassRefPtr<TransformOperation> blend(const TransformOperation* from, double progress, bool blendToIdentity = false) override;
 
     TranslateTransformOperation(const Length& tx, const Length& ty, const Length& tz, OperationType type)
         : m_x(tx)
@@ -79,7 +73,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;
@@ -88,6 +82,8 @@ private:
     OperationType m_type;
 };
 
+TRANSFORMOPERATION_TYPE_CASTS(TranslateTransformOperation, isTranslateTransformOperationType());
+
 } // namespace WebCore
 
 #endif // TranslateTransformOperation_h
index 2322f6f04a6d1356de8be52aafd5f08803b51bfc..926edf43fe4673670408e2be4f030f0776fd54ec 100644 (file)
@@ -1,3 +1,14 @@
+2014-05-25  David Kilzer  <ddkilzer@apple.com>
+
+        Add type-checked casts for TransformOperations
+        <http://webkit.org/b/133217>
+
+        Reviewed by Simon Fraser.
+
+        * Shared/CoordinatedGraphics/CoordinatedGraphicsArgumentCoders.cpp:
+        (IPC::ArgumentCoder<TransformOperations>::encode):
+        - Switch to type-checked casts.
+
 2014-05-25  David Kilzer  <ddkilzer@apple.com>
 
         Use type-checking FilterOperation casts in CoordinatedGraphicsArgumentCoders.cpp
index c9b23e05602106e60e71b639418f011eb301599f..e2156d56673e11c9b307eb91ea235d2abc78fef7 100644 (file)
@@ -186,42 +186,42 @@ void ArgumentCoder<TransformOperations>::encode(ArgumentEncoder& encoder, const
         case TransformOperation::SCALE:
         case TransformOperation::SCALE_Z:
         case TransformOperation::SCALE_3D:
-            encoder << static_cast<const ScaleTransformOperation*>(operation)->x();
-            encoder << static_cast<const ScaleTransformOperation*>(operation)->y();
-            encoder << static_cast<const ScaleTransformOperation*>(operation)->z();
+            encoder << toScaleTransformOperation(operation)->x();
+            encoder << toScaleTransformOperation(operation)->y();
+            encoder << toScaleTransformOperation(operation)->z();
             break;
         case TransformOperation::TRANSLATE_X:
         case TransformOperation::TRANSLATE_Y:
         case TransformOperation::TRANSLATE:
         case TransformOperation::TRANSLATE_Z:
         case TransformOperation::TRANSLATE_3D:
-            ArgumentCoder<Length>::encode(encoder, static_cast<const TranslateTransformOperation*>(operation)->x());
-            ArgumentCoder<Length>::encode(encoder, static_cast<const TranslateTransformOperation*>(operation)->y());
-            ArgumentCoder<Length>::encode(encoder, static_cast<const TranslateTransformOperation*>(operation)->z());
+            ArgumentCoder<Length>::encode(encoder, toTranslateTransformOperation(operation)->x());
+            ArgumentCoder<Length>::encode(encoder, toTranslateTransformOperation(operation)->y());
+            ArgumentCoder<Length>::encode(encoder, toTranslateTransformOperation(operation)->z());
             break;
         case TransformOperation::ROTATE:
         case TransformOperation::ROTATE_X:
         case TransformOperation::ROTATE_Y:
         case TransformOperation::ROTATE_3D:
-            encoder << static_cast<const RotateTransformOperation*>(operation)->x();
-            encoder << static_cast<const RotateTransformOperation*>(operation)->y();
-            encoder << static_cast<const RotateTransformOperation*>(operation)->z();
-            encoder << static_cast<const RotateTransformOperation*>(operation)->angle();
+            encoder << toRotateTransformOperation(operation)->x();
+            encoder << toRotateTransformOperation(operation)->y();
+            encoder << toRotateTransformOperation(operation)->z();
+            encoder << toRotateTransformOperation(operation)->angle();
             break;
         case TransformOperation::SKEW_X:
         case TransformOperation::SKEW_Y:
         case TransformOperation::SKEW:
-            encoder << static_cast<const SkewTransformOperation*>(operation)->angleX();
-            encoder << static_cast<const SkewTransformOperation*>(operation)->angleY();
+            encoder << toSkewTransformOperation(operation)->angleX();
+            encoder << toSkewTransformOperation(operation)->angleY();
             break;
         case TransformOperation::MATRIX:
-            ArgumentCoder<TransformationMatrix>::encode(encoder, static_cast<const MatrixTransformOperation*>(operation)->matrix());
+            ArgumentCoder<TransformationMatrix>::encode(encoder, toMatrixTransformOperation(operation)->matrix());
             break;
         case TransformOperation::MATRIX_3D:
-            ArgumentCoder<TransformationMatrix>::encode(encoder, static_cast<const Matrix3DTransformOperation*>(operation)->matrix());
+            ArgumentCoder<TransformationMatrix>::encode(encoder, toMatrix3DTransformOperation(operation)->matrix());
             break;
         case TransformOperation::PERSPECTIVE:
-            ArgumentCoder<Length>::encode(encoder, static_cast<const PerspectiveTransformOperation*>(operation)->perspective());
+            ArgumentCoder<Length>::encode(encoder, toPerspectiveTransformOperation(operation)->perspective());
             break;
         case TransformOperation::IDENTITY:
             break;