diff options
Diffstat (limited to 'src/sp-stop.cpp')
| -rw-r--r-- | src/sp-stop.cpp | 199 |
1 files changed, 191 insertions, 8 deletions
diff --git a/src/sp-stop.cpp b/src/sp-stop.cpp index 0c0a3b03a..d644a9b4b 100644 --- a/src/sp-stop.cpp +++ b/src/sp-stop.cpp @@ -17,9 +17,166 @@ #include "sp-stop.h" #include "style.h" +#include "attributes.h" +#include "streq.h" +#include "svg/svg.h" +#include "svg/svg-color.h" +#include "svg/css-ostringstream.h" +#include "xml/repr.h" + +#include "sp-factory.h" + +namespace { + SPObject* createStop() { + return new SPStop(); + } + + bool stopRegistered = SPFactory::instance().registerObject("svg:stop", createStop); +} + +SPStop::SPStop() : SPObject() { + this->path_string = NULL; + + this->offset = 0.0; + this->currentColor = false; + this->specified_color.set( 0x000000ff ); + this->opacity = 1.0; +} + +SPStop::~SPStop() { +} + +void SPStop::build(SPDocument* doc, Inkscape::XML::Node* repr) { + SPObject::build(doc, repr); + + this->readAttr( "offset" ); + this->readAttr( "stop-color" ); + this->readAttr( "stop-opacity" ); + this->readAttr( "style" ); + this->readAttr( "path" ); // For mesh +} + +/** + * Virtual build: set stop attributes from its associated XML node. + */ + +void SPStop::set(unsigned int key, const gchar* value) { + switch (key) { + case SP_ATTR_STYLE: { + /** \todo + * fixme: We are reading simple values 3 times during build (Lauris). + * \par + * We need presentation attributes etc. + * \par + * remove the hackish "style reading" from here: see comments in + * sp_object_get_style_property about the bugs in our current + * approach. However, note that SPStyle doesn't currently have + * stop-color and stop-opacity properties. + */ + { + gchar const *p = this->getStyleProperty( "stop-color", "black"); + if (streq(p, "currentColor")) { + this->currentColor = true; + } else { + this->specified_color = SPStop::readStopColor( p ); + } + } + { + gchar const *p = this->getStyleProperty( "stop-opacity", "1"); + gdouble opacity = sp_svg_read_percentage(p, this->opacity); + this->opacity = opacity; + } + this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + break; + } + case SP_PROP_STOP_COLOR: { + { + gchar const *p = this->getStyleProperty( "stop-color", "black"); + if (streq(p, "currentColor")) { + this->currentColor = true; + } else { + this->currentColor = false; + this->specified_color = SPStop::readStopColor( p ); + } + } + this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + break; + } + case SP_PROP_STOP_OPACITY: { + { + gchar const *p = this->getStyleProperty( "stop-opacity", "1"); + gdouble opacity = sp_svg_read_percentage(p, this->opacity); + this->opacity = opacity; + } + this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + break; + } + case SP_ATTR_OFFSET: { + this->offset = sp_svg_read_percentage(value, 0.0); + this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + break; + } + case SP_PROP_STOP_PATH: { + if (value) { + this->path_string = new Glib::ustring( value ); + //Geom::PathVector pv = sp_svg_read_pathv(value); + //SPCurve *curve = new SPCurve(pv); + //if( curve ) { + // std::cout << "Got Curve" << std::endl; + //curve->unref(); + //} + } + break; + } + default: { + SPObject::set(key, value); + break; + } + } +} + +/** + * Virtual set: set attribute to value. + */ + +Inkscape::XML::Node* SPStop::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) { + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = xml_doc->createElement("svg:stop"); + } + + Glib::ustring colorStr = this->specified_color.toString(); + gfloat opacity = this->opacity; + + SPObject::write(xml_doc, repr, flags); + + // Since we do a hackish style setting here (because SPStyle does not support stop-color and + // stop-opacity), we must do it AFTER calling the parent write method; otherwise + // sp_object_write would clear our style= attribute (bug 1695287) + + Inkscape::CSSOStringStream os; + os << "stop-color:"; + if (this->currentColor) { + os << "currentColor"; + } else { + os << colorStr; + } + os << ";stop-opacity:" << opacity; + repr->setAttribute("style", os.str().c_str()); + repr->setAttribute("stop-color", NULL); + repr->setAttribute("stop-opacity", NULL); + sp_repr_set_css_double(repr, "offset", this->offset); + /* strictly speaking, offset an SVG <number> rather than a CSS one, but exponents make no sense + * for offset proportions. */ + + return repr; +} + +/** + * Virtual write: write object attributes to repr. + */ + // A stop might have some non-stop siblings -SPStop* SPStop::getNextStop() -{ +SPStop* SPStop::getNextStop() { SPStop *result = 0; for (SPObject* obj = getNext(); obj && !result; obj = obj->getNext()) { @@ -31,8 +188,7 @@ SPStop* SPStop::getNextStop() return result; } -SPStop* SPStop::getPrevStop() -{ +SPStop* SPStop::getPrevStop() { SPStop *result = 0; for (SPObject* obj = getPrev(); obj; obj = obj->getPrev()) { @@ -52,22 +208,24 @@ SPStop* SPStop::getPrevStop() return result; } -SPColor SPStop::readStopColor( Glib::ustring const &styleStr, guint32 dfl ) -{ +SPColor SPStop::readStopColor(Glib::ustring const &styleStr, guint32 dfl) { SPColor color(dfl); SPStyle* style = sp_style_new(0); SPIPaint paint; paint.read( styleStr.c_str(), *style ); + if ( paint.isColor() ) { color = paint.value.color; } + sp_style_unref(style); + return color; } -SPColor SPStop::getEffectiveColor() const -{ +SPColor SPStop::getEffectiveColor() const { SPColor ret; + if (currentColor) { char const *str = getStyleProperty("color", NULL); /* Default value: arbitrarily black. (SVG1.1 and CSS2 both say that the initial @@ -77,10 +235,35 @@ SPColor SPStop::getEffectiveColor() const } else { ret = specified_color; } + return ret; } +/** + * Return stop's color as 32bit value. + */ +guint32 SPStop::get_rgba32() const { + guint32 rgb0 = 0; + + /* Default value: arbitrarily black. (SVG1.1 and CSS2 both say that the initial + * value depends on user agent, and don't give any further restrictions that I can + * see.) */ + if (this->currentColor) { + char const *str = this->getStyleProperty("color", NULL); + if (str) { + rgb0 = sp_svg_read_color(str, rgb0); + } + + unsigned const alpha = static_cast<unsigned>(this->opacity * 0xff + 0.5); + + g_return_val_if_fail((alpha & ~0xff) == 0, rgb0 | 0xff); + + return rgb0 | alpha; + } else { + return this->specified_color.toRGBA32(this->opacity); + } +} /* Local Variables: |
