summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Engel <markus.engel@tum.de>2013-09-24 21:32:23 +0000
committerMarkus Engel <markus.engel@tum.de>2013-09-24 21:32:23 +0000
commit2f017d2ef4974eba04515b9a155656ce9f2f7822 (patch)
tree33aac031c85048c2129e191e45c7667773f34c68
parentRefactored SPGenericEllipse::set_shape (diff)
downloadinkscape-2f017d2ef4974eba04515b9a155656ce9f2f7822.tar.gz
inkscape-2f017d2ef4974eba04515b9a155656ce9f2f7822.zip
Refactored SPUse.
(bzr r11608.1.128)
Diffstat (limited to '')
-rw-r--r--src/object-snapper.cpp12
-rw-r--r--src/selection-chemistry.cpp46
-rw-r--r--src/sp-flowtext.cpp58
-rw-r--r--src/sp-item-group.cpp90
-rw-r--r--src/sp-use.cpp256
-rw-r--r--src/sp-use.h32
-rw-r--r--src/ui/dialog/livepatheffect-editor.cpp4
7 files changed, 304 insertions, 194 deletions
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index 77ba3040f..3f3f0c1bf 100644
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
@@ -194,7 +194,7 @@ void Inkscape::ObjectSnapper::_collectNodes(SnapSourceType const &t,
//Geom::Affine i2doc(Geom::identity());
SPItem *root_item = (*i).item;
if (SP_IS_USE((*i).item)) {
- root_item = sp_use_root(SP_USE((*i).item));
+ root_item = SP_USE((*i).item)->root();
}
g_return_if_fail(root_item);
@@ -382,8 +382,8 @@ void Inkscape::ObjectSnapper::_collectPaths(Geom::Point /*p*/,
SPItem *root_item = NULL;
/* We might have a clone at hand, so make sure we get the root item */
if (SP_IS_USE((*i).item)) {
- i2doc = sp_use_get_root_transform(SP_USE((*i).item));
- root_item = sp_use_root(SP_USE((*i).item));
+ i2doc = SP_USE((*i).item)->get_root_transform();
+ root_item = SP_USE((*i).item)->root();
g_return_if_fail(root_item);
} else {
i2doc = (*i).item->i2doc_affine();
@@ -770,7 +770,7 @@ void Inkscape::ObjectSnapper::_clear_paths() const
Geom::PathVector* Inkscape::ObjectSnapper::_getBorderPathv() const
{
- Geom::Rect const border_rect = Geom::Rect(Geom::Point(0,0), Geom::Point((_snapmanager->getDocument())->getWidth(),(_snapmanager->getDocument())->getHeight()));
+ Geom::Rect const border_rect = Geom::Rect(Geom::Point(0,0), Geom::Point((_snapmanager->getDocument())->getWidth().value("px"),(_snapmanager->getDocument())->getHeight().value("px")));
return _getPathvFromRect(border_rect);
}
@@ -787,8 +787,8 @@ Geom::PathVector* Inkscape::ObjectSnapper::_getPathvFromRect(Geom::Rect const re
void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<SnapCandidatePoint> *points) const
{
- Geom::Coord w = (_snapmanager->getDocument())->getWidth();
- Geom::Coord h = (_snapmanager->getDocument())->getHeight();
+ Geom::Coord w = (_snapmanager->getDocument())->getWidth().value("px");
+ Geom::Coord h = (_snapmanager->getDocument())->getHeight().value("px");
points->push_back(SnapCandidatePoint(Geom::Point(0,0), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER));
points->push_back(SnapCandidatePoint(Geom::Point(0,h), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER));
points->push_back(SnapCandidatePoint(Geom::Point(w,h), SNAPSOURCE_UNDEFINED, SNAPTARGET_PAGE_CORNER));
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 91b99e3f4..8a7832d2a 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -499,7 +499,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone)
const gchar *id = old_ids[i];
SPObject *old_clone = doc->getObjectById(id);
if (SP_IS_USE(old_clone)) {
- SPItem *orig = sp_use_get_original(SP_USE(old_clone));
+ SPItem *orig = SP_USE(old_clone)->get_original();
if (!orig) // orphaned
continue;
for (unsigned int j = 0; j < old_ids.size(); j++) {
@@ -1104,18 +1104,21 @@ void sp_selection_cut(SPDesktop *desktop)
* \pre item != NULL
*/
SPCSSAttr *
-take_style_from_item(SPItem *item)
+take_style_from_item(SPObject *object)
{
+ // CPPIFY:
+ // This function should only take SPItems, but currently SPString is not an Item.
+
// write the complete cascaded style, context-free
- SPCSSAttr *css = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS);
+ SPCSSAttr *css = sp_css_attr_from_object(object, SP_STYLE_FLAG_ALWAYS);
if (css == NULL)
return NULL;
- if ((SP_IS_GROUP(item) && item->children) ||
- (SP_IS_TEXT(item) && item->children && item->children->next == NULL)) {
+ if ((SP_IS_GROUP(object) && object->children) ||
+ (SP_IS_TEXT(object) && object->children && object->children->next == NULL)) {
// if this is a text with exactly one tspan child, merge the style of that tspan as well
// If this is a group, merge the style of its topmost (last) child with style
- for (SPObject *last_element = item->lastChild(); last_element != NULL; last_element = last_element->getPrev()) {
+ for (SPObject *last_element = object->lastChild(); last_element != NULL; last_element = last_element->getPrev()) {
if ( last_element->style ) {
SPCSSAttr *temp = sp_css_attr_from_object(last_element, SP_STYLE_FLAG_IFSET);
if (temp) {
@@ -1126,15 +1129,18 @@ take_style_from_item(SPItem *item)
}
}
}
- if (!(SP_IS_TEXT(item) || SP_IS_TSPAN(item) || SP_IS_TREF(item) || SP_IS_STRING(item))) {
+
+ if (!(SP_IS_TEXT(object) || SP_IS_TSPAN(object) || SP_IS_TREF(object) || SP_IS_STRING(object))) {
// do not copy text properties from non-text objects, it's confusing
css = sp_css_attr_unset_text(css);
}
- // FIXME: also transform gradient/pattern fills, by forking? NO, this must be nondestructive
- double ex = item->i2doc_affine().descrim();
- if (ex != 1.0) {
- css = sp_css_attr_scale(css, ex);
+ if (SP_IS_ITEM(object)) {
+ // FIXME: also transform gradient/pattern fills, by forking? NO, this must be nondestructive
+ double ex = SP_ITEM(object)->i2doc_affine().descrim();
+ if (ex != 1.0) {
+ css = sp_css_attr_scale(css, ex);
+ }
}
return css;
@@ -1375,7 +1381,7 @@ selection_contains_original(SPItem *item, Inkscape::Selection *selection)
SPItem *item_use_first = item;
while (is_use && item_use && !contains_original)
{
- item_use = sp_use_get_original(SP_USE(item_use));
+ item_use = SP_USE(item_use)->get_original();
contains_original |= selection->includes(item_use);
if (item_use == item_use_first)
break;
@@ -1520,7 +1526,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons
// we need to cancel out the move compensation, too
// find out the clone move, same as in sp_use_move_compensate
- Geom::Affine parent = sp_use_get_parent_transform(SP_USE(item));
+ Geom::Affine parent = SP_USE(item)->get_parent_transform();
Geom::Affine clone_move = parent.inverse() * t * parent;
if (prefs_parallel) {
@@ -2616,7 +2622,7 @@ sp_selection_unlink(SPDesktop *desktop)
SPItem *unlink;
if (SP_IS_USE(item)) {
- unlink = sp_use_unlink(SP_USE(item));
+ unlink = SP_USE(item)->unlink();
// Unable to unlink use (external or invalid href?)
if (!unlink) {
new_select = g_slist_prepend(new_select, item);
@@ -2664,7 +2670,7 @@ sp_select_clone_original(SPDesktop *desktop)
SPItem *original = NULL;
if (SP_IS_USE(item)) {
- original = sp_use_get_original(SP_USE(item));
+ original = SP_USE(item)->get_original();
} else if (SP_IS_OFFSET(item) && SP_OFFSET(item)->sourceHref) {
original = sp_offset_get_source(SP_OFFSET(item));
} else if (SP_IS_TEXT_TEXTPATH(item)) {
@@ -2809,7 +2815,7 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply)
}
// calculate the transform to be applied to objects to move them to 0,0
- Geom::Point move_p = Geom::Point(0, doc->getHeight()) - *c;
+ Geom::Point move_p = Geom::Point(0, doc->getHeight().value("px")) - *c;
move_p[Geom::Y] = -move_p[Geom::Y];
Geom::Affine move = Geom::Affine(Geom::Translate(move_p));
@@ -3093,7 +3099,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply)
}
// calculate the transform to be applied to objects to move them to 0,0
- Geom::Point move_p = Geom::Point(0, doc->getHeight()) - (r->min() + Geom::Point(0, r->dimensions()[Geom::Y]));
+ Geom::Point move_p = Geom::Point(0, doc->getHeight().value("px")) - (r->min() + Geom::Point(0, r->dimensions()[Geom::Y]));
move_p[Geom::Y] = -move_p[Geom::Y];
Geom::Affine move = Geom::Affine(Geom::Translate(move_p));
@@ -3398,7 +3404,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop)
res = prefs_res;
} else if (0 < prefs_min) {
// If minsize is given, look up minimum bitmap size (default 250 pixels) and calculate resolution from it
- res = Inkscape::Util::Quantity::convert(1, "in", "px") * prefs_min / MIN(bbox->width(), bbox->height());
+ res = Inkscape::Util::Quantity::convert(prefs_min, "in", "px") / MIN(bbox->width(), bbox->height());
} else {
float hint_xdpi = 0, hint_ydpi = 0;
Glib::ustring hint_filename;
@@ -3419,8 +3425,8 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop)
}
// The width and height of the bitmap in pixels
- unsigned width = (unsigned) floor(bbox->width() * res / Inkscape::Util::Quantity::convert(1, "in", "px"));
- unsigned height =(unsigned) floor(bbox->height() * res / Inkscape::Util::Quantity::convert(1, "in", "px"));
+ unsigned width = (unsigned) floor(bbox->width() * Inkscape::Util::Quantity::convert(res, "px", "in"));
+ unsigned height =(unsigned) floor(bbox->height() * Inkscape::Util::Quantity::convert(res, "px", "in"));
// Find out if we have to run an external filter
gchar const *run = NULL;
diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp
index c7ef579ac..88564c0ac 100644
--- a/src/sp-flowtext.cpp
+++ b/src/sp-flowtext.cpp
@@ -28,6 +28,7 @@
#include "text-tag-attributes.h"
#include "text-chemistry.h"
#include "text-editing.h"
+#include "sp-text.h"
#include "livarot/Shape.h"
@@ -203,7 +204,7 @@ void SPFlowtext::set(unsigned int key, const gchar* value) {
if ( val == NULL ) {
this->par_indent = 0.0;
} else {
- sp_repr_get_double((Inkscape::XML::Node*)opts, "par-indent", &this->par_indent);
+ this->par_indent = g_ascii_strtod(val, NULL);
}
}
@@ -280,17 +281,20 @@ void SPFlowtext::print(SPPrintContext *ctx) {
this->layout.print(ctx, pbox, dbox, bbox, ctm);
}
+const char* SPFlowtext::displayName() {
+ if (SP_FLOWTEXT(this)->has_internal_frame()) {
+ return _("Flowed Text");
+ } else {
+ return _("Linked Flowed Text");
+ }
+}
+
gchar* SPFlowtext::description() {
Inkscape::Text::Layout const &layout = SP_FLOWTEXT(this)->layout;
int const nChars = layout.iteratorToCharIndex(layout.end());
-
char const *trunc = (layout.inputTruncated()) ? _(" [truncated]") : "";
- if (SP_FLOWTEXT(this)->has_internal_frame()) {
- return g_strdup_printf(ngettext("<b>Flowed text</b> (%d character%s)", "<b>Flowed text</b> (%d characters%s)", nChars), nChars, trunc);
- } else {
- return g_strdup_printf(ngettext("<b>Linked flowed text</b> (%d character%s)", "<b>Linked flowed text</b> (%d characters%s)", nChars), nChars, trunc);
- }
+ return g_strdup_printf(ngettext(_("(%d character%s)"), _("(%d characters%s)"), nChars), nChars, trunc);
}
void SPFlowtext::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) {
@@ -578,7 +582,7 @@ SPItem *SPFlowtext::get_frame(SPItem *after)
}
if ( frame && SP_IS_USE(frame) ) {
- frame = sp_use_get_original(SP_USE(frame));
+ frame = SP_USE(frame)->get_original();
}
}
return frame;
@@ -645,6 +649,44 @@ SPItem *create_flowtext_with_internal_frame (SPDesktop *desktop, Geom::Point p0,
return ft_item;
}
+Geom::Affine SPFlowtext::set_transform (Geom::Affine const &xform)
+{
+ if ((this->_optimizeScaledText && !xform.withoutTranslation().isNonzeroUniformScale())
+ || (!this->_optimizeScaledText && !xform.isNonzeroUniformScale())) {
+ this->_optimizeScaledText = false;
+ return xform;
+ }
+ this->_optimizeScaledText = false;
+
+ SPText *text = reinterpret_cast<SPText *>(this);
+
+ double const ex = xform.descrim();
+ if (ex == 0) {
+ return xform;
+ }
+
+ Geom::Affine ret(xform);
+ ret[0] /= ex;
+ ret[1] /= ex;
+ ret[2] /= ex;
+ ret[3] /= ex;
+
+ // Adjust font size
+ text->_adjustFontsizeRecursive (this, ex);
+
+ // Adjust stroke width
+ this->adjust_stroke_width_recursive (ex);
+
+ // Adjust pattern fill
+ this->adjust_pattern(xform * ret.inverse());
+
+ // Adjust gradient fill
+ this->adjust_gradient(xform * ret.inverse());
+
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG);
+
+ return ret;
+}
/*
Local Variables:
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 010cc5449..2becf7139 100644
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
@@ -50,6 +50,9 @@
#include "sp-switch.h"
#include "sp-defs.h"
#include "verbs.h"
+#include "layer-model.h"
+#include "sp-textpath.h"
+#include "sp-flowtext.h"
using Inkscape::DocumentUndo;
@@ -325,12 +328,14 @@ void SPGroup::print(SPPrintContext *ctx) {
}
}
+const char *SPGroup::displayName() {
+ return _("Group");
+}
+
gchar *SPGroup::description() {
gint len = this->getItemCount();
return g_strdup_printf(
- ngettext("<b>Group</b> of <b>%d</b> object",
- "<b>Group</b> of <b>%d</b> objects",
- len), len);
+ ngettext(_("of <b>%d</b> object"), _("of <b>%d</b> objects"), len), len);
}
void SPGroup::set(unsigned int key, gchar const* value) {
@@ -467,8 +472,8 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done)
// Merging transform
Geom::Affine ctrans;
Geom::Affine const g(gitem->transform);
- if (SP_IS_USE(citem) && sp_use_get_original (SP_USE(citem)) &&
- sp_use_get_original( SP_USE(citem) )->parent == SP_OBJECT(group)) {
+ if (SP_IS_USE(citem) && SP_USE(citem)->get_original() &&
+ SP_USE(citem)->get_original()->parent == SP_OBJECT(group)) {
// make sure a clone's effective transform is the same as was under group
ctrans = g.inverse() * citem->transform * g;
} else {
@@ -642,6 +647,81 @@ void SPGroup::translateChildItems(Geom::Translate const &tr)
}
}
+// Recursively scale child items around a point
+void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p)
+{
+ if ( hasChildren() ) {
+ for (SPObject *o = firstChild() ; o ; o = o->getNext() ) {
+ if ( SP_IS_ITEM(o) ) {
+ if (SP_IS_GROUP(o) && !SP_IS_BOX3D(o)) {
+ SP_GROUP(o)->scaleChildItemsRec(sc, p);
+ } else {
+ SPItem *item = SP_ITEM(o);
+ Geom::OptRect bbox = item->desktopVisualBounds();
+ if (bbox) {
+ // Scale item
+ Geom::Translate const s(p);
+ Geom::Affine final = s.inverse() * sc * s;
+
+ Geom::Point old_center(0,0);
+ if (item->isCenterSet()) {
+ old_center = item->getCenter();
+ }
+
+ gchar const *conn_type = NULL;
+ if (SP_IS_TEXT_TEXTPATH(item)) {
+ SP_TEXT(item)->optimizeTextpathText();
+ } else if (SP_IS_FLOWTEXT(item)) {
+ SP_FLOWTEXT(item)->optimizeScaledText();
+ } else if (SP_IS_BOX3D(item)) {
+ // Force recalculation from perspective
+ box3d_position_set(SP_BOX3D(item));
+ } else if (item->getAttribute("inkscape:connector-type") != NULL
+ && (item->getAttribute("inkscape:connection-start") == NULL
+ || item->getAttribute("inkscape:connection-end") == NULL)) {
+ // Remove and store connector type for transform if disconnected
+ conn_type = item->getAttribute("inkscape:connector-type");
+ item->removeAttribute("inkscape:connector-type");
+ }
+
+ if (SP_IS_PERSP3D(item)) {
+ persp3d_apply_affine_transformation(SP_PERSP3D(item), final);
+ } else if ((SP_IS_TEXT_TEXTPATH(item) || SP_IS_FLOWTEXT(item)) && !item->transform.isIdentity()) {
+ // Save and reset current transform
+ Geom::Affine tmp(item->transform);
+ item->transform = Geom::Affine();
+ // Apply scale
+ item->set_i2d_affine(item->i2dt_affine() * sc);
+ item->doWriteTransform(item->getRepr(), item->transform, NULL, true);
+ // Scale translation and restore original transform
+ tmp[4] *= sc[0];
+ tmp[5] *= sc[1];
+ item->doWriteTransform(item->getRepr(), tmp, NULL, true);
+ } else if (SP_IS_USE(item)) {
+ // calculate the matrix we need to apply to the clone
+ // to cancel its induced transform from its original
+ Geom::Affine move = final.inverse() * item->transform * final;
+ item->doWriteTransform(item->getRepr(), move, &move, true);
+ } else {
+ item->set_i2d_affine(item->i2dt_affine() * final);
+ item->doWriteTransform(item->getRepr(), item->transform, NULL, true);
+ }
+
+ if (conn_type != NULL) {
+ item->setAttribute("inkscape:connector-type", conn_type);
+ }
+
+ if (item->isCenterSet() && !(final.isTranslation() || final.isIdentity())) {
+ item->setCenter(old_center * final);
+ item->updateRepr();
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
gint SPGroup::getItemCount() {
gint len = 0;
for (SPObject *o = this->firstChild() ; o ; o = o->getNext() ) {
diff --git a/src/sp-use.cpp b/src/sp-use.cpp
index 44935e61d..a558c6bf4 100644
--- a/src/sp-use.cpp
+++ b/src/sp-use.cpp
@@ -37,12 +37,6 @@
#include "sp-use.h"
#include "sp-use-reference.h"
-/* fixme: */
-static void sp_use_href_changed(SPObject *old_ref, SPObject *ref, SPUse *use);
-static void sp_use_delete_self(SPObject *deleted, SPUse *self);
-
-#include "sp-factory.h"
-
namespace {
SPObject* createUse() {
return new SPUse();
@@ -51,23 +45,20 @@ namespace {
bool useRegistered = SPFactory::instance().registerObject("svg:use", createUse);
}
-SPUse::SPUse() : SPItem() {
- this->child = NULL;
-
+SPUse::SPUse()
+ : SPItem()
+ , child(NULL)
+ , href(NULL)
+ , ref(new SPUseReference(this))
+{
this->x.unset();
this->y.unset();
this->width.unset(SVGLength::PERCENT, 1.0, 1.0);
this->height.unset(SVGLength::PERCENT, 1.0, 1.0);
- this->href = NULL;
-
- //new (&this->_delete_connection) sigc::connection();
- //new (&this->_changed_connection) sigc::connection();
-
- //new (&this->_transformed_connection) sigc::connection();
- this->ref = new SPUseReference(this);
-
- this->_changed_connection = this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_use_href_changed), this));
+ this->_changed_connection = this->ref->changedSignal().connect(
+ sigc::hide(sigc::hide(sigc::mem_fun(this, &SPUse::href_changed)))
+ );
}
SPUse::~SPUse() {
@@ -79,11 +70,6 @@ SPUse::~SPUse() {
this->ref->detach();
delete this->ref;
this->ref = 0;
-
- //this->_delete_connection.~connection();
- //this->_changed_connection.~connection();
-
- //this->_transformed_connection.~connection();
}
void SPUse::build(SPDocument *document, Inkscape::XML::Node *repr) {
@@ -195,12 +181,8 @@ Inkscape::XML::Node* SPUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XM
Geom::OptRect SPUse::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) {
Geom::OptRect bbox;
- if (this->child && SP_IS_ITEM(this->child)) {
- SPItem *child = SP_ITEM(this->child);
- Geom::Affine const ct( child->transform
- * Geom::Translate(this->x.computed,
- this->y.computed)
- * transform );
+ if (this->child) {
+ Geom::Affine const ct(child->transform * Geom::Translate(this->x.computed, this->y.computed) * transform );
bbox = child->bounds(bboxtype, ct);
}
@@ -217,8 +199,8 @@ void SPUse::print(SPPrintContext* ctx) {
translated = true;
}
- if (this->child && SP_IS_ITEM(this->child)) {
- SP_ITEM(this->child)->invoke_print(ctx);
+ if (this->child) {
+ this->child->invoke_print(ctx);
}
if (translated) {
@@ -226,12 +208,18 @@ void SPUse::print(SPPrintContext* ctx) {
}
}
+const char* SPUse::displayName() {
+ if (this->child && SP_IS_SYMBOL( this->child )) {
+ return _("Symbol");
+ }
+
+ return _("Clone");
+}
+
gchar* SPUse::description() {
if (this->child) {
if( SP_IS_SYMBOL( this->child ) ) {
- char *symbol_desc = SP_ITEM(this->child)->title();
- return g_strdup_printf(_("<b>'%s' Symbol</b>"), symbol_desc );
- g_free(symbol_desc);
+ return g_strdup_printf(_("called %s"), this->child->title());
}
static unsigned recursion_depth = 0;
@@ -245,15 +233,15 @@ gchar* SPUse::description() {
}
++recursion_depth;
- char *child_desc = SP_ITEM(this->child)->getDetailedDescription();
+ char *child_desc = this->child->detailedDescription();
--recursion_depth;
- char *ret = g_strdup_printf(_("<b>Clone</b> of: %s"), child_desc);
+ char *ret = g_strdup_printf(_("of: %s"), child_desc);
g_free(child_desc);
return ret;
} else {
- return g_strdup(_("<b>Orphaned clone</b>"));
+ return g_strdup(_("[orphaned]"));
}
}
@@ -263,7 +251,8 @@ Inkscape::DrawingItem* SPUse::show(Inkscape::Drawing &drawing, unsigned int key,
ai->setStyle(this->style);
if (this->child) {
- Inkscape::DrawingItem *ac = SP_ITEM(this->child)->invoke_show(drawing, key, flags);
+ Inkscape::DrawingItem *ac = this->child->invoke_show(drawing, key, flags);
+
if (ac) {
ai->prependChild(ac);
}
@@ -277,7 +266,7 @@ Inkscape::DrawingItem* SPUse::show(Inkscape::Drawing &drawing, unsigned int key,
void SPUse::hide(unsigned int key) {
if (this->child) {
- SP_ITEM(this->child)->invoke_hide(key);
+ this->child->invoke_hide(key);
}
// SPItem::onHide(key);
@@ -292,38 +281,42 @@ void SPUse::hide(unsigned int key) {
* Note that the returned is the clone object, i.e. the child of an SPUse (of the argument one for
* the trivial case) and not the "true original".
*/
-SPItem *
-sp_use_root(SPUse *use)
-{
- SPObject *orig = use->child;
+SPItem *SPUse::root() {
+ SPItem *orig = this->child;
+
while (orig && SP_IS_USE(orig)) {
orig = SP_USE(orig)->child;
}
- if (!orig || !SP_IS_ITEM(orig))
+
+ if (!orig) {
return NULL;
- return SP_ITEM(orig);
+ }
+
+ return orig;
}
/**
* Returns the effective transform that goes from the ultimate original to given SPUse, both ends
* included.
*/
-Geom::Affine
-sp_use_get_root_transform(SPUse *use)
-{
+Geom::Affine SPUse::get_root_transform() {
//track the ultimate source of a chain of uses
- SPObject *orig = use->child;
+ SPObject *orig = this->child;
+
GSList *chain = NULL;
- chain = g_slist_prepend(chain, use);
+ chain = g_slist_prepend(chain, this);
+
while (SP_IS_USE(orig)) {
chain = g_slist_prepend(chain, orig);
orig = SP_USE(orig)->child;
}
+
chain = g_slist_prepend(chain, orig);
- //calculate the accummulated transform, starting from the original
+ // calculate the accummulated transform, starting from the original
Geom::Affine t(Geom::identity());
+
for (GSList *i = chain; i != NULL; i = i->next) {
SPItem *i_tem = SP_ITEM(i->data);
@@ -332,6 +325,7 @@ sp_use_get_root_transform(SPUse *use)
// represent the values of the x and y attributes on the 'use' element." - http://www.w3.org/TR/SVG11/struct.html#UseElement
if (SP_IS_USE(i_tem)) {
SPUse *i_use = SP_USE(i_tem);
+
if ((i_use->x._set && i_use->x.computed != 0) || (i_use->y._set && i_use->y.computed != 0)) {
t = t * Geom::Translate(i_use->x._set ? i_use->x.computed : 0, i_use->y._set ? i_use->y.computed : 0);
}
@@ -348,16 +342,14 @@ sp_use_get_root_transform(SPUse *use)
* Returns the transform that leads to the use from its immediate original.
* Does not inlcude the original's transform if any.
*/
-Geom::Affine
-sp_use_get_parent_transform(SPUse *use)
-{
+Geom::Affine SPUse::get_parent_transform() {
Geom::Affine t(Geom::identity());
- if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) {
- t *= Geom::Translate(use->x._set ? use->x.computed : 0,
- use->y._set ? use->y.computed : 0);
+
+ if ((this->x._set && this->x.computed != 0) || (this->y._set && this->y.computed != 0)) {
+ t *= Geom::Translate(this->x._set ? this->x.computed : 0, this->y._set ? this->y.computed : 0);
}
- t *= SP_ITEM(use)->transform;
+ t *= this->transform;
return t;
}
@@ -366,17 +358,15 @@ sp_use_get_parent_transform(SPUse *use)
* that the clone stays unmoved or moves in parallel (depending on user setting) regardless of the
* clone's transform.
*/
-static void
-sp_use_move_compensate(Geom::Affine const *mp, SPItem */*original*/, SPUse *self)
-{
+void SPUse::move_compensate(Geom::Affine const *mp) {
// the clone is orphaned; or this is not a real use, but a clone of another use;
// we skip it, otherwise duplicate compensation will occur
- if (self->cloned) {
+ if (this->cloned) {
return;
}
// never compensate uses which are used in flowtext
- if (self->parent && SP_IS_FLOWREGION(self->parent)) {
+ if (this->parent && SP_IS_FLOWREGION(this->parent)) {
return;
}
@@ -393,9 +383,9 @@ sp_use_move_compensate(Geom::Affine const *mp, SPItem */*original*/, SPUse *self
return;
// restore item->transform field from the repr, in case it was changed by seltrans
- self->readAttr ("transform");
+ this->readAttr ("transform");
- Geom::Affine t = sp_use_get_parent_transform(self);
+ Geom::Affine t = this->get_parent_transform();
Geom::Affine clone_move = t.inverse() * m * t;
// calculate the compensation matrix and the advertized movement matrix
@@ -411,77 +401,63 @@ sp_use_move_compensate(Geom::Affine const *mp, SPItem */*original*/, SPUse *self
}
// commit the compensation
- self->transform *= clone_move;
- self->doWriteTransform(self->getRepr(), self->transform, &advertized_move);
- self->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ this->transform *= clone_move;
+ this->doWriteTransform(this->getRepr(), this->transform, &advertized_move);
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
-static void
-sp_use_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPUse *use)
-{
- SPItem *item = SP_ITEM(use);
-
- use->_delete_connection.disconnect();
- use->_transformed_connection.disconnect();
+void SPUse::href_changed() {
+ this->_delete_connection.disconnect();
+ this->_transformed_connection.disconnect();
- if (use->child) {
- use->detach(use->child);
- use->child = NULL;
+ if (this->child) {
+ this->detach(this->child);
+ this->child = NULL;
}
- if (use->href) {
- SPItem *refobj = use->ref->getObject();
+ if (this->href) {
+ SPItem *refobj = this->ref->getObject();
+
if (refobj) {
Inkscape::XML::Node *childrepr = refobj->getRepr();
-// GType type = sp_repr_type_lookup(childrepr);
-// g_return_if_fail(type > G_TYPE_NONE);
-// if (g_type_is_a(type, SP_TYPE_ITEM)) {
-// use->child = (SPObject*) g_object_new(type, 0);
-// use->attach(use->child, use->lastChild());
-// sp_object_unref(use->child, use);
-// (use->child)->invoke_build(use->document, childrepr, TRUE);
-//
-// for (SPItemView *v = item->display; v != NULL; v = v->next) {
-// Inkscape::DrawingItem *ai;
-// ai = SP_ITEM(use->child)->invoke_show(v->arenaitem->drawing(), v->key, v->flags);
-// if (ai) {
-// v->arenaitem->prependChild(ai);
-// }
-// }
-// }
-
SPObject* obj = SPFactory::instance().createObject(NodeTraits::get_type_string(*childrepr));
+
if (SP_IS_ITEM(obj)) {
- use->child = obj;
+ this->child = SP_ITEM(obj);
+
+ this->attach(this->child, this->lastChild());
+ sp_object_unref(this->child, this);
- use->attach(use->child, use->lastChild());
- sp_object_unref(use->child, use);
- (use->child)->invoke_build(use->document, childrepr, TRUE);
+ this->child->invoke_build(this->document, childrepr, TRUE);
+
+ for (SPItemView *v = this->display; v != NULL; v = v->next) {
+ Inkscape::DrawingItem *ai = this->child->invoke_show(v->arenaitem->drawing(), v->key, v->flags);
- for (SPItemView *v = item->display; v != NULL; v = v->next) {
- Inkscape::DrawingItem *ai;
- ai = SP_ITEM(use->child)->invoke_show(v->arenaitem->drawing(), v->key, v->flags);
if (ai) {
v->arenaitem->prependChild(ai);
}
}
} else {
delete obj;
+ g_warning("Tried to create svg:use from invalid object");
}
- use->_delete_connection = refobj->connectDelete(sigc::bind(sigc::ptr_fun(&sp_use_delete_self), use));
- use->_transformed_connection = SP_ITEM(refobj)->connectTransformed(sigc::bind(sigc::ptr_fun(&sp_use_move_compensate), use));
+ this->_delete_connection = refobj->connectDelete(
+ sigc::hide(sigc::mem_fun(this, &SPUse::delete_self))
+ );
+
+ this->_transformed_connection = refobj->connectTransformed(
+ sigc::hide(sigc::mem_fun(this, &SPUse::move_compensate))
+ );
}
}
}
-static void
-sp_use_delete_self(SPObject */*deleted*/, SPUse *self)
-{
+void SPUse::delete_self() {
// always delete uses which are used in flowtext
- if (self->parent && SP_IS_FLOWREGION(self->parent)) {
- self->deleteObject();
+ if (this->parent && SP_IS_FLOWREGION(this->parent)) {
+ this->deleteObject();
return;
}
@@ -490,9 +466,9 @@ sp_use_delete_self(SPObject */*deleted*/, SPUse *self)
SP_CLONE_ORPHANS_UNLINK);
if (mode == SP_CLONE_ORPHANS_UNLINK) {
- sp_use_unlink(self);
+ this->unlink();
} else if (mode == SP_CLONE_ORPHANS_DELETE) {
- self->deleteObject();
+ this->deleteObject();
}
}
@@ -509,7 +485,7 @@ void SPUse::update(SPCtx *ctx, unsigned flags) {
flags &= SP_OBJECT_MODIFIED_CASCADE;
if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
- for (SPItemView *v = SP_ITEM(this)->display; v != NULL; v = v->next) {
+ for (SPItemView *v = this->display; v != NULL; v = v->next) {
Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
g->setStyle(this->style);
}
@@ -540,14 +516,10 @@ void SPUse::update(SPCtx *ctx, unsigned flags) {
sp_object_ref(this->child);
if (flags || (this->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
- if (SP_IS_ITEM(this->child)) {
- SPItem const &chi = *SP_ITEM(this->child);
- cctx.i2doc = chi.transform * ictx->i2doc;
- cctx.i2vp = chi.transform * ictx->i2vp;
- this->child->updateDisplay((SPCtx *)&cctx, flags);
- } else {
- this->child->updateDisplay(ctx, flags);
- }
+ SPItem const &chi = *SP_ITEM(this->child);
+ cctx.i2doc = chi.transform * ictx->i2doc;
+ cctx.i2vp = chi.transform * ictx->i2vp;
+ this->child->updateDisplay((SPCtx *)&cctx, flags);
}
sp_object_unref(this->child);
@@ -569,14 +541,12 @@ void SPUse::modified(unsigned int flags) {
flags &= SP_OBJECT_MODIFIED_CASCADE;
if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
- for (SPItemView *v = SP_ITEM(this)->display; v != NULL; v = v->next) {
+ for (SPItemView *v = this->display; v != NULL; v = v->next) {
Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
g->setStyle(this->style);
}
}
- SPObject *child = this->child;
-
if (child) {
sp_object_ref(child);
@@ -588,30 +558,26 @@ void SPUse::modified(unsigned int flags) {
}
}
-SPItem *sp_use_unlink(SPUse *use)
-{
- if (!use) {
- return NULL;
- }
+SPItem *SPUse::unlink() {
+ Inkscape::XML::Node *repr = this->getRepr();
- Inkscape::XML::Node *repr = use->getRepr();
if (!repr) {
return NULL;
}
Inkscape::XML::Node *parent = repr->parent();
- SPDocument *document = use->document;
+ SPDocument *document = this->document;
Inkscape::XML::Document *xml_doc = document->getReprDoc();
// Track the ultimate source of a chain of uses.
- SPItem *orig = sp_use_root(use);
+ SPItem *orig = this->root();
if (!orig) {
return NULL;
}
// Calculate the accumulated transform, starting from the original.
- Geom::Affine t = sp_use_get_root_transform(use);
+ Geom::Affine t = this->get_root_transform();
Inkscape::XML::Node *copy = NULL;
@@ -634,19 +600,19 @@ SPItem *sp_use_unlink(SPUse *use)
// Merge style from the use.
SPStyle *unli_sty = unlinked->style;
- SPStyle const *use_sty = use->style;
+ SPStyle const *use_sty = this->style;
sp_style_merge_from_dying_parent(unli_sty, use_sty);
sp_style_merge_from_parent(unli_sty, unlinked->parent->style);
unlinked->updateRepr();
// Hold onto our SPObject and repr for now.
- sp_object_ref(use, NULL);
+ sp_object_ref(this, NULL);
Inkscape::GC::anchor(repr);
// Remove ourselves, not propagating delete events to avoid a
// chain-reaction with other elements that might reference us.
- use->deleteObject(false);
+ this->deleteObject(false);
// Give the copy our old id and let go of our old repr.
copy->setAttribute("id", repr->attribute("id"));
@@ -660,10 +626,11 @@ SPItem *sp_use_unlink(SPUse *use)
copy->setAttribute("inkscape:tile-cy", NULL);
// Establish the succession and let go of our object.
- use->setSuccessor(unlinked);
- sp_object_unref(use, NULL);
+ this->setSuccessor(unlinked);
+ sp_object_unref(this, NULL);
SPItem *item = SP_ITEM(unlinked);
+
// Set the accummulated transform.
{
Geom::Affine nomove(Geom::identity());
@@ -674,21 +641,18 @@ SPItem *sp_use_unlink(SPUse *use)
return item;
}
-SPItem *sp_use_get_original(SPUse *use)
-{
+SPItem *SPUse::get_original() {
SPItem *ref = NULL;
- if (use) {
- if (use->ref){
- ref = use->ref->getObject();
+ if (this->ref){
+ ref = this->ref->getObject();
}
- }
return ref;
}
void SPUse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) {
- SPItem *root = sp_use_root(this);
+ SPItem *root = this->root();
if (!root) {
return;
diff --git a/src/sp-use.h b/src/sp-use.h
index 37ff2cf66..6a83c384f 100644
--- a/src/sp-use.h
+++ b/src/sp-use.h
@@ -30,7 +30,7 @@ public:
// item built from the original's repr (the visible clone)
// relative to the SPUse itself, it is treated as a child, similar to a grouped item relative to its group
- SPObject *child;
+ SPItem *child;
// SVG attrs
SVGLength x;
@@ -57,17 +57,35 @@ public:
virtual void modified(unsigned int flags);
virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype);
+ virtual const char* displayName();
virtual gchar* description();
virtual void print(SPPrintContext *ctx);
virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
virtual void hide(unsigned int key);
virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
-};
-SPItem *sp_use_unlink (SPUse *use);
-SPItem *sp_use_get_original (SPUse *use);
-Geom::Affine sp_use_get_parent_transform (SPUse *use);
-Geom::Affine sp_use_get_root_transform(SPUse *use);
+ SPItem *root();
+
+ SPItem *unlink();
+ SPItem *get_original();
+ Geom::Affine get_parent_transform();
+ Geom::Affine get_root_transform();
+
+private:
+ void href_changed();
+ void move_compensate(Geom::Affine const *mp);
+ void delete_self();
+};
-SPItem *sp_use_root(SPUse *use);
#endif
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp
index 6dc9c1ee3..0102977e4 100644
--- a/src/ui/dialog/livepatheffect-editor.cpp
+++ b/src/ui/dialog/livepatheffect-editor.cpp
@@ -296,7 +296,7 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
}
} else if ( SP_IS_USE(item) ) {
// test whether linked object is supported by the CLONE_ORIGINAL LPE
- SPItem *orig = sp_use_get_original( SP_USE(item) );
+ SPItem *orig = SP_USE(item)->get_original();
if ( SP_IS_SHAPE(orig) ||
SP_IS_TEXT(orig) )
{
@@ -433,7 +433,7 @@ LivePathEffectEditor::onAdd()
// convert to path, apply CLONE_ORIGINAL LPE, link it to the cloned path
// test whether linked object is supported by the CLONE_ORIGINAL LPE
- SPItem *orig = sp_use_get_original( SP_USE(item) );
+ SPItem *orig = SP_USE(item)->get_original();
if ( SP_IS_SHAPE(orig) ||
SP_IS_TEXT(orig) )
{