From dcc85626dc95ac855f9640f0e4727d7b9632f6e3 Mon Sep 17 00:00:00 2001 From: buliabyak Date: Fri, 20 Oct 2006 23:34:39 +0000 Subject: [PATCH] make blur slider a percentage; change opacity to 1..100 as well; ensure the filter margins are at least twice the blur radius --- src/dialogs/clonetiler.cpp | 5 ++++- src/dialogs/object-properties.cpp | 37 ++++++++++++++++++------------- src/filter-chemistry.cpp | 20 ++++++++++++----- src/filter-chemistry.h | 2 +- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/dialogs/clonetiler.cpp b/src/dialogs/clonetiler.cpp index 324a3d94b..f3cc9b4e0 100644 --- a/src/dialogs/clonetiler.cpp +++ b/src/dialogs/clonetiler.cpp @@ -1301,7 +1301,10 @@ clonetiler_apply (GtkWidget *widget, void *) SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); double diag = diag_original * t.expansion(); double radius = blur * diag; - SPFilter *constructed = new_filter_gaussian_blur(sp_desktop_document(desktop), radius); + // it's hard to figure out exact width/height of the tile without having an object + // that we can take bbox of; however here we only need a lower bound so that blur + // margins are not too small, and diag/2 should work + SPFilter *constructed = new_filter_gaussian_blur(sp_desktop_document(desktop), radius, diag/2, diag/2); sp_style_set_property_url (clone_object, "filter", SP_OBJECT(constructed), false); } diff --git a/src/dialogs/object-properties.cpp b/src/dialogs/object-properties.cpp index 5fe3d58f8..07b329fb2 100644 --- a/src/dialogs/object-properties.cpp +++ b/src/dialogs/object-properties.cpp @@ -205,7 +205,7 @@ sp_object_properties_dialog (void) gtk_box_pack_start (GTK_BOX (blur_hb), blur_s, TRUE, TRUE, 4); gtk_label_set_mnemonic_widget (GTK_LABEL(blur_l), blur_s); - GtkWidget *blur_sb = gtk_spin_button_new (GTK_ADJUSTMENT (blur_a), 0.01, 3); + GtkWidget *blur_sb = gtk_spin_button_new (GTK_ADJUSTMENT (blur_a), 0.01, 1); gtk_box_pack_start (GTK_BOX (blur_hb), blur_sb, FALSE, FALSE, 0); gtk_signal_connect ( blur_a, "value_changed", @@ -221,7 +221,7 @@ sp_object_properties_dialog (void) gtk_box_pack_start (GTK_BOX (vb), o_vb, FALSE, FALSE, 2); gtk_object_set_data (GTK_OBJECT (dlg), "master_opacity", o_vb); - GtkWidget *l_hb = gtk_hbox_new (FALSE, 4); + GtkWidget *l_hb = gtk_hbox_new (FALSE, 0); GtkWidget *l = gtk_label_new_with_mnemonic (_("Master _opacity")); gtk_misc_set_alignment (GTK_MISC (l), 0.0, 1.0); gtk_box_pack_start (GTK_BOX (l_hb), l, FALSE, FALSE, 4); @@ -230,7 +230,7 @@ sp_object_properties_dialog (void) GtkWidget *hb = gtk_hbox_new (FALSE, 4); gtk_box_pack_start (GTK_BOX (o_vb), hb, FALSE, FALSE, 0); - GtkObject *a = gtk_adjustment_new (1.0, 0.0, 1.0, 0.01, 0.1, 0.0); + GtkObject *a = gtk_adjustment_new (1.0, 0.0, 100.0, 1.0, 1.0, 0.0); gtk_object_set_data(GTK_OBJECT(dlg), "master_opacity_adjustment", a); GtkWidget *s = gtk_hscale_new (GTK_ADJUSTMENT (a)); @@ -238,7 +238,7 @@ sp_object_properties_dialog (void) gtk_box_pack_start (GTK_BOX (hb), s, TRUE, TRUE, 4); gtk_label_set_mnemonic_widget (GTK_LABEL(l), s); - GtkWidget *sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 0.01, 3); + GtkWidget *sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 0.01, 1); gtk_box_pack_start (GTK_BOX (hb), sb, FALSE, FALSE, 0); gtk_signal_connect ( a, "value_changed", @@ -252,7 +252,7 @@ sp_object_properties_dialog (void) g_signal_connect ( G_OBJECT (INKSCAPE), "modify_selection", G_CALLBACK (sp_fillstroke_selection_modified), dlg ); g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_fillstroke_selection_changed), dlg ); - sp_fillstroke_selection_changed(NULL, NULL, NULL); + sp_fillstroke_selection_changed(INKSCAPE, sp_desktop_selection(SP_ACTIVE_DESKTOP), NULL); gtk_widget_show (dlg); @@ -320,7 +320,7 @@ sp_fillstroke_selection_changed ( Inkscape::Application *inkscape, case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently case QUERY_STYLE_MULTIPLE_SAME: gtk_widget_set_sensitive (opa, TRUE); - gtk_adjustment_set_value(a, SP_SCALE24_TO_FLOAT(query->opacity.value)); + gtk_adjustment_set_value(a, 100 * SP_SCALE24_TO_FLOAT(query->opacity.value)); break; } @@ -337,11 +337,13 @@ sp_fillstroke_selection_changed ( Inkscape::Application *inkscape, case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: case QUERY_STYLE_MULTIPLE_SAME: + NR::Rect bbox = selection->bounds(); + double perimeter = bbox.extent(NR::X) + bbox.extent(NR::Y); gtk_widget_set_sensitive (b, TRUE); //update blur widget value float radius = query->filter_gaussianBlur_deviation.value; - // TODO: divide by bbox diagonal - gtk_adjustment_set_value(bluradjustment, radius); + float percent = radius * 400 / perimeter; // so that for a square, 100% == half side + gtk_adjustment_set_value(bluradjustment, percent); break; } @@ -351,7 +353,7 @@ sp_fillstroke_selection_changed ( Inkscape::Application *inkscape, } static void -sp_fillstroke_opacity_changed (GtkAdjustment *a, SPWidget *dlg) +sp_fillstroke_opacity_changed (GtkAdjustment *a, SPWidget *base) { if (gtk_object_get_data (GTK_OBJECT (dlg), "blocked")) return; @@ -361,7 +363,7 @@ sp_fillstroke_opacity_changed (GtkAdjustment *a, SPWidget *dlg) SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream os; - os << CLAMP (a->value, 0.0, 1.0); + os << CLAMP (a->value / 100, 0.0, 1.0); sp_repr_css_set_property (css, "opacity", os.str().c_str()); sp_desktop_set_style (SP_ACTIVE_DESKTOP, css); @@ -376,7 +378,7 @@ sp_fillstroke_opacity_changed (GtkAdjustment *a, SPWidget *dlg) static void -sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *dlg) +sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *base) { //if dialog is locked, return if (gtk_object_get_data (GTK_OBJECT (dlg), "blocked")) @@ -397,10 +399,11 @@ sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *dlg) GSList const *items = selection->itemList(); //get current document SPDocument *document = sp_desktop_document (desktop); - - //create new filter with feGaussianBlur primitive - SPFilter *constructed = new_filter_gaussian_blur(document, a->value); + NR::Rect bbox = selection->bounds(); + double perimeter = bbox.extent(NR::X) + bbox.extent(NR::Y); + double radius = a->value * perimeter / 400; + //apply created filter to every selected item for (GSList const *i = items; i != NULL; i = i->next) { @@ -408,9 +411,13 @@ sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *dlg) SPStyle *style = SP_OBJECT_STYLE(item); g_assert(style != NULL); - if (a->value == 0.0) { + if (radius == 0.0) { remove_filter (item, true); } else { + NR::Rect const r = sp_item_bbox_desktop(item); + double width = r.extent(NR::X); + double height = r.extent(NR::Y); + SPFilter *constructed = new_filter_gaussian_blur(document, radius, width, height); sp_style_set_property_url (SP_OBJECT(item), "filter", SP_OBJECT(constructed), false); } //request update diff --git a/src/filter-chemistry.cpp b/src/filter-chemistry.cpp index 0b374160c..e18e54ed6 100644 --- a/src/filter-chemistry.cpp +++ b/src/filter-chemistry.cpp @@ -27,26 +27,36 @@ * Creates a filter with blur primitive of specified stdDeviation */ SPFilter * -new_filter_gaussian_blur (SPDocument *document, gdouble stdDeviation) +new_filter_gaussian_blur (SPDocument *document, gdouble stdDeviation, double width, double height) { g_return_val_if_fail(document != NULL, NULL); SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document); - // create a new private filter + // create a new filter Inkscape::XML::Node *repr; repr = sp_repr_new("svg:filter"); repr->setAttribute("inkscape:collect", "always"); + if (width != 0 && height != 0 && (2 * stdDeviation > width * 0.1 || 2 * stdDeviation > height * 0.1)) { + // If not within the default 10% margin (see + // http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion), specify margins + double xmargin = 2 * stdDeviation / width; + double ymargin = 2 * stdDeviation / height; + + sp_repr_set_svg_double(repr, "x", -xmargin); + sp_repr_set_svg_double(repr, "width", 1 + 2 * xmargin); + sp_repr_set_svg_double(repr, "y", -ymargin); + sp_repr_set_svg_double(repr, "height", 1 + 2 * ymargin); + } + //create feGaussianBlur node Inkscape::XML::Node *b_repr; b_repr = sp_repr_new("svg:feGaussianBlur"); b_repr->setAttribute("inkscape:collect", "always"); //set stdDeviation attribute - Inkscape::CSSOStringStream os; - os << stdDeviation; - b_repr->setAttribute("stdDeviation", os.str().c_str()); + sp_repr_set_svg_double(b_repr, "stdDeviation", stdDeviation); //set feGaussianBlur as child of filter node repr->appendChild(b_repr); diff --git a/src/filter-chemistry.h b/src/filter-chemistry.h index 31776323e..4c6606fc0 100644 --- a/src/filter-chemistry.h +++ b/src/filter-chemistry.h @@ -16,7 +16,7 @@ #include "forward.h" #include "sp-filter.h" -SPFilter *new_filter_gaussian_blur (SPDocument *document, gdouble stdDeviation); +SPFilter *new_filter_gaussian_blur (SPDocument *document, gdouble stdDeviation, double width, double height); void remove_filter (SPObject *item, bool recursive); #endif -- 2.30.2