gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/shape.cpp server/shape.h...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/shape.cpp server/shape.h...
Date: Sat, 10 Nov 2007 18:07:15 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/11/10 18:07:15

Modified files:
        .              : ChangeLog 
        server         : shape.cpp shape.h 
        testsuite/misc-ming.all: DrawingApiTest.as 
                                 DrawingApiTestRunner.cpp 
        testsuite/server: EdgeTest.cpp 

Log message:
                * server/shape.{cpp,h}: add new poinOnCurve and 
squareDistancePtCurve
                  static methods for gnash::edge, have 
path::withinSquareDistance
                  use them for curves.
                * testsuite/misc-ming.all/DrawingApiTest.as: add self-contained
                  equivalent test for the previously failing one checking 
hitTest
                  on the green curve.
                * testsuite/misc-ming.all/DrawingApiTestRunner.cpp: success in
                  green curve hit test.
                * testsuite/server/EdgeTest.cpp: test edge poinOnCurve.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4825&r2=1.4826
http://cvs.savannah.gnu.org/viewcvs/gnash/server/shape.cpp?cvsroot=gnash&r1=1.46&r2=1.47
http://cvs.savannah.gnu.org/viewcvs/gnash/server/shape.h?cvsroot=gnash&r1=1.31&r2=1.32
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/DrawingApiTest.as?cvsroot=gnash&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/DrawingApiTestRunner.cpp?cvsroot=gnash&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/server/EdgeTest.cpp?cvsroot=gnash&r1=1.3&r2=1.4

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4825
retrieving revision 1.4826
diff -u -b -r1.4825 -r1.4826
--- ChangeLog   10 Nov 2007 14:39:51 -0000      1.4825
+++ ChangeLog   10 Nov 2007 18:07:13 -0000      1.4826
@@ -1,5 +1,17 @@
 2007-11-10 Sandro Santilli <address@hidden>
 
+       * server/shape.{cpp,h}: add new poinOnCurve and squareDistancePtCurve
+         static methods for gnash::edge, have path::withinSquareDistance
+         use them for curves.
+       * testsuite/misc-ming.all/DrawingApiTest.as: add self-contained
+         equivalent test for the previously failing one checking hitTest
+         on the green curve.
+       * testsuite/misc-ming.all/DrawingApiTestRunner.cpp: success in
+         green curve hit test.
+       * testsuite/server/EdgeTest.cpp: test edge poinOnCurve.
+
+2007-11-10 Sandro Santilli <address@hidden>
+
        * backend/render_handler_agg.cpp, backend/render_handler_cairo.cpp,
          backend/render_handler_ogl.cpp, server/shape.cpp, server/shape.h,
          server/parser/morph2_character_def.cpp,

Index: server/shape.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/shape.cpp,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -b -r1.46 -r1.47
--- server/shape.cpp    10 Nov 2007 14:39:52 -0000      1.46
+++ server/shape.cpp    10 Nov 2007 18:07:14 -0000      1.47
@@ -28,6 +28,10 @@
 #include <cfloat>
 #include <map>
 
+#ifdef DEBUG_POINT_ON_CURVE
+# include <sstream>
+#endif
+
 
 namespace gnash {
 
@@ -45,7 +49,7 @@
 void   edge::tesselate_curve() const
     // Send this segment to the tesselator.
 {
-       if ( is_straight() )
+       if ( isStraight() )
        {
                //log_msg("is straight!!");
                tesselate::add_line_segment(ap.x, ap.y);
@@ -56,6 +60,28 @@
        }
 }
 
+/* public static */
+point
+edge::pointOnCurve(const point& A, const point& C, const point& B, float t)
+{
+       // See 
http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Quadratic_B.C3.A9zier_curves
+
+       point Q1(A, C, t);
+       point Q2(C, B, t);
+       point R = point(Q1, Q2, t);
+
+#ifdef DEBUG_POINT_ON_CURVE
+       std::stringstream ss;
+       ss <<  "A:" << A << " C:" << C << " B:" << B
+               << " T:" << t
+               << " Q1:" << Q1 << " Q2:" << Q2
+               << " R:" << R;
+       log_debug("%s", ss.str().c_str());
+#endif
+
+       return R;
+}
+
 float
 edge::distancePtSeg(const point& pt, const point& A, const point& B)
 {
@@ -192,7 +218,7 @@
        float x1 = e.ap.x;
        float y1 = e.ap.y;
        
-       if (e.is_straight()) {
+       if (e.isStraight()) {
            // Straight-line case.
            
            // See if (x0,y0)-(x1,y1) crosses (x,y)-(infinity,y)
@@ -357,21 +383,57 @@
                const edge& e = m_edges[i];
                point np(e.ap.x, e.ap.y);
 
-               if ( e.is_straight() )
+               if ( e.isStraight() )
                {
                        float d = edge::squareDistancePtSeg(p, px, np);
                        if ( d < dist ) return true;
                }
                else
                {
+                       // It's a curve !
 
-                       // TODO: FIXME: we're not considering the control
-                       //       point at all so the check will only work
-                       //       for straight lines
-                       // TODO: for curves...
-                       // d(t)=(x(t)-a)^2+(y(t)-b)^2,
-                       float d = edge::squareDistancePtSeg(p, px, np);
-                       if ( d < dist ) return true;
+                       const point& A = px;
+                       const point& C = e.cp;
+                       const point& B = e.ap;
+
+                       // TODO: early break if point is NOT in the area
+                       //       defined by the triangle ACB and it's square 
+                       //       distance from it is > then the requested one
+
+                       // Brute force, try 100 times or give up
+                       //
+                       // TODO: use a binary search like thing, in where
+                       //       we try to find the 't' value taking the average
+                       //       between the 2 best 't' values found so far
+                       //       (best is the ones giving closer distance)
+                       //
+                       float minDist = std::numeric_limits<float>::max();
+                       bool gettingCloser = false;
+                       int attempts = 100; 
+                       int i=0;
+                       for (; i<=attempts; ++i)
+                       {
+                               float t = (float)i/attempts;
+                               float d = edge::squareDistancePtCurve(A, C, B, 
p, t);
+                               //log_debug("Factor %26.26g, distance %g (asked 
%g)", t, sqrt(d), sqrt(dist));
+                               if ( d <= dist ) return true;
+
+                               if ( ! i ) minDist = d;
+                               else if ( d < minDist )
+                               {
+                                       minDist = d;
+                                       gettingCloser = true;
+                               }
+                               else if ( d > minDist )
+                               {
+                                       if ( gettingCloser )
+                                       {
+                                               // we were getting closer 
before...
+                                               break;
+                                       }
+                               }
+                       }
+                       // log_debug("Gave up at attempt %d", i);
                }
 
                px = np;

Index: server/shape.h
===================================================================
RCS file: /sources/gnash/gnash/server/shape.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -b -r1.31 -r1.32
--- server/shape.h      10 Nov 2007 14:39:52 -0000      1.31
+++ server/shape.h      10 Nov 2007 18:07:14 -0000      1.32
@@ -5,7 +5,7 @@
 
 // Quadratic bezier outline shapes, the basis for most SWF rendering.
 
-/* $Id: shape.h,v 1.31 2007/11/10 14:39:52 strk Exp $ */
+/* $Id: shape.h,v 1.32 2007/11/10 18:07:14 strk Exp $ */
 
 #ifndef GNASH_SHAPE_H
 #define GNASH_SHAPE_H
@@ -66,6 +66,30 @@
                /// Return distance between point pt and segment A-B
                static float distancePtSeg(const point& pt, const point& A, 
const point& B);
                
+               /// Find point of the quadratic curve defined by points A,C,B
+               //
+               /// @param A The first point
+               /// @param C The second point (control point)
+               /// @param B The third point (anchor point)
+               /// @param ret The point to write result into
+               /// @param t the step factor between 0 and 1
+               ///
+               static point pointOnCurve(const point& A, const point& C, const 
point& B, float t);
+
+               /// Return square distance between point pt and the point on 
curve found by
+               /// applying the T parameter to the quadratic bezier curve 
function
+               //
+               /// @param A The first point of the bezier curve
+               /// @param C The second point of the bezier curve (control 
point)
+               /// @param B The third point of the bezier curve (anchor point)
+               /// @param p The point we want to compute distance from 
+               /// @param t the step factor between 0 and 1
+               ///
+               static float squareDistancePtCurve(const point& A, const point& 
C, const point& B, const point& p, float t)
+               {
+                       return p.squareDistance( pointOnCurve(A, C, B, t) );
+               }
+               
        //private:
                // *quadratic* bezier: point = p0 * t^2 + p1 * 2t(1-t) + p2 * 
(1-t)^2
                point cp; // "control" point

Index: testsuite/misc-ming.all/DrawingApiTest.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/DrawingApiTest.as,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- testsuite/misc-ming.all/DrawingApiTest.as   9 Nov 2007 23:20:22 -0000       
1.28
+++ testsuite/misc-ming.all/DrawingApiTest.as   10 Nov 2007 18:07:14 -0000      
1.29
@@ -17,7 +17,7 @@
 // 'h' toggles _visible
 //
 
-rcsid="$Id: DrawingApiTest.as,v 1.28 2007/11/09 23:20:22 strk Exp $";
+rcsid="$Id: DrawingApiTest.as,v 1.29 2007/11/10 18:07:14 strk Exp $";
 
 #include "../actionscript.all/check.as"
 
@@ -120,6 +120,8 @@
        // The green curve
        lineStyle(8, 0x00FF00, 100);
        curveTo(400, 120, 300, 100);
+       check( ! hitTest(376, 180, true) ); 
+       check( hitTest(376, 139, true) );
 
        bnd = printBounds(a.getBounds());
        check_equals(bnd, "80,80 410,260"); // the curve is all inside the 
current bounds

Index: testsuite/misc-ming.all/DrawingApiTestRunner.cpp
===================================================================
RCS file: 
/sources/gnash/gnash/testsuite/misc-ming.all/DrawingApiTestRunner.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- testsuite/misc-ming.all/DrawingApiTestRunner.cpp    9 Nov 2007 23:20:21 
-0000       1.35
+++ testsuite/misc-ming.all/DrawingApiTestRunner.cpp    10 Nov 2007 18:07:14 
-0000      1.36
@@ -172,13 +172,13 @@
        // In the middle of an imaginary line between
        // first and last point of the green curve
        tester.movePointerTo(376, 180);
-       xcheck(!tester.isMouseOverMouseEntity()); // fails due to 
edge::withinSquareDistance bug
+       check(!tester.isMouseOverMouseEntity()); // failed due to 
edge::withinSquareDistance bug
        check_pixel(376, 180, 2, white, 2);
 
        // Over the green curve
        tester.movePointerTo(376, 139);
-       xcheck(tester.isMouseOverMouseEntity()); // fails due to 
edge::withinSquareDistance bug
-       check_pixel(376, 139, 2, green, 2); // fails due to bug in AGG
+       check(tester.isMouseOverMouseEntity()); // failed due to 
edge::withinSquareDistance bug
+       check_pixel(376, 139, 2, green, 2); // failed due to bug in AGG
 
        // Over the center of the green circle fill
        tester.movePointerTo(330, 160);
@@ -187,7 +187,7 @@
 
        // Over the boundary of the green circle fill
        tester.movePointerTo(363, 174);
-       check(tester.isMouseOverMouseEntity());  // fails due to 
edge::withinSquareDistance bug
+       check(tester.isMouseOverMouseEntity());  // failed due to 
edge::withinSquareDistance bug
        check_pixel(363, 174, 2, black, 2); 
 
        // Check that nothing is drawin in the bottom line

Index: testsuite/server/EdgeTest.cpp
===================================================================
RCS file: /sources/gnash/gnash/testsuite/server/EdgeTest.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- testsuite/server/EdgeTest.cpp       1 Jul 2007 10:55:12 -0000       1.3
+++ testsuite/server/EdgeTest.cpp       10 Nov 2007 18:07:15 -0000      1.4
@@ -65,18 +65,41 @@
        //
 
        check_equals(edge::distancePtSeg(point(0,0), point(9, 0), point(9, 0)), 
9);
-
        check_equals(edge::distancePtSeg(point(0,0), point(0, 0), point(3, 0)), 
0);
-
        check_equals(edge::distancePtSeg(point(-5,0), point(0, 0), point(3, 
0)), 5);
-
        check_equals(edge::distancePtSeg(point(5,0), point(0, 0), point(3, 0)), 
2);
-
        check_equals(D(edge::distancePtSeg(point(0,0), point(-10, 0), point(3, 
0))), 0);
-
        check_equals(edge::distancePtSeg(point(0,0), point(-10, 0), point(-10, 
30)), 10);
-
        check_equals(edge::distancePtSeg(point(5,5), point(-10, 0), point(10, 
0)), 5);
 
+       //
+       // Test pointOnCurve
+       //
+
+       //
+       // A-----C
+       //       |
+       //       B
+       //
+       point A(10, 10);
+       point C(20, 10);
+       point B(20, 20);
+       check_equals(edge::pointOnCurve(A, C, B, 0), A);
+       check_equals(edge::pointOnCurve(A, C, B, 1), B);
+       check_equals(edge::pointOnCurve(A, C, B, 0.5), point(17.5, 12.5));
+       check_equals(sqrt(edge::squareDistancePtCurve(A, C, B, B, 1)), 0);
+       check_equals(sqrt(edge::squareDistancePtCurve(A, C, B, A, 0)), 0);
+
+       //
+       // A----B---C
+       //
+       A.setTo(10, 10);
+       C.setTo(40, 10);
+       B.setTo(20, 10);
+       check_equals(edge::pointOnCurve(A, C, B, 0), A);
+       check_equals(edge::pointOnCurve(A, C, B, 1), B);
+       check_equals(edge::pointOnCurve(A, C, B, 0.5), point(27.5, 10));
+       check_equals(sqrt(edge::squareDistancePtCurve(A, C, B, B, 1)), 0);
+       check_equals(sqrt(edge::squareDistancePtCurve(A, C, B, A, 0)), 0);
 }
 




reply via email to

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