void nr_arena_group_set_style (NRArenaGroup *group, SPStyle *style) { g_return_if_fail(group != NULL); g_return_if_fail(NR_IS_ARENA_GROUP(group)); if (style) sp_style_ref(style); if (group->style) sp_style_unref(group->style); group->style = style; //if group has a filter if (style->filter.set && style->getFilter()) { if (!group->filter) { int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); group->filter = new Inkscape::Filters::Filter(primitives); } sp_filter_build_renderer(SP_FILTER(style->getFilter()), group->filter); } else { //no filter set for this group delete group->filter; group->filter = NULL; } if (style && style->enable_background.set && style->enable_background.value == SP_CSS_BACKGROUND_NEW) { group->background_new = true; } }
int sp_filter_primitive_read_in(SPFilterPrimitive *prim, gchar const *name) { if (!name) return Inkscape::Filters::NR_FILTER_SLOT_NOT_SET; // TODO: are these case sensitive or not? (assumed yes) switch (name[0]) { case 'S': if (strcmp(name, "SourceGraphic") == 0) return Inkscape::Filters::NR_FILTER_SOURCEGRAPHIC; if (strcmp(name, "SourceAlpha") == 0) return Inkscape::Filters::NR_FILTER_SOURCEALPHA; if (strcmp(name, "StrokePaint") == 0) return Inkscape::Filters::NR_FILTER_STROKEPAINT; break; case 'B': if (strcmp(name, "BackgroundImage") == 0) return Inkscape::Filters::NR_FILTER_BACKGROUNDIMAGE; if (strcmp(name, "BackgroundAlpha") == 0) return Inkscape::Filters::NR_FILTER_BACKGROUNDALPHA; break; case 'F': if (strcmp(name, "FillPaint") == 0) return Inkscape::Filters::NR_FILTER_FILLPAINT; break; } SPFilter *parent = SP_FILTER(prim->parent); int ret = sp_filter_get_image_name(parent, name); if (ret >= 0) return ret; return Inkscape::Filters::NR_FILTER_SLOT_NOT_SET; }
/** * Receives update notifications. */ void SPFilterPrimitive::update(SPCtx *ctx, guint flags) { SPItemCtx *ictx = (SPItemCtx *) ctx; // Do here since we know viewport (Bounding box case handled during rendering) SPFilter *parent = SP_FILTER(this->parent); if( parent->primitiveUnits == SP_FILTER_UNITS_USERSPACEONUSE ) { if (this->x.unit == SVGLength::PERCENT) { this->x._set = true; this->x.computed = this->x.value * ictx->viewport.width(); } if (this->y.unit == SVGLength::PERCENT) { this->y._set = true; this->y.computed = this->y.value * ictx->viewport.height(); } if (this->width.unit == SVGLength::PERCENT) { this->width._set = true; this->width.computed = this->width.value * ictx->viewport.width(); } if (this->height.unit == SVGLength::PERCENT) { this->height._set = true; this->height.computed = this->height.value * ictx->viewport.height(); } } SPObject::update(ctx, flags); }
/** * Receives update notifications. */ static void sp_feComposite_update(SPObject *object, SPCtx *ctx, guint flags) { SPFeComposite *comp = SP_FECOMPOSITE(object); if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { /* do something to trigger redisplay, updates? */ } /* Unlike normal in, in2 is required attribute. Make sure, we can call * it by some name. */ if (comp->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET || comp->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT) { SPFilter *parent = SP_FILTER(object->parent); comp->in2 = sp_filter_primitive_name_previous_out(comp); object->repr->setAttribute("in2", sp_filter_name_for_image(parent, comp->in2)); } if (((SPObjectClass *) feComposite_parent_class)->update) { ((SPObjectClass *) feComposite_parent_class)->update(object, ctx, flags); } }
/** * Reads the Inkscape::XML::Node, and initializes SPFeComposite variables. For this to get called, * our name must be associated with a repr via "sp_object_type_register". Best done through * sp-object-repr.cpp's repr_name_entries array. */ static void sp_feComposite_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) { if (((SPObjectClass *) feComposite_parent_class)->build) { ((SPObjectClass *) feComposite_parent_class)->build(object, document, repr); } SPFeComposite *comp = SP_FECOMPOSITE(object); sp_object_read_attr(object, "operator"); if (comp->composite_operator == COMPOSITE_ARITHMETIC) { sp_object_read_attr(object, "k1"); sp_object_read_attr(object, "k2"); sp_object_read_attr(object, "k3"); sp_object_read_attr(object, "k4"); } sp_object_read_attr(object, "in2"); /* Unlike normal in, in2 is required attribute. Make sure, we can call * it by some name. */ if (comp->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET || comp->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT) { SPFilter *parent = SP_FILTER(object->parent); comp->in2 = sp_filter_primitive_name_previous_out(comp); repr->setAttribute("in2", sp_filter_name_for_image(parent, comp->in2)); } }
/** * Process information related to the new style. * * Note: _style is not used by DrawingGlyphs which uses its parent style. */ void DrawingItem::setStyle(SPStyle *style, SPStyle *context_style) { // std::cout << "DrawingItem::setStyle: " << name() << " " << style // << " " << context_style << std::endl; if( style != _style ) { if (style) sp_style_ref(style); if (_style) sp_style_unref(_style); _style = style; } if (style && style->filter.set && style->getFilter()) { if (!_filter) { int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); _filter = new Inkscape::Filters::Filter(primitives); } sp_filter_build_renderer(SP_FILTER(style->getFilter()), _filter); } else { // no filter set for this group delete _filter; _filter = NULL; } if (style && style->enable_background.set) { if (style->enable_background.value == SP_CSS_BACKGROUND_NEW && !_background_new) { _background_new = true; _markForUpdate(STATE_BACKGROUND, true); } else if (style->enable_background.value == SP_CSS_BACKGROUND_ACCUMULATE && _background_new) { _background_new = false; _markForUpdate(STATE_BACKGROUND, true); } } if (context_style != NULL) { _context_style = context_style; } else if (_parent != NULL) { _context_style = _parent->_context_style; } _markForUpdate(STATE_ALL, false); }
int sp_filter_primitive_read_result(SPFilterPrimitive *prim, gchar const *name) { SPFilter *parent = SP_FILTER(prim->parent); int ret = sp_filter_get_image_name(parent, name); if (ret >= 0) return ret; ret = sp_filter_set_image_name(parent, name); if (ret >= 0) return ret; return Inkscape::Filters::NR_FILTER_SLOT_NOT_SET; }
/** * Writes its settings to an incoming repr object, if any. */ static Inkscape::XML::Node * sp_feBlend_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) { SPFeBlend *blend = SP_FEBLEND(object); SPFilter *parent = SP_FILTER(object->parent); if (!repr) { repr = doc->createElement("svg:feBlend"); } gchar const *out_name = sp_filter_name_for_image(parent, blend->in2); if (out_name) { repr->setAttribute("in2", out_name); } else { SPObject *i = parent->children; while (i && i->next != object) i = i->next; SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i); out_name = sp_filter_name_for_image(parent, i_prim->image_out); repr->setAttribute("in2", out_name); if (!out_name) { g_warning("Unable to set in2 for feBlend"); } } char const *mode; switch(blend->blend_mode) { case Inkscape::Filters::BLEND_NORMAL: mode = "normal"; break; case Inkscape::Filters::BLEND_MULTIPLY: mode = "multiply"; break; case Inkscape::Filters::BLEND_SCREEN: mode = "screen"; break; case Inkscape::Filters::BLEND_DARKEN: mode = "darken"; break; case Inkscape::Filters::BLEND_LIGHTEN: mode = "lighten"; break; default: mode = 0; } repr->setAttribute("mode", mode); if (((SPObjectClass *) feBlend_parent_class)->write) { ((SPObjectClass *) feBlend_parent_class)->write(object, doc, repr, flags); } return repr; }
/** * Reads the Inkscape::XML::Node, and initializes SPFeBlend variables. For this to get called, * our name must be associated with a repr via "sp_object_type_register". Best done through * sp-object-repr.cpp's repr_name_entries array. */ void SPFeBlend::build(SPDocument *document, Inkscape::XML::Node *repr) { SPFilterPrimitive::build(document, repr); /*LOAD ATTRIBUTES FROM REPR HERE*/ this->readAttr( "mode" ); this->readAttr( "in2" ); /* Unlike normal in, in2 is required attribute. Make sure, we can call * it by some name. */ if (this->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET || this->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT) { SPFilter *parent = SP_FILTER(this->parent); this->in2 = sp_filter_primitive_name_previous_out(this); repr->setAttribute("in2", sp_filter_name_for_image(parent, this->in2)); } }
/** * Gives name for output of previous filter. Makes things clearer when prim * is a filter with two or more inputs. Returns the slot number of result * of previous primitive, or NR_FILTER_SOURCEGRAPHIC if this is the first * primitive. */ int sp_filter_primitive_name_previous_out(SPFilterPrimitive *prim) { SPFilter *parent = SP_FILTER(prim->parent); SPObject *i = parent->children; while (i && i->next != prim) i = i->next; if (i) { SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i); if (i_prim->image_out < 0) { Glib::ustring name = sp_filter_get_new_result_name(parent); int slot = sp_filter_set_image_name(parent, name.c_str()); i_prim->image_out = slot; //XML Tree is being directly used while it shouldn't be. i_prim->getRepr()->setAttribute("result", name.c_str()); return slot; } else { return i_prim->image_out; } } return Inkscape::Filters::NR_FILTER_SOURCEGRAPHIC; }
/** * Receives update notifications. */ void SPFeBlend::update(SPCtx *ctx, guint flags) { if (flags & SP_OBJECT_MODIFIED_FLAG) { this->readAttr( "mode" ); this->readAttr( "in2" ); } /* Unlike normal in, in2 is required attribute. Make sure, we can call * it by some name. */ if (this->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET || this->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT) { SPFilter *parent = SP_FILTER(this->parent); this->in2 = sp_filter_primitive_name_previous_out(this); // TODO: XML Tree being used directly here while it shouldn't be. this->getRepr()->setAttribute("in2", sp_filter_name_for_image(parent, this->in2)); } SPFilterPrimitive::update(ctx, flags); }
/** * Writes its settings to an incoming repr object, if any. */ Inkscape::XML::Node* SPFeDisplacementMap::write(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) { SPFilter *parent = SP_FILTER(this->parent); if (!repr) { repr = doc->createElement("svg:feDisplacementMap"); } gchar const *in2_name = sp_filter_name_for_image(parent, this->in2); if( !in2_name ) { // This code is very similar to sp_filter_primtive_name_previous_out() SPObject *i = parent->children; // Find previous filter primitive while (i && i->next != this) { i = i->next; } if( i ) { SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i); in2_name = sp_filter_name_for_image(parent, i_prim->image_out); } } if (in2_name) { repr->setAttribute("in2", in2_name); } else { g_warning("Unable to set in2 for feDisplacementMap"); } sp_repr_set_svg_double(repr, "scale", this->scale); repr->setAttribute("xChannelSelector", get_channelselector_name(this->xChannelSelector)); repr->setAttribute("yChannelSelector", get_channelselector_name(this->yChannelSelector)); SPFilterPrimitive::write(doc, repr, flags); return repr; }
/** * Writes its settings to an incoming repr object, if any. */ Inkscape::XML::Node* SPFilterPrimitive::write(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) { SPFilterPrimitive* object = this; SPFilterPrimitive *prim = SP_FILTER_PRIMITIVE(object); SPFilter *parent = SP_FILTER(object->parent); if (!repr) { repr = object->getRepr()->duplicate(doc); } gchar const *in_name = sp_filter_name_for_image(parent, prim->image_in); repr->setAttribute("in", in_name); gchar const *out_name = sp_filter_name_for_image(parent, prim->image_out); repr->setAttribute("result", out_name); /* Do we need to add x,y,width,height? */ SPObject::write(doc, repr, flags); return repr; }
/** * Receives update notifications. */ void SPFeDisplacementMap::update(SPCtx *ctx, guint flags) { if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { /* do something to trigger redisplay, updates? */ } /* Unlike normal in, in2 is required attribute. Make sure, we can call * it by some name. */ if (this->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET || this->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT) { SPFilter *parent = SP_FILTER(this->parent); this->in2 = sp_filter_primitive_name_previous_out(this); //XML Tree being used directly here while it shouldn't be. this->getRepr()->setAttribute("in2", sp_filter_name_for_image(parent, this->in2)); } SPFilterPrimitive::update(ctx, flags); }
/** * Reads the Inkscape::XML::Node, and initializes SPFeBlend variables. For this to get called, * our name must be associated with a repr via "sp_object_type_register". Best done through * sp-object-repr.cpp's repr_name_entries array. */ static void sp_feBlend_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) { SPFeBlend *blend = SP_FEBLEND(object); if (((SPObjectClass *) feBlend_parent_class)->build) { ((SPObjectClass *) feBlend_parent_class)->build(object, document, repr); } /*LOAD ATTRIBUTES FROM REPR HERE*/ sp_object_read_attr(object, "mode"); sp_object_read_attr(object, "in2"); /* Unlike normal in, in2 is required attribute. Make sure, we can call * it by some name. */ if (blend->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET || blend->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT) { SPFilter *parent = SP_FILTER(object->parent); blend->in2 = sp_filter_primitive_name_previous_out(blend); repr->setAttribute("in2", sp_filter_name_for_image(parent, blend->in2)); } }
/** * Receives update notifications. */ static void sp_feBlend_update(SPObject *object, SPCtx *ctx, guint flags) { SPFeBlend *blend = SP_FEBLEND(object); if (flags & SP_OBJECT_MODIFIED_FLAG) { sp_object_read_attr(object, "mode"); sp_object_read_attr(object, "in2"); } /* Unlike normal in, in2 is required attribute. Make sure, we can call * it by some name. */ if (blend->in2 == Inkscape::Filters::NR_FILTER_SLOT_NOT_SET || blend->in2 == Inkscape::Filters::NR_FILTER_UNNAMED_SLOT) { SPFilter *parent = SP_FILTER(object->parent); blend->in2 = sp_filter_primitive_name_previous_out(blend); object->repr->setAttribute("in2", sp_filter_name_for_image(parent, blend->in2)); } if (((SPObjectClass *) feBlend_parent_class)->update) { ((SPObjectClass *) feBlend_parent_class)->update(object, ctx, flags); } }
/** * Writes its settings to an incoming repr object, if any. */ static Inkscape::XML::Node * sp_feComposite_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) { SPFeComposite *comp = SP_FECOMPOSITE(object); SPFilter *parent = SP_FILTER(object->parent); if (!repr) { repr = doc->createElement("svg:feComposite"); } gchar const *out_name = sp_filter_name_for_image(parent, comp->in2); if (out_name) { repr->setAttribute("in2", out_name); } else { SPObject *i = parent->children; while (i && i->next != object) i = i->next; SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i); out_name = sp_filter_name_for_image(parent, i_prim->image_out); repr->setAttribute("in2", out_name); if (!out_name) { g_warning("Unable to set in2 for feComposite"); } } char const *comp_op; switch (comp->composite_operator) { case COMPOSITE_OVER: comp_op = "over"; break; case COMPOSITE_IN: comp_op = "in"; break; case COMPOSITE_OUT: comp_op = "out"; break; case COMPOSITE_ATOP: comp_op = "atop"; break; case COMPOSITE_XOR: comp_op = "xor"; break; case COMPOSITE_ARITHMETIC: comp_op = "arithmetic"; break; default: comp_op = 0; } repr->setAttribute("operator", comp_op); if (comp->composite_operator == COMPOSITE_ARITHMETIC) { sp_repr_set_svg_double(repr, "k1", comp->k1); sp_repr_set_svg_double(repr, "k2", comp->k2); sp_repr_set_svg_double(repr, "k3", comp->k3); sp_repr_set_svg_double(repr, "k4", comp->k4); } else { repr->setAttribute("k1", 0); repr->setAttribute("k2", 0); repr->setAttribute("k3", 0); repr->setAttribute("k4", 0); } if (((SPObjectClass *) feComposite_parent_class)->write) { ((SPObjectClass *) feComposite_parent_class)->write(object, doc, repr, flags); } return repr; }
/** * Writes its settings to an incoming repr object, if any. */ Inkscape::XML::Node* SPFeBlend::write(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) { SPFilter *parent = SP_FILTER(this->parent); if (!repr) { repr = doc->createElement("svg:feBlend"); } gchar const *out_name = sp_filter_name_for_image(parent, this->in2); if (out_name) { repr->setAttribute("in2", out_name); } else { SPObject *i = parent->children; while (i && i->next != this) { i = i->next; } SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i); out_name = sp_filter_name_for_image(parent, i_prim->image_out); repr->setAttribute("in2", out_name); if (!out_name) { g_warning("Unable to set in2 for feBlend"); } } char const *mode; switch(this->blend_mode) { case Inkscape::Filters::BLEND_NORMAL: mode = "normal"; break; case Inkscape::Filters::BLEND_MULTIPLY: mode = "multiply"; break; case Inkscape::Filters::BLEND_SCREEN: mode = "screen"; break; case Inkscape::Filters::BLEND_DARKEN: mode = "darken"; break; case Inkscape::Filters::BLEND_LIGHTEN: mode = "lighten"; break; // New case Inkscape::Filters::BLEND_OVERLAY: mode = "overlay"; break; case Inkscape::Filters::BLEND_COLORDODGE: mode = "color-dodge"; break; case Inkscape::Filters::BLEND_COLORBURN: mode = "color-burn"; break; case Inkscape::Filters::BLEND_HARDLIGHT: mode = "hard-light"; break; case Inkscape::Filters::BLEND_SOFTLIGHT: mode = "soft-light"; break; case Inkscape::Filters::BLEND_DIFFERENCE: mode = "difference"; break; case Inkscape::Filters::BLEND_EXCLUSION: mode = "exclusion"; break; case Inkscape::Filters::BLEND_HUE: mode = "hue"; break; case Inkscape::Filters::BLEND_SATURATION: mode = "saturation"; break; case Inkscape::Filters::BLEND_COLOR: mode = "color"; break; case Inkscape::Filters::BLEND_LUMINOSITY: mode = "luminosity"; break; default: mode = 0; } repr->setAttribute("mode", mode); SPFilterPrimitive::write(doc, repr, flags); return repr; }
void ObjectCompositeSettings::_blendBlurValueChanged() { if (!_subject) { return; } SPDesktop *desktop = _subject->getDesktop(); if (!desktop) { return; } SPDocument *document = sp_desktop_document (desktop); if (_blocked) return; _blocked = true; // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903 //sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); Geom::OptRect bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); double radius; if (bbox) { double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? radius = _fe_cb.get_blur_value() * perimeter / 400; } else { radius = 0; } const Glib::ustring blendmode = _fe_cb.get_blend_mode(); //apply created filter to every selected item for (StyleSubject::iterator i = _subject->begin() ; i != _subject->end() ; ++i ) { if (!SP_IS_ITEM(*i)) { continue; } SPItem * item = SP_ITEM(*i); SPStyle *style = item->style; g_assert(style != NULL); if (blendmode != "normal") { SPFilter *filter = new_filter_simple_from_item(document, item, blendmode.c_str(), radius); sp_style_set_property_url(item, "filter", filter, false); } else { sp_style_set_property_url(item, "filter", NULL, false); } if (radius == 0 && item->style->filter.set && filter_is_single_gaussian_blur(SP_FILTER(item->style->getFilter()))) { remove_filter(item, false); } else if (radius != 0) { SPFilter *filter = modify_filter_gaussian_blur_from_item(document, item, radius); sp_style_set_property_url(item, "filter", filter, false); } //request update item->requestDisplayUpdate(( SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG )); } DocumentUndo::maybeDone(document, _blur_tag.c_str(), _verb_code, _("Change blur")); // resume interruptibility //sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop)); _blocked = false; }