diff options
| author | Martin Owens <doctormo@gmail.com> | 2018-11-13 00:25:05 +0000 |
|---|---|---|
| committer | Martin Owens <doctormo@gmail.com> | 2018-11-13 00:25:05 +0000 |
| commit | db722f5b79ef1517f0b6e9a96968ad257dffc6f9 (patch) | |
| tree | f7992f8cc42739e3aef74233efaf840045c9cb87 | |
| parent | Support multiple style sheets or style elements in an svg document (diff) | |
| download | inkscape-db722f5b79ef1517f0b6e9a96968ad257dffc6f9.tar.gz inkscape-db722f5b79ef1517f0b6e9a96968ad257dffc6f9.zip | |
Add capability to get style rulesets as SPStyle objects
| -rw-r--r-- | src/object/sp-style-elem.cpp | 17 | ||||
| -rw-r--r-- | src/object/sp-style-elem.h | 14 | ||||
| -rw-r--r-- | src/style.cpp | 11 | ||||
| -rw-r--r-- | src/style.h | 1 | ||||
| -rw-r--r-- | testfiles/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | testfiles/src/style-elem-test.cpp | 77 |
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")); + } +} |
