Code

Object groups can be blurred. Blur slider updates when selection changes. Comments...
authorhaa_rodrigues <haa_rodrigues@users.sourceforge.net>
Sun, 20 Aug 2006 12:13:40 +0000 (12:13 +0000)
committerhaa_rodrigues <haa_rodrigues@users.sourceforge.net>
Sun, 20 Aug 2006 12:13:40 +0000 (12:13 +0000)
src/desktop-style.cpp
src/desktop-style.h
src/dialogs/object-properties.cpp
src/display/nr-arena-group.cpp
src/display/nr-arena-shape.cpp
src/display/nr-filter.cpp
src/sp-filter-primitive.cpp

index ff96f7e8ea033ca15f156cd9419d9f06e521cbec..66953aae7e5d0a11e284f8cf6f25623f7e9abdd7 100644 (file)
@@ -24,6 +24,8 @@
 #include "style.h"
 #include "prefs-utils.h"
 #include "sp-use.h"
+#include "sp-filter.h"
+#include "sp-gaussian-blur.h"
 #include "sp-flowtext.h"
 #include "sp-flowregion.h"
 #include "sp-flowdiv.h"
@@ -1010,15 +1012,77 @@ objects_query_fontfamily (GSList *objects, SPStyle *style_res)
 }
 
 /**
- * Write to style_res the average opacity of a list of objects.
+ * Write to style_res the average blurring of a list of objects.
  */
 int
 objects_query_blur (GSList *objects, SPStyle *style_res)
 {
-    /*************temporary**********/
-    //style_res->opacity.value = SP_SCALE24_FROM_FLOAT(0.5);
-    return QUERY_STYLE_MULTIPLE_SAME;
-    /*************temporary**********/
+   if (g_slist_length(objects) == 0) {
+        /* No objects, set empty */
+        return QUERY_STYLE_NOTHING;
+    }
+
+    float blur_sum = 0;
+    float blur_prev = -1;
+    bool same_blur = true;
+    guint blur_items = 0;
+    
+    for (GSList const *i = objects; i != NULL; i = i->next) {
+        SPObject *obj = SP_OBJECT (i->data);
+        SPStyle *style = SP_OBJECT_STYLE (obj);
+        if (!style) continue;
+
+        //if object has a filter
+        if (style->filter.set && style->filter.filter) {
+            //cycle through filter primitives
+            for(int i=0; i<style->filter.filter->_primitive_count; i++)
+            {
+                SPFilterPrimitive *primitive = style->filter.filter->_primitives[i];
+                //if primitive is gaussianblur
+        //            if(SP_IS_GAUSSIANBLUR(primitive))
+                {
+                    SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive);
+                    float num = spblur->stdDeviation.getNumber();
+                    blur_sum += num;
+                    if (blur_prev != -1 && num != blur_prev)
+                        same_blur = false;
+                    blur_prev = num;
+                    //TODO: deal with opt number, for the moment it's not necessary to the ui.
+                    blur_items ++;
+                }
+            }
+        }
+
+    }
+    if (blur_items > 0)
+    {
+        blur_sum /= blur_items;
+        style_res->filter.set = true;
+        style_res->filter.filter = new SPFilter();
+               //TODO: this SPFilter attributes should be set on sp-filter.cpp
+               //      when a new SPFilter is created, not here
+        style_res->filter.filter->_primitive_count=0;
+        style_res->filter.filter->_primitive_table_size = 1;
+        style_res->filter.filter->_primitives = new SPFilterPrimitive*[1];
+        style_res->filter.filter->_primitives[0] = NULL;
+
+        SPGaussianBlur * b = new SPGaussianBlur();
+        add_primitive(style_res->filter.filter, b);
+        sp_gaussianBlur_setDeviation(b, blur_sum);
+    }
+
+
+
+    if (blur_items == 0) {
+        return QUERY_STYLE_NOTHING;
+    } else if (blur_items == 1) {
+        return QUERY_STYLE_SINGLE;
+    } else {
+        if (same_blur)
+            return QUERY_STYLE_MULTIPLE_SAME;
+        else
+            return QUERY_STYLE_MULTIPLE_AVERAGED;
+    }
 }
 
 /**
@@ -1092,8 +1156,9 @@ sp_desktop_query_style_all (SPDesktop *desktop, SPStyle *query)
         int result_strokecap = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKECAP);
         int result_strokejoin = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKEJOIN);
         int result_opacity = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_MASTEROPACITY);
-
-        return (result_family != QUERY_STYLE_NOTHING && result_fstyle != QUERY_STYLE_NOTHING && result_fnumbers != QUERY_STYLE_NOTHING && result_fill != QUERY_STYLE_NOTHING && result_stroke != QUERY_STYLE_NOTHING && result_opacity != QUERY_STYLE_NOTHING && result_strokewidth != QUERY_STYLE_NOTHING && result_strokemiterlimit != QUERY_STYLE_NOTHING && result_strokecap != QUERY_STYLE_NOTHING && result_strokejoin != QUERY_STYLE_NOTHING);
+        int result_blur = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_BLUR);
+        
+        return (result_family != QUERY_STYLE_NOTHING && result_fstyle != QUERY_STYLE_NOTHING && result_fnumbers != QUERY_STYLE_NOTHING && result_fill != QUERY_STYLE_NOTHING && result_stroke != QUERY_STYLE_NOTHING && result_opacity != QUERY_STYLE_NOTHING && result_strokewidth != QUERY_STYLE_NOTHING && result_strokemiterlimit != QUERY_STYLE_NOTHING && result_strokecap != QUERY_STYLE_NOTHING && result_strokejoin != QUERY_STYLE_NOTHING && result_blur != QUERY_STYLE_NOTHING);
 }
 
 
index a1fd8a4ffa4d8b50f5f1bfa1b696121e4306a266..112fe1372a4ab94ed8bd50cf1dd935629dd5b911 100644 (file)
@@ -47,7 +47,7 @@ enum { // which property was queried (add when you need more)
     QUERY_STYLE_PROPERTY_FONTSTYLE, // font style 
     QUERY_STYLE_PROPERTY_FONTNUMBERS, // size, spacings
     QUERY_STYLE_PROPERTY_MASTEROPACITY, // opacity
-       QUERY_STYLE_PROPERTY_BLUR // opacity
+       QUERY_STYLE_PROPERTY_BLUR // blur
 };
 
 void sp_desktop_apply_css_recursive(SPObject *o, SPCSSAttr *css, bool skip_lines);
index 4d6298b05136fb0a354101d4bef86bb23707b4f5..a4dd49aebe8713b4dd060529e63f2fe3d2995831 100644 (file)
@@ -13,7 +13,9 @@
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
-
+//uncomment to display blur slider
+//#define WITH_BLUR
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
@@ -218,10 +220,10 @@ 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 );
 
-        
+
+#ifdef WITH_BLUR        
         /* Blur */
-/* uncomment to display blur slider*/
-/*        GtkWidget *b_vb = gtk_vbox_new (FALSE, 0);
+        GtkWidget *b_vb = gtk_vbox_new (FALSE, 0);
         gtk_box_pack_start (GTK_BOX (vb), b_vb, FALSE, FALSE, 2);
         gtk_object_set_data (GTK_OBJECT (dlg), "blur", b_vb);
 
@@ -250,7 +252,7 @@ sp_object_properties_dialog (void)
                              dlg );
                              
         gtk_widget_show_all (b_vb);
-*/ 
+#endif
         sp_fillstroke_selection_changed(NULL, NULL, NULL);
 
         gtk_widget_show (dlg);
@@ -323,6 +325,32 @@ sp_fillstroke_selection_changed ( Inkscape::Application *inkscape,
             break;
     }
 
+
+    GtkWidget *b = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (dlg), "blur"));
+    GtkAdjustment *bluradjustment = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(dlg), "blur_adjustment"));
+
+#ifdef WITH_BLUR
+    //query now for current average blurring of selection
+    int blur_result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_BLUR);
+
+    switch (blur_result) {
+        case QUERY_STYLE_NOTHING: //no blurring
+//                     gtk_widget_set_sensitive (b, FALSE);
+            break;
+        case QUERY_STYLE_SINGLE:
+        case QUERY_STYLE_MULTIPLE_AVERAGED:
+        case QUERY_STYLE_MULTIPLE_SAME: 
+            gtk_widget_set_sensitive (b, TRUE);
+            //update blur widget value
+            SPGaussianBlur * spblur = SP_GAUSSIANBLUR(query->filter.filter->_primitives[0]);
+            gtk_adjustment_set_value(bluradjustment, spblur->stdDeviation.getNumber());
+            break;
+    }
+#endif
+
+    
+    
+    
     g_free (query);
     gtk_object_set_data (GTK_OBJECT (dlg), "blocked", GUINT_TO_POINTER (FALSE));
 }
@@ -353,43 +381,44 @@ sp_fillstroke_opacity_changed (GtkAdjustment *a, SPWidget *dlg)
 
 
 /**
- * Creates new private filter for the given vector
+ * Creates a filter with blur primitive of specified stdDeviation
  */
-
 static SPFilter *
-sp_filter_get(SPDocument *document, gdouble stdDeviation)
+sp_fillstroke_get_new_filter(SPDocument *document, gdouble stdDeviation)
 {
     g_return_val_if_fail(document != NULL, NULL);
 
     SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document);
 
-    // create a new private filter of the requested type
+    // create a new private filter
     Inkscape::XML::Node *repr;
     repr = sp_repr_new("svg:filter");
-    // privates are garbage-collectable
     repr->setAttribute("inkscape:collect", "always");
 
+    //create feGaussianBlur node
     Inkscape::XML::Node *b_repr;
     b_repr = sp_repr_new("svg:feGaussianBlur");
-    // privates are garbage-collectable
-    //b_repr->setAttribute("inkscape:collect", "always");
-    
+    b_repr->setAttribute("inkscape:collect", "always");
     
+    //set stdDeviation attribute
     Inkscape::CSSOStringStream os;
     os << stdDeviation;
     b_repr->setAttribute("stdDeviation", os.str().c_str());
     
+    //set feGaussianBlur as child of filter node
     repr->appendChild(b_repr);
     Inkscape::GC::release(b_repr);
     
-    /* Append the new private filter to defs */
+    // Append the new filter node to defs
     SP_OBJECT_REPR(defs)->appendChild(repr);
     Inkscape::GC::release(repr);
 
     // get corresponding object
     SPFilter *f = SP_FILTER( document->getObjectByRepr(repr) );
     SPGaussianBlur *b = SP_GAUSSIANBLUR( document->getObjectByRepr(b_repr) );
-    add_primitive(f, /*(SPFilterPrimitive * )*/ b);
+    //add blur primitive to SPFilter object
+    add_primitive(f, b); //TODO: this should be triggered in SPFilter.cpp, when a child is added, not here...
+    
     g_assert(f != NULL);
     g_assert(SP_IS_FILTER(f));
     g_assert(b != NULL);
@@ -398,9 +427,7 @@ sp_filter_get(SPDocument *document, gdouble stdDeviation)
     return f;
 }
 
-/*
- * TODO: check if selection has a filter applied and change its parameters instead of creating a new one
- */
+
 static void
 sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *dlg)
 {
@@ -426,10 +453,9 @@ sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *dlg)
     
     
     //create new filter with feGaussianBlur primitive
-    SPFilter *constructed = sp_filter_get(document, a->value);
+    SPFilter *constructed = sp_fillstroke_get_new_filter(document, a->value);
 
-    
-   //apply created filter to every selected item
+    //apply created filter to every selected item
     for (GSList const *i = items; i != NULL; i = i->next) {
     
         SPItem * item = SP_ITEM(i->data);
@@ -441,7 +467,8 @@ sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *dlg)
             //if there is a filter attached, remove it
             SPCSSAttr *css = sp_repr_css_attr_new ();
             sp_repr_css_unset_property (css, "filter");
-            sp_desktop_set_style (desktop, css);
+            sp_repr_css_change_recursive(SP_OBJECT_REPR(item), css, "style");
+            sp_desktop_set_style (SP_ACTIVE_DESKTOP, css);
             sp_repr_css_attr_unref (css);
         }/* else if( style->filter.filter ) { //item has a filter assigned
             Inkscape::XML::Node *repr = SP_OBJECT_REPR ( style->filter.filter );
@@ -449,6 +476,7 @@ sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *dlg)
             os << a->value;
             repr->firstChild()->setAttribute("stdDeviation", os.str().c_str());
         }*/ else {
+            //add new filter attribute to object style
             gchar *val = g_strdup_printf("url(#%s)", SP_OBJECT_ID(constructed));
             SPCSSAttr *css = sp_repr_css_attr_new();
             sp_repr_css_set_property(css, "filter", val);
@@ -457,6 +485,7 @@ sp_fillstroke_blur_changed (GtkAdjustment *a, SPWidget *dlg)
             sp_desktop_set_style (SP_ACTIVE_DESKTOP, css);
             sp_repr_css_attr_unref(css);
         }
+        //request update
         SP_OBJECT(item)->requestDisplayUpdate(( SP_OBJECT_MODIFIED_FLAG |
                                             SP_OBJECT_STYLE_MODIFIED_FLAG ));
     }
index b4cc3930b1a5ad4807ee79bf040065c976801a35..8df0453327492b04ad65f4bef1d711ead3198542 100644 (file)
 
 #include "display/nr-arena-group.h"
 #include "display/nr-filter.h"
+#include "display/nr-filter-gaussian.h"
+#include "display/nr-filter-types.h"
 #include "style.h"
+#include "sp-filter.h"
+#include "sp-gaussian-blur.h"
 
 static void nr_arena_group_class_init (NRArenaGroupClass *klass);
 static void nr_arena_group_init (NRArenaGroup *group);
@@ -193,9 +197,41 @@ void nr_arena_group_set_style (NRArenaGroup *group, SPStyle *style)
   if (group->style) sp_style_unref(group->style);
   group->style = style;
 
+  //if there is a filter set for this group
   if (style && style->filter.set && style->filter.filter) {
-    group->filter = new NR::Filter();
-  }
+  
+        group->filter = new NR::Filter();
+        group->filter->set_x(style->filter.filter->x);
+        group->filter->set_y(style->filter.filter->y);
+        group->filter->set_width(style->filter.filter->width);
+        group->filter->set_height(style->filter.filter->height);
+        
+        //go through all SP filter primitives
+        for(int i=0; i<style->filter.filter->_primitive_count; i++)
+        {
+            SPFilterPrimitive *primitive = style->filter.filter->_primitives[i];
+            //if primitive is gaussianblur
+//            if(SP_IS_GAUSSIANBLUR(primitive))
+            {
+                NR::FilterGaussian * gaussian = (NR::FilterGaussian *) group->filter->add_primitive(NR::NR_FILTER_GAUSSIANBLUR);
+                SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive);
+                float num = spblur->stdDeviation.getNumber();
+                if( num>=0.0 )
+                {
+                    float optnum = spblur->stdDeviation.getOptNumber();
+                    if( optnum>=0.0 )
+                        gaussian->set_deviation((double) num, (double) optnum);
+                    else
+                        gaussian->set_deviation((double) num);
+                }
+            }
+        }
+    }
+    else
+    {
+        //no filter set for this group
+        group->filter = NULL;
+    }
 
   if (style && style->enable_background.set
       && style->enable_background.value == SP_CSS_BACKGROUND_NEW) {
index f9c2031874b671b24fb667f0819884e660f97781..2f278b3de56fa9ed92e6e09f2a4d9850c10cee83 100644 (file)
@@ -1089,9 +1089,8 @@ nr_arena_shape_set_style(NRArenaShape *shape, SPStyle *style)
     }
     shape->setMitreLimit(style->stroke_miterlimit.value);
 
-    /* TODO: after SPStyle handles filters, get the correct filter
-     * from there. */
-    if (style->filter.set && style->filter.filter)
+    //if shape has a filter
+    if (style->filter.set && style->filter.filter) 
     {
         shape->filter = new NR::Filter();
         shape->filter->set_x(style->filter.filter->x);
@@ -1120,6 +1119,11 @@ nr_arena_shape_set_style(NRArenaShape *shape, SPStyle *style)
             }
         }
     }
+    else
+    {
+        //no filter set for this shape
+        shape->filter = NULL;
+    }
 
     nr_arena_item_request_update(shape, NR_ARENA_ITEM_STATE_ALL, FALSE);
 }
index a96b02a621888c9753e224f6c4f5a4f61b8a2d97..35d8804e789a3c22d072b313c26f02e8e8645fe4 100644 (file)
@@ -131,7 +131,8 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb)
     in = NULL; // in is now handled by FilterSlot, we should not touch it
 
     // TODO: loop through the primitives and render them one at a time
-    _primitive[0]->render(slot, trans);
+    if(_primitive[0])
+               _primitive[0]->render(slot, trans);
 
     NRPixBlock *out = slot.get(_output_slot);
 
index 6b208f1be88523e8a823afee2f246b0467c567e7..a0c09a4cebba3ff9660435ce011078870cf143f8 100644 (file)
@@ -1,15 +1,8 @@
 #define __SP_FILTER_PRIMITIVE_CPP__\r
 \r
 /** \file\r
- * SVG <filter_primitive> implementation, used as an example for a base starting class\r
- * when implementing new sp-objects.\r
+ * Superclass for all the filter primitives\r
  *\r
- * In vi, three global search-and-replaces will let you rename everything\r
- * in this and the .h file:\r
- *\r
- *   :%s/FILTER_PRIMITIVE/YOURNAME/g\r
- *   :%s/FilterPrimitive/Yourname/g\r
- *   :%s/filter_primitive/yourname/g\r
  */\r
 /*\r
  * Authors:\r
@@ -95,22 +88,6 @@ sp_filter_primitive_build(SPObject *object, SPDocument *document, Inkscape::XML:
         ((SPObjectClass *) filter_primitive_parent_class)->build(object, document, repr);\r
     }\r
 \r
-    /*\r
-       Pay attention to certain settings here\r
-\r
-    sp_object_read_attr(object, "xlink:href");\r
-    sp_object_read_attr(object, "attributeName");\r
-    sp_object_read_attr(object, "attributeType");\r
-    sp_object_read_attr(object, "begin");\r
-    sp_object_read_attr(object, "dur");\r
-    sp_object_read_attr(object, "end");\r
-    sp_object_read_attr(object, "min");\r
-    sp_object_read_attr(object, "max");\r
-    sp_object_read_attr(object, "restart");\r
-    sp_object_read_attr(object, "repeatCount");\r
-    sp_object_read_attr(object, "repeatDur");\r
-    sp_object_read_attr(object, "fill");\r
-    */\r
 }\r
 \r
 /**\r
@@ -119,9 +96,7 @@ sp_filter_primitive_build(SPObject *object, SPDocument *document, Inkscape::XML:
 static void\r
 sp_filter_primitive_release(SPObject *object)\r
 {\r
-\r
     /* deal with our children and our selves here */\r
-\r
     if (((SPObjectClass *) filter_primitive_parent_class)->release)\r
         ((SPObjectClass *) filter_primitive_parent_class)->release(object);\r
 }\r
@@ -152,7 +127,6 @@ sp_filter_primitive_update(SPObject *object, SPCtx *ctx, guint flags)
                  SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {\r
 \r
         /* do something to trigger redisplay, updates? */\r
-\r
     }\r
 \r
     if (((SPObjectClass *) filter_primitive_parent_class)->update) {\r