21#include <glibmm/i18n.h>
22#include <sigc++/adaptors/bind.h>
60 while ( it != l->end()) {
70 , path_effects_enabled(1)
72 , current_path_effect(nullptr)
113 std::istringstream iss(value);
116 while (std::getline(iss, href,
';'))
118 auto path_effect_ref = std::make_shared<Inkscape::LivePathEffect::LPEObjectReference>(
this);
121 path_effect_ref->link(href.c_str());
123 g_warning(
"BadURIException when trying to find LPE: %s", e.what());
124 path_effect_ref->unlink();
128 if ( path_effect_ref->lpeobject && path_effect_ref->lpeobject->get_lpe() ) {
137 g_warning(
"Unknown LPE type specified, LPE stack effectively disabled");
171 if (flags & SP_OBJECT_WRITE_EXT) {
191 return clipnode !=
nullptr;
195 auto p = cast<SPLPEItem>(
parent);
196 return (p && p->onsymbol) || is<SPSymbol>(
this);
216 g_warning(
"SPLPEItem::performPathEffect - NULL lpeobj in list!");
225 if (hreflist.size()) {
226 if (path_effect_list_size != this->path_effect_list->size()) {
243 g_warning(
"SPLPEItem::performPathEffect - lpeobj with invalid lpe in the stack!");
260 if (!is<SPGroup>(
this)) {
267 current->bbox_vis_cache_is_valid =
false;
268 current->bbox_geom_cache_is_valid =
false;
270 auto group = cast<SPGroup>(
this);
271 if (!group && !is_clip_or_mask) {
280 catch (std::exception & e) {
281 g_warning(
"Exception during LPE %s execution. \n %s", lpe->
getName().c_str(), e.what());
282 if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) {
284 _(
"An exception occurred during execution of the Path Effect.") );
308 if (is<SPGroup>(
this)) {
349 return !prefs->
getBool(
"/options/preservetransform/value",
false);
387 g_message(
"sp_lpe_item_update_patheffect: %p\n", lpeitem);
389 g_return_if_fail (lpeitem !=
nullptr);
410 if (with_satellites) {
422 g_message(
"lpeobject_ref_modified");
424 if (!lpeitem->
document->
isSeeking() && flags != 29 && flags != 253 && !(flags & SP_OBJECT_STYLESHEET_MODIFIED_FLAG))
433 g_return_if_fail(lpeitem !=
nullptr);
437 std::vector<SPObject*> clip_path_list = clip_path->
childList(
true);
438 for (
auto iter : clip_path_list) {
439 auto clip_data = cast<SPLPEItem>(iter);
447 std::vector<SPObject*> mask_path_list = mask_path->
childList(
true);
448 for (
auto iter : mask_path_list) {
449 auto mask_data = cast<SPLPEItem>(iter);
454 if (is<SPGroup>(lpeitem)) {
455 std::vector<SPItem*> item_list = cast<SPGroup>(lpeitem)->item_list();
456 for (
auto subitem : item_list) {
457 if (is<SPLPEItem>(subitem)) {
461 }
else if (
auto path = cast<SPPath>(lpeitem)) {
462 if (!path->getAttribute(
"inkscape:original-d") ) {
463 if (gchar
const * value = path->getAttribute(
"d")) {
464 path->setAttribute(
"inkscape:original-d", value);
467 }
else if (
auto shape = cast<SPShape>(lpeitem)) {
468 if (!shape->curveBeforeLPE()) {
469 shape->setCurveBeforeLPE(shape->curve());
480 auto group = cast<SPGroup>(lpeitem);
481 auto shape = cast<SPShape>(lpeitem);
482 auto path = cast<SPPath>(lpeitem);
485 std::vector<SPObject*> clip_path_list = clip_path->
childList(
true);
486 for (
auto iter : clip_path_list) {
487 auto clip_data = cast<SPLPEItem>(iter);
497 std::vector<SPObject*> mask_path_list = mask_path->
childList(
true);
498 for (
auto iter : mask_path_list) {
499 auto mask_data = cast<SPLPEItem>(iter);
508 std::vector<SPItem*> item_list = cast<SPGroup>(lpeitem)->item_list();
509 for (
auto iter : item_list) {
510 if (
auto subitem = cast<SPLPEItem>(iter)) {
511 if (
auto shape = cast<SPShape>(iter)) {
512 if (gchar
const * value = shape->getAttribute(
"d")) {
521 if (repr->
attribute(
"inkscape:original-d") &&
524 ( is_clip_mask && force)))
530 path->setCurveBeforeLPE(
nullptr);
531 if (!(shape->curve()->get_segment_count())) {
541 SPCurve const *c_lpe = shape->curve();
545 }
else if (shape->getAttribute(
"d")) {
546 d_str = shape->getAttribute(
"d");
552 ( is_clip_mask && force)))
556 shape->setCurveBeforeLPE(
nullptr);
559 const char * style = repr->
attribute(
"style");
561 gint pos = shape->getRepr()->position();
565 char const *class_attr = shape->getRepr()->
attribute(
"class");
567 gchar *title = shape->title();
569 gchar *desc = shape->desc();
571 gchar
const *transform_str = shape->getRepr()->attribute(
"transform");
573 gchar
const *mask_str = (gchar *) shape->getRepr()->attribute(
"mask");
575 gchar
const *clip_str = (gchar *) shape->getRepr()->attribute(
"clip-path");
578 gchar
const *transform_center_x = shape->getRepr()->attribute(
"inkscape:transform-center-x");
579 gchar
const *transform_center_y = shape->getRepr()->attribute(
"inkscape:transform-center-y");
583 shape->deleteObject(
false);
597 repr->
setAttribute(
"inkscape:transform-center-x", transform_center_x);
599 repr->
setAttribute(
"inkscape:transform-center-y", transform_center_y);
605 parent->appendChild(repr);
607 if (title && newObj) {
611 if (desc && newObj) {
618 lpeitem = cast<SPLPEItem>(newObj);
636 if (!value.empty()) {
639 auto group = cast<SPGroup>(
this);
649 hreflist.emplace_back(it->lpeobject_href);
651 hreflist.push_back(std::move(value));
655 if( is<SPGenericEllipse>(
this)) {
662 if (lpeobj && lpeobj->
get_lpe()) {
684 gchar *hrefstr = g_strdup_printf(
"#%s", repr_id);
699 effect_->keep_paths = keep_paths;
700 effect_->on_remove_all =
false;
701 if (effect_->getHolderRemove()) {
705 effect_->doOnRemove_impl(
this);
711 if (
auto ell = cast<SPGenericEllipse>(
this)) {
724 auto grp = cast<SPGroup>(
this);
726 std::vector<SPItem *> item_list = grp->item_list();
727 for (
auto iter : item_list) {
730 for (
auto iter : item_list) {
731 auto subitem = cast<SPLPEItem>(iter);
732 if (subitem && subitem->document) {
733 subitem->removeAllPathEffects(keep_paths, recursive);
736 for (
auto iter : item_list) {
750 for (
auto &lperef : a_path_effect_list) {
773 if (
auto ell = cast<SPGenericEllipse>(
this)) {
788 auto const cur_it = std::find(new_list.begin(), new_list.end(), lperef);
789 if (cur_it != new_list.cend()) {
790 auto down_it = cur_it;
792 if (down_it != new_list.end()) {
793 std::iter_swap(cur_it, down_it);
809 auto const cur_it = std::find(this->
path_effect_list->cbegin(), this->path_effect_list->cend(), lperef);
811 for (
auto it = this->path_effect_list->cbegin(); it != this->path_effect_list->cend(); ++it) {
812 hreflist.emplace_back((*it)->lpeobject_href);
816 hreflist.push_back(std::string{
"#"} += duple->getId());
833 auto const cur_it = std::find(this->
path_effect_list->cbegin(), this->path_effect_list->cend(), lperef);
836 for (
auto it = this->path_effect_list->cbegin(); it != this->path_effect_list->cend(); ++it) {
838 hreflist2.emplace_back((*it)->lpeobject_href);
840 hreflist.emplace_back((*it)->lpeobject_href);
852 if ( hreflist2.size()) {
854 lpeitem->setAttributeOrRemoveIfEmpty(
"inkscape:path-effect",
hreflist_svg_string(hreflist2));
858 lpeitem->update_satellites(
true);
871 if (lperef->lpeobject == lpe->
getLPEObj()) {
881 g_warning(
"LPE dont exist to remove");
894 auto const nlpe = new_list.size();
903 auto insertme = new_list.begin();
904 auto insertto = new_list.begin();
905 std::advance(insertme,
origin);
907 std::advance(insertto, dest);
910 std::advance(insertto, dest + 1);
913 new_list.insert(insertto, *insertme);
914 auto removeme = new_list.begin();
916 std::advance(removeme,
origin + 1);
918 std::advance(removeme,
origin);
921 new_list.erase(removeme);
925 std::advance(select, selectme);
931 if (lperef->lpeobject == lpeobj) {
948 auto const cur_it = std::find(new_list.begin(), new_list.end(), lperef);
949 if (cur_it != new_list.end() && cur_it != new_list.begin()) {
952 std::iter_swap(cur_it, up_it);
965 auto grp = cast<SPGroup>(
this);
966 if (recursive && grp) {
967 std::vector<SPItem *> item_list = grp->item_list();
968 for (
auto iter : item_list) {
969 auto subitem = cast<SPLPEItem>(iter);
971 subitem->update_satellites(recursive);
981 if (
auto *lpe = lpeobj->
get_lpe()) {
982 lpe->update_satellites();
999 if (!lpeobj || !lpeobj->
get_lpe()) {
1009 auto parent_lpe_item = cast<SPLPEItem>(
parent);
1010 if (parent_lpe_item) {
1011 return hasPathEffectOfType(type, is_ready) || parent_lpe_item->hasPathEffectOfTypeRecursive(type, is_ready);
1024 auto const lpeobj = it->lpeobject;
1028 if (is_ready || lpe->
isReady()) {
1069 auto parent_lpe_item = cast<SPLPEItem>(
parent);
1070 if (parent_lpe_item) {
1088 if (!lpeobj || !lpeobj->
get_lpe()) {
1098 auto parent_lpe_item = cast<SPLPEItem>(
parent);
1099 if (parent_lpe_item) {
1100 return hasPathEffect() || parent_lpe_item->hasPathEffectRecursive();
1112 auto parent_lpe_item = cast<SPLPEItem>(
parent);
1116 return parent_lpe_item ? parent_lpe_item->getTopPathEffect() :
this;
1124 auto group = cast<SPGroup>(
this);
1125 auto shape = cast<SPShape>(
this);
1127 std::vector<SPItem*> item_list = group->item_list();
1128 for (
auto iter2 : item_list) {
1129 auto subitem = cast<SPLPEItem>(iter2);
1131 subitem->resetClipPathAndMaskLPE(
true);
1135 shape->setCurveInsync(shape->curveForEdit());
1137 shape->removeAttribute(
"inkscape:original-d");
1138 shape->setCurveBeforeLPE(
nullptr);
1148 std::vector<SPObject*> clip_path_list = clip_path->
childList(
true);
1149 for (
auto iter : clip_path_list) {
1150 auto group = cast<SPGroup>(iter);
1151 auto shape = cast<SPShape>(iter);
1153 std::vector<SPItem*> item_list = group->item_list();
1154 for (
auto iter2 : item_list) {
1155 auto subitem = cast<SPLPEItem>(iter2);
1157 subitem->resetClipPathAndMaskLPE(
true);
1161 shape->setCurveInsync(shape->curveForEdit());
1163 shape->removeAttribute(
"inkscape:original-d");
1164 shape->setCurveBeforeLPE(
nullptr);
1175 std::vector<SPObject*> mask_list = mask->
childList(
true);
1176 for (
auto iter : mask_list) {
1177 auto group = cast<SPGroup>(iter);
1178 auto shape = cast<SPShape>(iter);
1180 std::vector<SPItem*> item_list = group->item_list();
1181 for (
auto iter2 : item_list) {
1182 auto subitem = cast<SPLPEItem>(iter2);
1184 subitem->resetClipPathAndMaskLPE(
true);
1188 shape->setCurveInsync(shape->curveForEdit());
1190 shape->removeAttribute(
"inkscape:original-d");
1191 shape->setCurveBeforeLPE(
nullptr);
1210 std::vector<SPObject*> clip_path_list = clip_path->
childList(
true);
1211 for (
auto clip_data : clip_path_list) {
1226 std::vector<SPObject*> mask_list = mask->
childList(
true);
1227 for (
auto mask_data : mask_list) {
1237 auto group = cast<SPGroup>(clip_mask);
1238 auto shape = cast<SPShape>(clip_mask);
1241 std::vector<SPItem*> item_list = group->
item_list();
1242 for (
auto subitem : item_list) {
1246 if (
root->inkscape.getVersion().isInsideRangeInclusive({0, 1}, {0, 92})) {
1247 shape->removeAttribute(
"inkscape:original-d");
1249 if (shape->curve()) {
1250 auto c = *shape->curve();
1251 bool success =
false;
1258 }
catch (std::exception & e) {
1259 g_warning(
"Exception during LPE execution. \n %s", e.what());
1260 if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) {
1262 _(
"An exception occurred during execution of the Path Effect.") );
1268 shape->setCurveInsync(std::move(
c));
1269 shape->setAttribute(
"d", str);
1272 if (gchar
const * value = shape->getAttribute(
"d")) {
1276 shape->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
1285 std::as_const(*this).getFirstPathEffectOfType(type));
1302template <
bool as_const>
1306 using Ptr = std::add_pointer_t<std::conditional_t<as_const, std::add_const_t<Effect>, Effect>>;
1307 std::vector<Ptr> effects;
1308 if (!type) effects.reserve(path_effect_list.size());
1309 for (
auto const &lperef : path_effect_list) {
1310 if (
auto const lpeobj = lperef->lpeobject) {
1311 if (
auto const lpe = lpeobj->get_lpe(); lpe && (!type || lpe->effectType() == *type)) {
1312 effects.push_back(lpe);
1348 if (lperef && lperef->lpeobject && lperef->lpeobject->get_lpe()) {
1349 lperef->lpeobject->get_lpe()->editNextParamOncanvas(
this, dt);
1359 if ( ochild && is<SPLPEItem>(ochild) ) {
1378 for (
auto const &it : list) {
1379 hreflist.emplace_back(it->lpeobject_href);
1395 bool semicolon_first =
false;
1397 for (
auto const &it : list) {
1398 if (semicolon_first) {
1402 semicolon_first =
true;
1427 if (it->lpeobject_repr == lperef->lpeobject_repr) {
1443 if (it->lpeobject_repr == lperef->lpeobject_repr) {
1461 if (it->lpeobject_repr == lperef->lpeobject_repr) {
1466 return Glib::ustring::npos;
1484 if (lperef && lperef->lpeobject)
1485 return lperef->lpeobject->get_lpe();
1494 if (it->lpeobject == lpe->
getLPEObj()) {
1497 prev = it->lpeobject->get_lpe();
1507 return it->lpeobject->get_lpe();
1509 if (it->lpeobject == lpe->
getLPEObj()) {
1520 last = it->lpeobject->get_lpe();
1534 auto const lpeobj = it->lpeobject;
1538 if (is_ready || lpe->
isReady()) {
1553 if (it->lpeobject == lpe->
getLPEObj()) {
1558 return Glib::ustring::npos;
1564 if (it->lpeobject_repr == lperef->lpeobject_repr) {
1576 if (it->lpeobject_repr == lopeobj->
getRepr()) {
1587 std::vector<SPObject *> satellites;
1589 auto group = cast<SPGroup>(
this);
1591 std::vector<SPItem*> item_list = group->item_list();
1592 for (
auto child:item_list) {
1593 auto lpechild = cast<SPLPEItem>(
child);
1595 std::vector<SPObject *> tmp = lpechild->get_satellites(force, recursive);
1596 satellites.insert( satellites.end(), tmp.begin(), tmp.end() );
1607 satellites.insert(satellites.begin(), tmp.begin(), tmp.end());
1612 std::vector<SPObject *> allsatellites;
1613 for (
auto satellite : satellites) {
1615 if ( satellite && ( lpeitem = cast<SPLPEItem>(satellite) )) {
1616 std::vector<SPObject *> tmp = lpeitem->
get_satellites(force, recursive);
1617 allsatellites.insert(allsatellites.begin(), tmp.begin(), tmp.end());
1620 satellites.insert(satellites.begin(), allsatellites.begin(), allsatellites.end());
1630 std::vector<LivePathEffectObject const *>
const &new_lpeobjs )
1634 auto const current_lpeobj = it->lpeobject;
1635 auto const found_it = std::find(old_lpeobjs.cbegin(), old_lpeobjs.cend(), current_lpeobj);
1636 if (found_it != old_lpeobjs.cend()) {
1637 auto const found_index = std::distance(old_lpeobjs.cbegin(), found_it);
1638 const gchar * repr_id = new_lpeobjs[found_index]->getRepr()->attribute(
"id");
1639 gchar *hrefstr = g_strdup_printf(
"#%s", repr_id);
1640 hreflist.emplace_back(hrefstr);
1643 hreflist.emplace_back(it->lpeobject_href);
1658 bool forked =
false;
1659 auto group = cast<SPGroup>(
this);
1660 if (group && recursive) {
1661 std::vector<SPItem*> item_list = group->item_list();
1662 for (
auto child:item_list) {
1663 auto lpeitem = cast<SPLPEItem>(
child);
1664 if (lpeitem && lpeitem->forkPathEffectsIfNecessary(nr_of_allowed_users, recursive)) {
1682 nr_of_allowed_users = 1;
1684 std::vector<LivePathEffectObject const*> old_lpeobjs, new_lpeobjs;
1685 std::vector<LivePathEffectObject *> upd_lpeobjs;
1687 for (
auto & it : effect_list)
1692 if (forked_lpeobj && forked_lpeobj != lpeobj) {
1696 old_lpeobjs.push_back(lpeobj);
1697 new_lpeobjs.push_back(forked_lpeobj);
1698 upd_lpeobjs.push_back(forked_lpeobj);
1705 for (
auto &forked_lpeobj : upd_lpeobjs) {
1706 forked_lpeobj->get_lpe()->read_from_SVG();
Lookup dictionary for attributes/properties.
TODO: insert short description here.
3x3 matrix representing an affine transformation.
bool isUniformScale(Coord eps=EPSILON) const
Check whether this matrix represents pure uniform scaling.
void doBeforeEffect_impl(SPLPEItem const *lpeitem)
virtual void resetDefaults(SPItem const *item)
Sets all parameters to their default values and writes them to SVG.
void transform_multiply_impl(Geom::Affine const &postmul, SPLPEItem *)
bool apply_to_clippath_and_mask
std::vector< SPObject * > effect_get_satellites(bool force=true)
virtual bool getHolderRemove()
void doAfterEffect_impl(SPLPEItem const *lpeitem, SPCurve *curve)
virtual void doOnException(SPLPEItem const *lpeitem)
Geom::PathVector pathvector_before_effect
Glib::ustring getName() const
EffectType effectType() const
Geom::PathVector pathvector_after_effect
virtual void doEffect(SPCurve *curve)
void doOnRemove_impl(SPLPEItem const *lpeitem)
static int acceptsNumClicks(EffectType type)
void doOnApply_impl(SPLPEItem const *lpeitem)
void setCurrentShape(SPShape *shape)
LivePathEffectObject * getLPEObj()
Glib::ustring param_getSVGValue() const override
Preference storage class.
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
static Preferences * get()
Access the singleton Preferences object.
Interface for refcounted XML nodes.
virtual Node * parent()=0
Get the parent of this node.
virtual void setPosition(int pos)=0
Set the position of this node in parent's child order.
void setAttributeOrRemoveIfEmpty(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
Change an attribute of this node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
void removeAttribute(Inkscape::Util::const_char_ptr key)
Remove an attribute of this node.
virtual void removeChild(Node *child)=0
Remove a child of this node.
Inkscape::LivePathEffect::Effect * get_lpe()
LivePathEffectObject * fork_private_if_necessary(unsigned int nr_of_allowed_users=1)
If this has other users, create a new private duplicate and return it returns 'this' when no forking ...
Wrapper around a Geom::PathVector object.
Geom::PathVector const & get_pathvector() const
To do: update description of desktop.
Typed SVG document implementation.
SPRoot * getRoot()
Returns our SPRoot.
Inkscape::XML::Node * getReprRoot()
Inkscape::XML::Document * getReprDoc()
Our Inkscape::XML::Document.
SPObject * getObjectByRepr(Inkscape::XML::Node *repr) const
std::vector< SPItem * > item_list()
Base class for visual SVG elements.
void update(SPCtx *ctx, unsigned int flags) override
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
void set(SPAttr key, char const *value) override
SPMask * getMaskObject() const
void build(SPDocument *document, Inkscape::XML::Node *repr) override
SPClipPath * getClipObject() const
bool isOnClipboard()
The lpeitem is on clipboard.
void remove_child(Inkscape::XML::Node *child) override
std::vector< Inkscape::LivePathEffect::Effect * > getPathEffectsOfType(int type)
void notifyTransform(Geom::Affine const &postmul)
notify tranbsform applied to a LPE
void duplicateCurrentPathEffect()
void downCurrentPathEffect()
Inkscape::LivePathEffect::Effect * getCurrentLPE()
void resetClipPathAndMaskLPE(bool fromrecurse=false)
PathEffectSharedPtr getNextLPEReference(PathEffectSharedPtr const &lperef)
std::vector< Inkscape::LivePathEffect::Effect * > getPathEffects()
void applyToMask(SPItem *to, Inkscape::LivePathEffect::Effect *lpe=nullptr)
void upCurrentPathEffect()
bool performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask=false)
returns true when LPE was successful.
bool hasBrokenPathEffect() const
used for shapes so they can see if they should also disable shape calculation and read from d=
Inkscape::LivePathEffect::Effect * getFirstPathEffectOfType(int type)
bool hasPathEffect() const
void applyToClipPath(SPItem *to, Inkscape::LivePathEffect::Effect *lpe=nullptr)
SPLPEItem const * getTopPathEffect() const
returns top most LPE item with LPE
PathEffectSharedPtr current_path_effect
void movePathEffect(gint origin, gint dest, bool select_moved=false)
PathEffectSharedPtr getLastLPEReference()
std::list< sigc::scoped_connection > lpe_modified_connection_list
std::vector< SPObject * > get_satellites(bool force=true, bool recursive=false, bool onchilds=false)
void replacePathEffects(std::vector< LivePathEffectObject const * > const &old_lpeobjs, std::vector< LivePathEffectObject const * > const &new_lpeobjs)
Writes a new "inkscape:path-effect" string to xml, where the old_lpeobjects are substituted by the ne...
SPLPEItem * removeCurrentPathEffect(bool keep_paths)
If keep_path is true, the item should not be updated, effectively 'flattening' the LPE.
void update_satellites(bool recursive=true)
bool hasPathEffectOnClipOrMaskRecursive(SPLPEItem *shape) const
returns true when any LPE apply to clip or mask.
std::size_t getLPEReferenceIndex(PathEffectSharedPtr const &lperef) const
std::size_t getLPEIndex(Inkscape::LivePathEffect::Effect *lpe) const
bool hasPathEffectOfTypeRecursive(int const type, bool is_ready=true) const
std::size_t countLPEOfType(int const type, bool inc_hidden=true, bool is_ready=true) const
PathEffectList getEffectList()
void child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) override
bool hasPathEffectOfType(int const type, bool is_ready=true) const
SPLPEItem * removeAllPathEffects(bool keep_paths, bool recursive=false)
If keep_path is true, the item should not be updated, effectively 'flattening' the LPE.
SPLPEItem * flattenCurrentPathEffect()
void removePathEffect(Inkscape::LivePathEffect::Effect *lpe, bool keep_paths)
bool hasPathEffectRecursive() const
void addPathEffect(std::string value, bool reset)
void applyToClipPathOrMask(SPItem *clip_mask, SPItem *to, Inkscape::LivePathEffect::Effect *lpe=nullptr)
Inkscape::LivePathEffect::Effect * getLastLPE()
bool pathEffectsEnabled() const
virtual void update_patheffect(bool write)
PathEffectList * path_effect_list
void update(SPCtx *ctx, unsigned int flags) override
bool forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users=1, bool recursive=true, bool force=false)
Check all effects in the stack if they are used by other items, and fork them if so.
void build(SPDocument *doc, Inkscape::XML::Node *repr) override
bool performPathEffect(SPCurve *curve, SPShape *current, bool is_clip_or_mask=false)
returns true when LPE was successful.
void modified(unsigned int flags) override
bool hasPathEffectOnClipOrMask(SPLPEItem *shape) const
returns true when any LPE apply to clip or mask.
PathEffectSharedPtr getCurrentLPEReference()
Inkscape::XML::Node * write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags) override
PathEffectSharedPtr getPrevLPEReference(PathEffectSharedPtr const &lperef)
Inkscape::LivePathEffect::Effect * getPrevLPE(Inkscape::LivePathEffect::Effect *lpe)
bool optimizeTransforms()
returns false when LPE write unoptimiced
void editNextParamOncanvas(SPDesktop *dt)
void set(SPAttr key, char const *value) override
Inkscape::LivePathEffect::Effect * getNextLPE(Inkscape::LivePathEffect::Effect *lpe)
bool setCurrentPathEffect(PathEffectSharedPtr const &lperef)
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Inkscape::XML::Node * repr
void setAttributeOrRemoveIfEmpty(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
void removeAttribute(char const *key)
bool setDesc(char const *desc, bool verbatim=false)
Sets the description of this object.
std::vector< SPObject * > childList(bool add_ref, Action action=ActionGeneral)
Retrieves the children as a std vector object, optionally ref'ing the children in the process,...
SPObject * get_child_by_repr(Inkscape::XML::Node *repr)
Return object's child whose node pointer equals repr.
virtual void remove_child(Inkscape::XML::Node *child)
bool setTitle(char const *title, bool verbatim=false)
Sets the title of this object.
void readAttr(char const *key)
Read value of key attribute from XML node into object.
void deleteObject(bool propagate, bool propagate_descendants)
Deletes an object, unparenting it from its parent.
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
virtual void child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
char const * getAttribute(char const *name) const
std::list< SPObject * > hrefList
Base class for shapes, including <path> element.
Editable view implementation.
static char const *const current
static char const *const parent
LPE <lattice2> implementation, see lpe-lattice2.cpp.
Raw stack of active status messages.
static R & release(R &r)
Decrements the reference count of a anchored object.
static cairo_user_data_key_t key
Singleton class to access the preferences file in a convenient way.
Inkscape::XML::Node const * sp_repr_lookup_name(Inkscape::XML::Node const *repr, gchar const *name, gint maxdepth)
static SPLPEItem * sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem, bool keep_paths, bool force=false, bool is_clip_mask=false)
std::list< std::string > HRefList
void sp_lpe_item_update_patheffect(SPLPEItem *lpeitem, bool wholetree, bool write, bool with_satellites)
Calls any registered handlers for the update_patheffect action.
static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem)
void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable)
static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem)
Gets called when any of the lpestack's lpeobject repr contents change: i.e.
auto getPathEffectsOfTypeImpl(PathEffectList const &path_effect_list, std::optional< int > const type)
static std::string hreflist_svg_string(HRefList const &list)
THE function that should be used to generate any patheffectlist string.
static std::string patheffectlist_svg_string(PathEffectList const &list)
std::list< PathEffectSharedPtr > PathEffectList
void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable)
void sp_lpe_item_update_patheffect(SPLPEItem *lpeitem, bool wholetree, bool write, bool with_satellites=false)
Calls any registered handlers for the update_patheffect action.
std::shared_ptr< Inkscape::LivePathEffect::LPEObjectReference > PathEffectSharedPtr
SPObject * sp_object_unref(SPObject *object, SPObject *owner)
Decrease reference count of object, with possible debugging and finalization.
SPObject * sp_object_ref(SPObject *object, SPObject *owner)
Increase reference count of object, with possible debugging.
SPRoot: SVG <svg> implementation.
Interface for XML documents.
virtual Node * createElement(char const *name)=0
Geom::PathVector sp_svg_read_pathv(char const *str)
static void sp_svg_write_path(Inkscape::SVG::PathString &str, Geom::Path const &p, bool normalize=false)