gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog Makefile.am libbase/utility.h s...


From: Benjamin Wolsey
Subject: [Gnash-commit] gnash ChangeLog Makefile.am libbase/utility.h s...
Date: Thu, 19 Jun 2008 11:49:17 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Benjamin Wolsey <bwy>   08/06/19 11:49:17

Modified files:
        .              : ChangeLog Makefile.am 
        libbase        : utility.h 
        server         : as_object.h 
        server/asobj/flash/geom: Matrix_as.cpp Point_as.cpp 
                                 Rectangle_as.cpp 
        testsuite/actionscript.all: Matrix.as Point.as 

Log message:
                * server/as_object.h: typeid can cope with null pointers, but
                  deferencing them beforehand is UB. Pass the pointer to 
typeName
                  without deferencing. Fixes a crash in the swfdec testsuite.
                * server/asobj/flash/geom/Rectangle_as, Point_as, Matrix_as: 
don't
                  be so fussy about what sort of object methods are applied to. 
Most
                  of them work anyway.
                * testsuite/actionscript.all/{Point,Matrix}.as: add tests with
                  faked Matrix and Point objects.
                * libbase/utility.h: add a much faster version of non-UB
                  PIXELS_TO_TWIPS that only uses fmod when it would otherwise
                  overflow.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.6977&r2=1.6978
http://cvs.savannah.gnu.org/viewcvs/gnash/Makefile.am?cvsroot=gnash&r1=1.116&r2=1.117
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/utility.h?cvsroot=gnash&r1=1.64&r2=1.65
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_object.h?cvsroot=gnash&r1=1.113&r2=1.114
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/flash/geom/Matrix_as.cpp?cvsroot=gnash&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/flash/geom/Point_as.cpp?cvsroot=gnash&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/flash/geom/Rectangle_as.cpp?cvsroot=gnash&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Matrix.as?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Point.as?cvsroot=gnash&r1=1.6&r2=1.7

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6977
retrieving revision 1.6978
diff -u -b -r1.6977 -r1.6978
--- ChangeLog   19 Jun 2008 10:51:41 -0000      1.6977
+++ ChangeLog   19 Jun 2008 11:49:15 -0000      1.6978
@@ -1,3 +1,17 @@
+2008-06-19 Benjamin Wolsey <address@hidden>
+
+       * server/as_object.h: typeid can cope with null pointers, but
+         deferencing them beforehand is UB. Pass the pointer to typeName
+         without deferencing. Fixes a crash in the swfdec testsuite.
+       * server/asobj/flash/geom/Rectangle_as, Point_as, Matrix_as: don't
+         be so fussy about what sort of object methods are applied to. Most
+         of them work anyway.
+       * testsuite/actionscript.all/{Point,Matrix}.as: add tests with
+         faked Matrix and Point objects.
+       * libbase/utility.h: add a much faster version of non-UB
+         PIXELS_TO_TWIPS that only uses fmod when it would otherwise
+         overflow.
+
 2008-06-19 Sandro Santilli <address@hidden>
 
        * server/as_object.{cpp,h}: change get_super semantic again,

Index: Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/Makefile.am,v
retrieving revision 1.116
retrieving revision 1.117
diff -u -b -r1.116 -r1.117
--- Makefile.am 7 Jun 2008 14:14:18 -0000       1.116
+++ Makefile.am 19 Jun 2008 11:49:16 -0000      1.117
@@ -42,7 +42,6 @@
 
 STD_DIRS = \
        libbase \
-       libgeometry \
        libamf \
        libnet \
        libmedia \

Index: libbase/utility.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/utility.h,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -b -r1.64 -r1.65
--- libbase/utility.h   18 Jun 2008 21:55:57 -0000      1.64
+++ libbase/utility.h   19 Jun 2008 11:49:16 -0000      1.65
@@ -31,6 +31,7 @@
 #include <cmath>
 #include <boost/cstdint.hpp>
 #include <algorithm> // std::min, std::max
+#include <limits>
 
 #if defined(__GNUC__) && __GNUC__ > 2
 #  include <cxxabi.h>
@@ -91,7 +92,7 @@
 // Define this to enable fast float&double to uint32 conversion.
 // If the behaviour is undefined when overflow occurs with your 
 // compiler, disable this macro.
-#define TRUST_FLOAT_TO_UINT32_CONVERSION  1 
+//#define TRUST_FLOAT_TO_UINT32_CONVERSION  1 
 
 // Commonly-used inlined mathematical functions are defined in
 // namespace gnash::utility so that it's clear where they
@@ -158,16 +159,29 @@
     // truncate when overflow occurs.
     return (boost::int32_t)(boost::uint32_t)(a * 20); 
 #else
-    boost::int32_t  b;
-    if(a >= 0)
-    {
-       b = (boost::uint32_t)(std::fmod(a * 20.0, 4294967296.0));
-    }
-    else
+
+    // This truncates large values without relying on undefined behaviour.
+    // For very large values of 'a' it is noticeably slower than the UB
+    // version (due to fmod), but should always be legal behaviour. For
+    // ordinary values (within ±1.07374e+08 pixels) it is comparable to
+    // the UB version for speed. Because values outside the limit are
+    // extremely rare, using this safe version has no implications for
+    // performance under normal circumstances.
+    static const double upperUnsignedLimit =
+                std::numeric_limits<boost::uint32_t>::max() + 1.0;
+    static const double upperSignedLimit =
+                std::numeric_limits<boost::int32_t>::max() / 20.0;
+    static const double lowerSignedLimit =
+                std::numeric_limits<boost::int32_t>::min() / 20.0;
+
+    if (a >= lowerSignedLimit && a <= upperSignedLimit)
     {
-       b = -(boost::uint32_t)(std::fmod(-a * 20, 4294967296.0));
+        return static_cast<boost::int32_t>(a * 20.0);
     }
-    return b;
+
+    // This slow truncation happens only in very unlikely cases.
+    return a >= 0 ? static_cast<boost::uint32_t>(std::fmod(a * 20.0, 
upperUnsignedLimit))
+                : - static_cast<boost::uint32_t>(std::fmod( - a * 20.0, 
upperUnsignedLimit));
 #endif
 }
 

Index: server/as_object.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.h,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -b -r1.113 -r1.114
--- server/as_object.h  19 Jun 2008 10:51:43 -0000      1.113
+++ server/as_object.h  19 Jun 2008 11:49:16 -0000      1.114
@@ -1149,8 +1149,8 @@
        boost::intrusive_ptr<T> ret = boost::dynamic_pointer_cast<T>(obj);
 
        if (!ret) {
-               std::string     target = typeName(ret.get()),
-                               source = typeName(*obj.get());
+               std::string target = typeName(ret.get());
+               std::string source = typeName(obj.get());
 
                std::string msg = "builtin method or gettersetter for " +
                        target + " called from " + source + " instance.";

Index: server/asobj/flash/geom/Matrix_as.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/flash/geom/Matrix_as.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- server/asobj/flash/geom/Matrix_as.cpp       10 Jun 2008 16:52:00 -0000      
1.14
+++ server/asobj/flash/geom/Matrix_as.cpp       19 Jun 2008 11:49:17 -0000      
1.15
@@ -47,7 +47,19 @@
 /// where boost::ublas is overcomplicated and can easily fail its own
 /// consistency checks. For simpler multiplication, boost::ublas is very
 /// helpful for keep the code clear and tidy.
-
+//
+/// Most of the methods can be faked: that is, applied to non-Matrices by
+/// setting an object's method to the corresponding Matrix prototype method.
+/// The following code successfully inverts o as if it were a Matrix:
+//
+/// o = { a:3, b: 0, c: 1, d: 4, tx: 4, ty: 6};
+/// o.invert = flash.geom.Matrix.prototype.invert;
+/// o.invert();
+//
+/// Methods that apparently only work on Matrices are rotate, scale and
+/// createGradientBox. The method createBox fills in two values, which
+/// suggests how the PP implements it.
+///
 // Define this to get verbose debugging messages for matrix calculations
 //#define GNASH_DEBUG_GEOM_MATRIX 1
 
@@ -69,7 +81,7 @@
 static as_value Matrix_toString(const fn_call& fn);
 static as_value Matrix_transformPoint(const fn_call& fn);
 static as_value Matrix_translate(const fn_call& fn);
-static void fillMatrix(MatrixType& matrix, as_object* const matrixObject);
+static void fillMatrix(MatrixType& matrix, as_object& matrixObject);
 static PointType transformPoint(as_object* const pointObject, as_object* const 
matrixObject);
 
 as_value Matrix_ctor(const fn_call& fn);
@@ -128,12 +140,6 @@
     {
     }
 
-    // override from as_object ?
-    //std::string get_text_value() const { return "Matrix"; }
-
-    // override from as_object ?
-    //double get_numeric_value() const { return 0; }
-
 };
 
 as_function* getFlashGeomMatrixConstructor()
@@ -152,7 +158,9 @@
 static as_value
 Matrix_clone(const fn_call& fn)
 {
-    boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
+    // It doesn't matter whether it is a matrix or not; a new Matrix
+    // is created using any Matrix properties the object may have.
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
 
     as_value a, b, c, d, tx, ty;
     ptr->get_member(NSV::PROP_A, &a);
@@ -177,7 +185,8 @@
 static as_value
 Matrix_concat(const fn_call& fn)
 {
-    boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
+    // Doesn't have to be a Matrix.
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
 
     if (fn.nargs < 1)
     {
@@ -203,25 +212,16 @@
         return as_value();
     }
     
+    // The object to concatenate doesn't have to be a matrix.    
     as_object* obj = arg.to_object().get();
     assert(obj);
-    if ( ! obj->instanceOf(getFlashGeomMatrixConstructor()) )
-    {
-        /// Isn't a point.
-        IF_VERBOSE_ASCODING_ERRORS(
-            std::ostringstream ss;
-            fn.dump_args(ss);
-            log_aserror("Matrix.concat(%s): object must be a Matrix", 
ss.str());
-        );
-        return as_value();
-    }
 
     MatrixType concatMatrix;
-    fillMatrix(concatMatrix, obj);
+    fillMatrix(concatMatrix, *obj);
 
     // Current ('this') Matrix
     MatrixType currentMatrix;
-    fillMatrix(currentMatrix, ptr.get());
+    fillMatrix(currentMatrix, *ptr);
 
 #ifdef GNASH_DEBUG_GEOM_MATRIX
     log_debug("(Matrix.concat) This matrix (pre-transform): %s", 
currentMatrix);
@@ -253,7 +253,8 @@
 static as_value
 Matrix_createBox(const fn_call& fn)
 {
-    boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
+    // Doesn't have to be a Matrix
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
 
     if (fn.nargs < 2)
     {
@@ -384,7 +385,8 @@
 static as_value
 Matrix_deltaTransformPoint(const fn_call& fn)
 {
-    boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
+    // Doesn't have to be a Matrix
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
 
     if (fn.nargs < 1)
     {
@@ -409,18 +411,10 @@
         return as_value();
     }
     
+    // It doesn't have to be a point. If it has x and y
+    // properties, they will be used.    
     as_object* obj = arg.to_object().get();
     assert(obj);
-    if ( ! obj->instanceOf(getFlashGeomPointConstructor()) )
-    {
-        /// Isn't a point.
-        IF_VERBOSE_ASCODING_ERRORS(
-            std::ostringstream ss;
-            fn.dump_args(ss);
-            log_aserror("Matrix.deltaTransformPoint(%s): object must be a 
Point", ss.str());
-        );
-        return as_value();
-    }
 
     const PointType& point = transformPoint(obj, ptr.get());
 
@@ -442,7 +436,8 @@
 static as_value
 Matrix_identity(const fn_call& fn)
 {
-    boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
+    // Doesn't have to be a Matrix
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
 
     ptr->set_member(NSV::PROP_A, 1.0);
     ptr->set_member(NSV::PROP_B, 0.0);
@@ -465,13 +460,14 @@
 Matrix_invert(const fn_call& fn)
 {
 
-    boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
+    // Doesn't have to be a Matrix
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
 
     MatrixType currentMatrix;
     
     // This just saves repeating code to get doubles for each
     // value.
-    fillMatrix(currentMatrix, ptr.get());
+    fillMatrix(currentMatrix, *ptr);
 
     const double determinant = getMinorDeterminant(currentMatrix);
     
@@ -511,6 +507,7 @@
 static as_value
 Matrix_rotate(const fn_call& fn)
 {
+    // Apparently has to be a Matrix.
     boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
 
     if (fn.nargs < 1)
@@ -583,6 +580,7 @@
 static as_value
 Matrix_scale(const fn_call& fn)
 {
+    // Apparently does have to be a Matrix.
     boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
 
     if (fn.nargs < 2)
@@ -650,7 +648,8 @@
 static as_value
 Matrix_toString(const fn_call& fn)
 {
-    boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
+    // Doesn't have to be a Matrix
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
 
     as_value a, b, c, d, tx, ty;
 
@@ -676,7 +675,8 @@
 static as_value
 Matrix_transformPoint(const fn_call& fn)
 {
-    boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
+    // Doesn't have to be a Matrix
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
 
     if (fn.nargs < 1)
     {
@@ -730,7 +730,8 @@
 static as_value
 Matrix_translate(const fn_call& fn)
 {
-    boost::intrusive_ptr<Matrix_as> ptr = ensureType<Matrix_as>(fn.this_ptr);
+    // Doesn't have to be a Matrix
+    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
     
     if (fn.nargs < 2)
     {
@@ -810,7 +811,7 @@
 
 // A helper function to create a boost matrix from a Matrix object
 static void fillMatrix(MatrixType& matrix,
-                         as_object* const matrixObject)
+                         as_object& matrixObject)
 {
 
     const double u = 0.0;
@@ -819,12 +820,12 @@
 
     as_value a, b, c, d, tx, ty;
 
-    matrixObject->get_member(NSV::PROP_A, &a);
-    matrixObject->get_member(NSV::PROP_B, &b);
-    matrixObject->get_member(NSV::PROP_C, &c);
-    matrixObject->get_member(NSV::PROP_D, &d);
-    matrixObject->get_member(NSV::PROP_TX, &tx);
-    matrixObject->get_member(NSV::PROP_TY, &ty);
+    matrixObject.get_member(NSV::PROP_A, &a);
+    matrixObject.get_member(NSV::PROP_B, &b);
+    matrixObject.get_member(NSV::PROP_C, &c);
+    matrixObject.get_member(NSV::PROP_D, &d);
+    matrixObject.get_member(NSV::PROP_TX, &tx);
+    matrixObject.get_member(NSV::PROP_TY, &ty);
 
     matrix(0, 0) = a.to_number();
     matrix(0, 1) = c.to_number();

Index: server/asobj/flash/geom/Point_as.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/flash/geom/Point_as.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- server/asobj/flash/geom/Point_as.cpp        10 Jun 2008 12:59:25 -0000      
1.17
+++ server/asobj/flash/geom/Point_as.cpp        19 Jun 2008 11:49:17 -0000      
1.18
@@ -104,7 +104,7 @@
 static as_value
 Point_add(const fn_call& fn)
 {
-       boost::intrusive_ptr<Point_as> ptr = ensureType<Point_as>(fn.this_ptr);
+       boost::intrusive_ptr<as_object> ptr = 
ensureType<as_object>(fn.this_ptr);
 
        as_value x, y;
        ptr->get_member(NSV::PROP_X, &x);
@@ -143,7 +143,7 @@
                                IF_VERBOSE_ASCODING_ERRORS(
                                std::stringstream ss; fn.dump_args(ss);
                                log_aserror("Point.add(%s): %s", ss.str(),
-                                       _("first argument casted to object 
doesn't contain an 'x' member"));
+                                       _("first argument cast to object 
doesn't contain an 'x' member"));
                                );
                        }
                        if ( ! o->get_member(NSV::PROP_Y, &y1) )
@@ -151,7 +151,7 @@
                                IF_VERBOSE_ASCODING_ERRORS(
                                std::stringstream ss; fn.dump_args(ss);
                                log_aserror("Point.add(%s): %s", ss.str(),
-                                       _("first argument casted to object 
doesn't contain an 'y' member"));
+                                       _("first argument cast to object 
doesn't contain an 'y' member"));
                                );
                        }
                }
@@ -170,7 +170,7 @@
 static as_value
 Point_clone(const fn_call& fn)
 {
-       boost::intrusive_ptr<Point_as> ptr = ensureType<Point_as>(fn.this_ptr);
+       boost::intrusive_ptr<as_object> ptr = 
ensureType<as_object>(fn.this_ptr);
 
        as_value x, y;
        ptr->get_member(NSV::PROP_X, &x);
@@ -186,7 +186,7 @@
 static as_value
 Point_equals(const fn_call& fn)
 {
-       boost::intrusive_ptr<Point_as> ptr = ensureType<Point_as>(fn.this_ptr);
+       boost::intrusive_ptr<as_object> ptr = 
ensureType<as_object>(fn.this_ptr);
 
        if ( ! fn.nargs )
        {

Index: server/asobj/flash/geom/Rectangle_as.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/flash/geom/Rectangle_as.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- server/asobj/flash/geom/Rectangle_as.cpp    17 May 2008 10:47:16 -0000      
1.8
+++ server/asobj/flash/geom/Rectangle_as.cpp    19 Jun 2008 11:49:17 -0000      
1.9
@@ -137,7 +137,9 @@
 static as_value
 Rectangle_clone(const fn_call& fn)
 {
-       boost::intrusive_ptr<Rectangle_as> ptr = 
ensureType<Rectangle_as>(fn.this_ptr);
+    // The object will be interpreted as a rectangle. Any Rectangle
+    // properties that the object has (width, height, x, y) are used.
+       boost::intrusive_ptr<as_object> ptr = 
ensureType<as_object>(fn.this_ptr);
 
        as_value x, y, w, h;
 

Index: testsuite/actionscript.all/Matrix.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Matrix.as,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- testsuite/actionscript.all/Matrix.as        18 Jun 2008 08:43:12 -0000      
1.10
+++ testsuite/actionscript.all/Matrix.as        19 Jun 2008 11:49:17 -0000      
1.11
@@ -20,7 +20,7 @@
 // compile this test case with Ming makeswf, and then
 // execute it like this gnash -1 -r 0 -v out.swf
 
-rcsid="$Id: Matrix.as,v 1.10 2008/06/18 08:43:12 bwy Exp $";
+rcsid="$Id: Matrix.as,v 1.11 2008/06/19 11:49:17 bwy Exp $";
 
 
 // There are lots of floating point calculations here. Comparing them
@@ -102,12 +102,30 @@
 check (m.tx == 0);
 check (m.ty == 0);
 
+// A non-matrix with a matrix's rotate method (fails?).
+fakematrix = {a:1, b:1, c: 1, d: 1, tx:5, ty: 5};
+fakematrix.rotate = Matrix.prototype.rotate;
+fakematrix.rotate(2);
+check_equals(fakematrix.a.toString(), 1);
+check_equals(fakematrix.b.toString(), 1);
+check_equals(fakematrix.c.toString(), 1);
+check_equals(fakematrix.d.toString(), 1);
+check_equals(fakematrix.tx.toString(), 5);
+check_equals(fakematrix.ty.toString(), 5);
+
 m.scale(-343, 0.33874983);
 check_equals (m.toString(), "(a=-1406.99906373029, b=-1.23693717839177, 
c=514.393845024734, d=-1.49365801000499, tx=0, ty=0)");
 
 m.translate(333,-283747.22);
 check_equals (m.toString(), "(a=-1406.99906373029, b=-1.23693717839177, 
c=514.393845024734, d=-1.49365801000499, tx=333, ty=-283747.22)");
 
+// A non-matrix with a matrix's translate method (works).
+fakematrix = {a:1, b:1, c: 1, d: 1, tx:5, ty: 5};
+fakematrix.translate = Matrix.prototype.translate;
+fakematrix.translate(200,400);
+check_equals(fakematrix.tx.toString(), 205);
+check_equals(fakematrix.ty.toString(), 405);
+
 m.scale(4798747e+98, 0.33874983);
 // PP: (a=-6.75183253607854e+107, b=-0.419012258900892, 
c=2.46844592063091e+107, d=-0.505976396967328, tx=1.597982751e+107, 
ty=-96119.3225379726)
 // I get one discrepancy in 'a' here.
@@ -173,17 +191,46 @@
 check_equals(typeof(newP), "object");
 check_equals(newP.toString(), "(x=31.2567984378314, y=26.6085052458191)");
 
+fakepoint = {x: 34, y: -23};
+newP2 = m2.deltaTransformPoint(fakepoint);
+check_equals(typeof(newP2), "object");
+check(newP2 instanceof Point);
+check_equals(newP.toString(), newP2.toString());
+
+
+
+
 // Scale
 m3 = new Matrix(2, 0, 0, 2, 100, 100);
 m3.scale(3, 4);
 check_equals(m3.toString(), "(a=6, b=0, c=0, d=8, tx=300, ty=400)");
 // Do not change m3; it is used to test invert!
 
+// A non-matrix with a matrix's invert method (fails?).
+fakematrix = {a:3, b:2, c: 5, d: 3, tx:5, ty: 5};
+fakematrix.scale = Matrix.prototype.scale;
+fakematrix.scale(4, 5);
+check_equals(fakematrix.a.toString(), "3");
+check_equals(fakematrix.b.toString(), "2");
+check_equals(fakematrix.c.toString(), "5");
+check_equals(fakematrix.d.toString(), "3");
+check_equals(fakematrix.tx.toString(), "5");
+check_equals(fakematrix.ty.toString(), "5");
+fakematrix.toString = Matrix.prototype.toString;
+check_equals(fakematrix.toString(), "(a=3, b=2, c=5, d=3, tx=5, ty=5)");
+
 // Test clone
 m4 = m3.clone();
 check_equals(m4.toString(), "(a=6, b=0, c=0, d=8, tx=300, ty=400)");
 // Do not change m4; it's used later to test concat!
 
+// A non-matrix with a matrix's invert method (works).
+fakematrix = {a:3, b:2, c: 5, d: 3, tx:5, ty: 5};
+fakematrix.clone = Matrix.prototype.clone;
+r = fakematrix.clone();
+check_equals(r.toString(), "(a=3, b=2, c=5, d=3, tx=5, ty=5)");
+check(r instanceof Matrix);
+
 
 // Test invert
 m3.invert();
@@ -195,6 +242,13 @@
 m6.invert();
 check_equals(m6.toString(), "(a=1, b=0, c=0, d=1, tx=0, ty=0)");
 
+// A non-matrix with a matrix's invert method (half works).
+fakematrix = {a:3, b:2, c: 5, d: 3, tx:5, ty: 5};
+fakematrix.invert = Matrix.prototype.invert;
+fakematrix.invert();
+xcheck_equals(fakematrix.tx.toString(), "NaN");
+check_equals(fakematrix.a.toString(), -3);
+
 // Valid inverse2.
 m6 = new Matrix(4, 5, 0, 5, 2, 3);
 check_equals(m6.toString(), "(a=4, b=5, c=0, d=5, tx=2, ty=3)");
@@ -215,6 +269,19 @@
 p2 = m6.transformPoint(p2);
 check_equals(p2.toString(), "(x=-1014.78819244077, y=21.420285172384)");
 
+// Transforming points with a fake matrix.
+fakematrix = {a:3, b:2, c: 5, d: 3, tx:5, ty: 5};
+fakematrix.deltaTransformPoint = Matrix.prototype.deltaTransformPoint;
+f = fakematrix.deltaTransformPoint(p2);
+check (f instanceof Point);
+check_equals (f.toString(), "(x=-2937.26315146039, y=-1965.31552936439)");
+
+fakematrix.transformPoint = Matrix.prototype.transformPoint;
+f = fakematrix.transformPoint(p2);
+check (f instanceof Point);
+check_equals (f.toString(), "(x=-2932.26315146039, y=-1960.31552936439)");
+
+
 // Rotation applies to translation
 m3 = new Matrix(1, 0, 0, 1, 2, 2);
 m3.rotate (Math.PI / 2);
@@ -234,6 +301,17 @@
 check_equals(m3.tx.toString(), "0");
 check_equals(m3.ty.toString(), "0");
 
+t = new Object();
+check_equals(t.a, undefined)
+t.identity = Matrix.prototype.identity;
+t.identity();
+check_equals(t.a.toString(), "1");
+check_equals(t.b.toString(), "0");
+check_equals(t.c.toString(), "0");
+check_equals(t.d.toString(), "1");
+check_equals(t.tx.toString(), "0");
+check_equals(t.ty.toString(), "0");
+
 // m4 is still interesting
 m4.concat(m1);
 check_equals(m4.toString(), "(a=192, b=-40.8, c=768, d=-108.8, tx=48160, 
ty=-7500.4)");
@@ -241,6 +319,13 @@
 // Works for me.
 check_equals(m4.toString(), "(a=90.6729490609422, b=174.089219392218, 
c=310.274230957074, d=710.908813846049, tx=20109.8154004632, 
ty=44398.6139954762)");
 
+// A non-matrix with a matrix's concat method (works).
+fakematrix = {a:1, b:1, c: 1, d: 1, tx:5, ty: 5};
+fakematrix.concat = Matrix.prototype.concat;
+fakematrix.concat(new Matrix(4, 4, 4, 4, 4, 4));
+check_equals(fakematrix.tx.toString(), 44);
+check_equals(fakematrix.a.toString(), 8);
+
 m7 = new Matrix ("A string", undefined, new Object, true, NaN, new Point);
 check_equals("" + m7, "(a=A string, b=undefined, c=[object Object], d=true, 
tx=NaN, ty=(x=0, y=0))");
 
@@ -258,6 +343,19 @@
 m8.createBox("a", "b");
 check_equals(m8.toString(), "(a=NaN, b=NaN, c=NaN, d=NaN, tx=0, ty=0)");
 
+// A non-matrix with a matrix's createBox method (half works).
+delete fakematrix;
+fakematrix = new Object();
+fakematrix.createBox = Matrix.prototype.createBox;
+fakematrix.createBox(4, 3, 4, 2, 3);
+xcheck_equals(fakematrix.a.toString(), undefined);
+xcheck_equals(fakematrix.b.toString(), undefined);
+xcheck_equals(fakematrix.c.toString(), undefined);
+xcheck_equals(fakematrix.d.toString(), undefined);
+check_equals(fakematrix.tx.toString(), "2");
+check_equals(fakematrix.ty.toString(), "3");
+
+
 m8.createGradientBox(20, 30, 2 * Math.PI, 10, 25);
 
 // The very small numbers aren't very 'accurate', of course.
@@ -276,13 +374,26 @@
 m8.createGradientBox(5, 6, 2, 1, 1);
 check_equals(m8.toString(), "(a=-0.0012699793595799, b=0.00332994663144171, 
c=-0.00277495552620142, d=-0.00152397523149588, tx=3.5, ty=4)");
 
+// A non-matrix with a matrix's createGradientBox method (fails).
+delete fakematrix;
+fakematrix = new Object();
+fakematrix.createGradientBox = Matrix.prototype.createGradientBox;
+fakematrix.createGradientBox(20, 30, 2 * Math.PI, 10, 25);
+check_equals(fakematrix.a.toString(), undefined);
+check_equals(fakematrix.b.toString(), undefined);
+check_equals(fakematrix.c.toString(), undefined);
+check_equals(fakematrix.d.toString(), undefined);
+check_equals(fakematrix.tx.toString(), undefined);
+check_equals(fakematrix.ty.toString(), undefined);
+
+
 //-------------------------------------------------------------
 // END OF TEST
 //-------------------------------------------------------------
 #if MING_VERSION_CODE > 00040005
-totals(115);
+totals(162);
 #else
-totals(106);
+totals(153);
 #endif
 
 #endif // OUTPUT_VERSION >= 8

Index: testsuite/actionscript.all/Point.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Point.as,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- testsuite/actionscript.all/Point.as 19 May 2008 16:32:24 -0000      1.6
+++ testsuite/actionscript.all/Point.as 19 Jun 2008 11:49:17 -0000      1.7
@@ -20,7 +20,7 @@
 // compile this test case with Ming makeswf, and then
 // execute it like this gnash -1 -r 0 -v out.swf
 
-rcsid="$Id: Point.as,v 1.6 2008/05/19 16:32:24 strk Exp $";
+rcsid="$Id: Point.as,v 1.7 2008/06/19 11:49:17 bwy Exp $";
 
 #include "check.as"
 
@@ -130,6 +130,13 @@
 ret = p0.add(p1, 4, 5, 6);
 check_equals(ret.toString(), '(x=3, y=4)');
 
+// A non-point with a point's add method.
+fakepoint = {x:20, y:30};
+fakepoint.add = Point.prototype.add;
+ret = fakepoint.add(p0);
+check_equals(ret.toString(), "(x=22, y=33)");
+check(ret instanceof Point);
+
 //-------------------------------------------------------------
 // Test Point.clone
 //-------------------------------------------------------------
@@ -144,6 +151,13 @@
 check(p2 instanceof Point);
 check_equals(p2.toString(), "(x=3, y=4)");
 
+// A non-point with a point's clone method.
+fakepoint = {x:20, y:30};
+fakepoint.clone = Point.prototype.clone;
+ret = fakepoint.clone(p0);
+check_equals(ret.toString(), "(x=20, y=30)");
+check(ret instanceof Point);
+
 //-------------------------------------------------------------
 // Test Point.distance (static)
 //-------------------------------------------------------------
@@ -254,6 +268,12 @@
 String.prototype.__proto__ = Point.prototype;
 check(!p1.equals('string'));
 
+// A non-point with a point's equals method.
+fakepoint = {x:20, y:30};
+fakepoint.equals = Point.prototype.equals;
+ret = fakepoint.equals(new Point(20,30));
+check_equals(ret.toString(), "true");
+check_equals(typeof(ret), "boolean");
 
 //-------------------------------------------------------------
 // Test Point.interpolate (static)
@@ -400,6 +420,12 @@
 check_equals(typeof(ret), 'undefined');
 check_equals(p0.toString(), '(x=4-6, y=-3)');
 
+// A non-point with a point's offset method (fails)
+fakepoint = {x:20, y:30};
+fakepoint.offset = Point.prototype.offset;
+ret = fakepoint.offset(new Point(1, 3));
+check_equals(ret.toString(), undefined);
+check(! ret instanceof Point);
 //-------------------------------------------------------------
 // Test Point.polar (static)
 //-------------------------------------------------------------
@@ -482,6 +508,6 @@
 // END OF TEST
 //-------------------------------------------------------------
 
-check_totals(178);
+check_totals(186);
 
 #endif // OUTPUT_VERSION >= 8




reply via email to

[Prev in Thread] Current Thread [Next in Thread]