1 #define __SP_FILTER_CHEMISTRY_C__
3 /*
4 * Various utility methods for filters
5 *
6 * Authors:
7 * Hugo Rodrigues
8 * bulia byak
9 *
10 * Copyright (C) 2006 authors
11 *
12 * Released under GNU GPL, read the file 'COPYING' for more information
13 */
16 #include "style.h"
17 #include "document-private.h"
18 #include "desktop-style.h"
20 #include "sp-filter.h"
21 #include "sp-gaussian-blur.h"
22 #include "svg/css-ostringstream.h"
24 #include "xml/repr.h"
26 /**
27 * Creates a filter with blur primitive of specified radius for an item with the given matrix expansion, width and height
28 */
29 SPFilter *
30 new_filter_gaussian_blur (SPDocument *document, gdouble radius, double expansion, double width, double height)
31 {
32 g_return_val_if_fail(document != NULL, NULL);
34 SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document);
36 // create a new filter
37 Inkscape::XML::Node *repr;
38 repr = sp_repr_new("svg:filter");
39 repr->setAttribute("inkscape:collect", "always");
41 if (width != 0 && height != 0 && (2 * radius > width * 0.1 || 2 * radius > height * 0.1)) {
42 // If not within the default 10% margin (see
43 // http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion), specify margins
44 double xmargin = 2 * radius / width;
45 double ymargin = 2 * radius / height;
47 // TODO: set it in UserSpaceOnUse instead?
48 sp_repr_set_svg_double(repr, "x", -xmargin);
49 sp_repr_set_svg_double(repr, "width", 1 + 2 * xmargin);
50 sp_repr_set_svg_double(repr, "y", -ymargin);
51 sp_repr_set_svg_double(repr, "height", 1 + 2 * ymargin);
52 }
54 //create feGaussianBlur node
55 Inkscape::XML::Node *b_repr;
56 b_repr = sp_repr_new("svg:feGaussianBlur");
57 b_repr->setAttribute("inkscape:collect", "always");
59 double stdDeviation = radius;
60 if (expansion != 0)
61 stdDeviation /= expansion;
63 //set stdDeviation attribute
64 sp_repr_set_svg_double(b_repr, "stdDeviation", stdDeviation);
66 //set feGaussianBlur as child of filter node
67 repr->appendChild(b_repr);
68 Inkscape::GC::release(b_repr);
70 // Append the new filter node to defs
71 SP_OBJECT_REPR(defs)->appendChild(repr);
72 Inkscape::GC::release(repr);
74 // get corresponding object
75 SPFilter *f = SP_FILTER( document->getObjectByRepr(repr) );
76 SPGaussianBlur *b = SP_GAUSSIANBLUR( document->getObjectByRepr(b_repr) );
78 g_assert(f != NULL);
79 g_assert(SP_IS_FILTER(f));
80 g_assert(b != NULL);
81 g_assert(SP_IS_GAUSSIANBLUR(b));
83 return f;
84 }
86 /**
87 * Creates a filter with blur primitive of specified radius for the given item
88 */
89 SPFilter *
90 new_filter_gaussian_blur_from_item (SPDocument *document, SPItem *item, gdouble radius)
91 {
92 NR::Rect const r = sp_item_bbox_desktop(item);
93 double width = r.extent(NR::X);
94 double height = r.extent(NR::Y);
96 NR::Matrix i2d = sp_item_i2d_affine (item);
98 return (new_filter_gaussian_blur (document, radius, i2d.expansion(), width, height));
99 }
101 void remove_filter (SPObject *item, bool recursive)
102 {
103 SPCSSAttr *css = sp_repr_css_attr_new ();
104 sp_repr_css_unset_property (css, "filter");
105 if (recursive)
106 sp_repr_css_change_recursive(SP_OBJECT_REPR(item), css, "style");
107 else
108 sp_repr_css_change (SP_OBJECT_REPR(item), css, "style");
109 sp_repr_css_attr_unref (css);
110 }
112 /*
113 Local Variables:
114 mode:c++
115 c-file-style:"stroustrup"
116 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
117 indent-tabs-mode:nil
118 fill-column:99
119 End:
120 */
121 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :