From e11d953841f9fb3d42e9a1655ecaf43e825b1058 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 18 Jul 2010 01:46:40 -0700 Subject: [PATCH] Correcting black gradient stops when swatches are set or drug. --- src/sp-gradient.cpp | 47 +++++--------------------- src/sp-gradient.h | 1 + src/sp-stop.cpp | 29 ++++++++++++++++- src/sp-stop.h | 5 +++ src/style.cpp | 58 +++++++++++++++++++-------------- src/style.h | 3 ++ src/widgets/gradient-vector.cpp | 37 ++++++--------------- 7 files changed, 89 insertions(+), 91 deletions(-) diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index 34912d1da..68efd0832 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -45,6 +45,7 @@ #include "streq.h" #include "uri.h" #include "xml/repr.h" +#include "style.h" #define SP_MACROS_SILENT #include "macros.h" @@ -172,9 +173,7 @@ sp_stop_set(SPObject *object, unsigned key, gchar const *value) if (streq(p, "currentColor")) { stop->currentColor = true; } else { - // TODO need to properly read full color, including icc - guint32 const color = sp_svg_read_color(p, 0); - stop->specified_color.set( color ); + stop->specified_color = SPStop::readStopColor( p ); } } { @@ -192,8 +191,7 @@ sp_stop_set(SPObject *object, unsigned key, gchar const *value) stop->currentColor = true; } else { stop->currentColor = false; - guint32 const color = sp_svg_read_color(p, 0); - stop->specified_color.set( color ); + stop->specified_color = SPStop::readStopColor( p ); } } object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); @@ -233,11 +231,12 @@ sp_stop_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML: repr = xml_doc->createElement("svg:stop"); } - guint32 specifiedcolor = stop->specified_color.toRGBA32( 255 ); + Glib::ustring colorStr = stop->specified_color.toString(); gfloat opacity = stop->opacity; - if (((SPObjectClass *) stop_parent_class)->write) + if (((SPObjectClass *) stop_parent_class)->write) { (* ((SPObjectClass *) stop_parent_class)->write)(object, 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 @@ -248,9 +247,7 @@ sp_stop_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML: if (stop->currentColor) { os << "currentColor"; } else { - gchar c[64]; - sp_svg_write_color(c, sizeof(c), specifiedcolor); - os << c; + os << colorStr; } os << ";stop-opacity:" << opacity; repr->setAttribute("style", os.str().c_str()); @@ -324,29 +321,6 @@ sp_stop_get_rgba32(SPStop const *const stop) } } -/** - * Return stop's color as SPColor. - */ -static SPColor -sp_stop_get_color(SPStop const *const stop) -{ - if (stop->currentColor) { - char const *str = sp_object_get_style_property(stop, "color", NULL); - guint32 const dfl = 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.) */ - guint32 color = dfl; - if (str) { - color = sp_svg_read_color(str, dfl); - } - SPColor ret( color ); - return ret; - } else { - return stop->specified_color; - } -} - /* * Gradient */ @@ -664,7 +638,6 @@ void SPGradientImpl::removeChild(SPObject *object, Inkscape::XML::Node *child) } if ( gr->getStopCount() == 0 ) { - g_message("Check on remove"); gchar const * attr = gr->repr->attribute("osb:paint"); if ( attr && strcmp(attr, "solid") ) { sp_object_setAttribute( gr, "osb:paint", "solid", 0 ); @@ -1000,9 +973,7 @@ sp_gradient_repr_write_vector(SPGradient *gr) sp_repr_set_css_double(child, "offset", gr->vector.stops[i].offset); /* strictly speaking, offset an SVG rather than a CSS one, but exponents make no * sense for offset proportions. */ - gchar c[64]; - sp_svg_write_color(c, sizeof(c), gr->vector.stops[i].color.toRGBA32( 0x00 )); - os << "stop-color:" << c << ";stop-opacity:" << gr->vector.stops[i].opacity; + os << "stop-color:" << gr->vector.stops[i].color.toString() << ";stop-opacity:" << gr->vector.stops[i].opacity; child->setAttribute("style", os.str().c_str()); /* Order will be reversed here */ cl = g_slist_prepend(cl, child); @@ -1099,7 +1070,7 @@ void SPGradient::rebuildVector() // down to 100%." gstop.offset = CLAMP(gstop.offset, 0, 1); - gstop.color = sp_stop_get_color(stop); + gstop.color = stop->getEffectiveColor(); gstop.opacity = stop->opacity; vector.stops.push_back(gstop); diff --git a/src/sp-gradient.h b/src/sp-gradient.h index b05cb5fb8..97ea78fca 100644 --- a/src/sp-gradient.h +++ b/src/sp-gradient.h @@ -18,6 +18,7 @@ */ #include +#include #include "libnr/nr-matrix.h" #include "sp-paint-server.h" #include "sp-gradient-spread.h" diff --git a/src/sp-stop.cpp b/src/sp-stop.cpp index 740cfef78..031c6a3ea 100644 --- a/src/sp-stop.cpp +++ b/src/sp-stop.cpp @@ -15,7 +15,7 @@ #include "sp-stop.h" - +#include "style.h" // A stop might have some non-stop siblings SPStop* SPStop::getNextStop() @@ -52,6 +52,33 @@ SPStop* SPStop::getPrevStop() return result; } +SPColor SPStop::readStopColor( Glib::ustring const &styleStr, guint32 dfl ) +{ + SPColor color(dfl); + SPStyle style; + SPIPaint paint; + paint.read( styleStr.c_str(), style ); + if ( paint.isColor() ) { + color = paint.value.color; + } + return color; +} + +SPColor SPStop::getEffectiveColor() const +{ + SPColor ret; + if (currentColor) { + char const *str = sp_object_get_style_property(this, "color", NULL); + /* 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.) */ + ret = readStopColor( str, 0 ); + } else { + ret = specified_color; + } + return ret; +} + /* diff --git a/src/sp-stop.h b/src/sp-stop.h index bf6893db1..2cf8ad690 100644 --- a/src/sp-stop.h +++ b/src/sp-stop.h @@ -9,6 +9,7 @@ */ #include +#include #include "sp-object.h" #include "color.h" @@ -43,8 +44,12 @@ struct SPStop : public SPObject { gfloat opacity; + static SPColor readStopColor( Glib::ustring const &styleStr, guint32 dfl = 0 ); + SPStop* getNextStop(); SPStop* getPrevStop(); + + SPColor getEffectiveColor() const; }; /// The SPStop vtable. diff --git a/src/style.cpp b/src/style.cpp index ffc1fb0ae..380decc48 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -85,7 +85,6 @@ static void sp_style_read_ilength(SPILength *val, gchar const *str); static void sp_style_read_ilengthornormal(SPILengthOrNormal *val, gchar const *str); static void sp_style_read_itextdecoration(SPITextDecoration *val, gchar const *str); static void sp_style_read_icolor(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocument *document); -static void sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocument *document); static void sp_style_read_ifontsize(SPIFontSize *val, gchar const *str); static void sp_style_read_ibaselineshift(SPIBaselineShift *val, gchar const *str); static void sp_style_read_ifilter(gchar const *str, SPStyle *style, SPDocument *document); @@ -662,7 +661,7 @@ sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr) if (!style->fill.set) { val = repr->attribute("fill"); if (val) { - sp_style_read_ipaint(&style->fill, val, style, (object) ? SP_OBJECT_DOCUMENT(object) : NULL); + style->fill.read( val, *style, (object) ? SP_OBJECT_DOCUMENT(object) : NULL ); } } /* fill-opacity */ @@ -678,7 +677,7 @@ sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr) if (!style->stroke.set) { val = repr->attribute("stroke"); if (val) { - sp_style_read_ipaint(&style->stroke, val, style, (object) ? SP_OBJECT_DOCUMENT(object) : NULL); + style->stroke.read( val, *style, (object) ? SP_OBJECT_DOCUMENT(object) : NULL ); } } SPS_READ_PLENGTH_IF_UNSET(&style->stroke_width, repr, "stroke-width"); @@ -1083,7 +1082,7 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val) } case SP_PROP_FILL: if (!style->fill.set) { - sp_style_read_ipaint(&style->fill, val, style, (style->object) ? SP_OBJECT_DOCUMENT(style->object) : NULL); + style->fill.read( val, *style, (style->object) ? SP_OBJECT_DOCUMENT(style->object) : NULL ); } break; case SP_PROP_FILL_OPACITY: @@ -1150,7 +1149,7 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val) case SP_PROP_STROKE: if (!style->stroke.set) { - sp_style_read_ipaint(&style->stroke, val, style, (style->object) ? SP_OBJECT_DOCUMENT(style->object) : NULL); + style->stroke.read( val, *style, (style->object) ? SP_OBJECT_DOCUMENT(style->object) : NULL ); } break; case SP_PROP_STROKE_WIDTH: @@ -3200,18 +3199,17 @@ sp_style_read_icolor(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume * * \pre paint == \&style.fill || paint == \&style.stroke. */ -static void -sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocument *document) +void SPIPaint::read( gchar const *str, SPStyle &style, SPDocument *document ) { while (g_ascii_isspace(*str)) { ++str; } - paint->clear(); + clear(); if (streq(str, "inherit")) { - paint->set = TRUE; - paint->inherit = TRUE; + set = TRUE; + inherit = TRUE; } else { if ( strneq(str, "url", 3) ) { gchar *uri = extract_uri( str, &str ); @@ -3219,33 +3217,33 @@ sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume ++str; } // TODO check on and comment the comparrison "paint != &style->color". - if ( uri && *uri && (paint != &style->color) ) { - paint->set = TRUE; + if ( uri && *uri && (this != &style.color) ) { + set = TRUE; // it may be that this style's SPIPaint has not yet created its URIReference; // now that we have a document, we can create it here - if (!paint->value.href && document) { - paint->value.href = new SPPaintServerReference(document); - paint->value.href->changedSignal().connect(sigc::bind(sigc::ptr_fun((paint == &style->fill)? sp_style_fill_paint_server_ref_changed : sp_style_stroke_paint_server_ref_changed), style)); + if (!value.href && document) { + value.href = new SPPaintServerReference(document); + value.href->changedSignal().connect(sigc::bind(sigc::ptr_fun((this == &style.fill)? sp_style_fill_paint_server_ref_changed : sp_style_stroke_paint_server_ref_changed), &style)); } // TODO check what this does in light of move away from union - sp_style_set_ipaint_to_uri_string (style, paint, uri); + sp_style_set_ipaint_to_uri_string (&style, this, uri); } g_free( uri ); } - if (streq(str, "currentColor") && paint != &style->color) { - paint->set = TRUE; - paint->currentcolor = TRUE; - } else if (streq(str, "none") && paint != &style->color) { - paint->set = TRUE; - paint->noneSet = TRUE; + if (streq(str, "currentColor") && (this != &style.color)) { + set = TRUE; + currentcolor = TRUE; + } else if (streq(str, "none") && (this != &style.color)) { + set = TRUE; + noneSet = TRUE; } else { guint32 const rgb0 = sp_svg_read_color(str, &str, 0xff); if (rgb0 != 0xff) { - paint->setColor( rgb0 ); - paint->set = TRUE; + setColor( rgb0 ); + set = TRUE; while (g_ascii_isspace(*str)) { ++str; @@ -3256,7 +3254,7 @@ sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume delete tmp; tmp = 0; } - paint->value.color.icc = tmp; + value.color.icc = tmp; } } } @@ -4025,6 +4023,16 @@ sp_style_write_ifilter(gchar *p, gint const len, gchar const *key, return 0; } +SPIPaint::SPIPaint() : + set(0), + inherit(0), + currentcolor(0), + colorSet(0), + noneSet(0), + value() +{ + value.href = 0; +} void SPIPaint::clear() { diff --git a/src/style.h b/src/style.h index 8102ce0ea..f650cae60 100644 --- a/src/style.h +++ b/src/style.h @@ -159,6 +159,7 @@ struct SPIPaint { SPColor color; } value; + SPIPaint(); bool isSet() const { return true; /* set || colorSet*/} bool isSameType( SPIPaint const & other ) const {return (isPaintserver() == other.isPaintserver()) && (colorSet == other.colorSet) && (currentcolor == other.currentcolor);} @@ -174,6 +175,8 @@ struct SPIPaint { void setColor( float r, float g, float b ) {value.color.set( r, g, b ); colorSet = true;} void setColor( guint32 val ) {value.color.set( val ); colorSet = true;} void setColor( SPColor const& color ) {value.color = color; colorSet = true;} + + void read( gchar const *str, SPStyle &tyle, SPDocument *document = 0); }; /// Filter type internal to SPStyle diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index c49d9e06f..7f0256665 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -479,11 +479,8 @@ static void verify_grad(SPGradient *gradient) xml_doc = SP_OBJECT_REPR(gradient)->document(); if (i < 1) { - gchar c[64]; - sp_svg_write_color(c, sizeof(c), 0x00000000); - Inkscape::CSSOStringStream os; - os << "stop-color:" << c << ";stop-opacity:" << 1.0 << ";"; + os << "stop-color: #000000;stop-opacity:" << 1.0 << ";"; Inkscape::XML::Node *child; @@ -555,11 +552,9 @@ static void update_stop_list( GtkWidget *mnu, SPGradient *gradient, SPStop *new_ } else { for (; sl != NULL; sl = sl->next){ - SPStop *stop; - GtkWidget *i; if (SP_IS_STOP(sl->data)){ - stop = SP_STOP(sl->data); - i = gtk_menu_item_new(); + SPStop *stop = SP_STOP(sl->data); + GtkWidget *i = gtk_menu_item_new(); gtk_widget_show(i); g_object_set_data(G_OBJECT(i), "stop", stop); GtkWidget *hb = gtk_hbox_new(FALSE, 4); @@ -605,11 +600,8 @@ static void sp_grad_edit_select(GtkOptionMenu *mnu, GtkWidget *tbl) blocked = TRUE; SPColorSelector *csel = (SPColorSelector*)g_object_get_data(G_OBJECT(tbl), "cselector"); - guint32 const c = sp_stop_get_rgba32(stop); - csel->base->setAlpha(SP_RGBA32_A_F(c)); - SPColor color( SP_RGBA32_R_F(c), SP_RGBA32_G_F(c), SP_RGBA32_B_F(c) ); // set its color, from the stored array - csel->base->setColor( color ); + csel->base->setColorAlpha( stop->getEffectiveColor(), stop->opacity ); GtkWidget *offspin = GTK_WIDGET(g_object_get_data(G_OBJECT(tbl), "offspn")); GtkWidget *offslide =GTK_WIDGET(g_object_get_data(G_OBJECT(tbl), "offslide")); @@ -1026,15 +1018,11 @@ static void sp_gradient_vector_widget_load_gradient(GtkWidget *widget, SPGradien GtkOptionMenu *mnu = static_cast(g_object_get_data(G_OBJECT(widget), "stopmenu")); SPStop *stop = SP_STOP(g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(mnu)))), "stop")); - guint32 const c = sp_stop_get_rgba32(stop); - /// get the color selector + // get the color selector SPColorSelector *csel = SP_COLOR_SELECTOR(g_object_get_data(G_OBJECT(widget), "cselector")); - // set alpha - csel->base->setAlpha(SP_RGBA32_A_F(c)); - SPColor color( SP_RGBA32_R_F(c), SP_RGBA32_G_F(c), SP_RGBA32_B_F(c) ); - // set color - csel->base->setColor( color ); + + csel->base->setColorAlpha( stop->getEffectiveColor(), stop->opacity ); /* Fill preview */ GtkWidget *w = static_cast(g_object_get_data(G_OBJECT(widget), "preview")); @@ -1159,10 +1147,6 @@ static void sp_gradient_vector_color_dragged(SPColorSelector *csel, GtkObject *o static void sp_gradient_vector_color_changed(SPColorSelector *csel, GtkObject *object) { - SPColor color; - float alpha; - guint32 rgb; - if (blocked) { return; } @@ -1190,14 +1174,13 @@ static void sp_gradient_vector_color_changed(SPColorSelector *csel, GtkObject *o SPStop *stop = SP_STOP(g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(mnu)))), "stop")); csel = static_cast(g_object_get_data(G_OBJECT(object), "cselector")); + SPColor color; + float alpha = 0; csel->base->getColorAlpha( color, alpha ); - rgb = color.toRGBA32( 0x00 ); sp_repr_set_css_double(SP_OBJECT_REPR(stop), "offset", stop->offset); Inkscape::CSSOStringStream os; - gchar c[64]; - sp_svg_write_color(c, sizeof(c), rgb); - os << "stop-color:" << c << ";stop-opacity:" << static_cast(alpha) <<";"; + os << "stop-color:" << color.toString() << ";stop-opacity:" << static_cast(alpha) <<";"; SP_OBJECT_REPR(stop)->setAttribute("style", os.str().c_str()); // g_snprintf(c, 256, "stop-color:#%06x;stop-opacity:%g;", rgb >> 8, static_cast(alpha)); //SP_OBJECT_REPR(stop)->setAttribute("style", c); -- 2.30.2