filter-chemistry.cpp revision 437c1cd94c72c1a38636a923cd9c0a95189596ad
/*
* Various utility methods for filters
*
* Authors:
* Hugo Rodrigues
* bulia byak
* Niko Kiirala
* Jon A. Cruz <jon@joncruz.org>
* Abhishek Sharma
*
* Copyright (C) 2006-2008 authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include <cstring>
#include <glibmm.h>
#include "style.h"
#include "document-private.h"
#include "desktop-style.h"
#include "filter-chemistry.h"
#include "filter-enums.h"
#include "filters/gaussian-blur.h"
#include "sp-filter.h"
#include "sp-filter-reference.h"
#include "svg/css-ostringstream.h"
/**
* Count how many times the filter is used by the styles of o and its
* descendants
*/
{
if (!o)
return 1;
guint i = 0;
if (style
{
i ++;
}
}
return i;
}
/**
* Sets a suitable filter effects area according to given blur radius,
* expansion and object size.
*/
double expansion, double expansionX,
{
// TODO: make this more generic, now assumed, that only the blur
// being added can affect the required filter area
// If not within the default 10% margin (see
// http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion), specify margins
// The 2.4 is an empirical coefficient: at that distance the cutoff is practically invisible
// (the opacity at 2.4*radius is about 3e-3)
// TODO: set it in UserSpaceOnUse instead?
}
}
{
// create a new filter
// Inkscape now supports both sRGB and linear color-interpolation-filters.
// But, for the moment, keep sRGB as default value for new filters
// (historically set to sRGB and doesn't require conversion between
// filter cairo surfaces and other types of cairo surfaces).
// Append the new filter node to defs
// get corresponding object
g_assert(SP_IS_FILTER(f));
return f;
}
{
//create filter primitive node
// set default values
switch(type) {
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
default:
break;
}
//set primitive as child of filter node
// get corresponding object
return prim;
}
/**
* Creates a filter with blur primitive of specified radius for an item with the given matrix expansion, width and height
*/
SPFilter *
new_filter_gaussian_blur (SPDocument *document, gdouble radius, double expansion, double expansionX, double expansionY, double width, double height)
{
// create a new filter
//repr->setAttribute("inkscape:collect", "always");
/* Inkscape now supports both sRGB and linear color-interpolation-filters.
* But, for the moment, keep sRGB as default value for new filters.
* historically set to sRGB and doesn't require conversion between
* filter cairo surfaces and other types of cairo surfaces. lp:1127103 */
//create feGaussianBlur node
//b_repr->setAttribute("inkscape:collect", "always");
double stdDeviation = radius;
if (expansion != 0)
//set stdDeviation attribute
//set feGaussianBlur as child of filter node
// Append the new filter node to defs
// get corresponding object
g_assert(SP_IS_FILTER(f));
return f;
}
/**
* Creates a simple filter with a blend primitive and a blur primitive of specified radius for
* an item with the given matrix expansion, width and height
*/
static SPFilter *
new_filter_blend_gaussian_blur (SPDocument *document, const char *blendmode, gdouble radius, double expansion,
{
// create a new filter
/* Inkscape now supports both sRGB and linear color-interpolation-filters.
* But, for the moment, keep sRGB as default value for new filters.
* historically set to sRGB and doesn't require conversion between
* filter cairo surfaces and other types of cairo surfaces. lp:1127103 */
// Append the new filter node to defs
// get corresponding object
// Gaussian blur primitive
if(radius != 0) {
//create feGaussianBlur node
double stdDeviation = radius;
if (expansion != 0)
//set stdDeviation attribute
//set feGaussianBlur as child of filter node
}
// Blend primitive
// set feBlend as child of filter node
// Enable background image buffer for document
}
g_assert(SP_IS_FEBLEND(b));
}
g_assert(SP_IS_FILTER(f));
return f;
}
/**
* Creates a simple filter for the given item with blend and blur primitives, using the
* specified mode and radius, respectively
*/
SPFilter *
{
double width;
double height;
if (r) {
} else {
}
return (new_filter_blend_gaussian_blur (document, mode, radius, i2dt.descrim(), i2dt.expansionX(), i2dt.expansionY(), width, height));
}
/**
* Modifies the gaussian blur applied to the item.
* If no filters are applied to given item, creates a new blur filter.
* If a filter is applied and it contains a blur, modify that blur.
* If the filter doesn't contain blur, a blur is added to the filter.
* Should there be more references to modified filter, that filter is
* duplicated, so that other elements referring that filter are not modified.
*/
/* TODO: this should be made more generic, not just for blurs */
{
}
if (!filter) {
// We reach here when filter.set is true, but the href is not found in the document
}
// If there are more users for this filter, duplicate it
}
// Determine the required standard deviation value
double stdDeviation = radius;
if (expansion != 0)
// Get the object size
double width;
double height;
if (r) {
} else {
}
// Set the filter effects area
// Search for gaussian blur primitives. If found, set the stdDeviation
// of the first one and return.
while (primitive) {
return filter;
}
}
// If there were no gaussian blur primitives, create a new one
//create feGaussianBlur node
//b_repr->setAttribute("inkscape:collect", "always");
//set stdDeviation attribute
//set feGaussianBlur as child of filter node
return filter;
}
{
if (recursive) {
} else {
}
}
/**
* Removes the first feGaussianBlur from the filter attached to given item.
* Should this leave us with an empty filter, remove that filter.
*/
/* TODO: the removed filter primitive may had had a named result image, so
* after removing, the filter may be in erroneous state, this situation should
* be handled gracefully */
{
// Search for the first blur primitive and remove it. (if found)
while (primitive) {
break;
}
}
// If there are no more primitives left in this filter, discard it.
if (repr->childCount() == 0) {
remove_filter(item, false);
}
}
}
{
return (filter->firstChild() &&
}
{
if (filter->firstChild() &&
if (x > 0 && y > 0) {
return MAX(x, y);
}
return x;
}
return 0.0;
}
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :