sp-item.cpp revision 123caab26399613386f5b6d52d05f8add6f70653
235N/A#ifdef HAVE_CONFIG_H
235N/A#include "display/nr-arena.h"
235N/A#include "display/nr-arena-item.h"
235N/A#include "attributes.h"
235N/A#include "document.h"
235N/A#include "inkscape.h"
235N/A#include "desktop-handles.h"
235N/A#include "sp-clippath.h"
235N/A#include "sp-item-rm-unsatisfied-cns.h"
235N/A#include "sp-pattern.h"
235N/A#include "sp-switch.h"
235N/A#include "gradient-chemistry.h"
237N/A#include "preferences.h"
264N/A#include "conn-avoid-ref.h"
268N/A#include "conditions.h"
270N/A#include "sp-filter-reference.h"
271N/A#include "filter-chemistry.h"
272N/A#include "sp-guide.h"
273N/A#include "sp-title.h"
276N/A#include "libnr/nr-matrix-fns.h"
305N/A#include "libnr/nr-matrix-scale-ops.h"
406N/A#include "libnr/nr-matrix-translate-ops.h"
412N/A#include "libnr/nr-scale-translate-ops.h"
429N/A#include "libnr/nr-translate-scale-ops.h"
453N/A#include "libnr/nr-convert2geom.h"
500N/A#include "algorithms/find-last-if.h"
517N/A#include "util/reverse-list.h"
#include "extract-uri.h"
#include "live_effects/lpeobject.h"
#include "live_effects/effect.h"
#include "live_effects/lpeobject-reference.h"
#define noSP_ITEM_DEBUG_IDLE
static Inkscape::XML::Node *sp_item_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs);
static SPItemView *sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, NRArenaItem *arenaitem);
sp_item_get_type(void)
if (!type) {
sizeof(SPItemClass),
sizeof(SPItem),
return type;
this->transform_center_x = 0;
this->transform_center_y = 0;
this->_is_evaluated = true;
updateRepr();
if (!isEvaluated())
updateRepr();
if (!isEvaluated())
return _is_evaluated;
this->updateRepr();
if (bbox) {
transform_center_x = 0;
transform_center_y = 0;
transform_center_x = 0;
transform_center_y = 0;
if (bbox) {
return to_2geom(bbox->midpoint()) + Geom::Point (this->transform_center_x, this->transform_center_y);
if (topmost) {
if (next_higher) {
if (next_lower) {
++next_lower;
if (bottom) {
++bottom;
switch (key) {
case SP_ATTR_TRANSFORM: {
case SP_PROP_CLIP_PATH: {
if (uri) {
case SP_PROP_MASK: {
if (uri) {
case SP_ATTR_CONNECTOR_AVOID:
if (value) {
if (value) {
case SP_PROP_SYSTEM_LANGUAGE:
if (old_clip) {
SPItemView *v;
if (old_mask) {
if (flags & (SP_OBJECT_CHILD_MODIFIED_FLAG | SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG)) {
if (clip_path) {
if (mask) {
sp_item_write(SPObject *const object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
GSList *l;
l = NULL;
g_free(c);
return repr;
sp_item_invoke_bbox(SPItem const *item, Geom::OptRect &bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type)
sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type)
sp_item_invoke_bbox_full(SPItem const *item, Geom::OptRect &bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear)
if (clear) {
double dx0 = 0;
double dx1 = 0;
double dy0 = 0;
double dy1 = 0;
NRRect b;
// Do not use temp_bbox.upgrade() here, because it uses a test that returns an empty Geom::OptRect()
// would therefore be translated into empty Geom::OptRect() (see bug https://bugs.launchpad.net/inkscape/+bug/168684)
Geom::OptRect temp_bbox_new = Geom::Rect(Geom::Point(temp_bbox.x0, temp_bbox.y0), Geom::Point(temp_bbox.x1, temp_bbox.y1));
sp_item_invoke_bbox_full(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear)
if (clear) {
NRRect b;
unsigned pos=0;
return pos;
pos++;
return rect;
static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const */*snapprefs*/)
* see for example sp_genericellipse_snappoints in sp-ellipse.cpp
if (bbox) {
*p = p1;
*p = p2;
void sp_item_snappoints(SPItem const *item, SnapPointsIter p, Inkscape::SnapPreferences const *snapprefs)
for (std::list<SPObject const *>::const_iterator o = clips_and_masks.begin(); o != clips_and_masks.end(); o++) {
for (std::vector<Geom::Point>::const_iterator p_orig = p_clip_or_mask.begin(); p_orig != p_clip_or_mask.end(); p_orig++) {
static gchar *
gchar *
g_free (s);
s = snew;
g_free (s);
s = snew;
g_free (s);
s = snew;
return NULL;
static unsigned dkey = 0;
return ai;
while (v != NULL) {
if (!ref) {
g_free(v);
ref = v;
v = next;
if (t_attr) {
t_old = t;
return t_old;
if (SP_IS_ITEM(o))
if (SP_IS_ITEM(o))
sp_item_adjust_paint_recursive (SPItem *item, Geom::Matrix advertized_transform, Geom::Matrix t_ancestors, bool is_pattern)
// _After_ full pattern/gradient transform: t_paint_new * t_item * t_ancestors * advertised_transform
Geom::Matrix paint_delta = t_item * t_ancestors * advertized_transform * t_ancestors.inverse() * t_item.inverse();
if (SP_IS_ITEM(o)) {
sp_item_adjust_paint_recursive (SP_ITEM(o), advertized_transform, t_item * t_ancestors, is_pattern);
// and paintservers on leaves inheriting their values from ancestors could adjust themselves properly
if (is_pattern)
if (lpeobj) {
sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, Geom::Matrix const &transform, Geom::Matrix const *adv, bool compensate)
if (compensate) {
/// \todo FIXME: add the same else branch as for gradients below, to convert patterns to userSpaceOnUse as well
// the object does not have a filter, or the transform is translation (which is supposed to not affect filters)
return FALSE;
return ret;
* Returns the accumulated transformation of the item and all its ancestors, including root's viewport.
return ret;
static SPItemView *
sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, NRArenaItem *arenaitem)
return new_view;
static SPItemView *
return list;
return NULL;
SPItem *
return NULL;
(void)nv;
if (!bbox) {