summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2014-06-07 11:15:07 +0000
committerJabiertxof <jtx@jtx.marker.es>2014-06-07 11:15:07 +0000
commit5b67a95f4477d1a69e9a0f100d71a77277d86ef2 (patch)
tree8ce58a552f29107488147cc29bb6c6a435d96b0a /src
parentUndo changes in r13391 (diff)
downloadinkscape-5b67a95f4477d1a69e9a0f100d71a77277d86ef2.tar.gz
inkscape-5b67a95f4477d1a69e9a0f100d71a77277d86ef2.zip
Fix for Bug #1241902 -
(bzr r13341.1.52)
Diffstat (limited to 'src')
-rw-r--r--src/box3d-side.cpp2
-rw-r--r--src/selection-chemistry.cpp4
-rw-r--r--src/sp-ellipse.cpp2
-rw-r--r--src/sp-item-group.cpp36
-rw-r--r--src/sp-item-group.h2
-rw-r--r--src/sp-lpe-item.cpp146
-rw-r--r--src/sp-lpe-item.h2
-rw-r--r--src/sp-path.cpp2
-rw-r--r--src/sp-spiral.cpp2
-rw-r--r--src/sp-star.cpp2
10 files changed, 192 insertions, 8 deletions
diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp
index dfccb63bf..a5e7eaa94 100644
--- a/src/box3d-side.cpp
+++ b/src/box3d-side.cpp
@@ -213,6 +213,8 @@ void Box3DSide::set_shape() {
bool success = this->performPathEffect(c_lpe);
if (success) {
+ sp_lpe_item_apply_to_mask(this);
+ sp_lpe_item_apply_to_clippath(this);
this->setCurveInsync(c_lpe, TRUE);
}
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 868a9d743..a350dd7a7 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -3950,6 +3950,10 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) {
for ( SPObject *child = obj->firstChild() ; child; child = child->getNext() ) {
// Collect all clipped paths and masks within a single group
Inkscape::XML::Node *copy = SP_OBJECT(child)->getRepr()->duplicate(xml_doc);
+ if(copy->attribute("inkscape:original-d"))
+ {
+ copy->setAttribute("d", copy->attribute("inkscape:original-d"));
+ }
items_to_move = g_slist_prepend(items_to_move, copy);
}
diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp
index cda59e057..428e0e3dd 100644
--- a/src/sp-ellipse.cpp
+++ b/src/sp-ellipse.cpp
@@ -467,6 +467,8 @@ void SPGenericEllipse::set_shape()
bool success = this->performPathEffect(c_lpe);
if (success) {
+ sp_lpe_item_apply_to_mask(this);
+ sp_lpe_item_apply_to_clippath(this);
this->setCurveInsync(c_lpe, TRUE);
}
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 2cfe97db8..b3db0c1d7 100644
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
@@ -778,17 +778,31 @@ void SPGroup::update_patheffect(bool write) {
}
}
+
+void
+sp_gslist_update_by_clip_or_mask(GSList *item_list,SPItem * item)
+{
+ if(item->mask_ref->getObject()) {
+ SPObject * clipormask = item->mask_ref->getObject()->firstChild();
+ item_list = g_slist_append(item_list,clipormask);
+ }
+ if(item->clip_ref->getObject()) {
+ SPObject * clipormask = item->clip_ref->getObject()->firstChild();
+ item_list = g_slist_append(item_list,clipormask);
+ }
+}
+
static void
sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write)
{
- GSList const *item_list = sp_item_group_item_list(SP_GROUP(group));
-
- for ( GSList const *iter = item_list; iter; iter = iter->next ) {
+ GSList *item_list = sp_item_group_item_list(group);
+ sp_gslist_update_by_clip_or_mask(item_list,group);
+ for ( GSList *iter = item_list; iter; iter = iter->next ) {
SPObject *subitem = static_cast<SPObject *>(iter->data);
-
if (SP_IS_GROUP(subitem)) {
sp_group_perform_patheffect(SP_GROUP(subitem), topgroup, write);
} else if (SP_IS_SHAPE(subitem)) {
+ sp_gslist_update_by_clip_or_mask(item_list,SP_ITEM(subitem));
SPCurve * c = NULL;
if (SP_IS_PATH(subitem)) {
@@ -799,9 +813,17 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write)
// only run LPEs when the shape has a curve defined
if (c) {
- c->transform(i2anc_affine(subitem, topgroup));
+ if(SP_IS_MASK(subitem->parent) || SP_IS_CLIPPATH(subitem->parent)) {
+ c->transform(i2anc_affine(group, topgroup));
+ } else {
+ c->transform(i2anc_affine(subitem, topgroup));
+ }
SP_LPE_ITEM(topgroup)->performPathEffect(c);
- c->transform(i2anc_affine(subitem, topgroup).inverse());
+ if(SP_IS_MASK(subitem->parent) || SP_IS_CLIPPATH(subitem->parent)) {
+ c->transform(i2anc_affine(group, topgroup).inverse());
+ } else {
+ c->transform(i2anc_affine(subitem, topgroup).inverse());
+ }
SP_SHAPE(subitem)->setCurve(c, TRUE);
if (write) {
@@ -809,7 +831,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write)
gchar *str = sp_svg_write_path(c->get_pathvector());
repr->setAttribute("d", str);
#ifdef GROUP_VERBOSE
-g_message("sp_group_perform_patheffect writes 'd' attribute");
+ g_message("sp_group_perform_patheffect writes 'd' attribute");
#endif
g_free(str);
}
diff --git a/src/sp-item-group.h b/src/sp-item-group.h
index 2004a72b8..adec35571 100644
--- a/src/sp-item-group.h
+++ b/src/sp-item-group.h
@@ -88,7 +88,7 @@ public:
void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done = true);
-
+void sp_gslist_update_by_clip_or_mask(GSList *item_list, SPItem * item);
GSList *sp_item_group_item_list (SPGroup *group);
SPObject *sp_item_group_get_child_by_name (SPGroup *group, SPObject *ref, const gchar *name);
diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp
index 762dc3191..5818054a7 100644
--- a/src/sp-lpe-item.cpp
+++ b/src/sp-lpe-item.cpp
@@ -38,6 +38,11 @@
#include "desktop.h"
#include "shape-editor.h"
#include "sp-ellipse.h"
+#include "display/curve.h"
+#include "svg/svg.h"
+#include <2geom/pathvector.h>
+#include "sp-clippath.h"
+#include "sp-mask.h"
#include "tools-switch.h"
#include "ui/tools/node-tool.h"
#include "ui/tools/tool-base.h"
@@ -51,6 +56,8 @@ static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeit
static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem);
static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem);
+static void sp_lpe_item_apply_to_clip_or_mask_group(SPGroup * group, SPItem * item);
+
typedef std::list<std::string> HRefList;
static std::string patheffectlist_write_svg(PathEffectList const & list);
static std::string hreflist_write_svg(HRefList const & list);
@@ -332,6 +339,16 @@ lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem)
static void
sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem)
{
+ SPMask * mask = lpeitem->mask_ref->getObject();
+ if(mask)
+ {
+ sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(mask->firstChild()));
+ }
+ SPClipPath * clipPath = lpeitem->clip_ref->getObject();
+ if(clipPath)
+ {
+ sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(clipPath->firstChild()));
+ }
if (SP_IS_GROUP(lpeitem)) {
GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem));
for ( GSList const *iter = item_list; iter; iter = iter->next ) {
@@ -352,6 +369,17 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem)
static void
sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem)
{
+ SPMask * mask = lpeitem->mask_ref->getObject();
+ if(mask)
+ {
+ sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild()));
+ }
+ SPClipPath * clipPath = lpeitem->clip_ref->getObject();
+ if(clipPath)
+ {
+ sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clipPath->firstChild()));
+ }
+
if (SP_IS_GROUP(lpeitem)) {
GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem));
for ( GSList const *iter = item_list; iter; iter = iter->next ) {
@@ -597,6 +625,124 @@ bool SPLPEItem::hasPathEffectRecursive() const
}
}
+void
+sp_lpe_item_apply_to_clippath(SPItem * item)
+{
+ SPClipPath *clipPath = item->clip_ref->getObject();
+ if(clipPath) {
+ SPObject * clip_data = clipPath->firstChild();
+ SPCurve * clip_curve = NULL;
+
+ if (SP_IS_PATH(clip_data)) {
+ clip_curve = SP_PATH(clip_data)->get_original_curve();
+ } else if(SP_IS_SHAPE(clip_data)) {
+ clip_curve = SP_SHAPE(clip_data)->getCurve();
+ } else if(SP_IS_GROUP(clip_data)) {
+ sp_lpe_item_apply_to_clip_or_mask_group(SP_GROUP(clip_data), item);
+ return;
+ }
+ if(clip_curve) {
+ bool success = SP_LPE_ITEM(item)->performPathEffect(clip_curve);
+ Inkscape::XML::Node *reprClip = clip_data->getRepr();
+ if (success) {
+ gchar *str = sp_svg_write_path(clip_curve->get_pathvector());
+ reprClip->setAttribute("d", str);
+ g_free(str);
+ } else {
+ // LPE was unsuccesfull. Read the old 'd'-attribute.
+ if (gchar const * value = reprClip->attribute("d")) {
+ Geom::PathVector pv = sp_svg_read_pathv(value);
+ SPCurve *oldcurve = new SPCurve(pv);
+ if (oldcurve) {
+ SP_SHAPE(clip_data)->setCurve(oldcurve, TRUE);
+ oldcurve->unref();
+ }
+ }
+ }
+ clip_curve->unref();
+ }
+ }
+}
+
+void
+sp_lpe_item_apply_to_mask(SPItem * item)
+{
+ SPMask *mask = item->mask_ref->getObject();
+ if(mask) {
+ SPObject * mask_data = mask->firstChild();
+ SPCurve * mask_curve = NULL;
+ mask_data = mask->firstChild();
+ if (SP_IS_PATH(mask_data)) {
+ mask_curve = SP_PATH(mask_data)->get_original_curve();
+ } else if(SP_IS_SHAPE(mask_data)) {
+ mask_curve = SP_SHAPE(mask_data)->getCurve();
+ } else if(SP_IS_GROUP(mask_data)) {
+ sp_lpe_item_apply_to_clip_or_mask_group(SP_GROUP(mask_data), item);
+ return;
+ }
+ if(mask_curve) {
+ bool success = SP_LPE_ITEM(item)->performPathEffect(mask_curve);
+ Inkscape::XML::Node *reprmask = mask_data->getRepr();
+ if (success) {
+ gchar *str = sp_svg_write_path(mask_curve->get_pathvector());
+ reprmask->setAttribute("d", str);
+ g_free(str);
+ } else {
+ // LPE was unsuccesfull. Read the old 'd'-attribute.
+ if (gchar const * value = reprmask->attribute("d")) {
+ Geom::PathVector pv = sp_svg_read_pathv(value);
+ SPCurve *oldcurve = new SPCurve(pv);
+ if (oldcurve) {
+ SP_SHAPE(mask_data)->setCurve(oldcurve, TRUE);
+ oldcurve->unref();
+ }
+ }
+ }
+ mask_curve->unref();
+ }
+ }
+}
+
+static void
+sp_lpe_item_apply_to_clip_or_mask_group(SPGroup *group, SPItem *item)
+{
+ GSList *item_list = sp_item_group_item_list(group);
+ for ( GSList *iter = item_list; iter; iter = iter->next ) {
+ SPObject *subitem = static_cast<SPObject *>(iter->data);
+ if (SP_IS_GROUP(subitem)) {
+ sp_lpe_item_apply_to_clip_or_mask_group(SP_GROUP(subitem), item);
+ } else if (SP_IS_SHAPE(subitem)) {
+ SPCurve * c = NULL;
+
+ if (SP_IS_PATH(subitem)) {
+ c = SP_PATH(subitem)->get_original_curve();
+ } else {
+ c = SP_SHAPE(subitem)->getCurve();
+ }
+ if (c) {
+ bool success = SP_LPE_ITEM(item)->performPathEffect(c);
+ Inkscape::XML::Node *repr = subitem->getRepr();
+ if (success) {
+ gchar *str = sp_svg_write_path(c->get_pathvector());
+ repr->setAttribute("d", str);
+ g_free(str);
+ } else {
+ // LPE was unsuccesfull. Read the old 'd'-attribute.
+ if (gchar const * value = repr->attribute("d")) {
+ Geom::PathVector pv = sp_svg_read_pathv(value);
+ SPCurve *oldcurve = new SPCurve(pv);
+ if (oldcurve) {
+ SP_SHAPE(subitem)->setCurve(oldcurve, TRUE);
+ oldcurve->unref();
+ }
+ }
+ }
+ c->unref();
+ }
+ }
+ }
+}
+
Inkscape::LivePathEffect::Effect*
SPLPEItem::getPathEffectOfType(int type)
{
diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h
index 85878a95b..3e858748d 100644
--- a/src/sp-lpe-item.h
+++ b/src/sp-lpe-item.h
@@ -98,6 +98,8 @@ public:
void editNextParamOncanvas(SPDesktop *dt);
};
+void sp_lpe_item_apply_to_mask(SPItem * item);
+void sp_lpe_item_apply_to_clippath(SPItem * item);
void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write); // careful, class already has method with *very* similar name!
#endif /* !SP_LPE_ITEM_H_SEEN */
diff --git a/src/sp-path.cpp b/src/sp-path.cpp
index d1fb850e1..9d88ec732 100644
--- a/src/sp-path.cpp
+++ b/src/sp-path.cpp
@@ -325,6 +325,8 @@ g_message("sp_path_update_patheffect");
bool success = this->performPathEffect(curve);
if (success && write) {
+ sp_lpe_item_apply_to_mask(this);
+ sp_lpe_item_apply_to_clippath(this);
// could also do this->getRepr()->updateRepr(); but only the d attribute needs updating.
#ifdef PATH_VERBOSE
g_message("sp_path_update_patheffect writes 'd' attribute");
diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp
index 9ef73d56d..8d4a37bf0 100644
--- a/src/sp-spiral.cpp
+++ b/src/sp-spiral.cpp
@@ -385,6 +385,8 @@ void SPSpiral::set_shape() {
bool success = this->performPathEffect(c_lpe);
if (success) {
+ sp_lpe_item_apply_to_mask(this);
+ sp_lpe_item_apply_to_clippath(this);
this->setCurveInsync( c_lpe, TRUE);
}
diff --git a/src/sp-star.cpp b/src/sp-star.cpp
index eac33ed7b..170a863b5 100644
--- a/src/sp-star.cpp
+++ b/src/sp-star.cpp
@@ -465,6 +465,8 @@ void SPStar::set_shape() {
bool success = this->performPathEffect(c_lpe);
if (success) {
+ sp_lpe_item_apply_to_mask(this);
+ sp_lpe_item_apply_to_clippath(this);
this->setCurveInsync( c_lpe, TRUE);
}