summaryrefslogtreecommitdiffstats
path: root/src/sp-item-group.cpp
diff options
context:
space:
mode:
authorJabiertxof <jtx@jtx>2017-01-21 23:33:24 +0000
committerJabiertxof <jtx@jtx>2017-01-21 23:33:24 +0000
commiteeb5405c1b2734322ca9ed506e8a8e16a87c2a4f (patch)
tree5f98cdb1ee5633b69ec1f5c21d0d5e69f8770ad2 /src/sp-item-group.cpp
parentOrganize doeffect function (diff)
parentFix "swap fill and stroke" for multiple objects in selection (diff)
downloadinkscape-eeb5405c1b2734322ca9ed506e8a8e16a87c2a4f.tar.gz
inkscape-eeb5405c1b2734322ca9ed506e8a8e16a87c2a4f.zip
Update to trunk
(bzr r13645.1.165)
Diffstat (limited to 'src/sp-item-group.cpp')
-rw-r--r--src/sp-item-group.cpp189
1 files changed, 147 insertions, 42 deletions
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 83d67cf5a..7b2507b5e 100644
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
@@ -15,7 +15,7 @@
*/
#ifdef HAVE_CONFIG_H
-# include "config.h"
+#include <config.h>
#endif
#include <glibmm/i18n.h>
@@ -32,16 +32,13 @@
#include "attributes.h"
#include "sp-item-transform.h"
#include "sp-root.h"
-#include "sp-use.h"
#include "sp-offset.h"
#include "sp-clippath.h"
#include "sp-mask.h"
#include "sp-path.h"
#include "box3d.h"
#include "persp3d.h"
-#include "inkscape.h"
-#include "selection.h"
#include "live_effects/effect.h"
#include "live_effects/lpeobject.h"
#include "live_effects/lpeobject-reference.h"
@@ -50,9 +47,11 @@
#include "sp-switch.h"
#include "sp-defs.h"
#include "verbs.h"
-#include "layer-model.h"
#include "sp-textpath.h"
#include "sp-flowtext.h"
+#include "selection-chemistry.h"
+#include "xml/sp-css-attr.h"
+#include "svg/css-ostringstream.h"
using Inkscape::DocumentUndo;
@@ -133,7 +132,7 @@ void SPGroup::remove_child(Inkscape::XML::Node *child) {
void SPGroup::order_changed (Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref)
{
- SPLPEItem::order_changed(child, old_ref, new_ref);
+ SPLPEItem::order_changed(child, old_ref, new_ref);
SPItem *item = dynamic_cast<SPItem *>(get_child_by_repr(child));
if ( item ) {
@@ -200,11 +199,18 @@ void SPGroup::modified(guint flags) {
// std::cout << "SPGroup::modified(): " << (getId()?getId():"null") << std::endl;
SPLPEItem::modified(flags);
if (flags & SP_OBJECT_MODIFIED_FLAG) {
- flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
+ flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
}
flags &= SP_OBJECT_MODIFIED_CASCADE;
+ if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
+ for (SPItemView *v = this->display; v != NULL; v = v->next) {
+ Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
+ group->setStyle(this->style);
+ }
+ }
+
std::vector<SPObject*> l=this->childList(true);
for(std::vector<SPObject*>::const_iterator i=l.begin();i!=l.end();++i){
SPObject *child = *i;
@@ -231,9 +237,9 @@ Inkscape::XML::Node* SPGroup::write(Inkscape::XML::Document *xml_doc, Inkscape::
l = NULL;
- for (SPObject *child = firstChild(); child; child = child->getNext() ) {
- if ( !dynamic_cast<SPTitle *>(child) && !dynamic_cast<SPDesc *>(child) ) {
- Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags);
+ for (auto& child: children) {
+ if ( !dynamic_cast<SPTitle *>(&child) && !dynamic_cast<SPDesc *>(&child) ) {
+ Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, NULL, flags);
if (crepr) {
l = g_slist_prepend (l, crepr);
@@ -247,9 +253,9 @@ Inkscape::XML::Node* SPGroup::write(Inkscape::XML::Document *xml_doc, Inkscape::
l = g_slist_remove (l, l->data);
}
} else {
- for (SPObject *child = firstChild() ; child ; child = child->getNext() ) {
- if ( !dynamic_cast<SPTitle *>(child) && !dynamic_cast<SPDesc *>(child) ) {
- child->updateRepr(flags);
+ for (auto& child: children) {
+ if ( !dynamic_cast<SPTitle *>(&child) && !dynamic_cast<SPDesc *>(&child) ) {
+ child.updateRepr(flags);
}
}
}
@@ -293,9 +299,8 @@ Geom::OptRect SPGroup::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox
}
void SPGroup::print(SPPrintContext *ctx) {
- std::vector<SPObject*> l=this->childList(false);
- for(std::vector<SPObject*>::const_iterator i=l.begin();i!=l.end();++i){
- SPObject *o = *i;
+ for(auto& child: children){
+ SPObject *o = &child;
SPItem *item = dynamic_cast<SPItem *>(o);
if (item) {
item->invoke_print(ctx);
@@ -347,7 +352,7 @@ Inkscape::DrawingItem *SPGroup::show (Inkscape::Drawing &drawing, unsigned int k
}
void SPGroup::hide (unsigned int key) {
- std::vector<SPObject*> l=this->childList(false, SPObject::ActionShow);
+ std::vector<SPObject*> l=this->childList(false, SPObject::ActionShow);
for(std::vector<SPObject*>::const_iterator i=l.begin();i!=l.end();++i){
SPObject *o = *i;
@@ -362,9 +367,9 @@ void SPGroup::hide (unsigned int key) {
void SPGroup::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) const {
- for ( SPObject const *o = this->firstChild(); o; o = o->getNext() )
+ for (auto& o: children)
{
- SPItem const *item = dynamic_cast<SPItem const *>(o);
+ SPItem const *item = dynamic_cast<SPItem const *>(&o);
if (item) {
item->getSnappoints(p, snapprefs);
}
@@ -389,6 +394,89 @@ void sp_item_group_ungroup_handle_clones(SPItem *parent, Geom::Affine const g)
}
void
+sp_recursive_scale_text_size(Inkscape::XML::Node *repr, double scale){
+ for (Inkscape::XML::Node *child = repr->firstChild() ; child; child = child->next() ){
+ if ( child) {
+ sp_recursive_scale_text_size(child, scale);
+ }
+ }
+ SPCSSAttr * css = sp_repr_css_attr(repr,"style");
+ Glib::ustring element = g_quark_to_string(repr->code());
+ if ((css && element == "svg:text") || element == "svg:tspan") {
+ gchar const *w = sp_repr_css_property(css, "font-size", NULL);
+ if (w) {
+ gchar *units = NULL;
+ double wd = g_ascii_strtod(w, &units);
+ wd *= scale;
+ if (w != units) {
+ Inkscape::CSSOStringStream os;
+ os << wd << units; // reattach units
+ sp_repr_css_set_property(css, "font-size", os.str().c_str());
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ repr->setAttribute("style", css_str.c_str());
+ }
+ }
+ w = NULL;
+ w = sp_repr_css_property(css, "letter-spacing", NULL);
+ if (w) {
+ gchar *units = NULL;
+ double wd = g_ascii_strtod(w, &units);
+ wd *= scale;
+ if (w != units) {
+ Inkscape::CSSOStringStream os;
+ os << wd << units; // reattach units
+ sp_repr_css_set_property(css, "letter-spacing", os.str().c_str());
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ repr->setAttribute("style", css_str.c_str());
+ }
+ }
+ w = NULL;
+ w = sp_repr_css_property(css, "word-spacing", NULL);
+ if (w) {
+ gchar *units = NULL;
+ double wd = g_ascii_strtod(w, &units);
+ wd *= scale;
+ if (w != units) {
+ Inkscape::CSSOStringStream os;
+ os << wd << units; // reattach units
+ sp_repr_css_set_property(css, "word-spacing", os.str().c_str());
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ repr->setAttribute("style", css_str.c_str());
+ }
+ }
+ gchar const *dx = repr->attribute("dx");
+ if (dx) {
+ gchar ** dxarray = g_strsplit(dx, " ", 0);
+ Inkscape::SVGOStringStream dx_data;
+ while (*dxarray != NULL) {
+ double pos;
+ sp_svg_number_read_d(*dxarray, &pos);
+ pos *= scale;
+ dx_data << pos << " ";
+ dxarray++;
+ }
+ repr->setAttribute("dx", dx_data.str().c_str());
+ }
+ gchar const *dy = repr->attribute("dy");
+ if (dy) {
+ gchar ** dyarray = g_strsplit(dy, " ", 0);
+ Inkscape::SVGOStringStream dy_data;
+ while (*dyarray != NULL) {
+ double pos;
+ sp_svg_number_read_d(*dyarray, &pos);
+ pos *= scale;
+ dy_data << pos << " ";
+ dyarray++;
+ }
+ repr->setAttribute("dy", dy_data.str().c_str());
+ }
+ }
+}
+
+void
sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_done)
{
g_return_if_fail (group != NULL);
@@ -425,20 +513,21 @@ sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_d
GSList *objects = NULL;
Geom::Affine const g(group->transform);
- for (SPObject *child = group->firstChild() ; child; child = child->getNext() )
- if (SPItem *citem = dynamic_cast<SPItem *>(child))
- sp_item_group_ungroup_handle_clones(citem,g);
-
+ for (auto& child: group->children) {
+ if (SPItem *citem = dynamic_cast<SPItem *>(&child)) {
+ sp_item_group_ungroup_handle_clones(citem, g);
+ }
+ }
- for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) {
- SPItem *citem = dynamic_cast<SPItem *>(child);
+ for (auto& child: group->children) {
+ SPItem *citem = dynamic_cast<SPItem *>(&child);
if (citem) {
/* Merging of style */
// this converts the gradient/pattern fill/stroke, if any, to userSpaceOnUse; we need to do
// it here _before_ the new transform is set, so as to use the pre-transform bbox
citem->adjust_paint_recursive (Geom::identity(), Geom::identity(), false);
- child->style->merge( group->style );
+ child.style->merge( group->style );
/*
* fixme: We currently make no allowance for the case where child is cloned
* and the group has any style settings.
@@ -460,9 +549,9 @@ sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_d
* extra complication & maintenance burden and this case is rare.
*/
- child->updateRepr();
+ child.updateRepr();
- Inkscape::XML::Node *nrepr = child->getRepr()->duplicate(prepr->document());
+ Inkscape::XML::Node *nrepr = child.getRepr()->duplicate(prepr->document());
// Merging transform
Geom::Affine ctrans = citem->transform * g;
@@ -492,13 +581,29 @@ sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_d
// reattached outside of the group, the transform will be written more properly
// (i.e. optimized into the object if the corresponding preference is set)
gchar *affinestr=sp_svg_transform_write(ctrans);
- nrepr->setAttribute("transform", affinestr);
+ SPText * text = dynamic_cast<SPText *>(citem);
+ if (text) {
+ //this causes a change in text-on-path appearance when there is a non-conformal transform, see bug #1594565
+ SPTextPath * text_path = dynamic_cast<SPTextPath *>(text->firstChild());
+ if (!text_path) {
+ nrepr->setAttribute("transform", affinestr);
+ } else {
+ // The following breaks roundtripping group -> ungroup
+ // double scale = (ctrans.expansionX() + ctrans.expansionY()) / 2.0;
+ // sp_recursive_scale_text_size(nrepr, scale);
+ Geom::Affine ttrans = ctrans.inverse() * SP_ITEM(text)->transform * ctrans;
+ gchar *affinestr = sp_svg_transform_write(ttrans);
+ nrepr->setAttribute("transform", affinestr);
+ }
+ } else {
+ nrepr->setAttribute("transform", affinestr);
+ }
g_free(affinestr);
items = g_slist_prepend (items, nrepr);
} else {
- Inkscape::XML::Node *nrepr = child->getRepr()->duplicate(prepr->document());
+ Inkscape::XML::Node *nrepr = child.getRepr()->duplicate(prepr->document());
objects = g_slist_prepend (objects, nrepr);
}
}
@@ -560,9 +665,9 @@ std::vector<SPItem*> sp_item_group_item_list(SPGroup * group)
std::vector<SPItem*> s;
g_return_val_if_fail(group != NULL, s);
- for (SPObject *o = group->firstChild() ; o ; o = o->getNext() ) {
- if ( dynamic_cast<SPItem *>(o) ) {
- s.push_back((SPItem*)o);
+ for (auto& o: group->children) {
+ if ( dynamic_cast<SPItem *>(&o) ) {
+ s.push_back((SPItem*)&o);
}
}
return s;
@@ -633,8 +738,8 @@ void SPGroup::_updateLayerMode(unsigned int display_key) {
void SPGroup::translateChildItems(Geom::Translate const &tr)
{
if ( hasChildren() ) {
- for (SPObject *o = firstChild() ; o ; o = o->getNext() ) {
- SPItem *item = dynamic_cast<SPItem *>(o);
+ for (auto& o: children) {
+ SPItem *item = dynamic_cast<SPItem *>(&o);
if ( item ) {
sp_item_move_rel(item, tr);
}
@@ -646,14 +751,14 @@ void SPGroup::translateChildItems(Geom::Translate const &tr)
void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bool noRecurse)
{
if ( hasChildren() ) {
- for (SPObject *o = firstChild() ; o ; o = o->getNext() ) {
- if ( SPDefs *defs = dynamic_cast<SPDefs *>(o) ) { // select symbols from defs, ignore clips, masks, patterns
- for (SPObject *defschild = defs->firstChild() ; defschild ; defschild = defschild->getNext() ) {
- SPGroup *defsgroup = dynamic_cast<SPGroup *>(defschild);
+ for (auto& o: children) {
+ if ( SPDefs *defs = dynamic_cast<SPDefs *>(&o) ) { // select symbols from defs, ignore clips, masks, patterns
+ for (auto& defschild: defs->children) {
+ SPGroup *defsgroup = dynamic_cast<SPGroup *>(&defschild);
if (defsgroup)
defsgroup->scaleChildItemsRec(sc, p, false);
}
- } else if ( SPItem *item = dynamic_cast<SPItem *>(o) ) {
+ } else if ( SPItem *item = dynamic_cast<SPItem *>(&o) ) {
SPGroup *group = dynamic_cast<SPGroup *>(item);
if (group && !dynamic_cast<SPBox3D *>(item)) {
/* Using recursion breaks clipping because transforms are applied
@@ -769,8 +874,8 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo
gint SPGroup::getItemCount() const {
gint len = 0;
- for (SPObject const *o = this->firstChild() ; o ; o = o->getNext() ) {
- if (dynamic_cast<SPItem const *>(o)) {
+ for (auto& child: children) {
+ if (dynamic_cast<SPItem const *>(&child)) {
len++;
}
}