From 3a8e479f331858946168c32bfc7622c9010b6680 Mon Sep 17 00:00:00 2001 From: buliabyak Date: Wed, 27 Jun 2007 05:41:53 +0000 Subject: [PATCH] switch SPStyle to using SPFilterReference for filters; sp_style_new now requires an SPDocument; SPURIReference and SPFilterReference have an alternative constructor taking an owner_document instead of owner object --- src/desktop-style.cpp | 13 ++- src/dialogs/fill-style.cpp | 4 +- src/dialogs/object-properties.cpp | 2 +- src/dialogs/stroke-style.cpp | 6 +- src/dialogs/text-edit.cpp | 2 +- src/display/nr-arena-group.cpp | 7 +- src/display/nr-arena-image.cpp | 7 +- src/display/nr-arena-shape.cpp | 7 +- src/filter-chemistry.cpp | 13 ++- src/selection-chemistry.cpp | 7 +- src/sp-filter-reference.h | 1 + src/sp-item.cpp | 3 +- src/style.cpp | 176 +++++++++++++----------------- src/style.h | 11 +- src/text-editing.cpp | 6 +- src/ui/dialog/fill-and-stroke.cpp | 2 +- src/ui/widget/selected-style.cpp | 2 +- src/ui/widget/style-swatch.cpp | 2 +- src/uri-references.cpp | 17 ++- src/uri-references.h | 2 + src/widgets/dash-selector.cpp | 2 +- src/widgets/toolbox.cpp | 12 +- 22 files changed, 152 insertions(+), 152 deletions(-) diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 5685dc4d6..c6344da5c 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -26,6 +26,7 @@ #include "sp-use.h" #include "sp-feblend.h" #include "sp-filter.h" +#include "sp-filter-reference.h" #include "sp-gaussian-blur.h" #include "sp-flowtext.h" #include "sp-flowregion.h" @@ -351,7 +352,7 @@ sp_desktop_get_font_size_tool(SPDesktop *desktop) double ret = 12; if (style_str) { - SPStyle *style = sp_style_new(); + SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT); sp_style_merge_from_style_string(style, style_str); ret = style->font_size.computed; sp_style_unref(style); @@ -1029,12 +1030,12 @@ objects_query_blend (GSList *objects, SPStyle *style_res) items++; //if object has a filter - if (style->filter.set && style->filter.filter) { + if (style->filter.set && style->filter.href->getObject()) { int blurcount = 0; int blendcount = 0; // determine whether filter is simple (blend and/or blur) or complex - for(SPObject *primitive_obj = style->filter.filter->children; + for(SPObject *primitive_obj = style->filter.href->getObject()->children; primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); primitive_obj = primitive_obj->next) { SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj); @@ -1050,7 +1051,7 @@ objects_query_blend (GSList *objects, SPStyle *style_res) // simple filter if(blurcount == 1 || blendcount == 1) { - for(SPObject *primitive_obj = style->filter.filter->children; + for(SPObject *primitive_obj = style->filter.href->getObject()->children; primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); primitive_obj = primitive_obj->next) { if(SP_IS_FEBLEND(primitive_obj)) { @@ -1117,9 +1118,9 @@ objects_query_blur (GSList *objects, SPStyle *style_res) items ++; //if object has a filter - if (style->filter.set && style->filter.filter) { + if (style->filter.set && style->filter.href->getObject()) { //cycle through filter primitives - SPObject *primitive_obj = style->filter.filter->children; + SPObject *primitive_obj = style->filter.href->getObject()->children; while (primitive_obj) { if (SP_IS_FILTER_PRIMITIVE(primitive_obj)) { SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj); diff --git a/src/dialogs/fill-style.cpp b/src/dialogs/fill-style.cpp index 086838727..7ff5ebc96 100644 --- a/src/dialogs/fill-style.cpp +++ b/src/dialogs/fill-style.cpp @@ -185,7 +185,7 @@ sp_fill_style_widget_update (SPWidget *spw) SPPaintSelector *psel = SP_PAINT_SELECTOR (g_object_get_data (G_OBJECT (spw), "paint-selector")); // create temporary style - SPStyle *query = sp_style_new (); + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FILL); @@ -430,7 +430,7 @@ sp_fill_style_widget_paint_changed ( SPPaintSelector *psel, if (!vector) { /* No vector in paint selector should mean that we just changed mode */ - SPStyle *query = sp_style_new (); + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); int result = objects_query_fillstroke ((GSList *) items, query, true); guint32 common_rgb = 0; if (result == QUERY_STYLE_MULTIPLE_SAME) { diff --git a/src/dialogs/object-properties.cpp b/src/dialogs/object-properties.cpp index 7aa33fc5b..126deff38 100644 --- a/src/dialogs/object-properties.cpp +++ b/src/dialogs/object-properties.cpp @@ -304,7 +304,7 @@ sp_fillstroke_selection_changed ( Inkscape::Application *inkscape, GtkAdjustment *a = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(dlg), "master_opacity_adjustment")); // create temporary style - SPStyle *query = sp_style_new (); + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_MASTEROPACITY); diff --git a/src/dialogs/stroke-style.cpp b/src/dialogs/stroke-style.cpp index ed1082e26..fd43d374c 100644 --- a/src/dialogs/stroke-style.cpp +++ b/src/dialogs/stroke-style.cpp @@ -200,7 +200,7 @@ sp_stroke_style_paint_update (SPWidget *spw) SPPaintSelector *psel = SP_PAINT_SELECTOR(gtk_object_get_data(GTK_OBJECT(spw), "paint-selector")); // create temporary style - SPStyle *query = sp_style_new (); + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); // query into it int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKE); @@ -386,7 +386,7 @@ sp_stroke_style_paint_changed(SPPaintSelector *psel, SPWidget *spw) if (!vector) { /* No vector in paint selector should mean that we just changed mode */ - SPStyle *query = sp_style_new (); + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); int result = objects_query_fillstroke ((GSList *) items, query, false); guint32 common_rgb = 0; if (result == QUERY_STYLE_MULTIPLE_SAME) { @@ -1417,7 +1417,7 @@ sp_stroke_style_line_update(SPWidget *spw, Inkscape::Selection *sel) GtkWidget *dsel = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), "dash")); // create temporary style - SPStyle *query = sp_style_new (); + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); // query into it int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEWIDTH); int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); diff --git a/src/dialogs/text-edit.cpp b/src/dialogs/text-edit.cpp index b23023721..5a59fd2e5 100644 --- a/src/dialogs/text-edit.cpp +++ b/src/dialogs/text-edit.cpp @@ -734,7 +734,7 @@ sp_text_edit_dialog_read_selection ( GtkWidget *dlg, if (dostyle) { // create temporary style - SPStyle *query = sp_style_new (); + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); diff --git a/src/display/nr-arena-group.cpp b/src/display/nr-arena-group.cpp index da3a240a6..3f08f42f4 100644 --- a/src/display/nr-arena-group.cpp +++ b/src/display/nr-arena-group.cpp @@ -18,6 +18,7 @@ #include "display/nr-filter-types.h" #include "style.h" #include "sp-filter.h" +#include "sp-filter-reference.h" #include "sp-gaussian-blur.h" #include "sp-feblend.h" #include "display/nr-filter-blend.h" @@ -195,12 +196,12 @@ void nr_arena_group_set_style (NRArenaGroup *group, SPStyle *style) group->style = style; //if group has a filter - if (style->filter.set && style->filter.filter) { + if (style->filter.set && style->filter.href->getObject()) { if (!group->filter) { - int primitives = sp_filter_primitive_count(style->filter.filter); + int primitives = sp_filter_primitive_count(style->filter.href->getObject()); group->filter = new NR::Filter(primitives); } - sp_filter_build_renderer(style->filter.filter, group->filter); + sp_filter_build_renderer(style->filter.href->getObject(), group->filter); } else { //no filter set for this group delete group->filter; diff --git a/src/display/nr-arena-image.cpp b/src/display/nr-arena-image.cpp index 5f22dc5cd..87cc94e1b 100644 --- a/src/display/nr-arena-image.cpp +++ b/src/display/nr-arena-image.cpp @@ -23,6 +23,7 @@ #include #include #include "sp-filter.h" +#include "sp-filter-reference.h" #include "sp-gaussian-blur.h" #include "sp-feblend.h" #include "display/nr-filter-blend.h" @@ -368,12 +369,12 @@ void nr_arena_image_set_style (NRArenaImage *image, SPStyle *style) image->style = style; //if image has a filter - if (style->filter.set && style->filter.filter) { + if (style->filter.set && style->filter.href->getObject()) { if (!image->filter) { - int primitives = sp_filter_primitive_count(style->filter.filter); + int primitives = sp_filter_primitive_count(style->filter.href->getObject()); image->filter = new NR::Filter(primitives); } - sp_filter_build_renderer(style->filter.filter, image->filter); + sp_filter_build_renderer(style->filter.href->getObject(), image->filter); } else { //no filter set for this image delete image->filter; diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index c09bdb9dd..0e7dd2798 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -31,6 +31,7 @@ #include "inkscape-cairo.h" #include "sp-filter.h" +#include "sp-filter-reference.h" #include "display/nr-filter.h" #include @@ -1359,12 +1360,12 @@ nr_arena_shape_set_style(NRArenaShape *shape, SPStyle *style) shape->setMitreLimit(style->stroke_miterlimit.value); //if shape has a filter - if (style->filter.set && style->filter.filter) { + if (style->filter.set && style->filter.href->getObject()) { if (!shape->filter) { - int primitives = sp_filter_primitive_count(style->filter.filter); + int primitives = sp_filter_primitive_count(style->filter.href->getObject()); shape->filter = new NR::Filter(primitives); } - sp_filter_build_renderer(style->filter.filter, shape->filter); + sp_filter_build_renderer(style->filter.href->getObject(), shape->filter); } else { //no filter set for this shape delete shape->filter; diff --git a/src/filter-chemistry.cpp b/src/filter-chemistry.cpp index d3a02852e..5515d0a04 100644 --- a/src/filter-chemistry.cpp +++ b/src/filter-chemistry.cpp @@ -20,6 +20,7 @@ #include "sp-feblend.h" #include "sp-filter.h" +#include "sp-filter-reference.h" #include "sp-gaussian-blur.h" #include "svg/css-ostringstream.h" @@ -40,7 +41,7 @@ count_filter_hrefs(SPObject *o, SPFilter *filter) SPStyle *style = SP_OBJECT_STYLE(o); if (style && style->filter.set - && style->filter.filter == filter) + && style->filter.href->getObject() == filter) { i ++; } @@ -304,13 +305,13 @@ modify_filter_gaussian_blur_from_item(SPDocument *document, SPItem *item, //return new_filter_gaussian_blur_from_item(document, item, radius); } - SPFilter *filter = SP_FILTER(item->style->filter.filter); + SPFilter *filter = SP_FILTER(item->style->filter.href->getObject()); Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document); // If there are more users for this filter, duplicate it if (SP_OBJECT_HREFCOUNT(filter) > count_filter_hrefs(item, filter)) { Inkscape::XML::Node *repr; - repr = SP_OBJECT_REPR(item->style->filter.filter)->duplicate(xml_doc); + repr = SP_OBJECT_REPR(item->style->filter.href->getObject())->duplicate(xml_doc); SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document); SP_OBJECT_REPR(defs)->appendChild(repr); @@ -337,7 +338,7 @@ modify_filter_gaussian_blur_from_item(SPDocument *document, SPItem *item, } // Set the filter effects area - Inkscape::XML::Node *repr = SP_OBJECT_REPR(item->style->filter.filter); + Inkscape::XML::Node *repr = SP_OBJECT_REPR(item->style->filter.href->getObject()); set_filter_area(repr, radius, expansion, i2d.expansionX(), i2d.expansionY(), width, height); @@ -390,9 +391,9 @@ void remove_filter (SPObject *item, bool recursive) * be handled gracefully */ void remove_filter_gaussian_blur (SPObject *item) { - if (item->style && item->style->filter.set && item->style->filter.filter) { + if (item->style && item->style->filter.set && item->style->filter.href->getObject()) { // Search for the first blur primitive and remove it. (if found) - Inkscape::XML::Node *repr = SP_OBJECT_REPR(item->style->filter.filter); + Inkscape::XML::Node *repr = SP_OBJECT_REPR(item->style->filter.href->getObject()); Inkscape::XML::Node *primitive = repr->firstChild(); while (primitive) { if (strcmp("svg:feGaussianBlur", primitive->name()) == 0) { diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index ed8d6379e..27c04f1dd 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -73,6 +73,7 @@ #include "sp-item.h" #include "unit-constants.h" #include "xml/simple-document.h" +#include "sp-filter-reference.h" using NR::X; using NR::Y; @@ -952,8 +953,8 @@ void sp_copy_stuff_used_by_item (GSList **defs_clip, SPItem *item, const GSList } } - if (style->filter.filter) { - SPObject *filter = style->filter.filter; + if (style->filter.href->getObject()) { + SPObject *filter = style->filter.href->getObject(); if (SP_IS_FILTER(filter)) { sp_copy_single (defs_clip, filter, xml_doc); } @@ -1082,7 +1083,7 @@ void sp_selection_copy() sp_selection_copy_impl (items, &clipboard, &defs_clipboard, &style_clipboard, clipboard_document); if (tools_isactive (desktop, TOOLS_TEXT)) { // take style from cursor/text selection, overwriting the style just set by copy_impl - SPStyle *const query = sp_style_new(); + SPStyle *const query = sp_style_new(SP_ACTIVE_DOCUMENT); if (sp_desktop_query_style_all (desktop, query)) { SPCSSAttr *css = sp_css_attr_from_style (query, SP_STYLE_FLAG_ALWAYS); if (css != NULL) { diff --git a/src/sp-filter-reference.h b/src/sp-filter-reference.h index 226e033bb..216ff1d6f 100644 --- a/src/sp-filter-reference.h +++ b/src/sp-filter-reference.h @@ -8,6 +8,7 @@ class SPObject; class SPFilterReference : public Inkscape::URIReference { public: SPFilterReference(SPObject *obj) : URIReference(obj) {} + SPFilterReference(SPDocument *doc) : URIReference(doc) {} SPFilter *getObject() const { return (SPFilter *)URIReference::getObject(); diff --git a/src/sp-item.cpp b/src/sp-item.cpp index fbcc7b4a8..7c1a46447 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -50,6 +50,7 @@ #include "prefs-utils.h" #include "conn-avoid-ref.h" #include "conditions.h" +#include "sp-filter-reference.h" #include "libnr/nr-matrix-div.h" #include "libnr/nr-matrix-fns.h" @@ -1200,7 +1201,7 @@ sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix cons !preserve && // user did not chose to preserve all transforms !item->clip_ref->getObject() && // the object does not have a clippath !item->mask_ref->getObject() && // the object does not have a mask - !(!transform.is_translation() && SP_OBJECT_STYLE(item) && SP_OBJECT_STYLE(item)->filter.filter) + !(!transform.is_translation() && SP_OBJECT_STYLE(item) && SP_OBJECT_STYLE(item)->filter.href->getObject()) // the object does not have a filter, or the transform is translation (which is supposed to not affect filters) ) { transform_attr = ((SPItemClass *) G_OBJECT_GET_CLASS(item))->set_transform(item, transform); diff --git a/src/style.cpp b/src/style.cpp index e15c54636..46b544382 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -31,6 +31,7 @@ #include "document.h" #include "extract-uri.h" #include "uri-references.h" +#include "uri.h" #include "sp-paint-server.h" #include "streq.h" #include "strneq.h" @@ -39,6 +40,9 @@ #include "xml/repr.h" #include "unit-constants.h" #include "isnan.h" +#include "macros.h" + +#include "sp-filter-reference.h" #include #include @@ -386,14 +390,44 @@ sp_style_object_release(SPObject *object, SPStyle *style) style->object = NULL; } +/** + * Emit style modified signal on style's object if the filter changed. + */ +static void +sp_style_filter_ref_modified(SPObject *obj, guint flags, SPStyle *style) +{ + SPFilter *filter=static_cast(obj); + if (style->filter.href->getObject() == filter) + { + if (style->object) { + style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + } + } +} +/** + * Gets called when the filter is (re)attached to the style + */ +static void +sp_style_filter_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style) +{ + if (old_ref) { + sp_signal_disconnect_by_data(old_ref, style); + } + if ( SP_IS_FILTER(ref)) + { + ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_filter_ref_modified), style)); + } + + sp_style_filter_ref_modified(ref, 0, style); +} /** * Returns a new SPStyle object with settings as per sp_style_clear(). */ SPStyle * -sp_style_new() +sp_style_new(SPDocument *document) { SPStyle *const style = g_new0(SPStyle, 1); @@ -402,13 +436,17 @@ sp_style_new() style->text = sp_text_style_new(); style->text_private = TRUE; + if (document) { + style->filter.href = new SPFilterReference(document); + style->filter.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), style)); + } + sp_style_clear(style); style->cloned = false; style->fill_hreffed = false; style->stroke_hreffed = false; - style->filter_hreffed = false; new (&style->release_connection) sigc::connection(); @@ -418,9 +456,6 @@ sp_style_new() new (&style->stroke_release_connection) sigc::connection(); new (&style->stroke_modified_connection) sigc::connection(); - new (&style->filter_release_connection) sigc::connection(); - new (&style->filter_modified_connection) sigc::connection(); - return style; } @@ -434,7 +469,7 @@ sp_style_new_from_object(SPObject *object) g_return_val_if_fail(object != NULL, NULL); g_return_val_if_fail(SP_IS_OBJECT(object), NULL); - SPStyle *style = sp_style_new(); + SPStyle *style = sp_style_new(SP_OBJECT_DOCUMENT(object)); style->object = object; style->release_connection = object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_style_object_release), style)); @@ -487,10 +522,6 @@ sp_style_unref(SPStyle *style) style->stroke_release_connection.~connection(); style->stroke_modified_connection.disconnect(); style->stroke_modified_connection.~connection(); - style->filter_modified_connection.disconnect(); - style->filter_modified_connection.~connection(); - style->filter_release_connection.disconnect(); - style->filter_release_connection.~connection(); g_free(style->stroke_dash.dash); g_free(style); } @@ -699,7 +730,7 @@ sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr) } else { if (sp_repr_parent(repr)) { /// \todo fixme: This is not the prettiest thing (Lauris) - SPStyle *parent = sp_style_new(); + SPStyle *parent = sp_style_new(NULL); sp_style_read(parent, NULL, sp_repr_parent(repr)); sp_style_merge_from_parent(style, parent); sp_style_unref(parent); @@ -2061,38 +2092,6 @@ sp_style_paint_server_modified(SPObject *obj, guint flags, SPStyle *style) } } - - -/** - * Disconnects from filter. - */ -static void -sp_style_filter_release(SPObject *obj, SPStyle *style) -{ - SPFilter *filter=static_cast(obj); - if (style->filter.filter == filter) - { - sp_style_filter_clear(style); - } -} - - -/** - * Emit style modified signal on style's object if the filter changed. - */ -static void -sp_style_filter_modified(SPObject *obj, guint flags, SPStyle *style) -{ - SPFilter *filter=static_cast(obj); - if (style->filter.filter == filter) - { - if (style->object) { - style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - } - } -} - - /** * */ @@ -2162,20 +2161,15 @@ sp_style_merge_ifilter(SPStyle *style, SPIFilter const *parent) sp_style_filter_clear(style); style->filter.set = parent->set; style->filter.inherit = parent->inherit; - style->filter.filter = parent->filter; - style->filter.uri = parent->uri; - if (style->filter.filter) { - if (style->object && !style->cloned) { // href filter for style of non-clones only - sp_object_href(SP_OBJECT(style->filter.filter), style); - style->filter_hreffed = true; - } - if (style->object || style->cloned) { // connect to signals for style of real objects or clones (this excludes temp styles) - SPObject *filter = style->filter.filter; - style->filter_release_connection - = filter->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_style_filter_release), style)); - style->filter_modified_connection - = filter->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_style_filter_modified), style)); - } + + if (style->filter.href && style->filter.href->getObject()) + style->filter.href->detach(); + + try { + style->filter.href->attach(*parent->href->getURI()); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + style->filter.href->detach(); } } @@ -2574,10 +2568,6 @@ sp_style_clear(SPStyle *style) style->marker[i].set = FALSE; } - style->filter.set = FALSE; - style->filter.uri = NULL; - style->filter.filter = NULL; - style->enable_background.value = SP_CSS_BACKGROUND_ACCUMULATE; style->enable_background.set = false; style->enable_background.inherit = false; @@ -3162,49 +3152,46 @@ sp_style_read_ifilter(gchar const *str, SPStyle * style, SPDocument *document) if (streq(str, "inherit")) { f->set = TRUE; f->inherit = TRUE; - f->filter = NULL; + if (f->href && f->href->getObject()) + f->href->detach(); //f->filter = NULL; } else if(streq(str, "none")) { f->set = TRUE; f->inherit = FALSE; - f->filter = NULL; + if (f->href && f->href->getObject()) + f->href->detach(); //f->filter = NULL; } else if (strneq(str, "url", 3)) { - f->uri = extract_uri(str); - if(f->uri == NULL || f->uri[0] == '\0') { + char *uri = extract_uri(str); + if(uri == NULL || uri[0] == '\0') { g_warning("Specified filter url is empty"); f->set = TRUE; f->inherit = FALSE; - f->filter = NULL; return; } f->set = TRUE; f->inherit = FALSE; - f->filter = NULL; - if (document) { - SPObject *obj = sp_uri_reference_resolve(document, str); - if (SP_IS_FILTER(obj)) { - f->filter = SP_FILTER(obj); - if (style->object && !style->cloned) { - sp_object_href(obj, style); - style->filter_hreffed = true; - } - if (style->object || style->cloned) { // connect to signals for style of real objects or clones (this excludes temp styles) - SPObject *filter = style->filter.filter; - style->filter_release_connection - = filter->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_style_filter_release), style)); - style->filter_modified_connection - = filter->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_style_filter_modified), style)); - } - } else { - g_warning("Element '%s' not found or is not a filter", f->uri); - } + if (f->href && f->href->getObject()) + f->href->detach(); + + // it may be that this style has not yet created its SPFilterReference; + // now that we have a document, we can create it here + if (!f->href) { + f->href = new SPFilterReference(document); + f->href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), style)); + } + + try { + f->href->attach(Inkscape::URI(uri)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + f->href->detach(); } } else { /* We shouldn't reach this if SVG input is well-formed */ f->set = FALSE; f->inherit = FALSE; - f->filter = NULL; - f->uri = NULL; + if (f->href && f->href->getObject()) + f->href->detach(); } } @@ -3686,8 +3673,8 @@ sp_style_write_ifilter(gchar *p, gint const len, gchar const *key, { if (val->inherit) { return g_snprintf(p, len, "%s:inherit;", key); - } else if (val->uri) { - return g_snprintf(p, len, "%s:url(%s);", key, val->uri); + } else if (val->href->getURI()) { + return g_snprintf(p, len, "%s:url(%s);", key, val->href->getURI()->toString()); } } @@ -3735,15 +3722,8 @@ sp_style_paint_clear(SPStyle *style, SPIPaint *paint) static void sp_style_filter_clear(SPStyle *style) { - - if (style->filter_hreffed) { - sp_object_hunref(SP_OBJECT(style->filter.filter), style); - style->filter_hreffed = false; - } - style->filter_release_connection.disconnect(); - style->filter_modified_connection.disconnect(); - - style->filter.filter = NULL; + if (style->filter.href && style->filter.href->getObject()) + style->filter.href->detach(); } diff --git a/src/style.h b/src/style.h index 544bde557..df2ba127f 100644 --- a/src/style.h +++ b/src/style.h @@ -169,12 +169,13 @@ struct SPIPaint { } value; }; +struct SPFilterReference; + /// Filter type internal to SPStyle struct SPIFilter { unsigned set : 1; unsigned inherit : 1; - SPFilter *filter; - gchar *uri; + SPFilterReference *href; }; enum { @@ -351,7 +352,6 @@ struct SPStyle { /// style has hreffed its fill/stroke paintservers, needs to release. bool fill_hreffed; bool stroke_hreffed; - bool filter_hreffed; sigc::connection release_connection; @@ -360,12 +360,9 @@ struct SPStyle { sigc::connection stroke_release_connection; sigc::connection stroke_modified_connection; - - sigc::connection filter_release_connection; - sigc::connection filter_modified_connection; }; -SPStyle *sp_style_new(); +SPStyle *sp_style_new(SPDocument *document); SPStyle *sp_style_new_from_object(SPObject *object); diff --git a/src/text-editing.cpp b/src/text-editing.cpp index b84361324..233ac8d3f 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -1103,7 +1103,7 @@ as opposed to sp_style_merge_from_style_string which merges its parameter underneath the existing styles (ie ignoring already set properties). */ static void overwrite_style_with_string(SPObject *item, gchar const *style_string) { - SPStyle *new_style = sp_style_new(); + SPStyle *new_style = sp_style_new(SP_OBJECT_DOCUMENT(item)); sp_style_merge_from_style_string(new_style, style_string); gchar const *item_style_string = SP_OBJECT_REPR(item)->attribute("style"); if (item_style_string && *item_style_string) @@ -1128,7 +1128,7 @@ static bool objects_have_equal_style(SPObject const *parent, SPObject const *chi gchar *parent_style = sp_style_write_string(parent->style, SP_STYLE_FLAG_ALWAYS); // we have to write parent_style then read it again, because some properties format their values // differently depending on whether they're set or not (*cough*dash-offset*cough*) - SPStyle *parent_spstyle = sp_style_new(); + SPStyle *parent_spstyle = sp_style_new(SP_OBJECT_DOCUMENT(parent)); sp_style_merge_from_style_string(parent_spstyle, parent_style); g_free(parent_style); parent_style = sp_style_write_string(parent_spstyle, SP_STYLE_FLAG_ALWAYS); @@ -1144,7 +1144,7 @@ static bool objects_have_equal_style(SPObject const *parent, SPObject const *chi } child = SP_OBJECT_PARENT(child); } - SPStyle *child_spstyle = sp_style_new(); + SPStyle *child_spstyle = sp_style_new(SP_OBJECT_DOCUMENT(parent)); sp_style_merge_from_style_string(child_spstyle, child_style_construction.c_str()); gchar *child_style = sp_style_write_string(child_spstyle, SP_STYLE_FLAG_ALWAYS); sp_style_unref(child_spstyle); diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 2967cf151..fdcfc7636 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -239,7 +239,7 @@ FillAndStroke::selectionChanged(Inkscape::Application *inkscape, _blocked = true; // create temporary style - SPStyle *query = sp_style_new (); + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_MASTEROPACITY); diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index 2c5da4380..fcd56ad44 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -863,7 +863,7 @@ SelectedStyle::update() return; // create temporary style - SPStyle *query = sp_style_new (); + SPStyle *query = sp_style_new (sp_desktop_document(_desktop)); for (int i = SS_FILL; i <= SS_STROKE; i++) { Gtk::EventBox *place = (i == SS_FILL)? &_fill_place : &_stroke_place; diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp index 705083a8f..cad07fbd6 100644 --- a/src/ui/widget/style-swatch.cpp +++ b/src/ui/widget/style-swatch.cpp @@ -262,7 +262,7 @@ StyleSwatch::setStyle(SPCSSAttr *css) sp_repr_css_merge(_css, css); gchar const *css_string = sp_repr_css_write_string (_css); - SPStyle *temp_spstyle = sp_style_new(); + SPStyle *temp_spstyle = sp_style_new(SP_ACTIVE_DOCUMENT); if (css_string) sp_style_merge_from_style_string (temp_spstyle, css_string); diff --git a/src/uri-references.cpp b/src/uri-references.cpp index 6b2a8401f..8e14c9336 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -24,19 +24,32 @@ static gchar *uri_to_id(SPDocument *document, const gchar *uri); namespace Inkscape { URIReference::URIReference(SPObject *owner) -: _owner(owner), _obj(NULL), _uri(NULL) + : _owner(owner), _owner_document(NULL), _obj(NULL), _uri(NULL) { g_assert(_owner != NULL); /* FIXME !!! attach to owner's destroy signal to clean up in case */ } +URIReference::URIReference(SPDocument *owner_document) + : _owner_document(owner_document), _owner(NULL), _obj(NULL), _uri(NULL) +{ + g_assert(_owner_document != NULL); +} + URIReference::~URIReference() { detach(); } void URIReference::attach(const URI &uri) throw(BadURIException) { - SPDocument *document = SP_OBJECT_DOCUMENT(_owner); + SPDocument *document; + if (_owner) { + document = SP_OBJECT_DOCUMENT(_owner); + } else if (_owner_document) { + document = _owner_document; + } else { + g_assert_not_reached(); + } gchar const *fragment = uri.getFragment(); if ( !uri.isRelative() || uri.getQuery() || !fragment ) { throw UnsupportedURIException(); diff --git a/src/uri-references.h b/src/uri-references.h index 38f346987..89cdff827 100644 --- a/src/uri-references.h +++ b/src/uri-references.h @@ -41,6 +41,7 @@ public: * is holding a reference to the target object. */ URIReference(SPObject *owner); + URIReference(SPDocument *owner_document); /** * Destructor. Calls shutdown() if the reference has not been @@ -118,6 +119,7 @@ protected: private: SPObject *_owner; + SPDocument *_owner_document; sigc::connection _connection; sigc::connection _release_connection; SPObject *_obj; diff --git a/src/widgets/dash-selector.cpp b/src/widgets/dash-selector.cpp index 78303c60b..474ab90f9 100644 --- a/src/widgets/dash-selector.cpp +++ b/src/widgets/dash-selector.cpp @@ -139,7 +139,7 @@ sp_dash_selector_new (Inkscape::XML::Node *drepr) if (ndashes > 0) { int pos = 0; - SPStyle *style = sp_style_new (); + SPStyle *style = sp_style_new (NULL); dashes = g_new (double *, ndashes + 1); for (Inkscape::XML::Node *dr = drepr->firstChild(); dr; dr = dr->next()) { if (!strcmp (dr->name(), "dash")) { diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index c15337e0d..aa5165d15 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -3156,7 +3156,7 @@ void sp_text_toolbox_selection_changed (Inkscape::Selection *selection, GObject *tbl) { SPStyle *query = - sp_style_new (); + sp_style_new (SP_ACTIVE_DOCUMENT); int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); @@ -3350,7 +3350,7 @@ sp_text_toolbox_family_changed (GtkTreeSelection *selection, gtk_entry_set_text (GTK_ENTRY (entry), family); SPStyle *query = - sp_style_new (); + sp_style_new (SP_ACTIVE_DOCUMENT); int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); @@ -3443,7 +3443,7 @@ sp_text_toolbox_anchoring_toggled (GtkRadioButton *button, } SPStyle *query = - sp_style_new (); + sp_style_new (SP_ACTIVE_DOCUMENT); int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); @@ -3491,7 +3491,7 @@ sp_text_toolbox_style_toggled (GtkToggleButton *button, } SPStyle *query = - sp_style_new (); + sp_style_new (SP_ACTIVE_DOCUMENT); int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); @@ -3540,7 +3540,7 @@ sp_text_toolbox_orientation_toggled (GtkRadioButton *button, } SPStyle *query = - sp_style_new (); + sp_style_new (SP_ACTIVE_DOCUMENT); int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); @@ -3636,7 +3636,7 @@ sp_text_toolbox_size_changed (GtkComboBox *cbox, free (text); SPStyle *query = - sp_style_new (); + sp_style_new (SP_ACTIVE_DOCUMENT); int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); -- 2.30.2