Code

Correcting black gradient stops when swatches are set or drug.
authorJon A. Cruz <jon@joncruz.org>
Sun, 18 Jul 2010 08:46:40 +0000 (01:46 -0700)
committerJon A. Cruz <jon@joncruz.org>
Sun, 18 Jul 2010 08:46:40 +0000 (01:46 -0700)
src/sp-gradient.cpp
src/sp-gradient.h
src/sp-stop.cpp
src/sp-stop.h
src/style.cpp
src/style.h
src/widgets/gradient-vector.cpp

index 34912d1dafc11b0dccb1f9f78d0c7b93161327d7..68efd08322e2990a5bbdbde7638ca9bdce17d7bd 100644 (file)
@@ -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 <number> 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);
index b05cb5fb82f4dbb2fffa00f6014bbd91f1434935..97ea78fca4d773f2b7307f26ad299c2816a3ee3d 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <gdk/gdktypes.h>
+#include <glibmm/ustring.h>
 #include "libnr/nr-matrix.h"
 #include "sp-paint-server.h"
 #include "sp-gradient-spread.h"
index 740cfef7853e49dc0eedf63a13ea247ccb08d388..031c6a3ea8f00060f855c6c928de6ee031fd4061 100644 (file)
@@ -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;
+}
+
 
 
 /*
index bf6893db1262920a1dc84d8f373d30e68ef21108..2cf8ad6901aa034856508f54e3ccb6cf04079206 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <glib/gtypes.h>
+#include <glibmm/ustring.h>
 #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.
index ffc1fb0aeaf9eb6681eb8e352c851cc5f03e4ca5..380decc48776b4b3611a19f40b8ae748f83c1226 100644 (file)
@@ -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()
 {
index 8102ce0ea6834d199c1429bf33414f6d85111604..f650cae602a9d6412e42887c751f36a97ea6219c 100644 (file)
@@ -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
index c49d9e06f0685427023ec6d585f5927c7d65a8a0..7f02566653374ee4a5d66eb4d99135a57ffff706 100644 (file)
@@ -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<GtkOptionMenu *>(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<GtkWidget *>(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<SPColorSelector*>(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<gdouble>(alpha) <<";";
+    os << "stop-color:" << color.toString() << ";stop-opacity:" << static_cast<gdouble>(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<gdouble>(alpha));
     //SP_OBJECT_REPR(stop)->setAttribute("style", c);