summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build-x64.xml1
-rw-r--r--build.xml1
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Makefile_insert1
-rw-r--r--src/object-test.h209
5 files changed, 213 insertions, 0 deletions
diff --git a/build-x64.xml b/build-x64.xml
index aa8717bdd..afe9db724 100644
--- a/build-x64.xml
+++ b/build-x64.xml
@@ -241,6 +241,7 @@
<include name="extract-uri-test.h"/>
<include name="marker-test.h"/>
<include name="mod360-test.h"/>
+ <include name="object-test.h"/>
<include name="preferences-test.h"/>
<include name="round-test.h"/>
<include name="sp-gradient-test.h"/>
diff --git a/build.xml b/build.xml
index dd3bf0942..7da46b7c9 100644
--- a/build.xml
+++ b/build.xml
@@ -237,6 +237,7 @@
<include name="extract-uri-test.h"/>
<include name="marker-test.h"/>
<include name="mod360-test.h"/>
+ <include name="object-test.h"/>
<include name="preferences-test.h"/>
<include name="round-test.h"/>
<include name="sp-gradient-test.h"/>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1455b762e..a1f5fc3dd 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -365,6 +365,7 @@ set(inkscape_SRC
number-opt-number.h
object-hierarchy.h
object-snapper.h
+ object-test.h
path-chemistry.h
path-prefix.h
persp3d-reference.h
diff --git a/src/Makefile_insert b/src/Makefile_insert
index 2fff44cb8..107acdf31 100644
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
@@ -247,6 +247,7 @@ CXXTEST_TESTSUITES += \
$(srcdir)/extract-uri-test.h \
$(srcdir)/marker-test.h \
$(srcdir)/mod360-test.h \
+ $(srcdir)/object-test.h \
$(srcdir)/preferences-test.h \
$(srcdir)/round-test.h \
$(srcdir)/sp-gradient-test.h \
diff --git a/src/object-test.h b/src/object-test.h
new file mode 100644
index 000000000..77e9afa86
--- /dev/null
+++ b/src/object-test.h
@@ -0,0 +1,209 @@
+#ifndef SEEN_OBJECT_TEST_H
+#define SEEN_OBJECT_TEST_H
+
+#include <cassert>
+#include <ctime>
+#include <cxxtest/TestSuite.h>
+#include <string>
+#include <vector>
+
+#include "document.h"
+#include "sp-item-group.h"
+#include "sp-object.h"
+#include "sp-path.h"
+#include "sp-root.h"
+#include "xml/document.h"
+#include "xml/node.h"
+
+class ObjectTest : public CxxTest::TestSuite
+{
+public:
+ virtual ~ObjectTest() {}
+
+ static ObjectTest *createSuite() { return new ObjectTest(); }
+ static void destroySuite(ObjectTest *suite) { delete suite; }
+
+ void testObjects()
+ {
+ clock_t begin, end;
+ // Sample document
+ // svg:svg
+ // svg:defs
+ // svg:path
+ // svg:linearGradient
+ // svg:stop
+ // svg:filter
+ // svg:feGaussianBlur (feel free to implement for other filters)
+ // svg:clipPath
+ // svg:rect
+ // svg:g
+ // svg:use
+ // svg:circle
+ // svg:ellipse
+ // svg:text
+ // svg:polygon
+ // svg:polyline
+ // svg:image
+ // svg:line
+
+ char const *docString =
+ "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n"
+ "<!-- just a comment -->\n"
+ "<title id=\"title\">SVG test</title>\n"
+ "<defs>\n"
+ " <path id=\"P\" d=\"M -21,-4 -5,0 -18,12 -3,4 -4,21 0,5 12,17 4,2 21,3 5,-1 17,-12 2,-4 3,-21 -1,-5 -12,-18 -4,-3z\"/>\n"
+ " <linearGradient id=\"LG\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n"
+ " <stop offset=\"0%\" style=\"stop-color:#ffff00;stop-opacity:1\"/>\n"
+ " <stop offset=\"100%\" style=\"stop-color:red;stop-opacity:1\"/>\n"
+ " </linearGradient>\n"
+ " <clipPath id=\"clip\" clipPathUnits=\"userSpaceOnUse\">\n"
+ " <rect x=\"10\" y=\"10\" width=\"100\" height=\"100\"/>\n"
+ " </clipPath>\n"
+ " <filter style=\"color-interpolation-filters:sRGB\" id=\"filter\" x=\"-0.15\" width=\"1.34\" y=\"0\" height=\"1\">\n"
+ " <feGaussianBlur stdDeviation=\"4.26\"/>\n"
+ " </filter>\n"
+ "</defs>\n"
+
+ "<g id=\"G\" transform=\"skewX(10.5) translate(9,5)\">\n"
+ " <use id=\"U\" xlink:href=\"#P\" opacity=\"0.5\" fill=\"#1dace3\" transform=\"rotate(4)\"/>\n"
+ " <circle id=\"C\" cx=\"45.5\" cy=\"67\" r=\"23\" fill=\"#000\"/>\n"
+ " <ellipse id=\"E\" cx=\"200\" cy=\"70\" rx=\"85\" ry=\"55\" fill=\"url(#LG)\"/>\n"
+ " <text id=\"T\" fill=\"#fff\" style=\"font-size:45;font-family:Verdana\" x=\"150\" y=\"86\">TEST</text>\n"
+ " <polygon id=\"PG\" points=\"60,20 100,40 100,80 60,100 20,80 20,40\" clip-path=\"url(#clip)\" filter=\"url(#filter)\"/>\n"
+ " <polyline id=\"PL\" points=\"0,40 40,40 40,80 80,80 80,120 120,120 120,160\" style=\"fill:none;stroke:red;stroke-width:4\"/>\n"
+ " <image id=\"I\" xlink:href=\"data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE4MCIgd2lkdGg9IjUwMCI+PHBhdGggZD0iTTAsNDAgNDAsNDAgNDAs" // this is one line
+ "ODAgODAsODAgODAsMTIwIDEyMCwxMjAgMTIwLDE2MCIgc3R5bGU9ImZpbGw6d2hpdGU7c3Ryb2tlOnJlZDtzdHJva2Utd2lkdGg6NCIvPjwvc3ZnPgo=\"/>\n"
+ " <line id=\"L\" x1=\"20\" y1=\"100\" x2=\"100\" y2=\"20\" stroke=\"black\" stroke-width=\"2\"/>\n"
+ "</g>\n"
+ "</svg>\n";
+
+ begin = clock();
+ SPDocument *doc = SPDocument::createNewDocFromMem(docString, strlen(docString), false);
+ end = clock();
+
+ assert(doc != NULL); // cannot continue if doc is null, abort!
+ assert(doc->getRoot() != NULL);
+
+ SPRoot *root = doc->getRoot();
+ assert(root->getRepr() != NULL);
+ assert(root->hasChildren());
+
+ std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to construct the test document\n";
+
+ SPPath *path = dynamic_cast<SPPath *>(doc->getObjectById("P"));
+ testClones(path);
+
+ SPGroup *group = dynamic_cast<SPGroup *>(doc->getObjectById("G"));
+ testGrouping(group);
+ }
+
+ void testClones(SPPath *path)
+ {
+ clock_t begin, end;
+
+ assert(path != NULL);
+
+ // Since we don't yet have any clean way to do this (FIXME), we'll abuse the XML tree a bit.
+ Inkscape::XML::Node *node = path->getRepr();
+ assert(node != NULL);
+
+ Inkscape::XML::Document *xml_doc = node->document();
+
+ Inkscape::XML::Node *parent = node->parent();
+ assert(parent != NULL);
+
+ TS_TRACE("Benchmarking clones...");
+ const size_t num_clones = 10000;
+
+ std::string href(std::string("#") + std::string(path->getId()));
+ std::vector<Inkscape::XML::Node *> clones(num_clones, NULL);
+
+ begin = clock();
+ // Create num_clones clones of this path and stick them in the document
+ for (size_t i = 0; i < num_clones; ++i) {
+ Inkscape::XML::Node *clone = xml_doc->createElement("svg:use");
+ Inkscape::GC::release(clone);
+ clone->setAttribute("xlink:href", href.c_str());
+ parent->addChild(clone, node);
+ clones[i] = clone;
+ }
+ end = clock();
+
+ std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to write " << num_clones << " clones of a path\n";
+
+ begin = clock();
+ // Remove those clones
+ for (size_t i = num_clones - 1; i >= 1; --i) {
+ parent->removeChild(clones[i]);
+ }
+ end = clock();
+
+ std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to remove " << num_clones << " clones of a path\n";
+ }
+
+ void testGrouping(SPGroup *group)
+ {
+ clock_t begin, end;
+
+ assert(group != NULL);
+
+ // Since we don't yet have any clean way to do this (FIXME), we'll abuse the XML tree a bit.
+ Inkscape::XML::Node *node = group->getRepr();
+ assert(node != NULL);
+
+ Inkscape::XML::Document *xml_doc = node->document();
+
+ TS_TRACE("Benchmarking groups...");
+ const size_t num_elements = 10000;
+
+ Inkscape::XML::Node *new_group = xml_doc->createElement("svg:g");
+ Inkscape::GC::release(new_group);
+ node->addChild(new_group, NULL);
+
+ std::vector<Inkscape::XML::Node *> elements(num_elements, NULL);
+
+ begin = clock();
+ for (size_t i = 0; i < num_elements; ++i) {
+ Inkscape::XML::Node *circle = xml_doc->createElement("svg:circle");
+ Inkscape::GC::release(circle);
+ circle->setAttribute("cx", "2048");
+ circle->setAttribute("cy", "1024");
+ circle->setAttribute("r", "1.5");
+ new_group->addChild(circle, NULL);
+ elements[i] = circle;
+ }
+ end = clock();
+
+ std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to write " << num_elements << " elements into a group\n";
+
+ SPGroup *n_group = dynamic_cast<SPGroup *>(group->get_child_by_repr(new_group));
+ assert(n_group != NULL);
+
+ begin = clock();
+ sp_item_group_ungroup(n_group, NULL, false);
+ end = clock();
+
+ std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to ungroup a <g> with " << num_elements << " elements\n";
+
+ begin = clock();
+ // Remove those elements
+ for (size_t i = num_elements - 1; i >= 1; --i) {
+ elements[i]->parent()->removeChild(elements[i]);
+ }
+ end = clock();
+
+ std::cout << "Took " << double(end - begin) / double(CLOCKS_PER_SEC) << " seconds to remove " << num_elements << " elements\n";
+ }
+};
+#endif // SEEN_OBJECT_TEST_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :