diff options
| author | Markus Engel <markus.engel@tum.de> | 2013-04-05 19:07:38 +0000 |
|---|---|---|
| committer | Markus Engel <markus.engel@tum.de> | 2013-04-05 19:07:38 +0000 |
| commit | 61003d31ea058fdf94f4f80c753c3e38426f35e4 (patch) | |
| tree | de30fe5c58fc71682c9544448f8ef7f79de673cf /src/sp-flowtext.cpp | |
| parent | Merged more classes. (diff) | |
| download | inkscape-61003d31ea058fdf94f4f80c753c3e38426f35e4.tar.gz inkscape-61003d31ea058fdf94f4f80c753c3e38426f35e4.zip | |
Merged FlowX classes.
(bzr r11608.1.79)
Diffstat (limited to 'src/sp-flowtext.cpp')
| -rw-r--r-- | src/sp-flowtext.cpp | 220 |
1 files changed, 91 insertions, 129 deletions
diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index 1d08b8256..8cdf52000 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -33,10 +33,6 @@ #include "display/drawing-text.h" - -static void sp_flowtext_init(SPFlowtext *group); -static void sp_flowtext_dispose(GObject *object); - #include "sp-factory.h" namespace { @@ -47,71 +43,35 @@ namespace { bool flowtextRegistered = SPFactory::instance().registerObject("svg:flowRoot", createFlowtext); } -G_DEFINE_TYPE(SPFlowtext, sp_flowtext, G_TYPE_OBJECT); - -static void -sp_flowtext_class_init(SPFlowtextClass *klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - - object_class->dispose = sp_flowtext_dispose; -} - -CFlowtext::CFlowtext(SPFlowtext* flowtext) : CItem(flowtext) { - this->spflowtext = flowtext; -} - -CFlowtext::~CFlowtext() { -} - -SPFlowtext::SPFlowtext() : SPItem() { - SPFlowtext* group = this; - - group->cflowtext = new CFlowtext(group); - group->typeHierarchy.insert(typeid(SPFlowtext)); - - delete group->citem; - group->citem = group->cflowtext; - group->cobject = group->cflowtext; - - group->par_indent = 0; - new (&group->layout) Inkscape::Text::Layout(); -} +SPFlowtext::SPFlowtext() : SPItem(), CItem(this) { + delete this->citem; + this->citem = this; + this->cobject = this; -static void -sp_flowtext_init(SPFlowtext *group) -{ - new (group) SPFlowtext(); + this->par_indent = 0; + new (&this->layout) Inkscape::Text::Layout(); } -static void -sp_flowtext_dispose(GObject *object) -{ - SPFlowtext *group = (SPFlowtext*)object; - - group->layout.~Layout(); +SPFlowtext::~SPFlowtext() { + this->layout.~Layout(); } -void CFlowtext::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) { +void SPFlowtext::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) { CItem::child_added(child, ref); - this->spflowtext->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); } /* fixme: hide (Lauris) */ -void CFlowtext::remove_child(Inkscape::XML::Node* child) { +void SPFlowtext::remove_child(Inkscape::XML::Node* child) { CItem::remove_child(child); - this->spflowtext->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); } - -void CFlowtext::update(SPCtx* ctx, unsigned int flags) { - SPFlowtext* object = this->spflowtext; - - SPFlowtext *group = SP_FLOWTEXT(object); +void SPFlowtext::update(SPCtx* ctx, unsigned int flags) { SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; @@ -121,14 +81,18 @@ void CFlowtext::update(SPCtx* ctx, unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; - for (SPObject *child = object->firstChild() ; child ; child = child->getNext() ) { + + for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { sp_object_ref(child); l = g_slist_prepend(l, child); } + l = g_slist_reverse(l); + while (l) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { if (SP_IS_ITEM(child)) { SPItem const &chi = *SP_ITEM(child); @@ -139,42 +103,46 @@ void CFlowtext::update(SPCtx* ctx, unsigned int flags) { child->updateDisplay(ctx, flags); } } + sp_object_unref(child); } - group->rebuildLayout(); + this->rebuildLayout(); - Geom::OptRect pbox = group->geometricBounds(); - for (SPItemView *v = group->display; v != NULL; v = v->next) { + Geom::OptRect pbox = this->geometricBounds(); + + for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - group->_clearFlow(g); - g->setStyle(object->style); + this->_clearFlow(g); + g->setStyle(this->style); // pass the bbox of the flowtext object as paintbox (used for paintserver fills) - group->layout.show(g, pbox); + this->layout.show(g, pbox); } } -void CFlowtext::modified(unsigned int flags) { - SPFlowtext* object = this->spflowtext; - SPObject *ft = object; +void SPFlowtext::modified(unsigned int flags) { SPObject *region = NULL; - if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + if (flags & SP_OBJECT_MODIFIED_FLAG) { + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } + flags &= SP_OBJECT_MODIFIED_CASCADE; // FIXME: the below stanza is copied over from sp_text_modified, consider factoring it out if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG )) { - SPFlowtext *text = SP_FLOWTEXT(object); + SPFlowtext *text = SP_FLOWTEXT(this); Geom::OptRect pbox = text->geometricBounds(); + for (SPItemView* v = text->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); text->_clearFlow(g); - g->setStyle(object->style); + g->setStyle(this->style); text->layout.show(g, pbox); } } - for ( SPObject *o = ft->firstChild() ; o ; o = o->getNext() ) { + for ( SPObject *o = this->firstChild() ; o ; o = o->getNext() ) { if (SP_IS_FLOWREGION(o)) { region = o; break; @@ -188,36 +156,33 @@ void CFlowtext::modified(unsigned int flags) { } } -void CFlowtext::build(SPDocument* doc, Inkscape::XML::Node* repr) { - SPFlowtext* object = this->spflowtext; - - object->_requireSVGVersion(Inkscape::Version(1, 2)); +void SPFlowtext::build(SPDocument* doc, Inkscape::XML::Node* repr) { + this->_requireSVGVersion(Inkscape::Version(1, 2)); CItem::build(doc, repr); - object->readAttr( "inkscape:layoutOptions" ); // must happen after css has been read + this->readAttr( "inkscape:layoutOptions" ); // must happen after css has been read } -void CFlowtext::set(unsigned int key, const gchar* value) { - SPFlowtext* object = this->spflowtext; - SPFlowtext *group = (SPFlowtext *) object; - +void SPFlowtext::set(unsigned int key, const gchar* value) { switch (key) { case SP_ATTR_LAYOUT_OPTIONS: { // deprecated attribute, read for backward compatibility only //XML Tree being directly used while it shouldn't be. - SPCSSAttr *opts = sp_repr_css_attr(group->getRepr(), "inkscape:layoutOptions"); + SPCSSAttr *opts = sp_repr_css_attr(this->getRepr(), "inkscape:layoutOptions"); { gchar const *val = sp_repr_css_property(opts, "justification", NULL); - if (val != NULL && !object->style->text_align.set) { + + if (val != NULL && !this->style->text_align.set) { if ( strcmp(val, "0") == 0 || strcmp(val, "false") == 0 ) { - object->style->text_align.value = SP_CSS_TEXT_ALIGN_LEFT; + this->style->text_align.value = SP_CSS_TEXT_ALIGN_LEFT; } else { - object->style->text_align.value = SP_CSS_TEXT_ALIGN_JUSTIFY; + this->style->text_align.value = SP_CSS_TEXT_ALIGN_JUSTIFY; } - object->style->text_align.set = TRUE; - object->style->text_align.inherit = FALSE; - object->style->text_align.computed = object->style->text_align.value; + + this->style->text_align.set = TRUE; + this->style->text_align.inherit = FALSE; + this->style->text_align.computed = this->style->text_align.value; } } /* no equivalent css attribute for these two (yet) @@ -238,46 +203,52 @@ void CFlowtext::set(unsigned int key, const gchar* value) { */ { // This would probably translate to padding-left, if SPStyle had it. gchar const *val = sp_repr_css_property(opts, "par-indent", NULL); + if ( val == NULL ) { - group->par_indent = 0.0; + this->par_indent = 0.0; } else { - sp_repr_get_double((Inkscape::XML::Node*)opts, "par-indent", &group->par_indent); + sp_repr_get_double((Inkscape::XML::Node*)opts, "par-indent", &this->par_indent); } } + sp_repr_css_attr_unref(opts); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; } + default: CItem::set(key, value); break; } } -Inkscape::XML::Node* CFlowtext::write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags) { - SPFlowtext* object = this->spflowtext; - +Inkscape::XML::Node* SPFlowtext::write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags) { if ( flags & SP_OBJECT_WRITE_BUILD ) { if ( repr == NULL ) { repr = doc->createElement("svg:flowRoot"); } + 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_FLOWDIV(child) || SP_IS_FLOWPARA(child) || SP_IS_FLOWREGION(child) || SP_IS_FLOWREGIONEXCLUDE(child)) { c_repr = child->updateRepr(doc, NULL, flags); } + 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_FLOWDIV(child) || SP_IS_FLOWPARA(child) || SP_IS_FLOWREGION(child) || SP_IS_FLOWREGIONEXCLUDE(child) ) { child->updateRepr(flags); } @@ -289,91 +260,79 @@ Inkscape::XML::Node* CFlowtext::write(Inkscape::XML::Document* doc, Inkscape::XM return repr; } -Geom::OptRect CFlowtext::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { - SPFlowtext* item = this->spflowtext; - - SPFlowtext *group = SP_FLOWTEXT(item); - Geom::OptRect bbox = group->layout.bounds(transform); +Geom::OptRect SPFlowtext::bbox(Geom::Affine const &transform, SPItem::BBoxType type) { + Geom::OptRect bbox = this->layout.bounds(transform); // 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; } -void CFlowtext::print(SPPrintContext *ctx) { - SPFlowtext* item = this->spflowtext; - - SPFlowtext *group = SP_FLOWTEXT(item); +void SPFlowtext::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); } -gchar* CFlowtext::description() { - SPFlowtext* item = this->spflowtext; - - Inkscape::Text::Layout const &layout = SP_FLOWTEXT(item)->layout; +gchar* SPFlowtext::description() { + Inkscape::Text::Layout const &layout = SP_FLOWTEXT(this)->layout; int const nChars = layout.iteratorToCharIndex(layout.end()); char const *trunc = (layout.inputTruncated()) ? _(" [truncated]") : ""; - if (SP_FLOWTEXT(item)->has_internal_frame()) { + if (SP_FLOWTEXT(this)->has_internal_frame()) { return g_strdup_printf(ngettext("<b>Flowed text</b> (%d character%s)", "<b>Flowed text</b> (%d characters%s)", nChars), nChars, trunc); } else { return g_strdup_printf(ngettext("<b>Linked flowed text</b> (%d character%s)", "<b>Linked flowed text</b> (%d characters%s)", nChars), nChars, trunc); } } -void CFlowtext::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) { - SPFlowtext* item = this->spflowtext; - +void SPFlowtext::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((SPItem *) 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)); } } } } -Inkscape::DrawingItem* CFlowtext::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { - SPFlowtext* item = this->spflowtext; - - SPFlowtext *group = (SPFlowtext *) item; +Inkscape::DrawingItem* SPFlowtext::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { Inkscape::DrawingGroup *flowed = new Inkscape::DrawingGroup(drawing); flowed->setPickChildren(false); - flowed->setStyle(group->style); + flowed->setStyle(this->style); // pass the bbox of the flowtext object as paintbox (used for paintserver fills) - Geom::OptRect bbox = group->geometricBounds(); - group->layout.show(flowed, bbox); + Geom::OptRect bbox = this->geometricBounds(); + this->layout.show(flowed, bbox); return flowed; } -void CFlowtext::hide(unsigned int key) { +void SPFlowtext::hide(unsigned int key) { CItem::hide(key); } - /* * */ - void SPFlowtext::_buildLayoutInput(SPObject *root, Shape const *exclusion_shape, std::list<Shape> *shapes, SPObject **pending_line_break_object) { Inkscape::Text::Layout::OptionalTextTagAttrs pi; @@ -446,13 +405,14 @@ void SPFlowtext::_buildLayoutInput(SPObject *root, Shape const *exclusion_shape, Shape* SPFlowtext::_buildExclusionShape() const { - Shape *shape = new Shape; - Shape *shape_temp = new Shape; + Shape *shape = new Shape(); + Shape *shape_temp = new Shape(); for (SPObject *child = children ; child ; child = child->getNext() ) { // RH: is it right that this shouldn't be recursive? if ( SP_IS_FLOWREGIONEXCLUDE(child) ) { SPFlowregionExclude *c_child = SP_FLOWREGIONEXCLUDE(child); + if ( c_child->computed && c_child->computed->hasEdges() ) { if (shape->hasEdges()) { shape_temp->Booleen(shape, c_child->computed, bool_op_union); @@ -463,7 +423,9 @@ Shape* SPFlowtext::_buildExclusionShape() const } } } + delete shape_temp; + return shape; } |
