CVSROOT: /cvsroot/gnash Module name: gnash Changes by: Udo Giacomozzi <udog> 07/11/08 17:16:13
Modified files: . : ChangeLog server/parser : shape_character_def.cpp testsuite/misc-ming.all: DrawingApiTest.as Log message: * server/parser/shape_character_def.cpp: modified point_test_local() again to solve problems with some corner cases. It still fails some rare situations on very complex graphics - I'm still working on that; failure reports are greatly appreciated! * testsuite/misc-ming.all/DrawingApiTest.as: some new PASSes CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4809&r2=1.4810 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/shape_character_def.cpp?cvsroot=gnash&r1=1.45&r2=1.46 http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/DrawingApiTest.as?cvsroot=gnash&r1=1.23&r2=1.24 Patches: Index: ChangeLog =================================================================== RCS file: /cvsroot/gnash/gnash/ChangeLog,v retrieving revision 1.4809 retrieving revision 1.4810 diff -u -b -r1.4809 -r1.4810 --- ChangeLog 8 Nov 2007 16:43:16 -0000 1.4809 +++ ChangeLog 8 Nov 2007 17:16:12 -0000 1.4810 @@ -2,6 +2,11 @@ * testsuite/misc-ming.all/DrawingApiTestRunner.cpp: reverted because that problem is still not solved (false PASS earlier) + * server/parser/shape_character_def.cpp: modified point_test_local() + again to solve problems with some corner cases. It still fails some + rare situations on very complex graphics - I'm still working on that; + failure reports are greatly appreciated! + * testsuite/misc-ming.all/DrawingApiTest.as: some new PASSes 2007-11-08 Markus Gothe <[EMAIL PROTECTED]> Index: server/parser/shape_character_def.cpp =================================================================== RCS file: /cvsroot/gnash/gnash/server/parser/shape_character_def.cpp,v retrieving revision 1.45 retrieving revision 1.46 diff -u -b -r1.45 -r1.46 --- server/parser/shape_character_def.cpp 5 Nov 2007 17:26:30 -0000 1.45 +++ server/parser/shape_character_def.cpp 8 Nov 2007 17:16:12 -0000 1.46 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: shape_character_def.cpp,v 1.45 2007/11/05 17:26:30 udog Exp $ */ +/* $Id: shape_character_def.cpp,v 1.46 2007/11/08 17:16:12 udog Exp $ */ // Based on the public domain shape.cpp of Thatcher Ulrich <[EMAIL PROTECTED]> 2003 @@ -809,17 +809,35 @@ // Incoming coords are local coords. { + + /* + Principle: + For the fill of the shape, we project a ray from the test point to the left + side of the shape counting all crossings. When a line or curve segment is + crossed we add 1 if the left fill style is set. Regardless of the left fill + style we subtract 1 from the counter then the right fill style is set. + This is true when the line goes in downward direction. If it goes upward, + the fill styles are reversed. + + The final counter value reveals if the point is inside the shape (and depends + on filling rule, see below). + This method should not depend on subshapes and work for some malformed + shapes situations: + - wrong fill side (eg. left side set for a clockwise drawen rectangle) + - intersecting paths + */ + point pt(x, y); + bool even_odd = true; // later we will need non-zero for glyphs... (TODO) + if (m_bound.point_test(x, y) == false) { // Early out. return false; } - bool result = false; unsigned npaths = m_paths.size(); - float last_crossing; - bool first = true; + int counter = 0; // browse all paths for (unsigned pno=0; pno<npaths; pno++) { @@ -832,13 +850,13 @@ float pen_x, pen_y; if (pth.m_new_shape) { - // beginning new subshape. if the previous subshape found a hit, return - // immediately, otherwise process new subshape. - - if (result) + if ( (even_odd && (counter % 2) != 0) || + (!even_odd && (counter != 0)) ) { + // the point is inside the previous subshape, so exit now return true; - result = false; - first = true; + } + + counter=0; } // If the path has a line style, check for strokes there @@ -885,8 +903,9 @@ */ - float cross_x; - int cross_dir; // +1 = downward, -1 = upward + float cross1, cross2; + int dir1, dir2; // +1 = downward, -1 = upward + int crosscount=0; if (edg.is_straight()) { @@ -901,13 +920,15 @@ || ((pen_y >= y) && (edg.m_ay <= y)) ) { // calculate X crossing - cross_x = pen_x + (edg.m_ax - pen_x) * + cross1 = pen_x + (edg.m_ax - pen_x) * (y - pen_y) / (edg.m_ay - pen_y); if (pen_y > edg.m_ay) - cross_dir = -1; // upward + dir1 = -1; // upward else - cross_dir = +1; // downward + dir1 = +1; // downward + + crosscount=1; } else { @@ -920,17 +941,14 @@ // ==> curve case - float cross1, cross2; - int dir1, dir2; - - int scount = curve_x_crossings(pen_x, pen_y, edg.m_ax, edg.m_ay, + crosscount = curve_x_crossings(pen_x, pen_y, edg.m_ax, edg.m_ay, edg.m_cx, edg.m_cy, y, cross1, cross2); dir1 = pen_y > y ? -1 : +1; dir2 = dir1 * (-1); // second crossing always in opposite dir. /* - printf(" curve crosses at %d points\n", scount); + printf(" curve crosses at %d points\n", crosscount); if (scount>0) printf(" first crossing at %.2f / %.2f, dir %d\n", cross1, y, dir1); @@ -939,74 +957,39 @@ printf(" second crossing at %.2f / %.2f, dir %d\n", cross2, y, dir2); */ - // ignore crossings on the right side - if ((scount>1) && (cross2 > x)) - scount--; - - if ((scount>0) && (cross1 > x)) { - cross1 = cross2; - dir1 = dir2; - scount--; - } - - if (scount==0) - continue; // no crossing left - - // still two crossings? take the nearest - if (scount==2) { - if (cross2 > cross1) { - cross_x = cross2; - cross_dir = dir2; - } else { - cross_x = cross1; - cross_dir = dir1; - } - } else { - cross_x = cross1; - cross_dir = dir1; - } - } // curve // ==> we have now: - // - a valid cross_x - // - cross_dir tells the direction of the crossing + // - one (cross1) or two (cross1, cross2) ray crossings (X coordinate) + // - dir1/dir2 tells the direction of the crossing // (+1 = downward, -1 = upward) + // - crosscount tells the number of crossings - //printf(" found a crossing at %.2f / %.2f, dir %d\n", cross_x, y, cross_dir); + if (crosscount==0) + continue; // need at least one crossing - // we only want crossings at the left of the hit test point - if (cross_x > x) - continue; - - // we are looking for the crossing with the largest X coordinate, - // skip others - if (!first && (cross_x <= last_crossing)) - continue; - // ==> we found a valid crossing - - last_crossing = cross_x; - first = false; - - // choose the appropriate fill style index (we need the one - // in direction to the hit test point) - if (cross_dir < 0) - fill = pth.m_fill1; // upward -> right style - else - fill = pth.m_fill0; // downward -> left style - - result = fill > 0; // current result until we find a better crossing + // check first crossing + if (cross1 <= x) { + if (pth.m_fill0 > 0) counter += dir1; + if (pth.m_fill1 > 0) counter -= dir1; + } + // check optional second crossing (only possible with curves) + if ((crosscount>1) && (cross2 <= x)) { + if (pth.m_fill0 > 0) counter += dir2; + if (pth.m_fill1 > 0) counter -= dir2; + } } // for edge } // for path - return result; + return ( (even_odd && (counter % 2) != 0) || + (!even_odd && (counter != 0)) ); } Index: testsuite/misc-ming.all/DrawingApiTest.as =================================================================== RCS file: /cvsroot/gnash/gnash/testsuite/misc-ming.all/DrawingApiTest.as,v retrieving revision 1.23 retrieving revision 1.24 diff -u -b -r1.23 -r1.24 --- testsuite/misc-ming.all/DrawingApiTest.as 7 Nov 2007 16:15:17 -0000 1.23 +++ testsuite/misc-ming.all/DrawingApiTest.as 8 Nov 2007 17:16:13 -0000 1.24 @@ -17,7 +17,7 @@ // 'h' toggles _visible // -rcsid="$Id: DrawingApiTest.as,v 1.23 2007/11/07 16:15:17 strk Exp $"; +rcsid="$Id: DrawingApiTest.as,v 1.24 2007/11/08 17:16:13 udog Exp $"; #include "../actionscript.all/check.as" @@ -294,7 +294,7 @@ check( inv3.hitTest((4*4), 100 + (10*4), false) ); // Outside the left autofill (but in the boundaries) check( inv3.hitTest((20*4), 100 + (18*4), true) ); // Inside the right autofill - check( !inv3.hitTest((24*4), 100 + (10*4), true) ); // Outside the right autofill (but in the boundaries) + check( !inv3.hitTest(92, 150, true) ); // Outside the right autofill (but in the boundaries) check( inv3.hitTest((24*4), 100 + (10*4), false) ); // Outside the right autofill (but in the boundaries) // Nested squares (inner is an hole) @@ -331,7 +331,7 @@ check( inv4.hitTest(100 + (11*4), 100 + (19*4), true) ); // Lower-Left check( inv4.hitTest(100 + (14*4), 100 + (19*4), true) ); // Lower-Center check( inv4.hitTest(100 + (19*4), 100 + (19*4), true) ); // Lower-Right - xcheck( inv4.hitTest(100 + (19*4), 100 + (14*4), true) ); // Center-Right + check( inv4.hitTest(100 + (19*4), 100 + (14*4), true) ); // Center-Right check( inv4.hitTest(100 + (19*4), 100 + (11*4), true) ); // Upper-Right check( inv4.hitTest(100 + (14*4), 100 + (11*4), true) ); // Upper-Center @@ -496,16 +496,16 @@ inv8.onRollOver = function() {}; check( inv8.hitTest(200 + (15*2), 0 + (15*2), true) ); // Upper-Left - xcheck( inv8.hitTest(200 + (25*2), 0 + (15*2), true) ); // Upper-Center - xcheck( inv8.hitTest(200 + (35*2), 0 + (15*2), true) ); // Upper-Right + check( inv8.hitTest(200 + (25*2), 0 + (15*2), true) ); // Upper-Center + check( inv8.hitTest(200 + (35*2), 0 + (15*2), true) ); // Upper-Right check( !inv8.hitTest(200 + (15*2), 0 + (25*2), true) ); // Center-Left check( !inv8.hitTest(200 + (25*2), 0 + (25*2), true) ); // Center-Center check( inv8.hitTest(200 + (35*2), 0 + (25*2), true) ); // Center-Right check( !inv8.hitTest(200 + (15*2), 0 + (35*2), true) ); // Lower-Left - xcheck( inv8.hitTest(200 + (25*2), 0 + (35*2), true) ); // Lower-Center - xcheck( inv8.hitTest(200 + (35*2), 0 + (35*2), true) ); // Lower-Right + check( inv8.hitTest(200 + (25*2), 0 + (35*2), true) ); // Lower-Center + check( inv8.hitTest(200 + (35*2), 0 + (35*2), true) ); // Lower-Right check( !inv8.hitTest(200 + (20*2), 0 + (25*2), true) ); // On the 0-9 stroke, out of fill _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit