summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e3b6cd4)
raw | patch | inline | side by side (parent: e3b6cd4)
author | jaspervdg <jaspervdg@users.sourceforge.net> | |
Tue, 6 May 2008 11:56:53 +0000 (11:56 +0000) | ||
committer | jaspervdg <jaspervdg@users.sourceforge.net> | |
Tue, 6 May 2008 11:56:53 +0000 (11:56 +0000) |
src/svg/svg-path-test.h | [new file with mode: 0644] | patch | blob |
src/svg/svg-path.cpp | patch | blob | history |
diff --git a/src/svg/svg-path-test.h b/src/svg/svg-path-test.h
--- /dev/null
+++ b/src/svg/svg-path-test.h
@@ -0,0 +1,472 @@
+#include <cxxtest/TestSuite.h>\r
+#include "libnr/n-art-bpath.h"\r
+#include "svg/svg.h"\r
+#include "2geom/coord.h"\r
+#include <string>\r
+#include <vector>\r
+#include <glib/gmem.h>\r
+\r
+class SvgPathTest : public CxxTest::TestSuite\r
+{\r
+private:\r
+ std::vector<std::string> rectanglesAbsoluteClosed;\r
+ std::vector<std::string> rectanglesRelativeClosed;\r
+ std::vector<std::string> rectanglesAbsoluteOpen;\r
+ std::vector<std::string> rectanglesRelativeOpen;\r
+ NArtBpath rectangleBpath[5+1];\r
+public:\r
+ SvgPathTest() {\r
+ // Lots of ways to define the same rectangle\r
+ rectanglesAbsoluteClosed.push_back("M 1,2 L 4,2 L 4,8 L 1,8 L 1,2 Z");\r
+ rectanglesAbsoluteClosed.push_back("M 1,2 L 4,2 L 4,8 L 1,8 z");\r
+ rectanglesAbsoluteClosed.push_back("M 1,2 4,2 4,8 1,8 z");\r
+ rectanglesAbsoluteClosed.push_back("M 1,2 H 4 V 8 H 1 z");\r
+ rectanglesRelativeClosed.push_back("m 1,2 l 3,0 l 0,6 l -3,0 z");\r
+ rectanglesRelativeClosed.push_back("m 1,2 3,0 0,6 -3,0 z");\r
+ rectanglesRelativeClosed.push_back("m 1,2 h 3 v 6 h -3 z");\r
+ rectanglesAbsoluteOpen.push_back("M 1,2 L 4,2 L 4,8 L 1,8 L 1,2");\r
+ rectanglesAbsoluteOpen.push_back("M 1,2 4,2 4,8 1,8 1,2");\r
+ rectanglesAbsoluteOpen.push_back("M 1,2 H 4 V 8 H 1 V 2");\r
+ rectanglesRelativeOpen.push_back("m 1,2 l 3,0 l 0,6 l -3,0 l 0,-6");\r
+ rectanglesRelativeOpen.push_back("m 1,2 3,0 0,6 -3,0 0,-6");\r
+ rectanglesRelativeOpen.push_back("m 1,2 h 3 v 6 h -3 v -6");\r
+ rectangleBpath[0].code = NR_MOVETO;\r
+ rectangleBpath[0].x3 = 1;\r
+ rectangleBpath[0].y3 = 2;\r
+ rectangleBpath[1].code = NR_LINETO;\r
+ rectangleBpath[1].x3 = 4;\r
+ rectangleBpath[1].y3 = 2;\r
+ rectangleBpath[2].code = NR_LINETO;\r
+ rectangleBpath[2].x3 = 4;\r
+ rectangleBpath[2].y3 = 8;\r
+ rectangleBpath[3].code = NR_LINETO;\r
+ rectangleBpath[3].x3 = 1;\r
+ rectangleBpath[3].y3 = 8;\r
+ rectangleBpath[4].code = NR_LINETO;\r
+ rectangleBpath[4].x3 = 1;\r
+ rectangleBpath[4].y3 = 2;\r
+ rectangleBpath[5].code = NR_END;\r
+ // TODO: Also test some (smooth) cubic/quadratic beziers and elliptical arcs\r
+ }\r
+\r
+ void testReadRectanglesAbsoluteClosed()\r
+ {\r
+ rectangleBpath[0].code = NR_MOVETO;\r
+ for(size_t i=0; i<rectanglesAbsoluteClosed.size(); i++) {\r
+ NArtBpath * bpath = sp_svg_read_path(rectanglesAbsoluteClosed[i].c_str());\r
+ TS_ASSERT(bpathEqual(bpath,rectangleBpath));\r
+ g_free(bpath);\r
+ }\r
+ }\r
+\r
+ void testReadRectanglesRelativeClosed()\r
+ {\r
+ rectangleBpath[0].code = NR_MOVETO;\r
+ for(size_t i=0; i<rectanglesRelativeClosed.size(); i++) {\r
+ NArtBpath * bpath = sp_svg_read_path(rectanglesRelativeClosed[i].c_str());\r
+ TS_ASSERT(bpathEqual(bpath,rectangleBpath));\r
+ g_free(bpath);\r
+ }\r
+ }\r
+\r
+ void testReadRectanglesAbsoluteOpen()\r
+ {\r
+ rectangleBpath[0].code = NR_MOVETO_OPEN;\r
+ for(size_t i=0; i<rectanglesAbsoluteOpen.size(); i++) {\r
+ NArtBpath * bpath = sp_svg_read_path(rectanglesAbsoluteOpen[i].c_str());\r
+ TS_ASSERT(bpathEqual(bpath,rectangleBpath));\r
+ g_free(bpath);\r
+ }\r
+ }\r
+\r
+ void testReadRectanglesRelativeOpen()\r
+ {\r
+ rectangleBpath[0].code = NR_MOVETO_OPEN;\r
+ for(size_t i=0; i<rectanglesRelativeOpen.size(); i++) {\r
+ NArtBpath * bpath = sp_svg_read_path(rectanglesRelativeOpen[i].c_str());\r
+ TS_ASSERT(bpathEqual(bpath,rectangleBpath));\r
+ g_free(bpath);\r
+ }\r
+ }\r
+\r
+ void testReadConcatenatedPaths()\r
+ {\r
+ NArtBpath bpath_good[4*5+1];\r
+ for(size_t i=0; i<4; i++) {\r
+ memcpy(bpath_good+i*5,rectangleBpath,sizeof(rectangleBpath[0])*5);\r
+ }\r
+ bpath_good[0*5].code = NR_MOVETO;\r
+ bpath_good[1*5].code = NR_MOVETO_OPEN;\r
+ bpath_good[2*5].code = NR_MOVETO;\r
+ bpath_good[3*5].code = NR_MOVETO_OPEN;\r
+ bpath_good[4*5].code = NR_END;\r
+ for(size_t i=0; i<5; i++) {\r
+ bpath_good[1*5+i].x3 += bpath_good[0*5+4].x3;\r
+ bpath_good[1*5+i].y3 += bpath_good[0*5+4].y3;\r
+ }\r
+ for(size_t i=0; i<5; i++) {\r
+ bpath_good[2*5+i].x3 += bpath_good[1*5+4].x3;\r
+ bpath_good[2*5+i].y3 += bpath_good[1*5+4].y3;\r
+ }\r
+ std::string path_str = rectanglesAbsoluteClosed[0] + rectanglesRelativeOpen[0] + rectanglesRelativeClosed[0] + rectanglesAbsoluteOpen[0];\r
+ NArtBpath * bpath = sp_svg_read_path(path_str.c_str());\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+\r
+ void testReadZeroLengthSubpaths() {\r
+ // Per the SVG 1.1 specification (section F5) zero-length subpaths are relevant\r
+ NArtBpath bpath_good[8+1];\r
+ bpath_good[0].code = NR_MOVETO_OPEN;\r
+ bpath_good[0].x3 = bpath_good[0].y3 = 0;\r
+ bpath_good[1].code = NR_MOVETO_OPEN;\r
+ bpath_good[1].x3 = bpath_good[1].y3 = 1;\r
+ bpath_good[2].code = NR_LINETO;\r
+ bpath_good[2].x3 = bpath_good[2].y3 = 2;\r
+ bpath_good[3].code = NR_MOVETO;\r
+ bpath_good[3].x3 = bpath_good[3].y3 = 3;\r
+ bpath_good[4].code = NR_MOVETO;\r
+ bpath_good[4].x3 = bpath_good[4].y3 = 4;\r
+ bpath_good[5].code = NR_LINETO;\r
+ bpath_good[5].x3 = bpath_good[5].y3 = 5;\r
+ bpath_good[6].code = NR_LINETO;\r
+ bpath_good[6].x3 = bpath_good[6].y3 = 4;\r
+ bpath_good[7].code = NR_MOVETO_OPEN;\r
+ bpath_good[7].x3 = bpath_good[7].y3 = 6;\r
+ bpath_good[8].code = NR_END;\r
+ { // Test absolute version\r
+ char const * path_str = "M 0,0 M 1,1 L 2,2 M 3,3 z M 4,4 L 5,5 z M 6,6";\r
+ NArtBpath * bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+ { // Test relative version\r
+ char const * path_str = "m 0,0 m 1,1 l 1,1 m 1,1 z m 1,1 l 1,1 z m 2,2";\r
+ NArtBpath * bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+ }\r
+\r
+ void testReadImplicitMoveto() {\r
+ NArtBpath bpath_good[6+1];\r
+ bpath_good[0].code = NR_MOVETO;\r
+ bpath_good[0].x3 = bpath_good[0].y3 = 1;\r
+ bpath_good[1].code = NR_LINETO;\r
+ bpath_good[1].x3 = bpath_good[1].y3 = 2;\r
+ bpath_good[2].code = NR_LINETO;\r
+ bpath_good[2].x3 = bpath_good[2].y3 = 1;\r
+ bpath_good[3].code = NR_MOVETO;\r
+ bpath_good[3].x3 = bpath_good[3].y3 = 1;\r
+ bpath_good[4].code = NR_LINETO;\r
+ bpath_good[4].x3 = bpath_good[4].y3 = 3;\r
+ bpath_good[5].code = NR_LINETO;\r
+ bpath_good[5].x3 = bpath_good[5].y3 = 1;\r
+ bpath_good[6].code = NR_END;\r
+ { // Test absolute version\r
+ char const * path_str = "M 1,1 L 2,2 z L 3,3 z";\r
+ NArtBpath * bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+ { // Test relative version\r
+ char const * path_str = "M 1,1 L 2,2 z L 3,3 z";\r
+ NArtBpath * bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+ }\r
+\r
+ void testReadFloatingPoint() {\r
+ NArtBpath bpath_good[5+1];\r
+ bpath_good[0].code = NR_MOVETO;\r
+ bpath_good[0].x3 = .01;\r
+ bpath_good[0].y3 = .02;\r
+ bpath_good[1].code = NR_LINETO;\r
+ bpath_good[1].x3 = .04;\r
+ bpath_good[1].y3 = .02;\r
+ bpath_good[2].code = NR_LINETO;\r
+ bpath_good[2].x3 = .04;\r
+ bpath_good[2].y3 = .08;\r
+ bpath_good[3].code = NR_LINETO;\r
+ bpath_good[3].x3 = .01;\r
+ bpath_good[3].y3 = .08;\r
+ bpath_good[4].code = NR_LINETO;\r
+ bpath_good[4].x3 = .01;\r
+ bpath_good[4].y3 = .02;\r
+ bpath_good[5].code = NR_END;\r
+ { // Test decimals\r
+ char const * path_str = "M .01,.02 L 0.04,0.02 L.04,.08L0.01,0.08 z";\r
+ NArtBpath * bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+ { // Test exponent\r
+ char const * path_str = "M 1e-2,.2e-1 L 0.004e1,0.0002e+2 L04E-2,.08e0L1.0e-2,80e-3 z";\r
+ NArtBpath * bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+ }\r
+\r
+ void testReadImplicitSeparation() {\r
+ // Coordinates need not be separated by whitespace if they can still be read unambiguously\r
+ NArtBpath bpath_good[5+1];\r
+ bpath_good[0].code = NR_MOVETO;\r
+ bpath_good[0].x3 = .1;\r
+ bpath_good[0].y3 = .2;\r
+ bpath_good[1].code = NR_LINETO;\r
+ bpath_good[1].x3 = .4;\r
+ bpath_good[1].y3 = .2;\r
+ bpath_good[2].code = NR_LINETO;\r
+ bpath_good[2].x3 = .4;\r
+ bpath_good[2].y3 = .8;\r
+ bpath_good[3].code = NR_LINETO;\r
+ bpath_good[3].x3 = .1;\r
+ bpath_good[3].y3 = .8;\r
+ bpath_good[4].code = NR_LINETO;\r
+ bpath_good[4].x3 = .1;\r
+ bpath_good[4].y3 = .2;\r
+ bpath_good[5].code = NR_END;\r
+ { // Test absolute\r
+ char const * path_str = "M .1.2+0.4.2e0.4e0+8e-1.1.8 z";\r
+ NArtBpath * bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+ { // Test relative\r
+ char const * path_str = "m .1.2+0.3.0e0.0e0+6e-1-.3.0 z";\r
+ NArtBpath * bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good,.1e-8));\r
+ g_free(bpath);\r
+ }\r
+ }\r
+\r
+ void testReadErrorMisplacedCharacter() {\r
+ char const * path_str;\r
+ NArtBpath * bpath;\r
+ NArtBpath * bpath_good = rectangleBpath;\r
+ bpath_good[0].code = NR_MOVETO;\r
+ // Comma in the wrong place (commas may only appear between parameters)\r
+ path_str = "M 1,2 4,2 4,8 1,8 z , m 13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // Comma in the wrong place (commas may only appear between parameters)\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m,13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // Period in the wrong place (no numbers after a 'z')\r
+ path_str = "M 1,2 4,2 4,8 1,8 z . m 13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // Sign in the wrong place (no numbers after a 'z')\r
+ path_str = "M 1,2 4,2 4,8 1,8 z + - m 13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // Digit in the wrong place (no numbers after a 'z')\r
+ path_str = "M 1,2 4,2 4,8 1,8 z 9809 m 13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // Digit in the wrong place (no numbers after a 'z')\r
+ path_str = "M 1,2 4,2 4,8 1,8 z 9809 876 m 13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+\r
+ void testReadErrorUnrecognizedCharacter() {\r
+ char const * path_str;\r
+ NArtBpath * bpath;\r
+ NArtBpath * bpath_good = rectangleBpath;\r
+ bpath_good[0].code = NR_MOVETO;\r
+ // Unrecognized character\r
+ path_str = "M 1,2 4,2 4,8 1,8 z&m 13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // Unrecognized character\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m &13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+\r
+ void testReadErrorTypo() {\r
+ char const * path_str;\r
+ NArtBpath * bpath;\r
+ NArtBpath * bpath_good = rectangleBpath;\r
+ bpath_good[0].code = NR_MOVETO;\r
+ // Typo\r
+ path_str = "M 1,2 4,2 4,8 1,8 z j 13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+\r
+ bpath_good[0].code = NR_MOVETO_OPEN;\r
+ // Typo\r
+ path_str = "M 1,2 4,2 4,8 1,8 L 1,2 x m 13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+\r
+ void testReadErrorIllformedNumbers() {\r
+ char const * path_str;\r
+ NArtBpath * bpath;\r
+ NArtBpath * bpath_good = rectangleBpath;\r
+ bpath_good[0].code = NR_MOVETO;\r
+ // Double exponent\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m 13e4e5,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // Double sign\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m +-13,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // Double sign\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m 13e+-12,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // No digit\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m .e12,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // No digit\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m .,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // No digit\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m +,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // No digit\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m +.e+,15";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+\r
+ void testReadErrorJunk() {\r
+ char const * path_str;\r
+ NArtBpath * bpath;\r
+ NArtBpath * bpath_good = rectangleBpath;\r
+ bpath_good[0].code = NR_MOVETO;\r
+ // Junk\r
+ path_str = "M 1,2 4,2 4,8 1,8 z j 357 hkjh.,34e34 90ih6kj4 h5k6vlh4N.,6,45wikuyi3yere..3487 m 13,23";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+\r
+ void testReadErrorStopReading() {\r
+ char const * path_str;\r
+ NArtBpath * bpath;\r
+ NArtBpath * bpath_good = rectangleBpath;\r
+ bpath_good[0].code = NR_MOVETO;\r
+ // Unrecognized parameter\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m #$%,23,34";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // Invalid parameter\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m #$%,23,34";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ // Illformed parameter\r
+ path_str = "M 1,2 4,2 4,8 1,8 z m +-12,23,34";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+\r
+ bpath_good[0].code = NR_MOVETO_OPEN;\r
+ // "Third" parameter\r
+ path_str = "M 1,2 4,2 4,8 1,8 1,2,3 M 12,23";\r
+ bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,bpath_good));\r
+ g_free(bpath);\r
+ }\r
+\r
+ void testRoundTrip() {\r
+ // This is the easiest way to (also) test writing path data, as a path can be written in more than one way.\r
+ NArtBpath * bpath;\r
+ NArtBpath * new_bpath;\r
+ char * path_str;\r
+ // Rectangle (closed)\r
+ bpath = sp_svg_read_path(rectanglesAbsoluteClosed[0].c_str());\r
+ path_str = sp_svg_write_path(bpath);\r
+ new_bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,new_bpath));\r
+ g_free(bpath); g_free(path_str); g_free(new_bpath);\r
+ // Rectangle (open)\r
+ bpath = sp_svg_read_path(rectanglesAbsoluteOpen[0].c_str());\r
+ path_str = sp_svg_write_path(bpath);\r
+ new_bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,new_bpath));\r
+ g_free(bpath); g_free(path_str); g_free(new_bpath);\r
+ // Concatenated rectangles\r
+ bpath = sp_svg_read_path((rectanglesAbsoluteClosed[0] + rectanglesRelativeOpen[0] + rectanglesRelativeClosed[0] + rectanglesAbsoluteOpen[0]).c_str());\r
+ path_str = sp_svg_write_path(bpath);\r
+ new_bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,new_bpath));\r
+ g_free(bpath); g_free(path_str); g_free(new_bpath);\r
+ // Zero-length subpaths\r
+ bpath = sp_svg_read_path("M 0,0 M 1,1 L 2,2 M 3,3 z M 4,4 L 5,5 z M 6,6");\r
+ path_str = sp_svg_write_path(bpath);\r
+ new_bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,new_bpath));\r
+ g_free(bpath); g_free(path_str); g_free(new_bpath);\r
+ // Floating-point\r
+ bpath = sp_svg_read_path("M .01,.02 L 0.04,0.02 L.04,.08L0.01,0.08 z""M 1e-2,.2e-1 L 0.004e1,0.0002e+2 L04E-2,.08e0L1.0e-2,80e-3 z");\r
+ path_str = sp_svg_write_path(bpath);\r
+ new_bpath = sp_svg_read_path(path_str);\r
+ TS_ASSERT(bpathEqual(bpath,new_bpath));\r
+ g_free(bpath); g_free(path_str); g_free(new_bpath);\r
+ }\r
+\r
+private:\r
+ bool bpathEqual(NArtBpath const * a, NArtBpath const * b, double eps = 0) {\r
+ while(a->code != NR_END && b->code == a->code) {\r
+ switch(a->code) {\r
+ case NR_MOVETO:\r
+ case NR_MOVETO_OPEN:\r
+ case NR_LINETO:\r
+ if (!Geom::are_near(a->x3,b->x3, eps) || !Geom::are_near(a->y3,b->y3, eps)) return false;\r
+ break;\r
+ case NR_CURVETO:\r
+ if (!Geom::are_near(a->x1,b->x1, eps) || !Geom::are_near(a->y1,b->y1, eps)) return false;\r
+ if (!Geom::are_near(a->x2,b->x2, eps) || !Geom::are_near(a->y2,b->y2, eps)) return false;\r
+ if (!Geom::are_near(a->x3,b->x3, eps) || !Geom::are_near(a->y3,b->y3, eps)) return false;\r
+ break;\r
+ default:\r
+ TS_FAIL("Unknown path code!");\r
+ }\r
+ a++;\r
+ b++;\r
+ }\r
+ return a->code == b->code;\r
+ }\r
+};\r
+\r
+\r
+/*\r
+ Local Variables:\r
+ mode:c++\r
+ c-file-style:"stroustrup"\r
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+ indent-tabs-mode:nil\r
+ fill-column:99\r
+ End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
diff --git a/src/svg/svg-path.cpp b/src/svg/svg-path.cpp
index 36c0b0ce3c64e4397842550a7bb7f204d50c0538..460bec9220d3bcf24b4b99edd37a86c2a5f7e1d3 100644 (file)
--- a/src/svg/svg-path.cpp
+++ b/src/svg/svg-path.cpp
* At some point we'll need to do all of
* http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing.
*/
- do {
+ while(*begin) {
double val;
char const *end = rsvg_parse_float(&val, begin);
if (end != begin) {
}
ctx->params[ctx->param++] = val;
rsvg_parse_path_do_cmd (ctx, false, 0); // We don't know the next command yet
+ } else {
+ char c = *begin;
+ if (c >= 'A' && c <= 'Z' && c != 'E') {
+ char next_cmd = c + 'a' - 'A';
+ if (ctx->cmd)
+ rsvg_parse_path_do_cmd (ctx, true, next_cmd);
+ ctx->cmd = next_cmd;
+ ctx->rel = false;
+ } else if (c >= 'a' && c <= 'z' && c != 'e') {
+ char next_cmd = c;
+ if (ctx->cmd)
+ rsvg_parse_path_do_cmd (ctx, true, next_cmd);
+ ctx->cmd = next_cmd;
+ ctx->rel = true;
+ }
+ /* else c _should_ be whitespace or , */
+ begin++;
}
- char c = *begin;
- if (c >= 'A' && c <= 'Z' && c != 'E') {
- char next_cmd = c + 'a' - 'A';
- if (ctx->cmd)
- rsvg_parse_path_do_cmd (ctx, true, next_cmd);
- ctx->cmd = next_cmd;
- ctx->rel = false;
- } else if (c >= 'a' && c <= 'z' && c != 'e') {
- char next_cmd = c;
- if (ctx->cmd)
- rsvg_parse_path_do_cmd (ctx, true, next_cmd);
- ctx->cmd = next_cmd;
- ctx->rel = true;
- }
- /* else c _should_ be whitespace or , */
- } while(*(begin++));
+ }
if (ctx->cmd)
rsvg_parse_path_do_cmd (ctx, true, 0);
}