diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2013-09-19 22:33:11 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2013-09-19 22:33:11 +0000 |
| commit | 4bda89e32e33c7bdff5d3ea3c1ceee1f806de9f7 (patch) | |
| tree | caeb924426bcc861badc6fa81318b67460b26d47 /src/sp-tspan.cpp | |
| parent | Update to trunk (diff) | |
| parent | updates for cmake (diff) | |
| download | inkscape-4bda89e32e33c7bdff5d3ea3c1ceee1f806de9f7.tar.gz inkscape-4bda89e32e33c7bdff5d3ea3c1ceee1f806de9f7.zip | |
Update to trunk
(bzr r11950.1.141)
Diffstat (limited to 'src/sp-tspan.cpp')
| -rw-r--r-- | src/sp-tspan.cpp | 366 |
1 files changed, 151 insertions, 215 deletions
diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index 6f0b6ac39..63dcd07d8 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -43,172 +43,144 @@ #include "xml/repr.h" #include "document.h" +#include "sp-factory.h" -/*##################################################### -# SPTSPAN -#####################################################*/ +namespace { + SPObject* createTSpan() { + return new SPTSpan(); + } -static void sp_tspan_build(SPObject * object, SPDocument * document, Inkscape::XML::Node * repr); -static void sp_tspan_release(SPObject *object); -static void sp_tspan_set(SPObject *object, unsigned key, gchar const *value); -static void sp_tspan_update(SPObject *object, SPCtx *ctx, guint flags); -static void sp_tspan_modified(SPObject *object, unsigned flags); -static Geom::OptRect sp_tspan_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type); -static Inkscape::XML::Node *sp_tspan_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -static char *sp_tspan_description (SPItem *item); + SPObject* createTextPath() { + return new SPTextPath(); + } -G_DEFINE_TYPE(SPTSpan, sp_tspan, SP_TYPE_ITEM); - -static void -sp_tspan_class_init(SPTSpanClass *classname) -{ - SPObjectClass *sp_object_class = SP_OBJECT_CLASS(classname); - SPItemClass *item_class = SP_ITEM_CLASS(classname); - - sp_object_class->build = sp_tspan_build; - sp_object_class->release = sp_tspan_release; - sp_object_class->set = sp_tspan_set; - sp_object_class->update = sp_tspan_update; - sp_object_class->modified = sp_tspan_modified; - sp_object_class->write = sp_tspan_write; - - item_class->bbox = sp_tspan_bbox; - item_class->description = sp_tspan_description; + bool tspanRegistered = SPFactory::instance().registerObject("svg:tspan", createTSpan); + bool textPathRegistered = SPFactory::instance().registerObject("svg:textPath", createTextPath); } -static void -sp_tspan_init(SPTSpan *tspan) -{ - tspan->role = SP_TSPAN_ROLE_UNSPECIFIED; - new (&tspan->attributes) TextTagAttributes; +/*##################################################### +# SPTSPAN +#####################################################*/ +SPTSpan::SPTSpan() : SPItem() { + this->role = SP_TSPAN_ROLE_UNSPECIFIED; + //new (&this->attributes) TextTagAttributes; } -static void -sp_tspan_release(SPObject *object) -{ - SPTSpan *tspan = SP_TSPAN(object); +SPTSpan::~SPTSpan() { +} - tspan->attributes.~TextTagAttributes(); +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" ); - if ((SP_OBJECT_CLASS(sp_tspan_parent_class))->release) - (SP_OBJECT_CLASS(sp_tspan_parent_class))->release(object); + SPItem::build(doc, repr); } -static void -sp_tspan_build(SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr) -{ - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "dx" ); - object->readAttr( "dy" ); - object->readAttr( "rotate" ); - object->readAttr( "sodipodi:role" ); - - if ((SP_OBJECT_CLASS(sp_tspan_parent_class))->build) - (SP_OBJECT_CLASS(sp_tspan_parent_class))->build(object, doc, repr); -} +void SPTSpan::release() { + //this->attributes.~TextTagAttributes(); -static void -sp_tspan_set(SPObject *object, unsigned key, gchar const *value) -{ - SPTSpan *tspan = SP_TSPAN(object); + SPItem::release(); +} - 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: - if ((SP_OBJECT_CLASS(sp_tspan_parent_class))->set) - (SP_OBJECT_CLASS(sp_tspan_parent_class))->set(object, key, value); + SPItem::set(key, value); break; } } } -static void sp_tspan_update(SPObject *object, SPCtx *ctx, guint flags) -{ - if ((SP_OBJECT_CLASS(sp_tspan_parent_class))->update) { - (SP_OBJECT_CLASS(sp_tspan_parent_class))->update(object, ctx, flags); - } +void SPTSpan::update(SPCtx *ctx, guint flags) { + SPItem::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); } } } -static void sp_tspan_modified(SPObject *object, unsigned flags) -{ - if ((SP_OBJECT_CLASS(sp_tspan_parent_class))->modified) { - (SP_OBJECT_CLASS(sp_tspan_parent_class))->modified(object, flags); - } +void SPTSpan::modified(unsigned int flags) { +// SPItem::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); } } } -static Geom::OptRect -sp_tspan_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type) -{ +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; } -static Inkscape::XML::Node * -sp_tspan_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - 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) ) { @@ -216,17 +188,19 @@ sp_tspan_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML } 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) ) { @@ -237,18 +211,12 @@ sp_tspan_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML } } - if ((SP_OBJECT_CLASS(sp_tspan_parent_class))->write) { - (SP_OBJECT_CLASS(sp_tspan_parent_class))->write(object, xml_doc, repr, flags); - } + SPItem::write(xml_doc, repr, flags); return repr; } -static char * -sp_tspan_description(SPItem *item) -{ - g_return_val_if_fail(SP_IS_TSPAN(item), NULL); - +gchar* SPTSpan::description() { return g_strdup(_("<b>Text span</b>")); } @@ -256,79 +224,35 @@ sp_tspan_description(SPItem *item) /*##################################################### # SPTEXTPATH #####################################################*/ - -static void sp_textpath_finalize(GObject *obj); - -static void sp_textpath_build(SPObject * object, SPDocument * document, Inkscape::XML::Node * repr); -static void sp_textpath_release(SPObject *object); -static void sp_textpath_set(SPObject *object, unsigned key, gchar const *value); -static void sp_textpath_update(SPObject *object, SPCtx *ctx, guint flags); -static void sp_textpath_modified(SPObject *object, unsigned flags); -static Inkscape::XML::Node *sp_textpath_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); - void refresh_textpath_source(SPTextPath* offset); -G_DEFINE_TYPE(SPTextPath, sp_textpath, SP_TYPE_ITEM); - -static void sp_textpath_class_init(SPTextPathClass *classname) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS(classname); - SPObjectClass *sp_object_class = SP_OBJECT_CLASS(classname); - - gobject_class->finalize = sp_textpath_finalize; +SPTextPath::SPTextPath() : SPItem() { + //new (&this->attributes) TextTagAttributes; - sp_object_class->build = sp_textpath_build; - sp_object_class->release = sp_textpath_release; - sp_object_class->set = sp_textpath_set; - sp_object_class->update = sp_textpath_update; - sp_object_class->modified = sp_textpath_modified; - sp_object_class->write = sp_textpath_write; -} - -static void -sp_textpath_init(SPTextPath *textpath) -{ - 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; -} - -static void sp_textpath_finalize(GObject *obj) -{ - SPTextPath *textpath = static_cast<SPTextPath *>(obj); - - delete textpath->sourcePath; + this->sourcePath = new SPUsePath(this); + this->sourcePath->user_unlink = sp_textpath_to_text; } -static void sp_textpath_release(SPObject *object) -{ - SPTextPath *textpath = SP_TEXTPATH(object); - - textpath->attributes.~TextTagAttributes(); - - if (textpath->originalPath) delete textpath->originalPath; - textpath->originalPath = NULL; - - if ((SP_OBJECT_CLASS(sp_textpath_parent_class))->release) - (SP_OBJECT_CLASS(sp_textpath_parent_class))->release(object); +SPTextPath::~SPTextPath() { + delete this->sourcePath; } -static void sp_textpath_build(SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr) -{ - 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 ) { @@ -343,54 +267,58 @@ static void sp_textpath_build(SPObject *object, SPDocument *doc, Inkscape::XML:: repr->addChild(rch, NULL); } - if ((SP_OBJECT_CLASS(sp_textpath_parent_class))->build) { - (SP_OBJECT_CLASS(sp_textpath_parent_class))->build(object, doc, repr); - } + SPItem::build(doc, repr); } -static void sp_textpath_set(SPObject *object, unsigned key, gchar const *value) -{ - SPTextPath *textpath = SP_TEXTPATH(object); +void SPTextPath::release() { + //this->attributes.~TextTagAttributes(); - if (textpath->attributes.readSingleAttribute(key, value)) { - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + if (this->originalPath) { + delete this->originalPath; + } + + this->originalPath = NULL; + + SPItem::release(); +} + +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: - if ((SP_OBJECT_CLASS(sp_textpath_parent_class))->set) - (SP_OBJECT_CLASS(sp_textpath_parent_class))->set(object, key, value); + SPItem::set(key, value); break; } } } -static void sp_textpath_update(SPObject *object, SPCtx *ctx, guint flags) -{ - SPTextPath *textpath = SP_TEXTPATH(object); +void SPTextPath::update(SPCtx *ctx, guint flags) { + this->isUpdating = true; - textpath->isUpdating = true; - if ( textpath->sourcePath->sourceDirty ) { - refresh_textpath_source(textpath); + if ( this->sourcePath->sourceDirty ) { + refresh_textpath_source(this); } - textpath->isUpdating = false; - if ((SP_OBJECT_CLASS(sp_textpath_parent_class))->update) { - (SP_OBJECT_CLASS(sp_textpath_parent_class))->update(object, ctx, flags); - } + this->isUpdating = false; + + SPItem::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); } @@ -400,7 +328,10 @@ static void sp_textpath_update(SPObject *object, 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; @@ -409,61 +340,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); - } } -static void sp_textpath_modified(SPObject *object, unsigned flags) -{ - if ((SP_OBJECT_CLASS(sp_textpath_parent_class))->modified) { - (SP_OBJECT_CLASS(sp_textpath_parent_class))->modified(object, flags); - } +void SPTextPath::modified(unsigned int flags) { +// SPItem::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); } } } -static Inkscape::XML::Node * -sp_textpath_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - 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) { - Inkscape::SVGOStringStream os; - os << (textpath->startOffset.computed * 100.0) << "%"; - textpath->getRepr()->setAttribute("startOffset", os.str().c_str()); + this->attributes.writeTo(repr); + if (this->startOffset._set) { + if (this->startOffset.unit == SVGLength::PERCENT) { + Inkscape::SVGOStringStream os; + 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) ) { @@ -471,17 +400,19 @@ sp_textpath_write(SPObject *object, 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) ) { @@ -492,9 +423,7 @@ sp_textpath_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape:: } } - if ((SP_OBJECT_CLASS(sp_textpath_parent_class))->write) { - (SP_OBJECT_CLASS(sp_textpath_parent_class))->write(object, xml_doc, repr, flags); - } + SPItem::write(xml_doc, repr, flags); return repr; } @@ -504,8 +433,10 @@ SPItem *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 refobj; + } } return NULL; } @@ -515,11 +446,16 @@ void 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()); } |
