19#include <glibmm/i18n.h>
57 _insert_bottom(false),
84 auto item = cast<SPItem>(last_child);
87 for (
auto &v :
views) {
90 v.drawingitem->appendChild(ac);
100 for (
auto &v :
views) {
101 auto ac =
item->
invoke_show (v.drawingitem->drawing(), v.key, v.flags);
103 v.drawingitem->prependChild(ac);
104 ac->setZOrder(position);
131 v.drawingitem->setZOrder(position);
145 unsigned childflags = flags;
147 if (flags & SP_OBJECT_MODIFIED_FLAG) {
148 childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
150 childflags &= SP_OBJECT_MODIFIED_CASCADE;
153 if (childflags || (
child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
158 child->updateDisplay((
SPCtx *)&cctx, childflags);
160 child->updateDisplay(ctx, childflags);
173 if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
174 for (
auto &v :
views) {
175 auto group = cast<Inkscape::DrawingGroup>(v.drawingitem.get());
187 if (flags & SP_OBJECT_MODIFIED_FLAG) {
188 flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
191 flags &= SP_OBJECT_MODIFIED_CASCADE;
193 if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
194 for (
auto &v :
views) {
195 auto group = cast<Inkscape::DrawingGroup>(v.drawingitem.get());
196 group->setStyle(this->
style);
200 std::vector<SPObject*> l=this->
childList(
true);
202 if (flags || (
child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
203 child->emitModified(flags);
211 if (flags & SP_OBJECT_WRITE_BUILD) {
212 std::vector<Inkscape::XML::Node *> l;
215 if (is<SPSwitch>(
this)) {
223 if (!is<SPTitle>(&
child) && !is<SPDesc>(&
child)) {
231 for (
auto i=l.rbegin();i!=l.rend();++i) {
237 if (!is<SPTitle>(&
child) && !is<SPDesc>(&
child)) {
238 child.updateRepr(flags);
243 if ( flags & SP_OBJECT_WRITE_EXT ) {
248 value =
"maskhelper";
249 }
else if ( flags & SP_OBJECT_WRITE_ALL ) {
270 auto item = cast<SPItem>(o);
283 auto item = cast<SPItem>(o);
306 return _(
"Mask Helper");
309 return C_(
"Noun",
"Group");
315 return g_strdup_printf(
316 ngettext(
"of <b>%d</b> object",
"of <b>%d</b> objects",
len),
len);
322 if ( value && !strcmp(value,
"layer") ) {
324 }
else if ( value && !strcmp(value,
"maskhelper") ) {
355 auto item = cast<SPItem>(o);
366 std::vector<SPItem *> ret;
407 SPText *item_text =
nullptr;
409 SPUse *item_use =
nullptr;
410 auto lpeitemclone = cast<SPLPEItem>(
item);
412 bool override =
false;
413 if ((item_offset = cast<SPOffset>(
item))) {
415 }
else if ((item_text = cast<SPText>(
item))) {
417 }
else if (
auto textpath = cast<SPTextPath>(
item)) {
418 item_text = cast<SPText>(textpath->parent);
423 }
else if ((item_use = cast<SPUse>(
item))) {
429 if (source != expected_source && !
override) {
445 }
else if (item_offset) {
447 }
else if (item_use) {
467 auto hrefListCopy =
parent->hrefList;
469 for (
auto *cobj : hrefListCopy) {
478 auto shape = cast<SPShape>(
object);
481 auto curve = shape->curve();
484 std::vector<Geom::Point> nodes = pv.
nodes();
485 if (pv.
size() == 1 && nodes.size() == 4) {
491 bbox_clip = shape->visualBounds();
492 bbox_clip->expandBy(1);
504 auto shape = cast<SPShape>(
item);
505 auto shape_clip = cast<SPShape>(
clip);
507 if (shape && shape_clip) {
508 auto filter = shape->style->getFilter();
509 auto stroke = shape->style->getFillOrStroke(
false);
510 if (!filter && (!stroke || stroke->isNone())) {
511 auto curve = shape->curve();
512 auto curve_clip = shape_clip->curve();
513 if (
curve && curve_clip) {
514 equal =
curve->is_similar(curve_clip, 0.01);
530 auto hrefListCopy = group->
hrefList;
532 for (
auto *cobj : hrefListCopy) {
533 if (
auto clone = cast<SPUse>(cobj)) {
542 g_return_if_fail (group !=
nullptr);
550 prefs->setBool(
"/options/onungroup",
true);
554 g_return_if_fail (!strcmp (grepr->
name(),
"svg:g")
555 || !strcmp (grepr->
name(),
"svg:a")
556 || !strcmp (grepr->
name(),
"svg:switch")
557 || !strcmp (grepr->
name(),
"svg:svg"));
562 auto pitem = cast<SPItem>(group->
parent);
567 auto box = cast<SPBox3D>(group);
569 group = box->convert_to_group();
574 bool maskonungroup = prefs->getBool(
"/options/maskobject/maskonungroup",
true);
575 bool topmost = prefs->getBool(
"/options/maskobject/topmost",
true);
581 tmp_clip_set.
add(group);
583 tmp_mask_set.
add(group);
586 prefs->setBool(
"/options/maskobject/topmost",
true);
589 tmp_clip_set.
unsetMask(
true,
false,
true);
590 tmp_clip_set.
remove(group);
596 tmp_mask_set.
unsetMask(
false,
false,
true);
597 tmp_mask_set.
remove(group);
598 tmp_mask_set.
group();
603 std::vector<Inkscape::XML::Node *>
items;
604 std::vector<Inkscape::XML::Node *> objects;
612 if (
auto citem = cast<SPItem>(&
child)) {
613 auto lpeitem = cast<SPLPEItem>(citem);
619 SPObject *linked = clonelpe->linkeditem.getObject();
621 bool breakparent =
false;
622 for (
auto &child2 : group->
children) {
623 if (cast<SPItem>(&child2) == linked) {
642 auto citem = cast<SPItem>(&
child);
672 citem->transform *= g;
677 items.push_back(nrepr);
681 objects.push_back(nrepr);
693 if (!objects.empty()) {
695 for (
auto i=objects.rbegin();i!=objects.rend();++i) {
710 std::vector<SPLPEItem *> lpeitems;
711 for (
auto *repr :
items) {
713 prepr->
addChild(repr, insert_after);
718 auto lpeitem = cast<SPLPEItem>(
item);
721 lpeitems.push_back(lpeitem);
723 children.insert(children.begin(),
item);
726 children.insert(children.begin(),
item);
730 g_assert_not_reached();
737 if (!bbox_clip || !(*bbox_clip).
contains(*bbox_item)) {
748 result_mask_set.
add(mask);
749 result_mask_set.
setMask(
false,
false,
false);
752 for (
auto lpeitem : lpeitems) {
754 lpeitem->doWriteTransform(lpeitem->transform,
nullptr,
false);
755 lpeitem->requestModified(SP_OBJECT_MODIFIED_FLAG);
756 if (
clip && lpeitem) {
759 if (!bbox_clip || !(*bbox_clip).
contains(*bbox_item)) {
760 result_clip_set.
add(lpeitem);
766 if (result_clip_set.
size()) {
768 result_clip_set.
setMask(
true,
false,
false);
770 clip->deleteObject(
true,
false);
772 prefs->setBool(
"/options/maskobject/topmost", topmost);
773 prefs->setInt(
"/options/maskobject/grouping", grouping);
774 prefs->setBool(
"/options/onungroup",
false);
803 std::map<unsigned int, LayerMode>::const_iterator iter;
806 return (*iter).second;
826 for (
auto &v :
views) {
827 if (!display_key || v.key == display_key) {
828 if (
auto g = cast<Inkscape::DrawingGroup>(v.drawingitem.get())) {
839 if (
auto item = cast<SPItem>(&o)) {
851 if (
auto defs = cast<SPDefs>(&o) ) {
852 for (
auto& defschild: defs->children) {
853 auto defsgroup = cast<SPGroup>(&defschild);
855 defsgroup->scaleChildItemsRec(sc, p,
false);
857 }
else if (
auto item = cast<SPItem>(&o)) {
858 auto group = cast<SPGroup>(
item);
859 if (group && !is<SPBox3D>(
item)) {
878 if(std::abs(tAff[4]) < 1.0e-5 && std::abs(tAff[5]) < 1.0e-5){
885 SPItem *sub_item =
nullptr;
889 if (sub_item !=
nullptr) {
896 if (sub_item !=
nullptr) {
900 group->scaleChildItemsRec(sc, p,
false);
909 gchar
const *conn_type =
nullptr;
910 auto text_item = cast<SPText>(
item);
911 bool is_text_path = text_item && text_item->firstChild() && cast<SPTextPath>(text_item->firstChild());
913 text_item->optimizeTextpathText();
915 auto flowText = cast<SPFlowtext>(
item);
917 flowText->optimizeScaledText();
919 auto box = cast<SPBox3D>(
item);
944 }
else if (is<SPUse>(
item)) {
953 if (conn_type !=
nullptr) {
957 if (
item->
isCenterSet() && !(
final.isTranslation() ||
final.isIdentity())) {
971 if (is<SPItem>(&
child)) {
983 auto child = cast<SPItem>(o);
985 ac =
child->invoke_show (drawing,
key, flags);
995 std::vector<SPItem*>
result;
998 if (
auto group = cast<SPGroup>(
item)) {
1011 g_message(
"sp_group_update_patheffect: %p\n", lpeitem);
1019 auto sub_shape = cast<SPShape>(sub_item);
1020 if (sub_shape && sub_shape->hasPathEffectRecursive()) {
1021 sub_shape->bbox_vis_cache_is_valid =
false;
1022 sub_shape->bbox_geom_cache_is_valid =
false;
1024 auto lpe_item = cast<SPLPEItem>(sub_item);
1026 lpe_item->update_patheffect(
write);
1056 std::vector<SPItem*>
const item_list = group->
item_list();
1057 for (
auto sub_item : item_list) {
1058 auto sub_group = cast<SPGroup>(sub_item);
1062 auto sub_shape = cast<SPShape>(sub_item);
1064 auto clipmaskto = sub_item;
1070 bool success =
false;
1072 if (sub_shape->curve()) {
1073 auto c = *sub_shape->curve();
1076 sub_shape->setCurveInsync(&
c);
1081 sub_shape->setCurveInsync(&
c);
1083 sub_shape->bbox_vis_cache_is_valid =
false;
1084 sub_shape->bbox_geom_cache_is_valid =
false;
1090 g_message(
"sp_group_perform_patheffect writes 'd' attribute");
1098 auto clipmaskto = group;
Lookup dictionary for attributes/properties.
3x3 matrix representing an affine transformation.
Coord descrim() const
Calculate the descriminant.
bool isIdentity(Coord eps=EPSILON) const
Check whether this matrix is an identity matrix.
Affine inverse() const
Compute the inverse matrix.
bool contains(CRect const &r) const
Check whether the rectangle includes all points in the given rectangle.
Axis-aligned rectangle that can be empty.
size_type size() const
Get the number of paths in the vector.
std::vector< Point > nodes() const
Two-dimensional point that doubles as a vector.
Translate inverse() const
Get the inverse translation.
void setPickChildren(bool)
Set whether the group returns children from pick calls.
SVG drawing item for display.
void appendChild(DrawingItem *item)
virtual void setStyle(SPStyle const *style, SPStyle const *context_style=nullptr)
Process information related to the new style.
void doBeforeEffect_impl(SPLPEItem const *lpeitem)
void doAfterEffect_impl(SPLPEItem const *lpeitem, SPCurve *curve)
Geom::PathVector pathvector_before_effect
Geom::PathVector pathvector_after_effect
Glib::ustring param_getSVGValue() const override
Inkscape::XML::Node * group(bool is_anchor=false)
bool remove(SPObject *object)
Removes an item from the set of selected objects.
void unsetMask(const bool apply_clip_path, const bool delete_helper_group, bool remove_original)
bool add(SPObject *object, bool nosignal=false)
Add an SPObject to the set of selected objects.
int size()
Returns size of the selection.
SPItem * singleItem()
Returns a single selected item.
void setMask(bool apply_clip_path, bool apply_to_layer, bool remove_original)
Creates a mask or clipPath from selection.
static Preferences * get()
Access the singleton Preferences object.
Storing of snapping preferences.
Interface for refcounted XML nodes.
virtual void addChild(Node *child, Node *after)=0
Insert another node as a child of this node.
virtual char const * name() const =0
Get the name of the element node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
virtual Node * duplicate(Document *doc) const =0
Create a duplicate of this node.
virtual Document * document()=0
Get the node's associated document.
virtual Node * lastChild()=0
Get the last child of this node.
Inkscape::LivePathEffect::Effect * get_lpe()
Typed SVG document implementation.
bool removeResource(char const *key, SPObject *object)
SPRoot * getRoot()
Returns our SPRoot.
bool addResource(char const *key, SPObject *object)
SPObject * getObjectByRepr(Inkscape::XML::Node *repr) const
void setLayerMode(LayerMode mode)
void setInsertBottom(bool insertbottom)
void scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bool noRecurse)
void order_changed(Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref) override
void removeTransformsRecursively(SPObject const *root) override
Inkscape::DrawingItem * show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) override
void remove_child(Inkscape::XML::Node *child) override
void print(SPPrintContext *ctx) override
Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) const override
LayerMode layerDisplayMode(unsigned int display_key) const
char * description() const override
void setLayerDisplayMode(unsigned int display_key, LayerMode mode)
std::map< unsigned int, LayerMode > _display_modes
void translateChildItems(Geom::Translate const &tr)
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
const char * typeName() const override
The item's type name, not node tag name.
static std::vector< SPItem * > get_expanded(std::vector< SPItem * > const &items)
Return the result of recursively ungrouping all groups in items.
void build(SPDocument *document, Inkscape::XML::Node *repr) override
Inkscape::Colors::Color highlight_color() const override
Generate a highlight colour if one isn't set and return it.
void _updateLayerMode(unsigned int display_key=0)
std::vector< SPItem * > item_list()
void snappoints(std::vector< Inkscape::SnapCandidatePoint > &p, Inkscape::SnapPreferences const *snapprefs) const override
void child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) override
void update_patheffect(bool write) override
void modified(unsigned int flags) override
const char * displayName() const override
The item's type name as a translated human string.
LayerMode effectiveLayerMode(unsigned int display_key) const
void hide(unsigned int key) override
void update(SPCtx *ctx, unsigned int flags) override
virtual void _showChildren(Inkscape::Drawing &drawing, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags)
Base class for visual SVG elements.
void set_i2d_affine(Geom::Affine const &transform)
Geom::Affine i2dt_affine() const
Returns the transformation from item to desktop coords.
Geom::OptRect bounds(BBoxType type, Geom::Affine const &transform=Geom::identity()) const
virtual Inkscape::Colors::Color highlight_color() const
Inkscape::DrawingItem * invoke_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags)
SPMask * getMaskObject() const
void invoke_print(SPPrintContext *ctx)
void adjust_stroke_width_recursive(double ex)
Recursively scale stroke width in item and its children by expansion.
void adjust_paint_recursive(Geom::Affine advertized_transform, Geom::Affine t_ancestors, PaintServerType type=GRADIENT)
Recursively compensate pattern or gradient transform.
void invoke_hide(unsigned int key)
std::optional< Inkscape::Colors::Color > _highlightColor
void getSnappoints(std::vector< Inkscape::SnapCandidatePoint > &p, Inkscape::SnapPreferences const *snapprefs=nullptr) const
void move_rel(Geom::Translate const &tr)
void scaleCenter(Geom::Scale const &sc)
virtual void removeTransformsRecursively(SPObject const *root)
Geom::OptRect visualBounds(Geom::Affine const &transform=Geom::identity(), bool wfilter=true, bool wclip=true, bool wmask=true) const
Get item's visual bounding box in this item's coordinate system.
unsigned int pos_in_parent() const
void doWriteTransform(Geom::Affine const &transform, Geom::Affine const *adv=nullptr, bool compensate=true)
Set a new transform on an object.
std::vector< SPItemView > views
SPClipPath * getClipObject() const
void remove_child(Inkscape::XML::Node *child) override
void resetClipPathAndMaskLPE(bool fromrecurse=false)
void applyToMask(SPItem *to, Inkscape::LivePathEffect::Effect *lpe=nullptr)
bool performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape::LivePathEffect::Effect *lpe, bool is_clip_or_mask=false)
returns true when LPE was successful.
bool hasPathEffect() const
void applyToClipPath(SPItem *to, Inkscape::LivePathEffect::Effect *lpe=nullptr)
void child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) override
SPLPEItem * removeAllPathEffects(bool keep_paths, bool recursive=false)
If keep_path is true, the item should not be updated, effectively 'flattening' the LPE.
bool hasPathEffectRecursive() const
bool pathEffectsEnabled() const
PathEffectList * path_effect_list
void update(SPCtx *ctx, unsigned int flags) override
void build(SPDocument *doc, Inkscape::XML::Node *repr) override
void modified(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
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Inkscape::XML::Node * repr
void setAttribute(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
void requestModified(unsigned int flags)
Requests that a modification notification signal be emitted later (e.g.
void removeAttribute(char const *key)
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.
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
char const * defaultLabel() const
Returns a default label property for this object.
SPStyle * context_style
Represents the style that should be used to resolve 'context-fill' and 'context-stroke'.
Inkscape::XML::Node * updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT)
Updates the object's repr based on the object's state.
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.
char const * getAttribute(char const *name) const
std::list< SPObject * > hrefList
virtual void order_changed(Inkscape::XML::Node *child, Inkscape::XML::Node *old_repr, Inkscape::XML::Node *new_repr)
struct SPRoot::@40 inkscape
SPItem * get_first_shape_dependency()
Get the first shape reference which affects the position and layout of this text item.
static void _adjustFontsizeRecursive(SPItem *item, double ex, bool is_root=true)
SPItem * get_original() const
static char const *const parent
TODO: insert short description here.
Group belonging to an SVG drawing element.
@ PREFS_MASKOBJECT_GROUPING_NONE
Affine identity()
Create an identity matrix.
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
static R & release(R &r)
Decrements the reference count of a anchored object.
static T clip(T const &v, T const &a, T const &b)
static cairo_user_data_key_t key
Singleton class to access the preferences file in a convenient way.
bool sp_repr_is_meta_element(const Inkscape::XML::Node *node)
Determine if the node is a 'title', 'desc' or 'metadata' element.
C facade to Inkscape::XML::Node.
TODO: insert short description here.
static void _ungroup_compensate_source_transform(SPItem *item, SPItem const *const expected_source, Geom::Affine const &source_transform)
Helper function for ungrouping.
static void sp_group_perform_patheffect(SPGroup *group, SPGroup *top_group, Inkscape::LivePathEffect::Effect *lpe, bool write)
SPObject * sp_item_group_get_child_by_name(SPGroup *group, SPObject *ref, const gchar *name)
Geom::OptRect bbox_on_rect_clip(SPObject *object)
void set_default_highlight_colors(std::vector< guint32 > colors)
void sp_item_group_ungroup_handle_clones(SPItem *parent, Geom::Affine const g)
finds clones of a child of the group going out of the group; and inverse the group transform on its c...
void sp_item_group_ungroup(SPGroup *group, std::vector< SPItem * > &children)
std::vector< guint32 > default_highlights
bool equal_clip(SPItem *item, SPObject *clip)
static void unlink_clones_of(SPGroup *group)
Unlink all clones of the group.
bool SP_IS_LAYER(SPObject const *obj)
Geom::Affine i2anc_affine(SPObject const *object, SPObject const *ancestor)
void sp_lpe_item_update_patheffect(SPLPEItem *lpeitem, bool wholetree, bool write, bool with_satellites)
Calls any registered handlers for the update_patheffect action.
void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable)
std::list< PathEffectSharedPtr > PathEffectList
SPObject * sp_object_unref(SPObject *object, SPObject *owner)
Decrease reference count of object, with possible debugging and finalization.
SPItem * sp_offset_get_source(SPOffset *offset)
SPRoot: SVG <svg> implementation.
TODO: insert short description here.
SPItem * sp_textpath_get_path_item(SPTextPath const *tp)
Interface for XML documents.
virtual Node * createElement(char const *name)=0
Contains transformations to document/viewport and the viewport size.
Geom::Affine i2doc
Item to document transformation.
Geom::Affine i2vp
Item to viewport transformation.
SPStyle - a style object for SPItem objects.
static void sp_svg_write_path(Inkscape::SVG::PathString &str, Geom::Path const &p, bool normalize=false)