summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpe-clone-original.cpp150
-rw-r--r--src/live_effects/lpe-clone-original.h5
-rw-r--r--src/live_effects/lpe-copy_rotate.cpp1
-rw-r--r--src/sp-path.cpp27
4 files changed, 123 insertions, 60 deletions
diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp
index 81e6809f1..76cc56b8f 100644
--- a/src/live_effects/lpe-clone-original.cpp
+++ b/src/live_effects/lpe-clone-original.cpp
@@ -24,6 +24,7 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) :
linked_item(_("Linked Item:"), _("Item from which to take the original data"), "linked_item", &wr, this),
scale(_("Scale %"), _("Scale item %"), "scale", &wr, this, 100.0),
preserve_position(_("Preserve position"), _("Preserve position"), "preserve_position", &wr, this, false),
+ use_center(_("Relative center of element"), _("Relative center of element"), "use_center", &wr, this, true),
attributes("Attributes linked", "Attributes linked", "attributes", &wr, this,""),
style_attributes("Style attributes linked", "Style attributes linked", "style_attributes", &wr, this,"")
{
@@ -33,14 +34,28 @@ LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) :
registerParameter(&attributes);
registerParameter(&style_attributes);
registerParameter(&preserve_position);
+ registerParameter(&use_center);
scale.param_set_range(0.01, 999999.0);
scale.param_set_increments(1, 1);
scale.param_set_digits(2);
attributes.param_hide_canvas_text();
style_attributes.param_hide_canvas_text();
- preserve_position_changed = !preserve_position;
+ preserve_position_changed = preserve_position;
preserve_affine = Geom::identity();
- apply_to_clippath_and_mask = true;
+}
+
+bool hasLinkedTransform( const char * attributes) {
+ gchar ** attarray = g_strsplit(attributes, ",", 0);
+ gchar ** iter = attarray;
+ bool has_linked_transform = false;
+ while (*iter != NULL) {
+ const char* attribute = (*iter);
+ if ( std::strcmp(attribute, "transform") == 0 ) {
+ has_linked_transform = true;
+ }
+ iter++;
+ }
+ return has_linked_transform;
}
void
@@ -53,41 +68,69 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co
for (std::vector<SPObject * >::iterator obj_it = childs.begin();
obj_it != childs.end(); ++obj_it) {
SPObject *dest_child = dest->nthChild(index);
- cloneAttrbutes(*obj_it, dest_child, live, attributes, style_attributes, false);
+ cloneAttrbutes((*obj_it), dest_child, live, attributes, style_attributes, false);
index++;
}
}
//Attributes
SPShape * shape_origin = SP_SHAPE(origin);
+ SPPath * path_origin = SP_PATH(origin);
SPShape * shape_dest = SP_SHAPE(dest);
+ SPMask *mask_origin = SP_ITEM(origin)->mask_ref->getObject();
+ SPMask *mask_dest = SP_ITEM(dest)->mask_ref->getObject();
+ if(mask_origin && mask_dest) {
+ std::vector<SPObject*> mask_list = mask_origin->childList(true);
+ std::vector<SPObject*> mask_list_dest = mask_dest->childList(true);
+ if (mask_list.size() == mask_list_dest.size()) {
+ size_t i = 0;
+ for ( std::vector<SPObject*>::const_iterator iter=mask_list.begin();iter!=mask_list.end();++iter) {
+ SPObject * mask_data = *iter;
+ SPObject * mask_dest_data = mask_list_dest[i];
+ cloneAttrbutes(mask_data, mask_dest_data, live, attributes, style_attributes, false);
+ i++;
+ }
+ }
+ }
+ SPClipPath *clippath_origin = SP_ITEM(origin)->clip_ref->getObject();
+ SPClipPath *clippath_dest = SP_ITEM(dest)->clip_ref->getObject();
+ if(clippath_origin && clippath_dest) {
+ std::vector<SPObject*> clippath_list = clippath_origin->childList(true);
+ std::vector<SPObject*> clippath_list_dest = clippath_dest->childList(true);
+ if (clippath_list.size() == clippath_list_dest.size()) {
+ size_t i = 0;
+ for ( std::vector<SPObject*>::const_iterator iter=clippath_list.begin();iter!=clippath_list.end();++iter) {
+ SPObject * clippath_data = *iter;
+ SPObject * clippath_dest_data = clippath_list_dest[i];
+ cloneAttrbutes(clippath_data, clippath_dest_data, live, attributes, style_attributes, false);
+ i++;
+ }
+ }
+ }
gchar ** attarray = g_strsplit(attributes, ",", 0);
gchar ** iter = attarray;
-// if (SP_IS_CLIPPATH(SP_ITEM(origin)->parent) || SP_IS_MASK(SP_ITEM(origin)->parent)) {
-// Geom::Affine dest_affine = Geom::identity();
-// if (root && preserve_position) {
-// dest_affine *= Geom::Translate(preserve_affine.translation());
-// }
-// SP_ITEM(SP_ITEM(dest)->parent)->transform = dest_affine;
-// }
+ Geom::Affine affine_dest = Geom::identity();
+ Geom::Affine affine_origin = Geom::identity();
+ Geom::Affine affine_previous = Geom::identity();
+ sp_svg_transform_read(SP_ITEM(dest)->getAttribute("transform"), &affine_dest);
+ sp_svg_transform_read(SP_ITEM(origin)->getAttribute("transform"), &affine_origin);
while (*iter != NULL) {
const char* attribute = (*iter);
if ( std::strcmp(attribute, "transform") == 0 ) {
- Geom::Affine affine_dest = SP_ITEM(dest)->transform;
- Geom::Affine affine_origin = SP_ITEM(origin)->transform;
- //dest->getRepr()->setAttribute(attribute, origin->getRepr()->attribute(attribute));
if (preserve_position) {
Geom::Affine dest_affine = Geom::identity();
if (root) {
- std::cout << "root" << preserve_affine.translation() << "\n";
- dest_affine *= Geom::Translate(preserve_affine.translation());
- //preserve_affine = Geom::identity();
- dest_affine *= Geom::Translate(affine_dest.translation());
+ dest_affine *= affine_origin;
+ if (preserve_affine == Geom::identity()) {
+ dest_affine *= Geom::Translate(affine_dest.translation());
+ }
dest_affine *= Geom::Translate(affine_origin.translation()).inverse();
- }
- dest_affine *= affine_origin;
- SP_ITEM(dest)->transform = dest_affine;
+ dest_affine *= Geom::Translate(preserve_affine.translation());
+ affine_previous = preserve_affine;
+ preserve_affine = Geom::identity();
+ SP_ITEM(dest)->getRepr()->setAttribute("transform",sp_svg_transform_write(dest_affine));
+ }
} else {
- SP_ITEM(dest)->transform = affine_origin ;
+ SP_ITEM(dest)->getRepr()->setAttribute("transform",sp_svg_transform_write(affine_origin));
}
} else if ( shape_dest && shape_origin && live && (std::strcmp(attribute, "d") == 0 || std::strcmp(attribute, "inkscape:original-d") == 0)) {
SPCurve *c = NULL;
@@ -99,21 +142,33 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co
if (c) {
Geom::PathVector c_pv = c->get_pathvector();
Geom::OptRect orig_bbox = SP_ITEM(origin)->geometricBounds();
- if (orig_bbox && root) {
+ Geom::OptRect dest_bbox = SP_ITEM(dest)->geometricBounds();
+ if (dest_bbox && orig_bbox && root) {
+ Geom::Point orig_point = (*orig_bbox).corner(0);
+ Geom::Point dest_point = (*dest_bbox).corner(0);
+ if (use_center) {
+ orig_point = (*orig_bbox).midpoint();
+ dest_point = (*dest_bbox).midpoint();
+ }
if (scale != 100.0) {
double scale_affine = scale/100.0;
Geom::Scale scale = Geom::Scale(scale_affine);
- c_pv *= Geom::Translate((*orig_bbox).midpoint()).inverse();
+ c_pv *= Geom::Translate(orig_point).inverse();
c_pv *= scale;
- c_pv *= Geom::Translate((*orig_bbox).midpoint());
+ c_pv *= Geom::Translate(orig_point);
}
- if (preserve_position) {
- c_pv *= Geom::Translate(Geom::Point(boundingbox_X.middle(), boundingbox_Y.middle()) - (*orig_bbox).midpoint());
+ if (preserve_position && hasLinkedTransform(attributes)) {
+ c_pv *= Geom::Translate(dest_point - orig_point);
}
}
+ c_pv *= i2anc_affine(dest, sp_lpe_item);
c->set_pathvector(c_pv);
- shape_dest->setCurveInsync(c, TRUE);
- dest->getRepr()->setAttribute(attribute, sp_svg_write_path(c_pv));
+ if (!path_origin) {
+ shape_dest->setCurveInsync(c, TRUE);
+ dest->getRepr()->setAttribute(attribute, sp_svg_write_path(c_pv));
+ } else {
+ shape_dest->setCurve(c, TRUE);
+ }
c->unref();
} else {
dest->getRepr()->setAttribute(attribute, NULL);
@@ -124,8 +179,6 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co
iter++;
}
g_strfreev (attarray);
-
- //Style Attributes
SPCSSAttr *css_origin = sp_repr_css_attr_new();
sp_repr_css_attr_add_from_string(css_origin, origin->getRepr()->attribute("style"));
SPCSSAttr *css_dest = sp_repr_css_attr_new();
@@ -161,17 +214,14 @@ LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){
linked_item.param_readSVGValue(linked_path.param_getSVGValue());
linked_path.param_readSVGValue("");
}
+
if (linked_item.linksToItem()) {
- if (preserve_position) {
- preserve_affine = SP_ITEM(sp_lpe_item)->transform;
+ if ( preserve_position_changed != preserve_position ) {
+ if (!preserve_position) {
+ sp_svg_transform_read(SP_ITEM(sp_lpe_item)->getAttribute("transform"), &preserve_affine);
+ }
+ preserve_position_changed = preserve_position;
}
-// if ( preserve_position_changed != preserve_position ) {
-// if (!preserve_position) {
-// preserve_affine = SP_ITEM(sp_lpe_item)->transform;
-// preserve_affine *= Geom::Translate(SP_ITEM(linked_item.getObject())->transform.translation()).inverse();
-// }
-// preserve_position_changed = preserve_position;
-// }
cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, attributes.param_getSVGValue(), style_attributes.param_getSVGValue(), true);
}
}
@@ -219,7 +269,7 @@ LPECloneOriginal::doOnApply(SPLPEItem const* lpeitem){
Glib::ustring attributes_value("d,transform");
attributes.param_setValue(attributes_value);
attributes.write_to_SVG();
- Glib::ustring style_attributes_value("opacity,border-width");
+ Glib::ustring style_attributes_value("opacity,stroke-width");
style_attributes.param_setValue(style_attributes_value);
style_attributes.write_to_SVG();
}
@@ -229,11 +279,23 @@ LPECloneOriginal::~LPECloneOriginal()
}
-void LPECloneOriginal::doEffect (SPCurve * curve)
+void
+LPECloneOriginal::transform_multiply(Geom::Affine const& postmul, bool set)
+{
+ if (linked_item.linksToItem()) {
+ bool changed = false;
+ linked_item.getObject()->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+}
+
+void
+LPECloneOriginal::doEffect (SPCurve * curve)
{
- SPShape * shape = getCurrentShape();
- if(shape){
- curve->set_pathvector(shape->getCurve()->get_pathvector());
+ if (linked_item.linksToItem()) {
+ SPShape * shape = getCurrentShape();
+ if(shape){
+ curve->set_pathvector(shape->getCurve()->get_pathvector());
+ }
}
}
diff --git a/src/live_effects/lpe-clone-original.h b/src/live_effects/lpe-clone-original.h
index e8a9a7419..064fe84b2 100644
--- a/src/live_effects/lpe-clone-original.h
+++ b/src/live_effects/lpe-clone-original.h
@@ -24,10 +24,10 @@ class LPECloneOriginal : public Effect, GroupBBoxEffect {
public:
LPECloneOriginal(LivePathEffectObject *lpeobject);
virtual ~LPECloneOriginal();
-
+ virtual void doOnApply(SPLPEItem const* lpeitem);
virtual void doEffect (SPCurve * curve);
virtual void doBeforeEffect (SPLPEItem const* lpeitem);
- virtual void doOnApply(SPLPEItem const* lpeitem);
+ virtual void transform_multiply(Geom::Affine const& postmul, bool set);
virtual Gtk::Widget * newWidget();
void cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes, bool root);
@@ -36,6 +36,7 @@ private:
OriginalItemParam linked_item;
ScalarParam scale;
BoolParam preserve_position;
+ BoolParam use_center;
TextParam attributes;
TextParam style_attributes;
bool preserve_position_changed;
diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp
index 3dd35696a..aafd2c094 100644
--- a/src/live_effects/lpe-copy_rotate.cpp
+++ b/src/live_effects/lpe-copy_rotate.cpp
@@ -122,7 +122,6 @@ void
LPECopyRotate::transform_multiply(Geom::Affine const& postmul, bool set)
{
// cycle through all parameters. Most parameters will not need transformation, but path and point params do.
-
for (std::vector<Parameter *>::iterator it = param_vector.begin(); it != param_vector.end(); ++it) {
Parameter * param = *it;
param->param_transform_multiply(postmul, set);
diff --git a/src/sp-path.cpp b/src/sp-path.cpp
index 0a2ce4c09..6c69f3463 100644
--- a/src/sp-path.cpp
+++ b/src/sp-path.cpp
@@ -289,10 +289,23 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) {
if (!_curve) { // 0 nodes, nothing to transform
return Geom::identity();
}
+ // Adjust stroke
+ this->adjust_stroke(transform.descrim());
+
+ // Adjust pattern fill
+ this->adjust_pattern(transform);
+
+ // Adjust gradient fill
+ this->adjust_gradient(transform);
+
+ // Adjust LPE
+ this->adjust_livepatheffect(transform);
// Transform the original-d path if this is a valid LPE this, other else the (ordinary) path
if (_curve_before_lpe && hasPathEffectRecursive()) {
- if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) || this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH)) {
+ if (this->hasPathEffectOfType(Inkscape::LivePathEffect::CLONE_ORIGINAL) ||
+ this->hasPathEffectOfType(Inkscape::LivePathEffect::BEND_PATH))
+ {
// if path has the CLONE_ORIGINAL LPE applied, don't write the transform to the pathdata, but write it 'unoptimized'
// also if the effect is type BEND PATH to fix bug #179842
return transform;
@@ -303,18 +316,6 @@ Geom::Affine SPPath::set_transform(Geom::Affine const &transform) {
_curve->transform(transform);
}
- // Adjust stroke
- this->adjust_stroke(transform.descrim());
-
- // Adjust pattern fill
- this->adjust_pattern(transform);
-
- // Adjust gradient fill
- this->adjust_gradient(transform);
-
- // Adjust LPE
- this->adjust_livepatheffect(transform);
-
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
// nothing remains - we've written all of the transform, so return identity