diff options
| author | Markus Engel <markus.engel@tum.de> | 2013-04-05 17:42:32 +0000 |
|---|---|---|
| committer | Markus Engel <markus.engel@tum.de> | 2013-04-05 17:42:32 +0000 |
| commit | 19d00efa85cfc42ccae9bd17ef575602f0d22c50 (patch) | |
| tree | cab58b197a09a98c23b0a22ba9492207e7c14071 /src | |
| parent | Merged Group and subclasses. (diff) | |
| download | inkscape-19d00efa85cfc42ccae9bd17ef575602f0d22c50.tar.gz inkscape-19d00efa85cfc42ccae9bd17ef575602f0d22c50.zip | |
Merged more classes.
(bzr r11608.1.78)
Diffstat (limited to 'src')
| -rw-r--r-- | src/box3d-side.cpp | 1 | ||||
| -rw-r--r-- | src/box3d.cpp | 1 | ||||
| -rw-r--r-- | src/marker.cpp | 1 | ||||
| -rw-r--r-- | src/sp-anchor.cpp | 1 | ||||
| -rw-r--r-- | src/sp-ellipse.cpp | 4 | ||||
| -rw-r--r-- | src/sp-item-group.cpp | 28 | ||||
| -rw-r--r-- | src/sp-item-group.h | 2 | ||||
| -rw-r--r-- | src/sp-line.cpp | 1 | ||||
| -rw-r--r-- | src/sp-lpe-item.cpp | 177 | ||||
| -rw-r--r-- | src/sp-lpe-item.h | 23 | ||||
| -rw-r--r-- | src/sp-offset.cpp | 1 | ||||
| -rw-r--r-- | src/sp-path.cpp | 1 | ||||
| -rw-r--r-- | src/sp-polygon.cpp | 1 | ||||
| -rw-r--r-- | src/sp-polyline.cpp | 1 | ||||
| -rw-r--r-- | src/sp-rect.cpp | 1 | ||||
| -rw-r--r-- | src/sp-root.cpp | 1 | ||||
| -rw-r--r-- | src/sp-shape.cpp | 18 | ||||
| -rw-r--r-- | src/sp-shape.h | 2 | ||||
| -rw-r--r-- | src/sp-spiral.cpp | 1 | ||||
| -rw-r--r-- | src/sp-star.cpp | 1 | ||||
| -rw-r--r-- | src/sp-switch.cpp | 1 | ||||
| -rw-r--r-- | src/sp-symbol.cpp | 1 | ||||
| -rw-r--r-- | src/sp-text.cpp | 280 | ||||
| -rw-r--r-- | src/sp-text.h | 26 | ||||
| -rw-r--r-- | src/sp-textpath.h | 26 | ||||
| -rw-r--r-- | src/sp-tref.cpp | 234 | ||||
| -rw-r--r-- | src/sp-tref.h | 26 | ||||
| -rw-r--r-- | src/sp-tspan.cpp | 324 | ||||
| -rw-r--r-- | src/sp-tspan.h | 28 | ||||
| -rw-r--r-- | src/sp-use.cpp | 336 | ||||
| -rw-r--r-- | src/sp-use.h | 26 |
31 files changed, 599 insertions, 976 deletions
diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index 240a2ee98..2761bde61 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -37,7 +37,6 @@ namespace { } Box3DSide::Box3DSide() : SPPolygon() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/box3d.cpp b/src/box3d.cpp index 3c11d24d7..a2c92d880 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -54,7 +54,6 @@ namespace { } SPBox3D::SPBox3D() : SPGroup() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/marker.cpp b/src/marker.cpp index 1717c388e..ba7366ec3 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -53,7 +53,6 @@ namespace { } SPMarker::SPMarker() : SPGroup() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/sp-anchor.cpp b/src/sp-anchor.cpp index babec4537..5679aa13b 100644 --- a/src/sp-anchor.cpp +++ b/src/sp-anchor.cpp @@ -36,7 +36,6 @@ namespace { } SPAnchor::SPAnchor() : SPGroup() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 303a0cde6..d71ae04a9 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -89,7 +89,6 @@ static double sp_round(double x, double y) static gboolean sp_arc_set_elliptical_path_attribute(SPArc *arc, Inkscape::XML::Node *repr); SPGenericEllipse::SPGenericEllipse() : SPShape() { - this->clpeitem = this; this->citem = this; this->cobject = this; @@ -366,7 +365,6 @@ Inkscape::XML::Node* SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, I /* SVG <ellipse> element */ SPEllipse::SPEllipse() : SPGenericEllipse() { - this->clpeitem = this; this->citem = this; this->cobject = this; } @@ -459,7 +457,6 @@ sp_ellipse_position_set(SPEllipse *ellipse, gdouble x, gdouble y, gdouble rx, gd /* SVG <circle> element */ SPCircle::SPCircle() : SPGenericEllipse() { - this->clpeitem = this; this->citem = this; this->cobject = this; } @@ -523,7 +520,6 @@ gchar* SPCircle::description() { /* <path sodipodi:type="arc"> element */ SPArc::SPArc() : SPGenericEllipse() { - this->clpeitem = this; this->citem = this; this->cobject = this; } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 5956b16a9..77bf647dc 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -53,8 +53,6 @@ using Inkscape::DocumentUndo; -static void sp_group_dispose(GObject *object); - static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write); #include "sp-factory.h" @@ -67,9 +65,7 @@ namespace { bool groupRegistered = SPFactory::instance().registerObject("svg:g", createGroup); } -SPGroup::SPGroup() : SPLPEItem(), CLPEItem(this) { - delete this->clpeitem; - this->clpeitem = this; +SPGroup::SPGroup() : SPLPEItem() { this->citem = this; this->cobject = this; @@ -84,7 +80,7 @@ SPGroup::~SPGroup() { void SPGroup::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "inkscape:groupmode" ); - CLPEItem::build(document, repr); + SPLPEItem::build(document, repr); } void SPGroup::release() { @@ -92,11 +88,11 @@ void SPGroup::release() { this->document->removeResource("layer", this); } - CLPEItem::release(); + SPLPEItem::release(); } void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) { - CLPEItem::child_added(child, ref); + SPLPEItem::child_added(child, ref); SPObject *last_child = this->lastChild(); @@ -142,14 +138,14 @@ void SPGroup::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) /* fixme: hide (Lauris) */ void SPGroup::remove_child(Inkscape::XML::Node *child) { - CLPEItem::remove_child(child); + SPLPEItem::remove_child(child); this->requestModified(SP_OBJECT_MODIFIED_FLAG); } void SPGroup::order_changed (Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref) { - CLPEItem::order_changed(child, old_ref, new_ref); + SPLPEItem::order_changed(child, old_ref, new_ref); SPObject *ochild = this->get_child_by_repr(child); if ( ochild && SP_IS_ITEM(ochild) ) { @@ -165,7 +161,7 @@ void SPGroup::order_changed (Inkscape::XML::Node *child, Inkscape::XML::Node *ol } void SPGroup::update(SPCtx *ctx, unsigned int flags) { - CLPEItem::update(ctx, flags); + SPLPEItem::update(ctx, flags); SPItemCtx *ictx, cctx; @@ -206,7 +202,7 @@ void SPGroup::update(SPCtx *ctx, unsigned int flags) { } void SPGroup::modified(guint flags) { - CLPEItem::modified(flags); + SPLPEItem::modified(flags); SPObject *child; @@ -292,7 +288,7 @@ Inkscape::XML::Node* SPGroup::write(Inkscape::XML::Document *xml_doc, Inkscape:: repr->setAttribute("inkscape:groupmode", value); } - CLPEItem::write(xml_doc, repr, flags); + SPLPEItem::write(xml_doc, repr, flags); return repr; } @@ -353,7 +349,7 @@ void SPGroup::set(unsigned int key, gchar const* value) { break; default: - CLPEItem::set(key, value); + SPLPEItem::set(key, value); break; } } @@ -385,7 +381,7 @@ void SPGroup::hide (unsigned int key) { l = g_slist_remove (l, o); } -// CLPEItem::onHide(key); +// SPLPEItem::onHide(key); } @@ -684,7 +680,7 @@ void SPGroup::update_patheffect(bool write) { SPObject *subitem = static_cast<SPObject *>(iter->data); if (SP_IS_LPE_ITEM(subitem)) { - ((SPLPEItem*)subitem)->clpeitem->update_patheffect(write); + ((SPLPEItem*)subitem)->update_patheffect(write); } } diff --git a/src/sp-item-group.h b/src/sp-item-group.h index 1408eefe7..f8d9014ab 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -28,7 +28,7 @@ class DrawingItem; } // namespace Inkscape -class SPGroup : public SPLPEItem, public CLPEItem { +class SPGroup : public SPLPEItem { public: SPGroup(); virtual ~SPGroup(); diff --git a/src/sp-line.cpp b/src/sp-line.cpp index bb7abda8e..4c1fef70a 100644 --- a/src/sp-line.cpp +++ b/src/sp-line.cpp @@ -35,7 +35,6 @@ namespace { } SPLine::SPLine() : SPShape() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index fc75b6a69..e3bc32f37 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -39,8 +39,6 @@ #include <algorithm> /* LPEItem base class */ -static void sp_lpe_item_finalize(GObject *object); - static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); @@ -51,137 +49,107 @@ typedef std::list<std::string> HRefList; static std::string patheffectlist_write_svg(PathEffectList const & list); static std::string hreflist_write_svg(HRefList const & list); -G_DEFINE_TYPE(SPLPEItem, sp_lpe_item, G_TYPE_OBJECT); - -static void sp_lpe_item_class_init(SPLPEItemClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - gobject_class->finalize = sp_lpe_item_finalize; -} - -// CPPIFY: remove -CLPEItem::CLPEItem(SPLPEItem* lpeitem) : CItem(lpeitem) { - this->splpeitem = lpeitem; -} - -CLPEItem::~CLPEItem() { -} - -SPLPEItem::SPLPEItem() : SPItem() { - SPLPEItem* lpeitem = this; - - lpeitem->clpeitem = new CLPEItem(lpeitem); - lpeitem->typeHierarchy.insert(typeid(SPLPEItem)); - - delete lpeitem->citem; - lpeitem->citem = lpeitem->clpeitem; - lpeitem->cobject = lpeitem->clpeitem; +SPLPEItem::SPLPEItem() : SPItem(), CItem(this) { + delete this->citem; + this->citem = this; + this->cobject = this; - lpeitem->path_effects_enabled = 1; + this->path_effects_enabled = 1; - lpeitem->path_effect_list = new PathEffectList(); - lpeitem->current_path_effect = NULL; + this->path_effect_list = new PathEffectList(); + this->current_path_effect = NULL; - lpeitem->lpe_modified_connection_list = new std::list<sigc::connection>(); + this->lpe_modified_connection_list = new std::list<sigc::connection>(); } -static void -sp_lpe_item_init(SPLPEItem *lpeitem) -{ - new (lpeitem) SPLPEItem(); -} - -static void sp_lpe_item_finalize(GObject *object) -{ - if (((GObjectClass *) (sp_lpe_item_parent_class))->finalize) { - (* ((GObjectClass *) (sp_lpe_item_parent_class))->finalize)(object); - } +SPLPEItem::~SPLPEItem() { } -void CLPEItem::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPLPEItem* object = this->splpeitem; - - object->readAttr( "inkscape:path-effect" ); +void SPLPEItem::build(SPDocument *document, Inkscape::XML::Node *repr) { + this->readAttr( "inkscape:path-effect" ); CItem::build(document, repr); } -void CLPEItem::release() { - SPLPEItem *lpeitem = this->splpeitem; - +void SPLPEItem::release() { // disconnect all modified listeners: - for (std::list<sigc::connection>::iterator mod_it = lpeitem->lpe_modified_connection_list->begin(); - mod_it != lpeitem->lpe_modified_connection_list->end(); ++mod_it) + for (std::list<sigc::connection>::iterator mod_it = this->lpe_modified_connection_list->begin(); + mod_it != this->lpe_modified_connection_list->end(); ++mod_it) { mod_it->disconnect(); } - delete lpeitem->lpe_modified_connection_list; - lpeitem->lpe_modified_connection_list = NULL; - PathEffectList::iterator it = lpeitem->path_effect_list->begin(); - while ( it != lpeitem->path_effect_list->end() ) { + delete this->lpe_modified_connection_list; + this->lpe_modified_connection_list = NULL; + + PathEffectList::iterator it = this->path_effect_list->begin(); + + while ( it != this->path_effect_list->end() ) { // unlink and delete all references in the list (*it)->unlink(); delete *it; - it = lpeitem->path_effect_list->erase(it); + it = this->path_effect_list->erase(it); } + // delete the list itself - delete lpeitem->path_effect_list; - lpeitem->path_effect_list = NULL; + delete this->path_effect_list; + this->path_effect_list = NULL; CItem::release(); } -void CLPEItem::set(unsigned int key, gchar const* value) { - SPLPEItem *lpeitem = this->splpeitem; - SPLPEItem* object = lpeitem; - +void SPLPEItem::set(unsigned int key, gchar const* value) { switch (key) { case SP_ATTR_INKSCAPE_PATH_EFFECT: { - lpeitem->current_path_effect = NULL; + this->current_path_effect = NULL; // Disable the path effects while populating the LPE list - sp_lpe_item_enable_path_effects(lpeitem, false); + sp_lpe_item_enable_path_effects(this, false); // disconnect all modified listeners: - for ( std::list<sigc::connection>::iterator mod_it = lpeitem->lpe_modified_connection_list->begin(); - mod_it != lpeitem->lpe_modified_connection_list->end(); + for ( std::list<sigc::connection>::iterator mod_it = this->lpe_modified_connection_list->begin(); + mod_it != this->lpe_modified_connection_list->end(); ++mod_it) { mod_it->disconnect(); } - lpeitem->lpe_modified_connection_list->clear(); + + this->lpe_modified_connection_list->clear(); // Clear the path effect list - PathEffectList::iterator it = lpeitem->path_effect_list->begin(); - while ( it != lpeitem->path_effect_list->end() ) + PathEffectList::iterator it = this->path_effect_list->begin(); + + while ( it != this->path_effect_list->end() ) { (*it)->unlink(); delete *it; - it = lpeitem->path_effect_list->erase(it); + it = this->path_effect_list->erase(it); } // Parse the contents of "value" to rebuild the path effect reference list if ( value ) { std::istringstream iss(value); std::string href; + while (std::getline(iss, href, ';')) { - Inkscape::LivePathEffect::LPEObjectReference *path_effect_ref = new Inkscape::LivePathEffect::LPEObjectReference(object); + Inkscape::LivePathEffect::LPEObjectReference *path_effect_ref = new Inkscape::LivePathEffect::LPEObjectReference(this); + try { path_effect_ref->link(href.c_str()); - } catch (Inkscape::BadURIException e) { + } catch (Inkscape::BadURIException& e) { g_warning("BadURIException when trying to find LPE: %s", e.what()); path_effect_ref->unlink(); delete path_effect_ref; path_effect_ref = NULL; } - lpeitem->path_effect_list->push_back(path_effect_ref); + this->path_effect_list->push_back(path_effect_ref); + if ( path_effect_ref->lpeobject && path_effect_ref->lpeobject->get_lpe() ) { // connect modified-listener - lpeitem->lpe_modified_connection_list->push_back( - path_effect_ref->lpeobject->connectModified(sigc::bind(sigc::ptr_fun(&lpeobject_ref_modified), lpeitem)) ); + this->lpe_modified_connection_list->push_back( + path_effect_ref->lpeobject->connectModified(sigc::bind(sigc::ptr_fun(&lpeobject_ref_modified), this)) ); } else { // something has gone wrong in finding the right patheffect. g_warning("Unknown LPE type specified, LPE stack effectively disabled"); @@ -190,39 +158,35 @@ void CLPEItem::set(unsigned int key, gchar const* value) { } } - sp_lpe_item_enable_path_effects(lpeitem, true); + sp_lpe_item_enable_path_effects(this, true); } break; + default: CItem::set(key, value); break; } } -void CLPEItem::update(SPCtx* ctx, unsigned int flags) { +void SPLPEItem::update(SPCtx* ctx, unsigned int flags) { CItem::update(ctx, flags); // update the helperpaths of all LPEs applied to the item // TODO: re-add for the new node tool } -void CLPEItem::modified(unsigned int flags) { - SPLPEItem *lpeitem = this->splpeitem; - SPLPEItem* object = lpeitem; - - if (SP_IS_GROUP(object) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { - sp_lpe_item_update_patheffect(SP_LPE_ITEM(object), true, true); +void SPLPEItem::modified(unsigned int flags) { + if (SP_IS_GROUP(this) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { + sp_lpe_item_update_patheffect(this, true, true); } // CItem::onModified(flags); } -Inkscape::XML::Node* CLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPLPEItem *lpeitem = this->splpeitem; - +Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if (flags & SP_OBJECT_WRITE_EXT) { - if ( sp_lpe_item_has_path_effect(lpeitem) ) { - std::string href = patheffectlist_write_svg(*lpeitem->path_effect_list); + if ( sp_lpe_item_has_path_effect(this) ) { + std::string href = patheffectlist_write_svg(*this->path_effect_list); repr->setAttribute("inkscape:path-effect", href.c_str()); } else { repr->setAttribute("inkscape:path-effect", NULL); @@ -238,8 +202,13 @@ Inkscape::XML::Node* CLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape: * returns true when LPE was successful. */ bool sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) { - if (!lpeitem) return false; - if (!curve) return false; + if (!lpeitem) { + return false; + } + + if (!curve) { + return false; + } if (sp_lpe_item_has_path_effect(lpeitem) && sp_lpe_item_path_effects_enabled(lpeitem)) { for (PathEffectList::iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->path_effect_list->end(); ++it) @@ -292,7 +261,7 @@ bool sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) { } // CPPIFY: make pure virtual -void CLPEItem::update_patheffect(bool write) { +void SPLPEItem::update_patheffect(bool write) { //throw; } @@ -342,7 +311,7 @@ sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) top = lpeitem; } - top->clpeitem->update_patheffect(write); + top->update_patheffect(write); } /** @@ -609,23 +578,21 @@ void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt) } } -void CLPEItem::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) { - SPLPEItem* object = this->splpeitem; - +void SPLPEItem::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) { CItem::child_added(child, ref); - if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) { - SPObject *ochild = object->get_child_by_repr(child); + if (sp_lpe_item_has_path_effect_recursive(this)) { + SPObject *ochild = this->get_child_by_repr(child); + if ( ochild && SP_IS_LPE_ITEM(ochild) ) { sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(ochild)); } } } -void CLPEItem::remove_child(Inkscape::XML::Node * child) { - SPLPEItem* object = this->splpeitem; +void SPLPEItem::remove_child(Inkscape::XML::Node * child) { + if (sp_lpe_item_has_path_effect_recursive(this)) { + SPObject *ochild = this->get_child_by_repr(child); - if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) { - SPObject *ochild = object->get_child_by_repr(child); if ( ochild && SP_IS_LPE_ITEM(ochild) ) { sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(ochild)); } @@ -637,10 +604,12 @@ void CLPEItem::remove_child(Inkscape::XML::Node * child) { static std::string patheffectlist_write_svg(PathEffectList const & list) { HRefList hreflist; + for (PathEffectList::const_iterator it = list.begin(); it != list.end(); ++it) { hreflist.push_back( std::string((*it)->lpeobject_href) ); } + return hreflist_write_svg(hreflist); } @@ -655,15 +624,18 @@ static std::string hreflist_write_svg(HRefList const & list) { std::string r; bool semicolon_first = false; + for (HRefList::const_iterator it = list.begin(); it != list.end(); ++it) { if (semicolon_first) { r += ';'; } + semicolon_first = true; r += (*it); } + return r; } @@ -672,6 +644,7 @@ PathEffectList sp_lpe_item_get_effect_list(SPLPEItem *lpeitem) { return *(lpeitem->path_effect_list); } + // Return a copy of the effect list PathEffectList const sp_lpe_item_get_effect_list(SPLPEItem const *lpeitem) { @@ -721,6 +694,7 @@ void SPLPEItem::replacePathEffects( std::vector<LivePathEffectObject const *> co { LivePathEffectObject const * current_lpeobj = (*it)->lpeobject; std::vector<LivePathEffectObject const *>::const_iterator found_it(std::find(old_lpeobjs.begin(), old_lpeobjs.end(), current_lpeobj)); + if ( found_it != old_lpeobjs.end() ) { std::vector<LivePathEffectObject const *>::difference_type found_index = std::distance (old_lpeobjs.begin(), found_it); const gchar * repr_id = new_lpeobjs[found_index]->getRepr()->attribute("id"); @@ -732,6 +706,7 @@ void SPLPEItem::replacePathEffects( std::vector<LivePathEffectObject const *> co hreflist.push_back( std::string((*it)->lpeobject_href) ); } } + std::string r = hreflist_write_svg(hreflist); this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); } diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 322f767b5..9a59a897f 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -18,9 +18,7 @@ #include <list> -#define SP_TYPE_LPE_ITEM (sp_lpe_item_get_type()) #define SP_LPE_ITEM(obj) ((SPLPEItem*)obj) -//#define SP_IS_LPE_ITEM(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPLPEItem))) #define SP_IS_LPE_ITEM(obj) (dynamic_cast<const SPLPEItem*>((SPObject*)obj)) class CLPEItem; @@ -40,10 +38,10 @@ namespace LivePathEffect{ typedef std::list<Inkscape::LivePathEffect::LPEObjectReference *> PathEffectList; -class SPLPEItem : public SPItem { +class SPLPEItem : public SPItem, public CItem { public: SPLPEItem(); - CLPEItem* clpeitem; + virtual ~SPLPEItem(); int path_effects_enabled; @@ -55,18 +53,7 @@ public: void replacePathEffects( std::vector<LivePathEffectObject const *> const &old_lpeobjs, std::vector<LivePathEffectObject const *> const &new_lpeobjs ); -}; - -struct SPLPEItemClass { - SPItemClass parent_class; -}; - - -class CLPEItem : public CItem { -public: - CLPEItem(SPLPEItem* lpeitem); - virtual ~CLPEItem(); virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); @@ -82,14 +69,8 @@ public: virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); virtual void update_patheffect(bool write); - -protected: - SPLPEItem* splpeitem; }; - -GType sp_lpe_item_get_type(); - void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write); bool sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve); void sp_lpe_item_add_path_effect(SPLPEItem *lpeitem, gchar *value, bool reset); diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp index 5a8d3e1d0..3743ad88d 100644 --- a/src/sp-offset.cpp +++ b/src/sp-offset.cpp @@ -96,7 +96,6 @@ static void sp_offset_source_modified (SPObject *iSource, guint flags, SPItem *i static bool use_slow_but_correct_offset_method=false; SPOffset::SPOffset() : SPShape() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/sp-path.cpp b/src/sp-path.cpp index a1a084b77..5b50eeee6 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -120,7 +120,6 @@ void SPPath::convert_to_guides() { } SPPath::SPPath() : SPShape(), connEndPair(this) { - this->clpeitem = this; this->citem = this; this->cobject = this; } diff --git a/src/sp-polygon.cpp b/src/sp-polygon.cpp index 5ac5e1714..e5b2e0cd8 100644 --- a/src/sp-polygon.cpp +++ b/src/sp-polygon.cpp @@ -36,7 +36,6 @@ namespace { } SPPolygon::SPPolygon() : SPShape() { - this->clpeitem = this; this->citem = this; this->cobject = this; } diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index a85d0d64a..448c5a27b 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -31,7 +31,6 @@ namespace { } SPPolyLine::SPPolyLine() : SPShape() { - this->clpeitem = this; this->citem = this; this->cobject = this; } diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp index 6bdfb2c6c..ff158974c 100644 --- a/src/sp-rect.cpp +++ b/src/sp-rect.cpp @@ -39,7 +39,6 @@ namespace { SPRect::SPRect() : SPShape() { - this->clpeitem = this; this->citem = this; this->cobject = this; } diff --git a/src/sp-root.cpp b/src/sp-root.cpp index 77ae15f85..c0e71ed2c 100644 --- a/src/sp-root.cpp +++ b/src/sp-root.cpp @@ -42,7 +42,6 @@ namespace { } SPRoot::SPRoot() : SPGroup() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 64e905328..eda4fce49 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -55,9 +55,7 @@ static void sp_shape_update_marker_view (SPShape *shape, Inkscape::DrawingItem *ai); -SPShape::SPShape() : SPLPEItem(), CLPEItem(this) { - delete this->clpeitem; - this->clpeitem = this; +SPShape::SPShape() : SPLPEItem() { this->citem = this; this->cobject = this; @@ -79,7 +77,7 @@ SPShape::~SPShape() { } void SPShape::build(SPDocument *document, Inkscape::XML::Node *repr) { - CLPEItem::build(document, repr); + SPLPEItem::build(document, repr); for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { sp_shape_set_marker (this, i, this->style->marker[i].value); @@ -122,21 +120,21 @@ void SPShape::release() { this->_curve_before_lpe = this->_curve_before_lpe->unref(); } - CLPEItem::release(); + SPLPEItem::release(); } void SPShape::set(unsigned int key, const gchar* value) { - CLPEItem::set(key, value); + SPLPEItem::set(key, value); } Inkscape::XML::Node* SPShape::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - CLPEItem::write(xml_doc, repr, flags); + SPLPEItem::write(xml_doc, repr, flags); return repr; } void SPShape::update(SPCtx* ctx, guint flags) { - CLPEItem::update(ctx, flags); + SPLPEItem::update(ctx, flags); /* This stanza checks that an object's marker style agrees with * the marker objects it has allocated. sp_shape_set_marker ensures @@ -392,7 +390,7 @@ sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) } void SPShape::modified(unsigned int flags) { - CLPEItem::modified(flags); + SPLPEItem::modified(flags); if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { @@ -775,7 +773,7 @@ void SPShape::hide(unsigned int key) { } } - //CLPEItem::onHide(key); + //SPLPEItem::onHide(key); } /** diff --git a/src/sp-shape.h b/src/sp-shape.h index 1cd10640e..980bae934 100644 --- a/src/sp-shape.h +++ b/src/sp-shape.h @@ -33,7 +33,7 @@ namespace Inkscape { class DrawingItem; } /** * Base class for shapes, including <path> element */ -class SPShape : public SPLPEItem, public CLPEItem { +class SPShape : public SPLPEItem { public: SPShape(); virtual ~SPShape(); diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index e041e4f7d..905a05a5f 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -40,7 +40,6 @@ namespace { } SPSpiral::SPSpiral() : SPShape() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 68e85c1fd..8c7ebaf52 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -43,7 +43,6 @@ namespace { } SPStar::SPStar() : SPPolygon() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/sp-switch.cpp b/src/sp-switch.cpp index d36406cef..6aa179d14 100644 --- a/src/sp-switch.cpp +++ b/src/sp-switch.cpp @@ -36,7 +36,6 @@ namespace { } SPSwitch::SPSwitch() : SPGroup() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/sp-symbol.cpp b/src/sp-symbol.cpp index 9429046be..a9a8ed639 100644 --- a/src/sp-symbol.cpp +++ b/src/sp-symbol.cpp @@ -37,7 +37,6 @@ namespace { } SPSymbol::SPSymbol() : SPGroup() { - this->clpeitem = this; this->citem = this; this->cobject = this; diff --git a/src/sp-text.cpp b/src/sp-text.cpp index f35b9bb3b..386b49d26 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -71,84 +71,55 @@ namespace { /*##################################################### # SPTEXT #####################################################*/ -G_DEFINE_TYPE(SPText, sp_text, G_TYPE_OBJECT); +SPText::SPText() : SPItem(), CItem(this) { + delete this->citem; + this->citem = this; + this->cobject = this; -static void -sp_text_class_init (SPTextClass *classname) -{ -} - -CText::CText(SPText* text) : CItem(text) { - this->sptext = text; + new (&this->layout) Inkscape::Text::Layout; + new (&this->attributes) TextTagAttributes; } -CText::~CText() { +SPText::~SPText() { } -SPText::SPText() : SPItem() { - SPText* text = this; - - text->ctext = new CText(text); - text->typeHierarchy.insert(typeid(SPText)); +void SPText::build(SPDocument *doc, Inkscape::XML::Node *repr) { + this->readAttr( "x" ); + this->readAttr( "y" ); + this->readAttr( "dx" ); + this->readAttr( "dy" ); + this->readAttr( "rotate" ); - delete text->citem; - text->citem = text->ctext; - text->cobject = text->ctext; - - new (&text->layout) Inkscape::Text::Layout; - new (&text->attributes) TextTagAttributes; -} + CItem::build(doc, repr); -static void -sp_text_init (SPText *text) -{ - new (text) SPText(); + this->readAttr( "sodipodi:linespacing" ); // has to happen after the styles are read } -void CText::release() { - SPText* object = this->sptext; - - SPText *text = SP_TEXT(object); - text->attributes.~TextTagAttributes(); - text->layout.~Layout(); +void SPText::release() { + this->attributes.~TextTagAttributes(); + this->layout.~Layout(); CItem::release(); } -void CText::build(SPDocument *doc, Inkscape::XML::Node *repr) { - SPText* object = this->sptext; - - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "dx" ); - object->readAttr( "dy" ); - object->readAttr( "rotate" ); - - CItem::build(doc, repr); - - object->readAttr( "sodipodi:linespacing" ); // has to happen after the styles are read -} - -void CText::set(unsigned int key, const gchar* value) { - SPText* object = this->sptext; - - SPText *text = SP_TEXT (object); - - if (text->attributes.readSingleAttribute(key, value)) { - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +void SPText::set(unsigned int key, const gchar* value) { + if (this->attributes.readSingleAttribute(key, value)) { + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } else { switch (key) { case SP_ATTR_SODIPODI_LINESPACING: // convert deprecated tag to css if (value) { - text->style->line_height.set = TRUE; - text->style->line_height.inherit = FALSE; - text->style->line_height.normal = FALSE; - text->style->line_height.unit = SP_CSS_UNIT_PERCENT; - text->style->line_height.value = text->style->line_height.computed = sp_svg_read_percentage (value, 1.0); + this->style->line_height.set = TRUE; + this->style->line_height.inherit = FALSE; + this->style->line_height.normal = FALSE; + this->style->line_height.unit = SP_CSS_UNIT_PERCENT; + this->style->line_height.value = this->style->line_height.computed = sp_svg_read_percentage (value, 1.0); } - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); break; + default: CItem::set(key, value); break; @@ -156,54 +127,50 @@ void CText::set(unsigned int key, const gchar* value) { } } -void CText::child_added(Inkscape::XML::Node *rch, Inkscape::XML::Node *ref) { - SPText* object = this->sptext; - - SPText *text = SP_TEXT (object); - +void SPText::child_added(Inkscape::XML::Node *rch, Inkscape::XML::Node *ref) { CItem::child_added(rch, ref); - text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_CONTENT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_CONTENT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); } -void CText::remove_child(Inkscape::XML::Node *rch) { - SPText* object = this->sptext; - - SPText *text = SP_TEXT (object); - +void SPText::remove_child(Inkscape::XML::Node *rch) { CItem::remove_child(rch); - text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_CONTENT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_CONTENT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); } -void CText::update(SPCtx *ctx, guint flags) { - SPText* object = this->sptext; - - SPText *text = SP_TEXT (object); - +void SPText::update(SPCtx *ctx, guint flags) { CItem::update(ctx, flags); guint cflags = (flags & SP_OBJECT_MODIFIED_CASCADE); - if (flags & SP_OBJECT_MODIFIED_FLAG) cflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + if (flags & SP_OBJECT_MODIFIED_FLAG) { + cflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } // Create temporary list of children GSList *l = NULL; - for (SPObject *child = object->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child, object); + + for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { + sp_object_ref(child, this); l = g_slist_prepend (l, child); } + l = g_slist_reverse (l); + while (l) { SPObject *child = reinterpret_cast<SPObject*>(l->data); // We just built this list, so cast is safe. l = g_slist_remove (l, child); + if (cflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { /* fixme: Do we need transform? */ child->updateDisplay(ctx, cflags); } - sp_object_unref(child, object); + + sp_object_unref(child, this); } + if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG ) ) @@ -211,95 +178,103 @@ void CText::update(SPCtx *ctx, guint flags) { /* fixme: It is not nice to have it here, but otherwise children content changes does not work */ /* fixme: Even now it may not work, as we are delayed */ /* fixme: So check modification flag everywhere immediate state is used */ - text->rebuildLayout(); + this->rebuildLayout(); + + Geom::OptRect paintbox = this->geometricBounds(); - Geom::OptRect paintbox = text->geometricBounds(); - for (SPItemView* v = text->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); - text->_clearFlow(g); - g->setStyle(object->style); - // pass the bbox of the text object as paintbox (used for paintserver fills) - text->layout.show(g, paintbox); + this->_clearFlow(g); + g->setStyle(this->style); + // pass the bbox of the this this as paintbox (used for paintserver fills) + this->layout.show(g, paintbox); } } } -void CText::modified(guint flags) { - SPText* object = this->sptext; - +void SPText::modified(guint flags) { // CItem::onModified(flags); guint cflags = (flags & SP_OBJECT_MODIFIED_CASCADE); + if (flags & SP_OBJECT_MODIFIED_FLAG) { cflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } // FIXME: all that we need to do here is to call setStyle, to set the changed // style, but there's no easy way to access the drawing glyphs or texts corresponding to a - // text object. Therefore we do here the same as in _update, that is, destroy all items + // text this. Therefore we do here the same as in _update, that is, destroy all items // and create new ones. This is probably quite wasteful. if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG )) { - SPText *text = SP_TEXT (object); - Geom::OptRect paintbox = text->geometricBounds(); - for (SPItemView* v = text->display; v != NULL; v = v->next) { + Geom::OptRect paintbox = this->geometricBounds(); + + for (SPItemView* v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - text->_clearFlow(g); - g->setStyle(object->style); - text->layout.show(g, paintbox); + this->_clearFlow(g); + g->setStyle(this->style); + this->layout.show(g, paintbox); } } // Create temporary list of children GSList *l = NULL; - for (SPObject *child = object->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child, object); + + for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { + sp_object_ref(child, this); l = g_slist_prepend (l, child); } + l = g_slist_reverse (l); + while (l) { SPObject *child = reinterpret_cast<SPObject*>(l->data); // We just built this list, so cast is safe. l = g_slist_remove (l, child); + if (cflags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { child->emitModified(cflags); } - sp_object_unref(child, object); + + sp_object_unref(child, this); } } -Inkscape::XML::Node *CText::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPText* object = this->sptext; - - SPText *text = SP_TEXT (object); - +Inkscape::XML::Node *SPText::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if (flags & SP_OBJECT_WRITE_BUILD) { if (!repr) { - repr = xml_doc->createElement("svg:text"); + repr = xml_doc->createElement("svg:this"); } + GSList *l = NULL; - for (SPObject *child = object->firstChild() ; child ; child = child->getNext() ) { + + for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { if (SP_IS_TITLE(child) || SP_IS_DESC(child)) { continue; } + Inkscape::XML::Node *crepr = NULL; + if (SP_IS_STRING(child)) { crepr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); } else { crepr = child->updateRepr(xml_doc, NULL, flags); } + if (crepr) { l = g_slist_prepend (l, crepr); } } + while (l) { repr->addChild((Inkscape::XML::Node *) l->data, NULL); Inkscape::GC::release((Inkscape::XML::Node *) l->data); l = g_slist_remove (l, l->data); } } else { - for (SPObject *child = object->firstChild() ; child ; child = child->getNext() ) { + for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { if (SP_IS_TITLE(child) || SP_IS_DESC(child)) { continue; } + if (SP_IS_STRING(child)) { child->getRepr()->setContent(SP_STRING(child)->string.c_str()); } else { @@ -308,15 +283,15 @@ Inkscape::XML::Node *CText::write(Inkscape::XML::Document *xml_doc, Inkscape::XM } } - text->attributes.writeTo(repr); + this->attributes.writeTo(repr); // deprecated attribute, but keep it around for backwards compatibility - if (text->style->line_height.set && !text->style->line_height.inherit && !text->style->line_height.normal && text->style->line_height.unit == SP_CSS_UNIT_PERCENT) { + if (this->style->line_height.set && !this->style->line_height.inherit && !this->style->line_height.normal && this->style->line_height.unit == SP_CSS_UNIT_PERCENT) { Inkscape::SVGOStringStream os; - os << (text->style->line_height.value * 100.0) << "%"; - text->getRepr()->setAttribute("sodipodi:linespacing", os.str().c_str()); + os << (this->style->line_height.value * 100.0) << "%"; + this->getRepr()->setAttribute("sodipodi:linespacing", os.str().c_str()); } else { - text->getRepr()->setAttribute("sodipodi:linespacing", NULL); + this->getRepr()->setAttribute("sodipodi:linespacing", NULL); } CItem::write(xml_doc, repr, flags); @@ -324,50 +299,43 @@ Inkscape::XML::Node *CText::write(Inkscape::XML::Document *xml_doc, Inkscape::XM return repr; } -Geom::OptRect CText::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { - SPText* item = this->sptext; - - Geom::OptRect bbox = SP_TEXT(item)->layout.bounds(transform); +Geom::OptRect SPText::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { + Geom::OptRect bbox = SP_TEXT(this)->layout.bounds(transform); // FIXME this code is incorrect - if (bbox && type == SPItem::VISUAL_BBOX && !item->style->stroke.isNone()) { + if (bbox && type == SPItem::VISUAL_BBOX && !this->style->stroke.isNone()) { double scale = transform.descrim(); - bbox->expandBy(0.5 * item->style->stroke_width.computed * scale); + bbox->expandBy(0.5 * this->style->stroke_width.computed * scale); } + return bbox; } -Inkscape::DrawingItem* CText::show(Inkscape::Drawing &drawing, unsigned key, unsigned flags) { - SPText* item = this->sptext; - - SPText *group = (SPText *) item; - +Inkscape::DrawingItem* SPText::show(Inkscape::Drawing &drawing, unsigned key, unsigned flags) { Inkscape::DrawingGroup *flowed = new Inkscape::DrawingGroup(drawing); flowed->setPickChildren(false); - flowed->setStyle(group->style); + flowed->setStyle(this->style); // pass the bbox of the text object as paintbox (used for paintserver fills) - group->layout.show(flowed, group->geometricBounds()); + this->layout.show(flowed, this->geometricBounds()); return flowed; } -void CText::hide(unsigned int key) { +void SPText::hide(unsigned int key) { // CItem::onHide(key); } -gchar* CText::description() { - SPText* item = this->sptext; - - SPText *text = reinterpret_cast<SPText *>(item); - SPStyle *style = text->style; +gchar* SPText::description() { + SPStyle *style = this->style; font_instance *tf = font_factory::Default()->FaceFromStyle(style); char name_buf[256]; char *n; + if (tf) { tf->Family(name_buf, sizeof(name_buf)); n = xml_quote_strdup(name_buf); @@ -380,41 +348,38 @@ gchar* CText::description() { GString *xs = SP_PX_TO_METRIC_STRING(style->font_size.computed, sp_desktop_namedview(SP_ACTIVE_DESKTOP)->getDefaultMetric()); char const *trunc = ""; - Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) item); + Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) this); + if (layout && layout->inputTruncated()) { trunc = _(" [truncated]"); } - char *ret = ( SP_IS_TEXT_TEXTPATH(item) + char *ret = ( SP_IS_TEXT_TEXTPATH(this) ? g_strdup_printf(_("<b>Text on path</b>%s (%s, %s)"), trunc, n, xs->str) : g_strdup_printf(_("<b>Text</b>%s (%s, %s)"), trunc, n, xs->str) ); g_free(n); return ret; } -void CText::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) { - SPText* item = this->sptext; - +void SPText::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) { if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_TEXT_BASELINE)) { // Choose a point on the baseline for snapping from or to, with the horizontal position // of this point depending on the text alignment (left vs. right) - Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) item); + Inkscape::Text::Layout const *layout = te_get_layout(this); + if (layout != NULL && layout->outputExists()) { boost::optional<Geom::Point> pt = layout->baselineAnchorPoint(); + if (pt) { - p.push_back(Inkscape::SnapCandidatePoint((*pt) * item->i2dt_affine(), Inkscape::SNAPSOURCE_TEXT_ANCHOR, Inkscape::SNAPTARGET_TEXT_ANCHOR)); + p.push_back(Inkscape::SnapCandidatePoint((*pt) * this->i2dt_affine(), Inkscape::SNAPSOURCE_TEXT_ANCHOR, Inkscape::SNAPTARGET_TEXT_ANCHOR)); } } } } -Geom::Affine CText::set_transform(Geom::Affine const &xform) { - SPText* item = this->sptext; - - SPText *text = SP_TEXT(item); - +Geom::Affine SPText::set_transform(Geom::Affine const &xform) { // we cannot optimize textpath because changing its fontsize will break its match to the path - if (SP_IS_TEXT_TEXTPATH (text)) + if (SP_IS_TEXT_TEXTPATH (this)) return xform; /* This function takes care of scaling & translation only, we return whatever parts we can't @@ -438,37 +403,34 @@ Geom::Affine CText::set_transform(Geom::Affine const &xform) { ret[3] /= ex; // Adjust x/y, dx/dy - text->_adjustCoordsRecursive (item, xform * ret.inverse(), ex); + this->_adjustCoordsRecursive (this, xform * ret.inverse(), ex); // Adjust font size - text->_adjustFontsizeRecursive (item, ex); + this->_adjustFontsizeRecursive (this, ex); // Adjust stroke width - item->adjust_stroke_width_recursive (ex); + this->adjust_stroke_width_recursive (ex); // Adjust pattern fill - item->adjust_pattern(xform * ret.inverse()); + this->adjust_pattern(xform * ret.inverse()); // Adjust gradient fill - item->adjust_gradient(xform * ret.inverse()); + this->adjust_gradient(xform * ret.inverse()); - item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); return ret; } -void CText::print(SPPrintContext *ctx) { - SPText* item = this->sptext; - - SPText *group = SP_TEXT (item); +void SPText::print(SPPrintContext *ctx) { Geom::OptRect pbox, bbox, dbox; + pbox = this->geometricBounds(); + bbox = this->desktopVisualBounds(); + dbox = Geom::Rect::from_xywh(Geom::Point(0,0), this->document->getDimensions()); - pbox = item->geometricBounds(); - bbox = item->desktopVisualBounds(); - dbox = Geom::Rect::from_xywh(Geom::Point(0,0), item->document->getDimensions()); - Geom::Affine const ctm (item->i2dt_affine()); + Geom::Affine const ctm (this->i2dt_affine()); - group->layout.print(ctx,pbox,dbox,bbox,ctm); + this->layout.print(ctx,pbox,dbox,bbox,ctm); } /* diff --git a/src/sp-text.h b/src/sp-text.h index 6ed069f6b..f3113e59f 100644 --- a/src/sp-text.h +++ b/src/sp-text.h @@ -21,23 +21,19 @@ #include "text-tag-attributes.h" #include "libnrtype/Layout-TNG.h" - -#define SP_TYPE_TEXT (sp_text_get_type()) #define SP_TEXT(obj) ((SPText*)obj) -#define SP_IS_TEXT(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPText))) +#define SP_IS_TEXT(obj) (dynamic_cast<const SPText*>((SPObject*)obj)) /* Text specific flags */ #define SP_TEXT_CONTENT_MODIFIED_FLAG SP_OBJECT_USER_MODIFIED_FLAG_A #define SP_TEXT_LAYOUT_MODIFIED_FLAG SP_OBJECT_USER_MODIFIED_FLAG_A -class CText; /* SPText */ - -class SPText : public SPItem { +class SPText : public SPItem, public CItem { public: SPText(); - CText* ctext; + virtual ~SPText(); /** Converts the text object to its component curves */ SPCurve *getNormalizedBpath() const @@ -69,18 +65,8 @@ private: breaks and makes sure both that they are assigned the correct SPObject and that we don't get a spurious extra one at the end of the flow. */ unsigned _buildLayoutInput(SPObject *root, Inkscape::Text::Layout::OptionalTextTagAttrs const &parent_optional_attrs, unsigned parent_attrs_offset, bool in_textpath); -}; - -struct SPTextClass { - SPItemClass parent_class; -}; - -class CText : public CItem { public: - CText(SPText* text); - virtual ~CText(); - virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); @@ -97,14 +83,8 @@ public: virtual void hide(unsigned int key); virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs); virtual Geom::Affine set_transform(Geom::Affine const &transform); - -protected: - SPText* sptext; }; - -GType sp_text_get_type(); - #endif /* diff --git a/src/sp-textpath.h b/src/sp-textpath.h index e45122d13..f4f0aa5bf 100644 --- a/src/sp-textpath.h +++ b/src/sp-textpath.h @@ -9,16 +9,13 @@ class SPUsePath; class Path; -#define SP_TYPE_TEXTPATH (sp_textpath_get_type()) #define SP_TEXTPATH(obj) ((SPTextPath*)obj) -#define SP_IS_TEXTPATH(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPTextPath))) +#define SP_IS_TEXTPATH(obj) (dynamic_cast<const SPTextPath*>((SPObject*)obj)) -class CTextPath; - -class SPTextPath : public SPItem { +class SPTextPath : public SPItem, public CItem { public: SPTextPath(); - CTextPath* ctextpath; + virtual ~SPTextPath(); TextTagAttributes attributes; SVGLength startOffset; @@ -26,17 +23,6 @@ public: Path *originalPath; bool isUpdating; SPUsePath *sourcePath; -}; - -struct SPTextPathClass { - SPItemClass parent_class; -}; - - -class CTextPath : public CItem { -public: - CTextPath(SPTextPath* textpath); - virtual ~CTextPath(); virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); @@ -44,14 +30,8 @@ public: virtual void update(SPCtx* ctx, unsigned int flags); virtual void modified(unsigned int flags); virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); - -protected: - SPTextPath* sptextpath; }; - -GType sp_textpath_get_type(); - #define SP_IS_TEXT_TEXTPATH(obj) (SP_IS_TEXT(obj) && obj->firstChild() && SP_IS_TEXTPATH(obj->firstChild())) SPItem *sp_textpath_get_path_item(SPTextPath *tp); diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp index e52879a03..1929b6820 100644 --- a/src/sp-tref.cpp +++ b/src/sp-tref.cpp @@ -60,149 +60,99 @@ namespace { static void build_string_from_root(Inkscape::XML::Node *root, Glib::ustring *retString); /* TRef base class */ - -static void sp_tref_finalize(GObject *obj); - static void sp_tref_href_changed(SPObject *old_ref, SPObject *ref, SPTRef *tref); static void sp_tref_delete_self(SPObject *deleted, SPTRef *self); -G_DEFINE_TYPE(SPTRef, sp_tref, G_TYPE_OBJECT); - -static void -sp_tref_class_init(SPTRefClass *tref_class) -{ - GObjectClass *gobject_class = (GObjectClass *) tref_class; - gobject_class->finalize = sp_tref_finalize; -} - -CTRef::CTRef(SPTRef* tref) : CItem(tref) { - this->sptref = tref; -} - -CTRef::~CTRef() { -} - -SPTRef::SPTRef() : SPItem() { - SPTRef* tref = this; +SPTRef::SPTRef() : SPItem(), CItem(this) { + delete this->citem; + this->citem = this; + this->cobject = this; - tref->ctref = new CTRef(tref); - tref->typeHierarchy.insert(typeid(SPTRef)); + this->stringChild = NULL; - delete tref->citem; - tref->citem = tref->ctref; - tref->cobject = tref->ctref; + new (&this->attributes) TextTagAttributes; - tref->stringChild = NULL; + this->href = NULL; + this->uriOriginalRef = new SPTRefReference(this); + new (&this->_delete_connection) sigc::connection(); + new (&this->_changed_connection) sigc::connection(); - new (&tref->attributes) TextTagAttributes; - - tref->href = NULL; - tref->uriOriginalRef = new SPTRefReference(tref); - new (&tref->_delete_connection) sigc::connection(); - new (&tref->_changed_connection) sigc::connection(); - - tref->_changed_connection = - tref->uriOriginalRef->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_tref_href_changed), tref)); + this->_changed_connection = + this->uriOriginalRef->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_tref_href_changed), this)); } -static void -sp_tref_init(SPTRef *tref) -{ - new (tref) SPTRef(); -} +SPTRef::~SPTRef() { + delete this->uriOriginalRef; -static void -sp_tref_finalize(GObject *obj) -{ - SPTRef *tref = (SPTRef *) obj; - - delete tref->uriOriginalRef; - - tref->_delete_connection.~connection(); - tref->_changed_connection.~connection(); + this->_delete_connection.~connection(); + this->_changed_connection.~connection(); } -void CTRef::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPTRef* object = this->sptref; - +void SPTRef::build(SPDocument *document, Inkscape::XML::Node *repr) { CItem::build(document, repr); - object->readAttr( "xlink:href" ); - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "dx" ); - object->readAttr( "dy" ); - object->readAttr( "rotate" ); + this->readAttr( "xlink:href" ); + this->readAttr( "x" ); + this->readAttr( "y" ); + this->readAttr( "dx" ); + this->readAttr( "dy" ); + this->readAttr( "rotate" ); } -void CTRef::release() { - SPTRef* object = this->sptref; +void SPTRef::release() { + this->attributes.~TextTagAttributes(); - SPTRef *tref = SP_TREF(object); + this->_delete_connection.disconnect(); + this->_changed_connection.disconnect(); - tref->attributes.~TextTagAttributes(); + g_free(this->href); + this->href = NULL; - tref->_delete_connection.disconnect(); - tref->_changed_connection.disconnect(); - - g_free(tref->href); - tref->href = NULL; - - tref->uriOriginalRef->detach(); + this->uriOriginalRef->detach(); CItem::release(); } -void CTRef::set(unsigned int key, const gchar* value) { - SPTRef* object = this->sptref; - - debug("0x%p %s(%u): '%s'",object, +void SPTRef::set(unsigned int key, const gchar* value) { + debug("0x%p %s(%u): '%s'",this, sp_attribute_name(key),key,value ? value : "<no value>"); - SPTRef *tref = SP_TREF(object); - - if (tref->attributes.readSingleAttribute(key, value)) { // x, y, dx, dy, rotate - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + if (this->attributes.readSingleAttribute(key, value)) { // x, y, dx, dy, rotate + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } else if (key == SP_ATTR_XLINK_HREF) { // xlink:href if ( !value ) { // No value - g_free(tref->href); - tref->href = NULL; - tref->uriOriginalRef->detach(); - } else if ((tref->href && strcmp(value, tref->href) != 0) || (!tref->href)) { - + g_free(this->href); + this->href = NULL; + this->uriOriginalRef->detach(); + } else if ((this->href && strcmp(value, this->href) != 0) || (!this->href)) { // Value has changed - if ( tref->href ) { - g_free(tref->href); - tref->href = NULL; + if ( this->href ) { + g_free(this->href); + this->href = NULL; } - tref->href = g_strdup(value); + this->href = g_strdup(value); try { - tref->uriOriginalRef->attach(Inkscape::URI(value)); - tref->uriOriginalRef->updateObserver(); + this->uriOriginalRef->attach(Inkscape::URI(value)); + this->uriOriginalRef->updateObserver(); } catch ( Inkscape::BadURIException &e ) { g_warning("%s", e.what()); - tref->uriOriginalRef->detach(); + this->uriOriginalRef->detach(); } // No matter what happened, an update should be in order - tref->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } - } else { // default CItem::set(key, value); } } -void CTRef::update(SPCtx *ctx, guint flags) { - SPTRef* object = this->sptref; - - debug("0x%p",object); - - SPTRef *tref = SP_TREF(object); +void SPTRef::update(SPCtx *ctx, guint flags) { + debug("0x%p",this); CItem::update(ctx, flags); @@ -212,7 +162,8 @@ void CTRef::update(SPCtx *ctx, guint flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - SPObject *child = tref->stringChild; + SPObject *child = this->stringChild; + if (child) { if ( flags || ( child->uflags & SP_OBJECT_MODIFIED_FLAG )) { child->updateDisplay(ctx, flags); @@ -220,42 +171,37 @@ void CTRef::update(SPCtx *ctx, guint flags) { } } -void CTRef::modified(unsigned int flags) { - SPTRef* object = this->sptref; - - SPTRef *tref_obj = SP_TREF(object); - +void SPTRef::modified(unsigned int flags) { if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } flags &= SP_OBJECT_MODIFIED_CASCADE; - SPObject *child = tref_obj->stringChild; + SPObject *child = this->stringChild; + if (child) { sp_object_ref(child); + if (flags || (child->mflags & SP_OBJECT_MODIFIED_FLAG)) { child->emitModified(flags); } + sp_object_unref(child); } } -Inkscape::XML::Node* CTRef::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPTRef* object = this->sptref; - - debug("0x%p",object); - - SPTRef *tref = SP_TREF(object); +Inkscape::XML::Node* SPTRef::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { + debug("0x%p",this); if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:tref"); } - tref->attributes.writeTo(repr); + this->attributes.writeTo(repr); - if (tref->uriOriginalRef->getURI()) { - gchar *uri_string = tref->uriOriginalRef->getURI()->toString(); + if (this->uriOriginalRef->getURI()) { + gchar *uri_string = this->uriOriginalRef->getURI()->toString(); debug("uri_string=%s", uri_string); repr->setAttribute("xlink:href", uri_string); g_free(uri_string); @@ -266,58 +212,54 @@ Inkscape::XML::Node* CTRef::write(Inkscape::XML::Document *xml_doc, Inkscape::XM return repr; } -Geom::OptRect CTRef::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { - SPTRef* item = this->sptref; - +Geom::OptRect SPTRef::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { Geom::OptRect bbox; // find out the ancestor text which holds our layout - SPObject const *parent_text = item; + SPObject const *parent_text = this; + while ( parent_text && !SP_IS_TEXT(parent_text) ) { parent_text = parent_text->parent; } + if (parent_text == NULL) { return bbox; } // get the bbox of our portion of the layout bbox = SP_TEXT(parent_text)->layout.bounds(transform, - sp_text_get_length_upto(parent_text, item), sp_text_get_length_upto(item, NULL) - 1); + sp_text_get_length_upto(parent_text, this), sp_text_get_length_upto(this, NULL) - 1); // Add stroke width // FIXME this code is incorrect - if (bbox && type == SPItem::VISUAL_BBOX && !item->style->stroke.isNone()) { + if (bbox && type == SPItem::VISUAL_BBOX && !this->style->stroke.isNone()) { double scale = transform.descrim(); - bbox->expandBy(0.5 * item->style->stroke_width.computed * scale); + bbox->expandBy(0.5 * this->style->stroke_width.computed * scale); } + return bbox; } -gchar* CTRef::description() { - SPTRef* item = this->sptref; +gchar* SPTRef::description() { + SPObject *referred = this->getObjectReferredTo(); + + if (this->getObjectReferredTo()) { + char *child_desc; + + if (SP_IS_ITEM(referred)) { + child_desc = SP_ITEM(referred)->description(); + } else { + child_desc = g_strdup(""); + } + + char *ret = g_strdup_printf( + _("<b>Cloned character data</b>%s%s"), + (SP_IS_ITEM(referred) ? _(" from ") : ""), + child_desc); + g_free(child_desc); + + return ret; + } - SPTRef *tref = SP_TREF(item); - - if (tref) - { - SPObject *referred = tref->getObjectReferredTo(); - - if (tref->getObjectReferredTo()) { - char *child_desc; - - if (SP_IS_ITEM(referred)) { - child_desc = SP_ITEM(referred)->description(); - } else { - child_desc = g_strdup(""); - } - - char *ret = g_strdup_printf( - _("<b>Cloned character data</b>%s%s"), - (SP_IS_ITEM(referred) ? _(" from ") : ""), - child_desc); - g_free(child_desc); - return ret; - } - } return g_strdup(_("<b>Orphaned cloned character data</b>")); } diff --git a/src/sp-tref.h b/src/sp-tref.h index f4271bf61..29183047b 100644 --- a/src/sp-tref.h +++ b/src/sp-tref.h @@ -22,16 +22,13 @@ /* tref base class */ -#define SP_TYPE_TREF (sp_tref_get_type()) #define SP_TREF(obj) ((SPTRef*)obj) -#define SP_IS_TREF(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPTRef))) +#define SP_IS_TREF(obj) (dynamic_cast<const SPTRef*>((SPObject*)obj)) -class CTRef; - -class SPTRef : public SPItem { +class SPTRef : public SPItem, public CItem { public: SPTRef(); - CTRef* ctref; + virtual ~SPTRef(); // Attributes that are used in the same way they would be in a tspan TextTagAttributes attributes; @@ -52,17 +49,6 @@ public: sigc::connection _changed_connection; SPObject * getObjectReferredTo(); -}; - -struct SPTRefClass { - SPItemClass parent_class; -}; - - -class CTRef : public CItem { -public: - CTRef(SPTRef* tref); - virtual ~CTRef(); virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); @@ -73,14 +59,8 @@ public: virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type); virtual gchar* description(); - -protected: - SPTRef* sptref; }; - -GType sp_tref_get_type(); - void sp_tref_update_text(SPTRef *tref); bool sp_tref_reference_allowed(SPTRef *tref, SPObject *possible_ref); bool sp_tref_fully_contained(SPObject *start_item, Glib::ustring::iterator &start, diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index 29786f244..f72fe4c41 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -61,80 +61,48 @@ namespace { /*##################################################### # SPTSPAN #####################################################*/ -G_DEFINE_TYPE(SPTSpan, sp_tspan, G_TYPE_OBJECT); +SPTSpan::SPTSpan() : SPItem(), CItem(this) { + delete this->citem; + this->citem = this; + this->cobject = this; -static void -sp_tspan_class_init(SPTSpanClass *classname) -{ -} - -CTSpan::CTSpan(SPTSpan* span) : CItem(span) { - this->sptspan = span; + this->role = SP_TSPAN_ROLE_UNSPECIFIED; + new (&this->attributes) TextTagAttributes; } -CTSpan::~CTSpan() { +SPTSpan::~SPTSpan() { } -SPTSpan::SPTSpan() : SPItem() { - SPTSpan* tspan = this; +void SPTSpan::build(SPDocument *doc, Inkscape::XML::Node *repr) { + this->readAttr( "x" ); + this->readAttr( "y" ); + this->readAttr( "dx" ); + this->readAttr( "dy" ); + this->readAttr( "rotate" ); + this->readAttr( "sodipodi:role" ); - tspan->ctspan = new CTSpan(tspan); - tspan->typeHierarchy.insert(typeid(SPTSpan)); - - delete tspan->citem; - tspan->citem = tspan->ctspan; - tspan->cobject = tspan->ctspan; - - tspan->role = SP_TSPAN_ROLE_UNSPECIFIED; - new (&tspan->attributes) TextTagAttributes; -} - -static void -sp_tspan_init(SPTSpan *tspan) -{ - new (tspan) SPTSpan(); + CItem::build(doc, repr); } -void CTSpan::release() { - SPTSpan* object = this->sptspan; - - SPTSpan *tspan = SP_TSPAN(object); - - tspan->attributes.~TextTagAttributes(); +void SPTSpan::release() { + this->attributes.~TextTagAttributes(); CItem::release(); } -void CTSpan::build(SPDocument *doc, Inkscape::XML::Node *repr) { - SPTSpan* object = this->sptspan; - - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "dx" ); - object->readAttr( "dy" ); - object->readAttr( "rotate" ); - object->readAttr( "sodipodi:role" ); - - CItem::build(doc, repr); -} - - -void CTSpan::set(unsigned int key, const gchar* value) { - SPTSpan* object = this->sptspan; - - SPTSpan *tspan = SP_TSPAN(object); - - if (tspan->attributes.readSingleAttribute(key, value)) { - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +void SPTSpan::set(unsigned int key, const gchar* value) { + if (this->attributes.readSingleAttribute(key, value)) { + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } else { switch (key) { case SP_ATTR_SODIPODI_ROLE: if (value && (!strcmp(value, "line") || !strcmp(value, "paragraph"))) { - tspan->role = SP_TSPAN_ROLE_LINE; + this->role = SP_TSPAN_ROLE_LINE; } else { - tspan->role = SP_TSPAN_ROLE_UNSPECIFIED; + this->role = SP_TSPAN_ROLE_UNSPECIFIED; } break; + default: CItem::set(key, value); break; @@ -142,81 +110,81 @@ void CTSpan::set(unsigned int key, const gchar* value) { } } -void CTSpan::update(SPCtx *ctx, guint flags) { - SPTSpan* object = this->sptspan; - +void SPTSpan::update(SPCtx *ctx, guint flags) { CItem::update(ctx, flags); if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } + flags &= SP_OBJECT_MODIFIED_CASCADE; - for ( SPObject *ochild = object->firstChild() ; ochild ; ochild = ochild->getNext() ) { + for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { if ( flags || ( ochild->uflags & SP_OBJECT_MODIFIED_FLAG )) { - ochild->updateDisplay(ctx, flags); + ochild->updateDisplay(ctx, flags); } } } -void CTSpan::modified(unsigned int flags) { - SPTSpan* object = this->sptspan; - +void SPTSpan::modified(unsigned int flags) { // CItem::onModified(flags); if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } + flags &= SP_OBJECT_MODIFIED_CASCADE; - for ( SPObject *ochild = object->firstChild() ; ochild ; ochild = ochild->getNext() ) { + for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { if (flags || (ochild->mflags & SP_OBJECT_MODIFIED_FLAG)) { ochild->emitModified(flags); } } } -Geom::OptRect CTSpan::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { - SPTSpan* item = this->sptspan; - +Geom::OptRect SPTSpan::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { Geom::OptRect bbox; // find out the ancestor text which holds our layout - SPObject const *parent_text = item; + SPObject const *parent_text = this; + while (parent_text && !SP_IS_TEXT(parent_text)) { parent_text = parent_text->parent; } + if (parent_text == NULL) { return bbox; } // get the bbox of our portion of the layout - bbox = SP_TEXT(parent_text)->layout.bounds(transform, sp_text_get_length_upto(parent_text, item), sp_text_get_length_upto(item, NULL) - 1); - if (!bbox) return bbox; + bbox = SP_TEXT(parent_text)->layout.bounds(transform, sp_text_get_length_upto(parent_text, this), sp_text_get_length_upto(this, NULL) - 1); + + if (!bbox) { + return bbox; + } // Add stroke width // FIXME this code is incorrect - if (type == SPItem::VISUAL_BBOX && !item->style->stroke.isNone()) { + if (type == SPItem::VISUAL_BBOX && !this->style->stroke.isNone()) { double scale = transform.descrim(); - bbox->expandBy(0.5 * item->style->stroke_width.computed * scale); + bbox->expandBy(0.5 * this->style->stroke_width.computed * scale); } + return bbox; } -Inkscape::XML::Node* CTSpan::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPTSpan* object = this->sptspan; - - SPTSpan *tspan = SP_TSPAN(object); - +Inkscape::XML::Node* SPTSpan::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:tspan"); } - tspan->attributes.writeTo(repr); + this->attributes.writeTo(repr); if ( flags&SP_OBJECT_WRITE_BUILD ) { GSList *l = NULL; - for (SPObject* child = object->firstChild() ; child ; child = child->getNext() ) { + + for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { Inkscape::XML::Node* c_repr=NULL; + if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { c_repr = child->updateRepr(xml_doc, NULL, flags); } else if ( SP_IS_TEXTPATH(child) ) { @@ -224,17 +192,19 @@ Inkscape::XML::Node* CTSpan::write(Inkscape::XML::Document *xml_doc, Inkscape::X } else if ( SP_IS_STRING(child) ) { c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); } + if ( c_repr ) { l = g_slist_prepend(l, c_repr); } } + while ( l ) { repr->addChild((Inkscape::XML::Node *) l->data, NULL); Inkscape::GC::release((Inkscape::XML::Node *) l->data); l = g_slist_remove(l, l->data); } } else { - for (SPObject* child = object->firstChild() ; child ; child = child->getNext() ) { + for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { child->updateRepr(flags); } else if ( SP_IS_TEXTPATH(child) ) { @@ -250,11 +220,7 @@ Inkscape::XML::Node* CTSpan::write(Inkscape::XML::Document *xml_doc, Inkscape::X return repr; } -gchar* CTSpan::description() { - SPTSpan* item = this->sptspan; - - g_return_val_if_fail(SP_IS_TSPAN(item), NULL); - +gchar* SPTSpan::description() { return g_strdup(_("<b>Text span</b>")); } @@ -262,87 +228,39 @@ gchar* CTSpan::description() { /*##################################################### # SPTEXTPATH #####################################################*/ - -static void sp_textpath_finalize(GObject *obj); - void refresh_textpath_source(SPTextPath* offset); -G_DEFINE_TYPE(SPTextPath, sp_textpath, G_TYPE_OBJECT); - -static void -sp_textpath_class_init(SPTextPathClass *classname) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(classname); - gobject_class->finalize = sp_textpath_finalize; -} - - -CTextPath::CTextPath(SPTextPath* textpath) : CItem(textpath) { - this->sptextpath = textpath; -} - -CTextPath::~CTextPath() { -} - -SPTextPath::SPTextPath() : SPItem() { - SPTextPath* textpath = this; - - textpath->ctextpath = new CTextPath(textpath); - textpath->typeHierarchy.insert(typeid(SPTextPath)); +SPTextPath::SPTextPath() : SPItem(), CItem(this) { + delete this->citem; + this->citem = this; + this->cobject = this; - delete textpath->citem; - textpath->citem = textpath->ctextpath; - textpath->cobject = textpath->ctextpath; + new (&this->attributes) TextTagAttributes; - new (&textpath->attributes) TextTagAttributes; + this->startOffset._set = false; + this->originalPath = NULL; + this->isUpdating=false; - textpath->startOffset._set = false; - textpath->originalPath = NULL; - textpath->isUpdating=false; // set up the uri reference - textpath->sourcePath = new SPUsePath(textpath); - textpath->sourcePath->user_unlink = sp_textpath_to_text; + this->sourcePath = new SPUsePath(this); + this->sourcePath->user_unlink = sp_textpath_to_text; } -static void -sp_textpath_init(SPTextPath *textpath) -{ - new (textpath) SPTextPath(); -} - -static void -sp_textpath_finalize(GObject *obj) -{ - SPTextPath *textpath = (SPTextPath *) obj; - - delete textpath->sourcePath; +SPTextPath::~SPTextPath() { + delete this->sourcePath; } -void CTextPath::release() { - SPTextPath* object = this->sptextpath; - - SPTextPath *textpath = SP_TEXTPATH(object); - - textpath->attributes.~TextTagAttributes(); - - if (textpath->originalPath) delete textpath->originalPath; - textpath->originalPath = NULL; - - CItem::release(); -} - -void CTextPath::build(SPDocument *doc, Inkscape::XML::Node *repr) { - SPTextPath* object = this->sptextpath; - - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "dx" ); - object->readAttr( "dy" ); - object->readAttr( "rotate" ); - object->readAttr( "startOffset" ); - object->readAttr( "xlink:href" ); +void SPTextPath::build(SPDocument *doc, Inkscape::XML::Node *repr) { + this->readAttr( "x" ); + this->readAttr( "y" ); + this->readAttr( "dx" ); + this->readAttr( "dy" ); + this->readAttr( "rotate" ); + this->readAttr( "startOffset" ); + this->readAttr( "xlink:href" ); bool no_content = true; + for (Inkscape::XML::Node* rch = repr->firstChild() ; rch != NULL; rch = rch->next()) { if ( rch->type() == Inkscape::XML::TEXT_NODE ) { @@ -360,21 +278,29 @@ void CTextPath::build(SPDocument *doc, Inkscape::XML::Node *repr) { CItem::build(doc, repr); } -void CTextPath::set(unsigned int key, const gchar* value) { - SPTextPath* object = this->sptextpath; +void SPTextPath::release() { + this->attributes.~TextTagAttributes(); + + if (this->originalPath) { + delete this->originalPath; + } + + this->originalPath = NULL; - SPTextPath *textpath = SP_TEXTPATH(object); + CItem::release(); +} - if (textpath->attributes.readSingleAttribute(key, value)) { - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +void SPTextPath::set(unsigned int key, const gchar* value) { + if (this->attributes.readSingleAttribute(key, value)) { + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } else { switch (key) { case SP_ATTR_XLINK_HREF: - textpath->sourcePath->link((char*)value); + this->sourcePath->link((char*)value); break; case SP_ATTR_STARTOFFSET: - textpath->startOffset.readOrUnset(value); - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->startOffset.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; default: CItem::set(key, value); @@ -383,25 +309,24 @@ void CTextPath::set(unsigned int key, const gchar* value) { } } -void CTextPath::update(SPCtx *ctx, guint flags) { - SPTextPath* object = this->sptextpath; +void SPTextPath::update(SPCtx *ctx, guint flags) { + this->isUpdating = true; - SPTextPath *textpath = SP_TEXTPATH(object); - - textpath->isUpdating = true; - if ( textpath->sourcePath->sourceDirty ) { - refresh_textpath_source(textpath); + if ( this->sourcePath->sourceDirty ) { + refresh_textpath_source(this); } - textpath->isUpdating = false; + + this->isUpdating = false; CItem::update(ctx, flags); if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } + flags &= SP_OBJECT_MODIFIED_CASCADE; - for ( SPObject *ochild = object->firstChild() ; ochild ; ochild = ochild->getNext() ) { + for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { if ( flags || ( ochild->uflags & SP_OBJECT_MODIFIED_FLAG )) { ochild->updateDisplay(ctx, flags); } @@ -411,7 +336,10 @@ void CTextPath::update(SPCtx *ctx, guint flags) { void refresh_textpath_source(SPTextPath* tp) { - if ( tp == NULL ) return; + if ( tp == NULL ) { + return; + } + tp->sourcePath->refresh_source(); tp->sourcePath->sourceDirty=false; @@ -420,60 +348,59 @@ void refresh_textpath_source(SPTextPath* tp) if (tp->originalPath) { delete tp->originalPath; } + tp->originalPath = NULL; tp->originalPath = new Path; tp->originalPath->Copy(tp->sourcePath->originalPath); tp->originalPath->ConvertWithBackData(0.01); - } } -void CTextPath::modified(unsigned int flags) { - SPTextPath* object = this->sptextpath; - +void SPTextPath::modified(unsigned int flags) { // CItem::onModified(flags); if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } + flags &= SP_OBJECT_MODIFIED_CASCADE; - for ( SPObject *ochild = object->firstChild() ; ochild ; ochild = ochild->getNext() ) { + for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { if (flags || (ochild->mflags & SP_OBJECT_MODIFIED_FLAG)) { ochild->emitModified(flags); } } } -Inkscape::XML::Node* CTextPath::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPTextPath* object = this->sptextpath; - - SPTextPath *textpath = SP_TEXTPATH(object); - +Inkscape::XML::Node* SPTextPath::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:textPath"); } - textpath->attributes.writeTo(repr); - if (textpath->startOffset._set) { - if (textpath->startOffset.unit == SVGLength::PERCENT) { + this->attributes.writeTo(repr); + if (this->startOffset._set) { + if (this->startOffset.unit == SVGLength::PERCENT) { Inkscape::SVGOStringStream os; - os << (textpath->startOffset.computed * 100.0) << "%"; - textpath->getRepr()->setAttribute("startOffset", os.str().c_str()); + os << (this->startOffset.computed * 100.0) << "%"; + this->getRepr()->setAttribute("startOffset", os.str().c_str()); } else { /* FIXME: This logic looks rather undesirable if e.g. startOffset is to be in ems. */ - sp_repr_set_svg_double(repr, "startOffset", textpath->startOffset.computed); + sp_repr_set_svg_double(repr, "startOffset", this->startOffset.computed); } } - if ( textpath->sourcePath->sourceHref ) repr->setAttribute("xlink:href", textpath->sourcePath->sourceHref); + if ( this->sourcePath->sourceHref ) { + repr->setAttribute("xlink:href", this->sourcePath->sourceHref); + } - if ( flags&SP_OBJECT_WRITE_BUILD ) { + if ( flags & SP_OBJECT_WRITE_BUILD ) { GSList *l = NULL; - for (SPObject* child = object->firstChild() ; child ; child = child->getNext() ) { + + for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { Inkscape::XML::Node* c_repr=NULL; + if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { c_repr = child->updateRepr(xml_doc, NULL, flags); } else if ( SP_IS_TEXTPATH(child) ) { @@ -481,17 +408,19 @@ Inkscape::XML::Node* CTextPath::write(Inkscape::XML::Document *xml_doc, Inkscape } else if ( SP_IS_STRING(child) ) { c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); } + if ( c_repr ) { l = g_slist_prepend(l, c_repr); } } + while ( l ) { repr->addChild((Inkscape::XML::Node *) l->data, NULL); Inkscape::GC::release((Inkscape::XML::Node *) l->data); l = g_slist_remove(l, l->data); } } else { - for (SPObject* child = object->firstChild() ; child ; child = child->getNext() ) { + for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { child->updateRepr(flags); } else if ( SP_IS_TEXTPATH(child) ) { @@ -513,8 +442,10 @@ sp_textpath_get_path_item(SPTextPath *tp) { if (tp && tp->sourcePath) { SPItem *refobj = tp->sourcePath->getObject(); - if (SP_IS_ITEM(refobj)) + + if (SP_IS_ITEM(refobj)) { return (SPItem *) refobj; + } } return NULL; } @@ -525,11 +456,16 @@ sp_textpath_to_text(SPObject *tp) SPObject *text = tp->parent; Geom::OptRect bbox = SP_ITEM(text)->geometricBounds(SP_ITEM(text)->i2doc_affine()); - if (!bbox) return; + + if (!bbox) { + return; + } + Geom::Point xy = bbox->min(); // make a list of textpath children GSList *tp_reprs = NULL; + for (SPObject *o = tp->firstChild() ; o != NULL; o = o->next) { tp_reprs = g_slist_prepend(tp_reprs, o->getRepr()); } diff --git a/src/sp-tspan.h b/src/sp-tspan.h index 69a950e2d..1f399f6cf 100644 --- a/src/sp-tspan.h +++ b/src/sp-tspan.h @@ -9,11 +9,8 @@ #include "sp-item.h" #include "text-tag-attributes.h" -G_BEGIN_DECLS - -#define SP_TYPE_TSPAN (sp_tspan_get_type()) #define SP_TSPAN(obj) ((SPTSpan*)obj) -#define SP_IS_TSPAN(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPTSpan))) +#define SP_IS_TSPAN(obj) (dynamic_cast<const SPTSpan*>((SPObject*)obj)) enum { SP_TSPAN_ROLE_UNSPECIFIED, @@ -21,27 +18,13 @@ enum { SP_TSPAN_ROLE_LINE }; -class CTSpan; - -class SPTSpan : public SPItem { +class SPTSpan : public SPItem, public CItem { public: SPTSpan(); - CTSpan* ctspan; + virtual ~SPTSpan(); guint role : 2; TextTagAttributes attributes; -}; - -struct SPTSpanClass { - SPItemClass parent_class; -}; - -GType sp_tspan_get_type() G_GNUC_CONST; - -class CTSpan : public CItem { -public: - CTSpan(SPTSpan* span); - virtual ~CTSpan(); virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); @@ -52,13 +35,8 @@ public: virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type); virtual gchar* description(); - -protected: - SPTSpan* sptspan; }; -G_END_DECLS - #endif /* !INKSCAPE_SP_TSPAN_H */ /* diff --git a/src/sp-use.cpp b/src/sp-use.cpp index 65c8602df..8b73844e5 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -39,16 +39,9 @@ #include "sp-factory.h" /* fixme: */ - -static void sp_use_finalize(GObject *obj); - static void sp_use_href_changed(SPObject *old_ref, SPObject *ref, SPUse *use); - static void sp_use_delete_self(SPObject *deleted, SPUse *self); -//void m_print(gchar *say, Geom::Affine m) -//{ g_print("%s %g %g %g %g %g %g\n", say, m[0], m[1], m[2], m[3], m[4], m[5]); } - #include "sp-factory.h" namespace { @@ -59,154 +52,119 @@ namespace { bool useRegistered = SPFactory::instance().registerObject("svg:use", createUse); } -G_DEFINE_TYPE(SPUse, sp_use, G_TYPE_OBJECT); - -static void -sp_use_class_init(SPUseClass *classname) -{ - GObjectClass *gobject_class = (GObjectClass *) classname; - gobject_class->finalize = sp_use_finalize; -} +SPUse::SPUse() : SPItem(), CItem(this) { + delete this->citem; + this->citem = this; + this->cobject = this; -CUse::CUse(SPUse* use) : CItem(use) { - this->spuse = use; -} + this->child = NULL; -CUse::~CUse() { -} + 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; -SPUse::SPUse() : SPItem() { - SPUse* use = this; + new (&this->_delete_connection) sigc::connection(); + new (&this->_changed_connection) sigc::connection(); - use->cuse = new CUse(use); - use->typeHierarchy.insert(typeid(SPUse)); + new (&this->_transformed_connection) sigc::connection(); - delete use->citem; - use->citem = use->cuse; - use->cobject = use->cuse; + this->ref = new SPUseReference(this); - use->child = NULL; - - use->x.unset(); - use->y.unset(); - use->width.unset(SVGLength::PERCENT, 1.0, 1.0); - use->height.unset(SVGLength::PERCENT, 1.0, 1.0); - use->href = NULL; - - new (&use->_delete_connection) sigc::connection(); - new (&use->_changed_connection) sigc::connection(); - - new (&use->_transformed_connection) sigc::connection(); - - use->ref = new SPUseReference(use); - - use->_changed_connection = use->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_use_href_changed), use)); -} - -static void -sp_use_init(SPUse *use) -{ - new (use) SPUse(); + this->_changed_connection = this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_use_href_changed), this)); } -static void -sp_use_finalize(GObject *obj) -{ - SPUse *use = reinterpret_cast<SPUse *>(obj); - - if (use->child) { - use->detach(use->child); - use->child = NULL; +SPUse::~SPUse() { + if (this->child) { + this->detach(this->child); + this->child = NULL; } - use->ref->detach(); - delete use->ref; - use->ref = 0; + this->ref->detach(); + delete this->ref; + this->ref = 0; - use->_delete_connection.~connection(); - use->_changed_connection.~connection(); + this->_delete_connection.~connection(); + this->_changed_connection.~connection(); - use->_transformed_connection.~connection(); + this->_transformed_connection.~connection(); } -void CUse::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPUse* object = this->spuse; - +void SPUse::build(SPDocument *document, Inkscape::XML::Node *repr) { CItem::build(document, repr); - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "width" ); - object->readAttr( "height" ); - object->readAttr( "xlink:href" ); + this->readAttr( "x" ); + this->readAttr( "y" ); + this->readAttr( "width" ); + this->readAttr( "height" ); + this->readAttr( "xlink:href" ); // We don't need to create child here: // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, // which will call sp_use_href_changed, and that will take care of the child } -void CUse::release() { - SPUse *use = this->spuse; - SPUse* object = use; - - if (use->child) { - object->detach(use->child); - use->child = NULL; +void SPUse::release() { + if (this->child) { + this->detach(this->child); + this->child = NULL; } - use->_delete_connection.disconnect(); - use->_changed_connection.disconnect(); - use->_transformed_connection.disconnect(); + this->_delete_connection.disconnect(); + this->_changed_connection.disconnect(); + this->_transformed_connection.disconnect(); - g_free(use->href); - use->href = NULL; + g_free(this->href); + this->href = NULL; - use->ref->detach(); + this->ref->detach(); CItem::release(); } -void CUse::set(unsigned int key, const gchar* value) { - SPUse *use = this->spuse; - SPUse* object = use; - +void SPUse::set(unsigned int key, const gchar* value) { switch (key) { case SP_ATTR_X: - use->x.readOrUnset(value); - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->x.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_Y: - use->y.readOrUnset(value); - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->y.readOrUnset(value); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_WIDTH: - use->width.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0); - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->width.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_HEIGHT: - use->height.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0); - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + this->height.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_XLINK_HREF: { - if ( value && use->href && ( strcmp(value, use->href) == 0 ) ) { + if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) { /* No change, do nothing. */ } else { - g_free(use->href); - use->href = NULL; + g_free(this->href); + this->href = NULL; + if (value) { // First, set the href field, because sp_use_href_changed will need it. - use->href = g_strdup(value); + this->href = g_strdup(value); // Now do the attaching, which emits the changed signal. try { - use->ref->attach(Inkscape::URI(value)); + this->ref->attach(Inkscape::URI(value)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); - use->ref->detach(); + this->ref->detach(); } } else { - use->ref->detach(); + this->ref->detach(); } } break; @@ -218,22 +176,20 @@ void CUse::set(unsigned int key, const gchar* value) { } } -Inkscape::XML::Node* CUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - SPUse *use = this->spuse; - +Inkscape::XML::Node* SPUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:use"); } CItem::write(xml_doc, repr, flags); - sp_repr_set_svg_double(repr, "x", use->x.computed); - sp_repr_set_svg_double(repr, "y", use->y.computed); - sp_repr_set_svg_double(repr, "width", use->width.computed); - sp_repr_set_svg_double(repr, "height", use->height.computed); + sp_repr_set_svg_double(repr, "x", this->x.computed); + sp_repr_set_svg_double(repr, "y", this->y.computed); + sp_repr_set_svg_double(repr, "width", this->width.computed); + sp_repr_set_svg_double(repr, "height", this->height.computed); - if (use->ref->getURI()) { - gchar *uri_string = use->ref->getURI()->toString(); + if (this->ref->getURI()) { + gchar *uri_string = this->ref->getURI()->toString(); repr->setAttribute("xlink:href", uri_string); g_free(uri_string); } @@ -241,35 +197,33 @@ Inkscape::XML::Node* CUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML return repr; } -Geom::OptRect CUse::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) { - SPUse const *use = this->spuse; - +Geom::OptRect SPUse::bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) { Geom::OptRect bbox; - if (use->child && SP_IS_ITEM(use->child)) { - SPItem *child = SP_ITEM(use->child); + if (this->child && SP_IS_ITEM(this->child)) { + SPItem *child = SP_ITEM(this->child); Geom::Affine const ct( child->transform - * Geom::Translate(use->x.computed, - use->y.computed) + * Geom::Translate(this->x.computed, + this->y.computed) * transform ); + bbox = child->bounds(bboxtype, ct); } + return bbox; } -void CUse::print(SPPrintContext* ctx) { - SPUse *use = this->spuse; - +void SPUse::print(SPPrintContext* ctx) { bool translated = false; - if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { - Geom::Affine tp(Geom::Translate(use->x.computed, use->y.computed)); + if ((this->x._set && this->x.computed != 0) || (this->y._set && this->y.computed != 0)) { + Geom::Affine tp(Geom::Translate(this->x.computed, this->y.computed)); sp_print_bind(ctx, tp, 1.0); translated = true; } - if (use->child && SP_IS_ITEM(use->child)) { - SP_ITEM(use->child)->invoke_print(ctx); + if (this->child && SP_IS_ITEM(this->child)) { + SP_ITEM(this->child)->invoke_print(ctx); } if (translated) { @@ -277,20 +231,19 @@ void CUse::print(SPPrintContext* ctx) { } } -gchar* CUse::description() { - SPUse *use = this->spuse; - +gchar* SPUse::description() { char *ret; - if (use->child) { - if( SP_IS_SYMBOL( use->child ) ) { - //char *symbol_desc = SP_ITEM(use->child)->description(); + if (this->child) { + if( SP_IS_SYMBOL( this->child ) ) { + //char *symbol_desc = SP_ITEM(this->child)->description(); //g_free(symbol_desc); return g_strdup(_("<b>Clone of Symbol</b>")); //return g_strdup_printf(_("<b>Clone of Symbol</b>: %s"), symbol_desc ); } static unsigned recursion_depth = 0; + if (recursion_depth >= 4) { /* TRANSLATORS: Used for statusbar description for long <use> chains: * "Clone of: Clone of: ... in Layer 1". */ @@ -298,44 +251,41 @@ gchar* CUse::description() { /* We could do better, e.g. chasing the href chain until we reach something other than * a <use>, and giving its description. */ } + ++recursion_depth; - char *child_desc = SP_ITEM(use->child)->description(); + char *child_desc = SP_ITEM(this->child)->description(); --recursion_depth; ret = g_strdup_printf(_("<b>Clone</b> of: %s"), child_desc); g_free(child_desc); + return ret; } else { return g_strdup(_("<b>Orphaned clone</b>")); } } -Inkscape::DrawingItem* CUse::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { - SPUse *use = this->spuse; - SPUse* item = use; - +Inkscape::DrawingItem* SPUse::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(drawing); ai->setPickChildren(false); - ai->setStyle(item->style); + ai->setStyle(this->style); - if (use->child) { - Inkscape::DrawingItem *ac = SP_ITEM(use->child)->invoke_show(drawing, key, flags); + if (this->child) { + Inkscape::DrawingItem *ac = SP_ITEM(this->child)->invoke_show(drawing, key, flags); if (ac) { ai->prependChild(ac); } - Geom::Translate t(use->x.computed, - use->y.computed); + + Geom::Translate t(this->x.computed, this->y.computed); ai->setChildTransform(t); } return ai; } -void CUse::hide(unsigned int key) { - SPUse *use = this->spuse; - - if (use->child) { - SP_ITEM(use->child)->invoke_hide(key); +void SPUse::hide(unsigned int key) { + if (this->child) { + SP_ITEM(this->child)->invoke_hide(key); } // CItem::onHide(key); @@ -554,11 +504,7 @@ sp_use_delete_self(SPObject */*deleted*/, SPUse *self) } } -void CUse::update(SPCtx *ctx, unsigned flags) { - SPUse* object = this->spuse; - - SPItem *item = SP_ITEM(object); - SPUse *use = SP_USE(object); +void SPUse::update(SPCtx *ctx, unsigned flags) { SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; @@ -567,78 +513,85 @@ void CUse::update(SPCtx *ctx, unsigned flags) { if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } + flags &= SP_OBJECT_MODIFIED_CASCADE; if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = SP_ITEM(object)->display; v != NULL; v = v->next) { + for (SPItemView *v = SP_ITEM(this)->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - g->setStyle(object->style); + g->setStyle(this->style); } } /* Set up child viewport */ - if (use->x.unit == SVGLength::PERCENT) { - use->x.computed = use->x.value * ictx->viewport.width(); + if (this->x.unit == SVGLength::PERCENT) { + this->x.computed = this->x.value * ictx->viewport.width(); } - if (use->y.unit == SVGLength::PERCENT) { - use->y.computed = use->y.value * ictx->viewport.height(); + + if (this->y.unit == SVGLength::PERCENT) { + this->y.computed = this->y.value * ictx->viewport.height(); } - if (use->width.unit == SVGLength::PERCENT) { - use->width.computed = use->width.value * ictx->viewport.width(); + + if (this->width.unit == SVGLength::PERCENT) { + this->width.computed = this->width.value * ictx->viewport.width(); } - if (use->height.unit == SVGLength::PERCENT) { - use->height.computed = use->height.value * ictx->viewport.height(); + + if (this->height.unit == SVGLength::PERCENT) { + this->height.computed = this->height.value * ictx->viewport.height(); } - cctx.viewport = Geom::Rect::from_xywh(0, 0, use->width.computed, use->height.computed); + + cctx.viewport = Geom::Rect::from_xywh(0, 0, this->width.computed, this->height.computed); cctx.i2vp = Geom::identity(); flags&=~SP_OBJECT_USER_MODIFIED_FLAG_B; - if (use->child) { - sp_object_ref(use->child); - if (flags || (use->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - if (SP_IS_ITEM(use->child)) { - SPItem const &chi = *SP_ITEM(use->child); + if (this->child) { + 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; - use->child->updateDisplay((SPCtx *)&cctx, flags); + this->child->updateDisplay((SPCtx *)&cctx, flags); } else { - use->child->updateDisplay(ctx, flags); + this->child->updateDisplay(ctx, flags); } } - sp_object_unref(use->child); + + sp_object_unref(this->child); } /* As last step set additional transform of arena group */ - for (SPItemView *v = item->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); - Geom::Affine t(Geom::Translate(use->x.computed, use->y.computed)); + Geom::Affine t(Geom::Translate(this->x.computed, this->y.computed)); g->setChildTransform(t); } } -void CUse::modified(unsigned int flags) { - SPUse* object = this->spuse; - - SPUse *use_obj = SP_USE(object); - +void SPUse::modified(unsigned int flags) { if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } + flags &= SP_OBJECT_MODIFIED_CASCADE; if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { - for (SPItemView *v = SP_ITEM(object)->display; v != NULL; v = v->next) { + for (SPItemView *v = SP_ITEM(this)->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - g->setStyle(object->style); + g->setStyle(this->style); } } - SPObject *child = use_obj->child; + SPObject *child = this->child; + if (child) { sp_object_ref(child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { child->emitModified(flags); } + sp_object_unref(child); } } @@ -660,6 +613,7 @@ SPItem *sp_use_unlink(SPUse *use) // Track the ultimate source of a chain of uses. SPItem *orig = sp_use_root(use); + if (!orig) { return NULL; } @@ -668,8 +622,10 @@ SPItem *sp_use_unlink(SPUse *use) Geom::Affine t = sp_use_get_root_transform(use); Inkscape::XML::Node *copy = NULL; + if (SP_IS_SYMBOL(orig)) { // make a group, copy children copy = xml_doc->createElement("svg:g"); + for (Inkscape::XML::Node *child = orig->getRepr()->firstChild() ; child != NULL; child = child->next()) { Inkscape::XML::Node *newchild = child->duplicate(xml_doc); copy->appendChild(newchild); @@ -722,31 +678,29 @@ SPItem *sp_use_unlink(SPUse *use) // Advertise ourselves as not moving. item->doWriteTransform(item->getRepr(), t, &nomove); } + return item; } SPItem *sp_use_get_original(SPUse *use) { SPItem *ref = NULL; - if (use){ + + if (use) { if (use->ref){ ref = use->ref->getObject(); } } + return ref; } -void CUse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) { - SPUse* item = this->spuse; +void SPUse::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) { + SPItem *root = sp_use_root(this); - g_assert (item != NULL); - g_assert (SP_IS_ITEM(item)); - g_assert (SP_IS_USE(item)); - - SPUse *use = SP_USE(item); - SPItem *root = sp_use_root(use); - if (!root) + if (!root) { return; + } root->citem->snappoints(p, snapprefs); } diff --git a/src/sp-use.h b/src/sp-use.h index f8b3c2f66..83059b672 100644 --- a/src/sp-use.h +++ b/src/sp-use.h @@ -18,18 +18,15 @@ #include "svg/svg-length.h" #include "sp-item.h" - -#define SP_TYPE_USE (sp_use_get_type ()) #define SP_USE(obj) ((SPUse*)obj) -#define SP_IS_USE(obj) (obj != NULL && static_cast<const SPObject*>(obj)->typeHierarchy.count(typeid(SPUse))) +#define SP_IS_USE(obj) (dynamic_cast<const SPUse*>((SPObject*)obj)) class SPUseReference; -class CUse; -class SPUse : public SPItem { +class SPUse : public SPItem, public CItem { public: SPUse(); - CUse* cuse; + virtual ~SPUse(); // 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 @@ -51,17 +48,6 @@ public: // a sigc connection for transformed signal, used to do move compensation sigc::connection _transformed_connection; -}; - -struct SPUseClass { - SPItemClass parent_class; -}; - - -class CUse : public CItem { -public: - CUse(SPUse* use); - virtual ~CUse(); virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); @@ -76,14 +62,8 @@ public: 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); - -protected: - SPUse* spuse; }; - -GType sp_use_get_type (void); - SPItem *sp_use_unlink (SPUse *use); SPItem *sp_use_get_original (SPUse *use); Geom::Affine sp_use_get_parent_transform (SPUse *use); |
