From 74ba6bbc2af90e342434b2a1b7a65bfe70f9d33f Mon Sep 17 00:00:00 2001 From: buliabyak Date: Tue, 14 Mar 2006 02:24:35 +0000 Subject: [PATCH] differentiate _hreffed and _listening flags for color, fill, and stroke paintservers - fixes two crashes --- src/style.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++--------- src/style.h | 12 +++++--- 2 files changed, 74 insertions(+), 17 deletions(-) diff --git a/src/style.cpp b/src/style.cpp index 3ed6f335f..deffba366 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -390,8 +390,14 @@ sp_style_new() sp_style_clear(style); style->cloned = false; - style->hreffed = false; - style->listening = 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; return style; } @@ -2003,15 +2009,27 @@ sp_style_merge_ipaint(SPStyle *style, SPIPaint *paint, SPIPaint const *parent) paint->value.paint.uri = parent->value.paint.uri; if (paint->value.paint.server) { if (style->object && !style->cloned) { // href paintserver for style of non-clones only - style->hreffed = true; sp_object_href(SP_OBJECT(paint->value.paint.server), style); + if (paint == &style->fill) { + style->fill_hreffed = true; + } else if (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) g_signal_connect(G_OBJECT(paint->value.paint.server), "release", G_CALLBACK(sp_style_paint_server_release), style); g_signal_connect(G_OBJECT(paint->value.paint.server), "modified", G_CALLBACK(sp_style_paint_server_modified), style); - style->listening = true; + if (paint == &style->fill) { + style->fill_listening = true; + } else if (paint == &style->stroke) { + style->stroke_listening = true; + } else if (paint == &style->color) { + style->color_listening = true; + } } } break; @@ -2859,14 +2877,26 @@ sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume paint->value.paint.server = SP_PAINT_SERVER(ps); if (style->object && !style->cloned) { sp_object_href(SP_OBJECT(paint->value.paint.server), style); - style->hreffed = true; + if (paint == &style->fill) { + style->fill_hreffed = true; + } else if (paint == &style->stroke) { + style->stroke_hreffed = true; + } else if (paint == &style->color) { + style->color_hreffed = true; + } } if (style->object || style->cloned) { g_signal_connect(G_OBJECT(paint->value.paint.server), "release", G_CALLBACK(sp_style_paint_server_release), style); g_signal_connect(G_OBJECT(paint->value.paint.server), "modified", G_CALLBACK(sp_style_paint_server_modified), style); - style->listening = true; + if (paint == &style->fill) { + style->fill_listening = true; + } else if (paint == &style->stroke) { + style->stroke_listening = true; + } else if (paint == &style->color) { + style->color_listening = true; + } } } else { paint->value.paint.server = NULL; @@ -3404,15 +3434,38 @@ sp_style_paint_clear(SPStyle *style, SPIPaint *paint, unsigned hunref, unsigned unset) { if (hunref && (paint->type == SP_PAINT_TYPE_PAINTSERVER) && paint->value.paint.server) { - if (style->hreffed) { - sp_object_hunref(SP_OBJECT(paint->value.paint.server), style); - style->hreffed = false; - } - if (style->listening) { - g_signal_handlers_disconnect_matched(G_OBJECT(paint->value.paint.server), + if (paint == &style->fill) { + if (style->fill_hreffed) { + sp_object_hunref(SP_OBJECT(paint->value.paint.server), style); + style->fill_hreffed = false; + } + if (style->fill_listening) { + g_signal_handlers_disconnect_matched(G_OBJECT(paint->value.paint.server), + G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, style); + style->fill_listening = false; + } + } else if (paint == &style->stroke) { + if (style->stroke_hreffed) { + sp_object_hunref(SP_OBJECT(paint->value.paint.server), style); + style->stroke_hreffed = false; + } + if (style->stroke_listening) { + g_signal_handlers_disconnect_matched(G_OBJECT(paint->value.paint.server), + 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->listening = false; + style->color_listening = false; + } } + paint->value.paint.server = NULL; paint->value.paint.uri = NULL; paint->type = SP_PAINT_TYPE_NONE; diff --git a/src/style.h b/src/style.h index 333344ad9..cad454efd 100644 --- a/src/style.h +++ b/src/style.h @@ -321,10 +321,14 @@ struct SPStyle { /// style belongs to a cloned object, must not href anything bool cloned; - /// style has hreffed its paintservers, needs to release - bool hreffed; - /// style is listening to changes in paintservers, need to disconnect - bool listening; + /// style has hreffed its color/fill/stroke paintservers, needs to release + bool color_hreffed; + bool fill_hreffed; + bool stroke_hreffed; + /// style is listening to changes in color/fill/stroke paintservers, needs to disconnect + bool color_listening; + bool fill_listening; + bool stroke_listening; }; SPStyle *sp_style_new(); -- 2.30.2