summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Owens <doctormo@gmail.com>2018-11-13 00:25:05 +0000
committerMartin Owens <doctormo@gmail.com>2018-11-13 00:25:05 +0000
commitdb722f5b79ef1517f0b6e9a96968ad257dffc6f9 (patch)
treef7992f8cc42739e3aef74233efaf840045c9cb87
parentSupport multiple style sheets or style elements in an svg document (diff)
downloadinkscape-db722f5b79ef1517f0b6e9a96968ad257dffc6f9.tar.gz
inkscape-db722f5b79ef1517f0b6e9a96968ad257dffc6f9.zip
Add capability to get style rulesets as SPStyle objects
-rw-r--r--src/object/sp-style-elem.cpp17
-rw-r--r--src/object/sp-style-elem.h14
-rw-r--r--src/style.cpp11
-rw-r--r--src/style.h1
-rw-r--r--testfiles/CMakeLists.txt1
-rw-r--r--testfiles/src/style-elem-test.cpp77
6 files changed, 115 insertions, 6 deletions
diff --git a/src/object/sp-style-elem.cpp b/src/object/sp-style-elem.cpp
index 14e4a8d90..de2041764 100644
--- a/src/object/sp-style-elem.cpp
+++ b/src/object/sp-style-elem.cpp
@@ -450,6 +450,23 @@ void update_style_recursively( SPObject *object ) {
}
}
+/*
+ * Returns each statement as an SPStyle
+ */
+std::vector<SPStyle *> SPStyleElem::getStyles() {
+ std::vector<SPStyle *> ret;
+ gint count = cr_stylesheet_nr_rules(style_sheet);
+
+ for (gint x = 0; x < count; x++) {
+ SPStyle *item = new SPStyle(nullptr, nullptr);
+ CRStatement *statement = cr_stylesheet_statement_get_from_list(style_sheet, x);
+ item->mergeStatement(statement);
+ ret.push_back(item);
+ }
+
+ return ret;
+}
+
void SPStyleElem::read_content() {
// First, create the style-sheet object and track it in this
diff --git a/src/object/sp-style-elem.h b/src/object/sp-style-elem.h
index b2c38f20b..76089172e 100644
--- a/src/object/sp-style-elem.h
+++ b/src/object/sp-style-elem.h
@@ -15,8 +15,8 @@
class SPStyleElem : public SPObject {
public:
- SPStyleElem();
- ~SPStyleElem() override;
+ SPStyleElem();
+ ~SPStyleElem() override;
// Container for the libcroco style sheet instance created on load.
CRStyleSheet *style_sheet;
@@ -24,10 +24,12 @@ public:
Media media;
bool is_css;
- void build(SPDocument* doc, Inkscape::XML::Node* repr) override;
- void set(SPAttributeEnum key, char const* value) override;
- void read_content() override;
- Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags) override;
+ void build(SPDocument* doc, Inkscape::XML::Node* repr) override;
+ void set(SPAttributeEnum key, char const* value) override;
+ void read_content() override;
+ Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags) override;
+
+ std::vector<SPStyle *> getStyles();
};
diff --git a/src/style.cpp b/src/style.cpp
index 529b9bb0a..09f7f763c 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -807,6 +807,17 @@ SPStyle::mergeString( gchar const *const p ) {
_mergeString( p );
}
+/**
+ * Append an existing css statement into this style, used in css editing
+ * always appends declarations as STYLE_SHEET properties.
+ */
+void
+SPStyle::mergeStatement( CRStatement *statement ) {
+ CRDeclaration *decl_list = NULL;
+ cr_statement_ruleset_get_declarations (statement, &decl_list);
+ _mergeDeclList(decl_list, SP_STYLE_SRC_STYLE_SHEET);
+}
+
// Mostly for unit testing
bool
SPStyle::operator==(const SPStyle& rhs) {
diff --git a/src/style.h b/src/style.h
index 2552449c8..47874096a 100644
--- a/src/style.h
+++ b/src/style.h
@@ -58,6 +58,7 @@ public:
void cascade( SPStyle const *const parent );
void merge( SPStyle const *const parent );
void mergeString( char const *const p );
+ void mergeStatement( CRStatement *statement );
bool operator==(const SPStyle& rhs);
int style_ref() { ++_refcount; return _refcount; }
diff --git a/testfiles/CMakeLists.txt b/testfiles/CMakeLists.txt
index 1b793cb10..d19d64dce 100644
--- a/testfiles/CMakeLists.txt
+++ b/testfiles/CMakeLists.txt
@@ -21,6 +21,7 @@ set(TEST_SOURCES
sp-object-test
object-set-test
object-style-test
+ style-elem-test
style-test
sp-gradient-test
object-test)
diff --git a/testfiles/src/style-elem-test.cpp b/testfiles/src/style-elem-test.cpp
new file mode 100644
index 000000000..443c547ac
--- /dev/null
+++ b/testfiles/src/style-elem-test.cpp
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/** @file
+ * Test the API to the style element, access, read and write functions.
+ *//*
+ *
+ * Authors:
+ * Martin Owens
+ *
+ * Copyright (C) 2018 Authors
+ *
+ * Released under GNU GPL version 2 or later, read the file 'COPYING' for more information
+ */
+
+#include <gtest/gtest.h>
+#include <doc-per-case-test.h>
+
+#include <src/style.h>
+#include <src/object/sp-root.h>
+#include <src/object/sp-style-elem.h>
+
+using namespace Inkscape;
+using namespace Inkscape::XML;
+
+class ObjectTest: public DocPerCaseTest {
+public:
+ ObjectTest() {
+ char const *docString = "\
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>\
+<style id='style01'>\
+rect { fill: red; opacity:0.5; }\
+#id1, #id2 { fill: red; stroke: #c0c0c0; }\
+.cls1 { fill: red; opacity:1.0; }\
+</style>\
+<style id='style02'>\
+rect { fill: green; opacity:1.0; }\
+#id3, #id4 { fill: green; stroke: #606060; }\
+.cls2 { fill: green; opacity:0.5; }\
+</style>\
+</svg>";
+ doc = SPDocument::createNewDocFromMem(docString, static_cast<int>(strlen(docString)), false);
+ }
+
+ ~ObjectTest() {
+ doc->doUnref();
+ }
+
+ SPDocument *doc;
+};
+
+/*
+ * Test sp-style-element objects created in document.
+ */
+TEST_F(ObjectTest, StyleElems) {
+ ASSERT_TRUE(doc != nullptr);
+ ASSERT_TRUE(doc->getRoot() != nullptr);
+
+ SPRoot *root = doc->getRoot();
+ ASSERT_TRUE(root->getRepr() != nullptr);
+
+ SPStyleElem *one = dynamic_cast<SPStyleElem *>(doc->getObjectById("style01"));
+ ASSERT_TRUE(one != nullptr);
+
+ std::vector<SPStyle *> styles = one->getStyles();
+
+ for(auto style: styles) {
+ EXPECT_EQ(style->fill.get_value(), Glib::ustring("#ff0000"));
+ }
+
+ SPStyleElem *two = dynamic_cast<SPStyleElem *>(doc->getObjectById("style02"));
+ ASSERT_TRUE(one != nullptr);
+
+ std::vector<SPStyle *> styles_two = two->getStyles();
+
+ for(auto style: styles_two) {
+ EXPECT_EQ(style->fill.get_value(), Glib::ustring("#008000"));
+ }
+}