X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fstyle.cpp;h=2a0a30bd165b91fb4b12171307aa3bb3463b90da;hb=2c9c6838241516364d68db0d30520e18f70fc70d;hp=deffba366670dca9018b8e66ba5ed195e7142511;hpb=74ba6bbc2af90e342434b2a1b7a65bfe70f9d33f;p=inkscape.git diff --git a/src/style.cpp b/src/style.cpp index deffba366..2a0a30bd1 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -24,6 +24,7 @@ #include "svg/svg.h" #include "svg/svg-color.h" +#include "svg/svg-icc-color.h" #include "display/canvas-bpath.h" #include "attributes.h" @@ -40,6 +41,9 @@ #include "unit-constants.h" #include "isnan.h" +using Inkscape::CSSOStringStream; +using std::vector; + namespace Inkscape { /** @@ -148,7 +152,7 @@ static gint sp_style_write_itextdecoration(gchar *p, gint const len, gchar const static void css2_unescape_unquote(SPIString *val); -static void sp_style_paint_clear(SPStyle *style, SPIPaint *paint, unsigned hunref, unsigned unset); +static void sp_style_paint_clear(SPStyle *style, SPIPaint *paint); #define SPS_READ_IENUM_IF_UNSET(v,s,d,i) if (!(v)->set) {sp_style_read_ienum((v), (s), (d), (i));} #define SPS_READ_PENUM_IF_UNSET(v,r,k,d,i) if (!(v)->set) {sp_style_read_penum((v), (r), (k), (d), (i));} @@ -391,11 +395,9 @@ sp_style_new() style->cloned = false; - style->color_hreffed = false; style->fill_hreffed = false; style->stroke_hreffed = false; - style->color_listening = false; style->fill_listening = false; style->stroke_listening = false; @@ -455,8 +457,8 @@ sp_style_unref(SPStyle *style) g_signal_handlers_disconnect_matched(G_OBJECT(style->object), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, style); if (style->text) sp_text_style_unref(style->text); - sp_style_paint_clear(style, &style->fill, TRUE, FALSE); - sp_style_paint_clear(style, &style->stroke, TRUE, FALSE); + sp_style_paint_clear(style, &style->fill); + sp_style_paint_clear(style, &style->stroke); g_free(style->stroke_dash.dash); g_free(style); } @@ -1936,13 +1938,13 @@ sp_style_paint_server_release(SPPaintServer *server, SPStyle *style) if ((style->fill.type == SP_PAINT_TYPE_PAINTSERVER) && (server == style->fill.value.paint.server)) { - sp_style_paint_clear(style, &style->fill, TRUE, FALSE); + sp_style_paint_clear(style, &style->fill); } if ((style->stroke.type == SP_PAINT_TYPE_PAINTSERVER) && (server == style->stroke.value.paint.server)) { - sp_style_paint_clear(style, &style->stroke, TRUE, FALSE); + sp_style_paint_clear(style, &style->stroke); } } @@ -1990,7 +1992,7 @@ sp_style_paint_server_modified(SPPaintServer *server, guint flags, SPStyle *styl static void sp_style_merge_ipaint(SPStyle *style, SPIPaint *paint, SPIPaint const *parent) { - sp_style_paint_clear(style, paint, TRUE, FALSE); + sp_style_paint_clear(style, paint); if ((paint->set && paint->currentcolor) || parent->currentcolor) { paint->currentcolor = TRUE; @@ -2012,10 +2014,9 @@ sp_style_merge_ipaint(SPStyle *style, SPIPaint *paint, SPIPaint const *parent) sp_object_href(SP_OBJECT(paint->value.paint.server), style); if (paint == &style->fill) { style->fill_hreffed = true; - } else if (paint == &style->stroke) { + } else { + assert(paint == &style->stroke); style->stroke_hreffed = true; - } else if (paint == &style->color) { - style->color_hreffed = true; } } if (style->object || style->cloned) { // connect to signals for style of real objects or clones (this excludes temp styles) @@ -2025,10 +2026,9 @@ sp_style_merge_ipaint(SPStyle *style, SPIPaint *paint, SPIPaint const *parent) G_CALLBACK(sp_style_paint_server_modified), style); if (paint == &style->fill) { style->fill_listening = true; - } else if (paint == &style->stroke) { + } else { + assert(paint == &style->stroke); style->stroke_listening = true; - } else if (paint == &style->color) { - style->color_listening = true; } } } @@ -2306,8 +2306,8 @@ sp_style_clear(SPStyle *style) { g_return_if_fail(style != NULL); - sp_style_paint_clear(style, &style->fill, TRUE, FALSE); - sp_style_paint_clear(style, &style->stroke, TRUE, FALSE); + sp_style_paint_clear(style, &style->fill); + sp_style_paint_clear(style, &style->stroke); if (style->stroke_dash.dash) { g_free(style->stroke_dash.dash); } @@ -2838,6 +2838,8 @@ sp_style_read_icolor(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume /** * Set SPIPaint object from string. + * + * \pre paint == \&style.fill || paint == \&style.stroke. */ static void sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocument *document) @@ -2850,16 +2852,16 @@ sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume paint->set = TRUE; paint->inherit = TRUE; paint->currentcolor = FALSE; - } else if (streq(str, "currentColor")) { + } else if (streq(str, "currentColor") && paint != &style->color) { paint->set = TRUE; paint->inherit = FALSE; paint->currentcolor = TRUE; - } else if (streq(str, "none")) { + } else if (streq(str, "none") && paint != &style->color) { paint->type = SP_PAINT_TYPE_NONE; paint->set = TRUE; paint->inherit = FALSE; paint->currentcolor = FALSE; - } else if (strneq(str, "url", 3)) { + } else if (strneq(str, "url", 3) && paint != &style->color) { // this is alloc'd uri, but seems to be shared with a parent // potentially, so it's not any easy g_free case... paint->value.paint.uri = extract_uri(str); @@ -2879,10 +2881,9 @@ sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume sp_object_href(SP_OBJECT(paint->value.paint.server), style); if (paint == &style->fill) { style->fill_hreffed = true; - } else if (paint == &style->stroke) { + } else { + assert(paint == &style->stroke); style->stroke_hreffed = true; - } else if (paint == &style->color) { - style->color_hreffed = true; } } if (style->object || style->cloned) { @@ -2892,10 +2893,9 @@ sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume G_CALLBACK(sp_style_paint_server_modified), style); if (paint == &style->fill) { style->fill_listening = true; - } else if (paint == &style->stroke) { + } else { + assert(paint == &style->stroke); style->stroke_listening = true; - } else if (paint == &style->color) { - style->color_listening = true; } } } else { @@ -2903,13 +2903,25 @@ sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume } } } else { - guint32 const rgb0 = sp_svg_read_color(str, 0xff); + guint32 const rgb0 = sp_svg_read_color(str, &str, 0xff); if (rgb0 != 0xff) { paint->type = SP_PAINT_TYPE_COLOR; sp_color_set_rgb_rgba32(&paint->value.color, rgb0); paint->set = TRUE; paint->inherit = FALSE; paint->currentcolor = FALSE; + + while (g_ascii_isspace(*str)) { + ++str; + } + if (strneq(str, "icc-color(", 10)) { + SVGICCColor* tmp = new SVGICCColor(); + if ( ! sp_svg_read_icc_color( str, &str, tmp ) ) { + delete tmp; + tmp = 0; + } + paint->iccColor = tmp; + } } } } @@ -3329,7 +3341,13 @@ sp_paint_differ(SPIPaint const *const a, SPIPaint const *const b) if (a->type != b->type) return true; if (a->type == SP_PAINT_TYPE_COLOR) - return !sp_color_is_equal(&a->value.color, &b->value.color); + return !(sp_color_is_equal(&a->value.color, &b->value.color) + && ((a->iccColor == b->iccColor) + || (a->iccColor && b->iccColor + && (a->iccColor->colorProfile == b->iccColor->colorProfile) + && (a->iccColor->colors == b->iccColor->colors)))); + /* todo: Allow for epsilon differences in iccColor->colors, e.g. changes small enough not to show up + * in the string representation. */ if (a->type == SP_PAINT_TYPE_PAINTSERVER) return (a->value.paint.server != b->value.paint.server); return false; @@ -3358,7 +3376,19 @@ sp_style_write_ipaint(gchar *b, gint const len, gchar const *const key, case SP_PAINT_TYPE_COLOR: { char color_buf[8]; sp_svg_write_color(color_buf, sizeof(color_buf), sp_color_get_rgba32_ualpha(&paint->value.color, 0)); - return g_snprintf(b, len, "%s:%s;", key, color_buf); + if (paint->iccColor) { + CSSOStringStream css; + css << color_buf << " icc-color(" << paint->iccColor->colorProfile; + for (vector::const_iterator i(paint->iccColor->colors.begin()), + iEnd(paint->iccColor->colors.end()); + i != iEnd; ++i) { + css << ", " << *i; + } + css << ')'; + return g_snprintf(b, len, "%s:%s;", key, css.gcharp()); + } else { + return g_snprintf(b, len, "%s:%s;", key, color_buf); + } } case SP_PAINT_TYPE_PAINTSERVER: return g_snprintf(b, len, "%s:url(%s);", key, paint->value.paint.uri); @@ -3427,13 +3457,12 @@ sp_style_write_ifontsize(gchar *p, gint const len, gchar const *key, /** - * Clear paint object; conditionally disconnect style from paintserver. + * Clear paint object, and disconnect style from paintserver (if present). */ static void -sp_style_paint_clear(SPStyle *style, SPIPaint *paint, - unsigned hunref, unsigned unset) +sp_style_paint_clear(SPStyle *style, SPIPaint *paint) { - if (hunref && (paint->type == SP_PAINT_TYPE_PAINTSERVER) && paint->value.paint.server) { + if ((paint->type == SP_PAINT_TYPE_PAINTSERVER) && paint->value.paint.server) { if (paint == &style->fill) { if (style->fill_hreffed) { sp_object_hunref(SP_OBJECT(paint->value.paint.server), style); @@ -3444,7 +3473,8 @@ sp_style_paint_clear(SPStyle *style, SPIPaint *paint, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, style); style->fill_listening = false; } - } else if (paint == &style->stroke) { + } else { + assert(paint == &style->stroke); // Only fill & stroke can have a paint server. if (style->stroke_hreffed) { sp_object_hunref(SP_OBJECT(paint->value.paint.server), style); style->stroke_hreffed = false; @@ -3454,27 +3484,14 @@ sp_style_paint_clear(SPStyle *style, SPIPaint *paint, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, style); style->stroke_listening = false; } - } else if (paint == &style->color) { - if (style->color_hreffed) { - sp_object_hunref(SP_OBJECT(paint->value.paint.server), style); - style->color_hreffed = false; - } - if (style->color_listening) { - g_signal_handlers_disconnect_matched(G_OBJECT(paint->value.paint.server), - G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, style); - style->color_listening = false; - } } paint->value.paint.server = NULL; - paint->value.paint.uri = NULL; - paint->type = SP_PAINT_TYPE_NONE; - } - - if (unset) { - paint->set = FALSE; - paint->inherit = FALSE; } + paint->value.paint.uri = NULL; + paint->type = SP_PAINT_TYPE_NONE; + delete paint->iccColor; + paint->iccColor = NULL; } /**