summaryrefslogtreecommitdiffstats
path: root/src/live_effects/lpe-clone-original.cpp
diff options
context:
space:
mode:
authorJabiertxof <jtx@jtx>2017-01-24 14:17:37 +0000
committerJabiertxof <jtx@jtx>2017-01-24 14:17:37 +0000
commit6065dda92002a05f31d58ce373bbcccdbe761907 (patch)
tree376d1a771f47d66b714ed28cd3563f3d9ad838b4 /src/live_effects/lpe-clone-original.cpp
parentfixing to new trunk (diff)
parentFix a translation bug in rotate copies LPE (diff)
downloadinkscape-6065dda92002a05f31d58ce373bbcccdbe761907.tar.gz
inkscape-6065dda92002a05f31d58ce373bbcccdbe761907.zip
Update to trunk
(bzr r15142.1.39)
Diffstat (limited to 'src/live_effects/lpe-clone-original.cpp')
-rw-r--r--src/live_effects/lpe-clone-original.cpp331
1 files changed, 324 insertions, 7 deletions
diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp
index 10418a02d..31d5bab65 100644
--- a/src/live_effects/lpe-clone-original.cpp
+++ b/src/live_effects/lpe-clone-original.cpp
@@ -6,6 +6,12 @@
#include "live_effects/lpe-clone-original.h"
#include "display/curve.h"
+#include "svg/path-string.h"
+#include "svg/svg.h"
+#include "sp-clippath.h"
+#include "sp-mask.h"
+#include "xml/sp-css-attr.h"
+
// TODO due to internal breakage in glibmm headers, this must be last:
#include <glibmm/i18n.h>
@@ -14,9 +20,310 @@ namespace LivePathEffect {
LPECloneOriginal::LPECloneOriginal(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
- linked_path(_("Linked path:"), _("Path from which to take the original path data"), "linkedpath", &wr, this)
+ linked_path("LEGACY FALLBACK", "LEGACY FALLBACK", "linkedpath", &wr, this),
+ 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),
+ inverse(_("Inverse clone"), _("Use LPE item as origin"), "inverse", &wr, this, false),
+ d(_("Clone shape -d-"), _("Clone shape -d-"), "d", &wr, this, true),
+ transform(_("Clone transforms"), _("Clone transforms"), "transform", &wr, this, true),
+ fill(_("Clone fill"), _("Clone fill"), "fill", &wr, this, false),
+ stroke(_("Clone stroke"), _("Clone stroke"), "stroke", &wr, this, false),
+ paintorder(_("Clone paint order"), _("Clone paint order"), "paintorder", &wr, this, false),
+ opacity(_("Clone opacity"), _("Clone opacity"), "opacity", &wr, this, false),
+ filter(_("Clone filter"), _("Clone filter"), "filter", &wr, this, false),
+ attributes("Attributes linked", "Attributes linked, comma separated atributes", "attributes", &wr, this,""),
+ style_attributes("Style attributes linked", "Style attributes linked, comma separated atributes", "style_attributes", &wr, this,""),
+ expanded(false)
{
- registerParameter( dynamic_cast<Parameter *>(&linked_path) );
+ registerParameter(&linked_path);
+ registerParameter(&linked_item);
+ registerParameter(&scale);
+ registerParameter(&attributes);
+ registerParameter(&style_attributes);
+ registerParameter(&preserve_position);
+ registerParameter(&inverse);
+ registerParameter(&d);
+ registerParameter(&transform);
+ registerParameter(&fill);
+ registerParameter(&stroke);
+ registerParameter(&paintorder);
+ registerParameter(&opacity);
+ registerParameter(&filter);
+ 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_affine = Geom::identity();
+}
+
+void
+LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, const char * attributes, const char * style_attributes, bool root)
+{
+ SPDocument * document = SP_ACTIVE_DOCUMENT;
+ if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) {
+ std::vector< SPObject * > childs = origin->childList(true);
+ size_t index = 0;
+ 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);
+ 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;
+ 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 ) {
+ if (preserve_position) {
+ Geom::Affine dest_affine = Geom::identity();
+ if (root) {
+ 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 *= 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)->getRepr()->setAttribute("transform",sp_svg_transform_write(affine_origin));
+ }
+ } else if ( shape_dest && shape_origin && live && (std::strcmp(attribute, "d") == 0)) {
+ SPCurve *c = NULL;
+ if (inverse) {
+ c = shape_origin->getCurveBeforeLPE();
+ } else {
+ c = shape_origin->getCurve();
+ }
+ if (c) {
+ Geom::PathVector c_pv = c->get_pathvector();
+ Geom::OptRect orig_bbox = SP_ITEM(origin)->geometricBounds();
+ 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 (scale != 100.0) {
+ double scale_affine = scale/100.0;
+ Geom::Scale scale = Geom::Scale(scale_affine);
+ c_pv *= Geom::Translate(orig_point).inverse();
+ c_pv *= scale;
+ c_pv *= Geom::Translate(orig_point);
+ }
+ if (preserve_position) {
+ c_pv *= Geom::Translate(dest_point - orig_point);
+ }
+ }
+ if (inverse) {
+ c_pv *= i2anc_affine(origin, sp_lpe_item);
+ } else {
+ c_pv *= i2anc_affine(dest, sp_lpe_item);
+ }
+ c->set_pathvector(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);
+ }
+ } else {
+ dest->getRepr()->setAttribute(attribute, origin->getRepr()->attribute(attribute));
+ }
+ iter++;
+ }
+ g_strfreev (attarray);
+ 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();
+ sp_repr_css_attr_add_from_string(css_dest, dest->getRepr()->attribute("style"));
+ gchar ** styleattarray = g_strsplit(style_attributes, ",", 0);
+ gchar ** styleiter = styleattarray;
+ while (*styleiter != NULL) {
+ const char* attribute = (*styleiter);
+ const char* origin_attribute = sp_repr_css_property(css_origin, attribute, "");
+ if (origin_attribute == "") {
+ sp_repr_css_set_property (css_dest, attribute, NULL);
+ } else {
+ sp_repr_css_set_property (css_dest, attribute, origin_attribute);
+ }
+ styleiter++;
+ }
+ g_strfreev (styleattarray);
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css_dest,css_str);
+ dest->getRepr()->setAttribute("style", css_str.c_str());
+}
+
+void
+LPECloneOriginal::doBeforeEffect (SPLPEItem const* lpeitem){
+ if (linked_path.linksToPath()) { //Legacy staff
+ Glib::ustring attributes_value("d");
+ attributes.param_setValue(attributes_value);
+ attributes.write_to_SVG();
+ Glib::ustring style_attributes_value("");
+ style_attributes.param_setValue(style_attributes_value);
+ style_attributes.write_to_SVG();
+ linked_item.param_readSVGValue(linked_path.param_getSVGValue());
+ linked_path.param_readSVGValue("");
+ }
+
+ if (linked_item.linksToItem()) {
+ linked_item.setInverse(inverse);
+ 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;
+ }
+ Glib::ustring attr = "";
+ if (d) {
+ attr.append("d,");
+ }
+ if (transform) {
+ attr.append("transform,");
+ }
+ attr.append(Glib::ustring(attributes.param_getSVGValue()).append(","));
+ if (attr.size() && !Glib::ustring(attributes.param_getSVGValue()).size()) {
+ attr.erase (attr.size()-1, 1);
+ }
+ Glib::ustring style_attr = "";
+ if (fill) {
+ style_attr.append("fill,").append("fill-rule,");
+ }
+ if (stroke) {
+ style_attr.append("stroke,").append("stroke-width,").append("stroke-linecap,").append("stroke-linejoin,");
+ style_attr.append("stroke-opacity,").append("stroke-miterlimit,").append("stroke-dasharray,");
+ style_attr.append("stroke-opacity,").append("stroke-dashoffset,").append("marker-start,");
+ style_attr.append("marker-mid,").append("marker-end,");
+ }
+ if (paintorder) {
+ style_attr.append("paint-order,");
+ }
+ if (filter) {
+ style_attr.append("filter,");
+ }
+ if (opacity) {
+ style_attr.append("opacity,");
+ }
+ if (style_attr.size() && !Glib::ustring(style_attributes.param_getSVGValue()).size()) {
+ style_attr.erase (style_attr.size()-1, 1);
+ }
+ style_attr.append(Glib::ustring(style_attributes.param_getSVGValue()).append(","));
+ if (inverse) {
+ cloneAttrbutes(SP_OBJECT(sp_lpe_item), linked_item.getObject(), true, g_strdup(attr.c_str()), g_strdup(style_attr.c_str()), true);
+ } else {
+ cloneAttrbutes(linked_item.getObject(), SP_OBJECT(sp_lpe_item), true, g_strdup(attr.c_str()), g_strdup(style_attr.c_str()), true);
+ }
+ }
+}
+
+
+Gtk::Widget *
+LPECloneOriginal::newWidget()
+{
+ // use manage here, because after deletion of Effect object, others might
+ // still be pointing to this widget.
+ Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget()));
+ vbox->set_border_width(5);
+ vbox->set_homogeneous(false);
+ vbox->set_spacing(2);
+ Gtk::VBox * vbox_expander = Gtk::manage( new Gtk::VBox(Effect::newWidget()) );
+ vbox_expander->set_border_width(0);
+ vbox_expander->set_spacing(2);
+ std::vector<Parameter *>::iterator it = param_vector.begin();
+ while (it != param_vector.end()) {
+ if ((*it)->widget_is_visible) {
+ Parameter * param = *it;
+ if (param->param_key == "linkedpath") {
+ ++it;
+ continue;
+ }
+ Gtk::Widget * widg = param->param_newWidget();
+ Glib::ustring * tip = param->param_getTooltip();
+ if (widg) {
+ if (param->param_key != "attributes" &&
+ param->param_key != "style_attributes") {
+ vbox->pack_start(*widg, true, true, 2);
+ } else {
+ vbox_expander->pack_start(*widg, true, true, 2);
+ }
+ if (tip) {
+ widg->set_tooltip_text(*tip);
+ } else {
+ widg->set_tooltip_text("");
+ widg->set_has_tooltip(false);
+ }
+ }
+ }
+
+ ++it;
+ }
+ expander = Gtk::manage(new Gtk::Expander(Glib::ustring(_("Show attributes override"))));
+ expander->add(*vbox_expander);
+ expander->set_expanded(expanded);
+ expander->property_expanded().signal_changed().connect(sigc::mem_fun(*this, &LPECloneOriginal::onExpanderChanged) );
+ vbox->pack_start(*expander, true, true, 2);
+ this->upd_params = false;
+ return dynamic_cast<Gtk::Widget *>(vbox);
+}
+
+void
+LPECloneOriginal::onExpanderChanged()
+{
+ expanded = expander->get_expanded();
+ if(expanded) {
+ expander->set_label (Glib::ustring(_("Hide attributes override")));
+ } else {
+ expander->set_label (Glib::ustring(_("Show attributes override")));
+ }
}
LPECloneOriginal::~LPECloneOriginal()
@@ -24,12 +331,22 @@ 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)
{
- if ( linked_path.linksToPath() ) {
- Geom::PathVector linked_pathv = linked_path.get_pathvector();
- if ( !linked_pathv.empty() ) {
- curve->set_pathvector(linked_pathv);
+ if (linked_item.linksToItem() && !inverse) {
+ SPShape * shape = getCurrentShape();
+ if(shape){
+ curve->set_pathvector(shape->getCurve()->get_pathvector());
}
}
}