From b6d303d11e572d8888d29c44e11d06d256821a03 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 21 Dec 2014 15:29:02 +0100 Subject: Implement rendering for 'context-fill' and 'context-stroke' (text not handled yet). (bzr r13807) --- src/sp-text.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/sp-text.cpp') diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 8922d3c73..a35a58bd9 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -195,7 +195,7 @@ void SPText::update(SPCtx *ctx, guint flags) { for (SPItemView* v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast(v->arenaitem); this->_clearFlow(g); - g->setStyle(this->style); + g->setStyle(this->style, this->parent->style); // pass the bbox of the this this as paintbox (used for paintserver fills) this->layout.show(g, paintbox); } @@ -221,7 +221,7 @@ void SPText::modified(guint flags) { for (SPItemView* v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast(v->arenaitem); this->_clearFlow(g); - g->setStyle(this->style); + g->setStyle(this->style, this->parent->style); this->layout.show(g, paintbox); } } @@ -333,7 +333,7 @@ Geom::OptRect SPText::bbox(Geom::Affine const &transform, SPItem::BBoxType type) Inkscape::DrawingItem* SPText::show(Inkscape::Drawing &drawing, unsigned /*key*/, unsigned /*flags*/) { Inkscape::DrawingGroup *flowed = new Inkscape::DrawingGroup(drawing); flowed->setPickChildren(false); - flowed->setStyle(this->style); + flowed->setStyle(this->style, this->parent->style); // pass the bbox of the text object as paintbox (used for paintserver fills) this->layout.show(flowed, this->geometricBounds()); -- cgit v1.2.3 From 6c78ab7deeea3b32791437ade35e8911e7c73c8e Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 21 Dec 2014 14:58:38 -0500 Subject: Purge sp_desktop_namedview in favor of SPDesktop::getNamedView (bzr r13810) --- src/sp-text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/sp-text.cpp') diff --git a/src/sp-text.cpp b/src/sp-text.cpp index a35a58bd9..1cd690729 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -38,7 +38,7 @@ #include "attributes.h" #include "document.h" #include "preferences.h" -#include "desktop-handles.h" +#include "desktop.h" #include "sp-namedview.h" #include "style.h" #include "inkscape.h" @@ -362,7 +362,7 @@ gchar* SPText::description() const { char *n = xml_quote_strdup( style->font_family.value ); Inkscape::Util::Quantity q = Inkscape::Util::Quantity(style->font_size.computed, "px"); - GString *xs = g_string_new(q.string(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->display_units).c_str()); + GString *xs = g_string_new(q.string(SP_ACTIVE_DESKTOP->getNamedView()->display_units).c_str()); char const *trunc = ""; Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) this); -- cgit v1.2.3 From 374aa610cb550cf7dcd283ca93ad0ad844732d32 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 5 Jan 2015 11:17:51 +0100 Subject: Implement SVG 1.1 textLength and textAdjust attributes. Code from Dmitry Kirsanov (buliabyak). (bzr r13839) --- src/sp-text.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 6 deletions(-) (limited to 'src/sp-text.cpp') diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 1cd690729..755a4f769 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -81,6 +81,10 @@ void SPText::build(SPDocument *doc, Inkscape::XML::Node *repr) { this->readAttr( "dy" ); this->readAttr( "rotate" ); + // textLength and friends + this->readAttr( "textLength" ); + this->readAttr( "lengthAdjust" ); + // SVG 2 Auto wrapped text this->readAttr( "width" ); this->readAttr( "height" ); @@ -403,6 +407,10 @@ Geom::Affine SPText::set_transform(Geom::Affine const &xform) { } } + // we cannot optimize text with textLength because it may show different size than specified + if (this->attributes.getTextLength()->_set) + return xform; + /* This function takes care of scaling & translation only, we return whatever parts we can't handle. */ @@ -466,6 +474,13 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio if (SP_IS_TEXT(root)) { SP_TEXT(root)->attributes.mergeInto(&optional_attrs, parent_optional_attrs, parent_attrs_offset, true, true); + if (SP_TEXT(root)->attributes.getTextLength()->_set) { // set textLength on the entire layout, see note in TNG-Layout.h + layout.textLength._set = true; + layout.textLength.value = SP_TEXT(root)->attributes.getTextLength()->value; + layout.textLength.computed = SP_TEXT(root)->attributes.getTextLength()->computed; + layout.textLength.unit = SP_TEXT(root)->attributes.getTextLength()->unit; + layout.lengthAdjust = (Inkscape::Text::Layout::LengthAdjust) SP_TEXT(root)->attributes.getLengthAdjust(); + } } else if (SP_IS_TSPAN(root)) { SPTSpan *tspan = SP_TSPAN(root); @@ -611,6 +626,8 @@ void TextTagAttributes::readFrom(Inkscape::XML::Node const *node) readSingleAttribute(SP_ATTR_DX, node->attribute("dx")); readSingleAttribute(SP_ATTR_DY, node->attribute("dy")); readSingleAttribute(SP_ATTR_ROTATE, node->attribute("rotate")); + readSingleAttribute(SP_ATTR_TEXTLENGTH, node->attribute("textLength")); + readSingleAttribute(SP_ATTR_LENGTHADJUST, node->attribute("lengthAdjust")); } bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) @@ -622,6 +639,16 @@ bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) case SP_ATTR_DX: attr_vector = &attributes.dx; break; case SP_ATTR_DY: attr_vector = &attributes.dy; break; case SP_ATTR_ROTATE: attr_vector = &attributes.rotate; break; + case SP_ATTR_TEXTLENGTH: + attributes.textLength.readOrUnset(value); + return true; + break; + case SP_ATTR_LENGTHADJUST: + attributes.lengthAdjust = (value && !strcmp(value, "spacingAndGlyphs")? + Inkscape::Text::Layout::LENGTHADJUST_SPACINGANDGLYPHS : + Inkscape::Text::Layout::LENGTHADJUST_SPACING); // default is "spacing" + return true; + break; default: return false; } @@ -632,14 +659,34 @@ bool TextTagAttributes::readSingleAttribute(unsigned key, gchar const *value) void TextTagAttributes::writeTo(Inkscape::XML::Node *node) const { - writeSingleAttribute(node, "x", attributes.x); - writeSingleAttribute(node, "y", attributes.y); - writeSingleAttribute(node, "dx", attributes.dx); - writeSingleAttribute(node, "dy", attributes.dy); - writeSingleAttribute(node, "rotate", attributes.rotate); + writeSingleAttributeVector(node, "x", attributes.x); + writeSingleAttributeVector(node, "y", attributes.y); + writeSingleAttributeVector(node, "dx", attributes.dx); + writeSingleAttributeVector(node, "dy", attributes.dy); + writeSingleAttributeVector(node, "rotate", attributes.rotate); + + writeSingleAttributeLength(node, "textLength", attributes.textLength); + + if (attributes.textLength._set) { + if (attributes.lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACING) { + node->setAttribute("lengthAdjust", "spacing"); + } else if (attributes.lengthAdjust == Inkscape::Text::Layout::LENGTHADJUST_SPACINGANDGLYPHS) { + node->setAttribute("lengthAdjust", "spacingAndGlyphs"); + } + } +} + +void TextTagAttributes::writeSingleAttributeLength(Inkscape::XML::Node *node, gchar const *key, const SVGLength &length) +{ + if (length._set) { + gchar single_value_string[32]; + g_ascii_formatd(single_value_string, sizeof (single_value_string), "%.8g", length.computed); + node->setAttribute(key, single_value_string); + } else + node->setAttribute(key, NULL); } -void TextTagAttributes::writeSingleAttribute(Inkscape::XML::Node *node, gchar const *key, std::vector const &attr_vector) +void TextTagAttributes::writeSingleAttributeVector(Inkscape::XML::Node *node, gchar const *key, std::vector const &attr_vector) { if (attr_vector.empty()) node->setAttribute(key, NULL); @@ -697,6 +744,13 @@ void TextTagAttributes::mergeInto(Inkscape::Text::Layout::OptionalTextTagAttrs * mergeSingleAttribute(&output->dx, parent_attrs.dx, parent_attrs_offset, copy_dxdyrotate ? &attributes.dx : NULL); mergeSingleAttribute(&output->dy, parent_attrs.dy, parent_attrs_offset, copy_dxdyrotate ? &attributes.dy : NULL); mergeSingleAttribute(&output->rotate, parent_attrs.rotate, parent_attrs_offset, copy_dxdyrotate ? &attributes.rotate : NULL); + if (attributes.textLength._set) { // only from current node, this is not inherited from parent + output->textLength.value = attributes.textLength.value; + output->textLength.computed = attributes.textLength.computed; + output->textLength.unit = attributes.textLength.unit; + output->textLength._set = attributes.textLength._set; + output->lengthAdjust = attributes.lengthAdjust; + } } void TextTagAttributes::mergeSingleAttribute(std::vector *output_list, std::vector const &parent_list, unsigned parent_offset, std::vector const *overlay_list) -- cgit v1.2.3 From df941b780ca42ea1cd48835694e23a40c978da37 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 16 Jan 2015 09:31:31 +0100 Subject: Start to implement SVG 2 text in a shape. (bzr r13857) --- src/sp-text.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 5 deletions(-) (limited to 'src/sp-text.cpp') diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 755a4f769..fdf57577c 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -57,6 +57,12 @@ #include "sp-factory.h" +// For SVG 2 text flow +#include "livarot/Path.h" +#include "livarot/Shape.h" +#include "sp-shape.h" +#include "display/curve.h" + namespace { SPObject* createText() { return new SPText(); @@ -472,6 +478,49 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio int child_attrs_offset = 0; Inkscape::Text::Layout::OptionalTextTagAttrs optional_attrs; + // Test SVG 2 text in shape implementation + // To do: follow SPItem clip_ref/mask_ref code + if (style->shape_inside.set ) { + + // Extract out id + Glib::ustring shape_url = style->shape_inside.value; + if ( shape_url.compare(0,5,"url(#") != 0 || shape_url.compare(shape_url.size()-1,1,")") != 0 ){ + std::cerr << "SPText::_buildLayoutInput(): Invalid shape-inside value: " << shape_url << std::endl; + } else { + shape_url.erase(0,5); + shape_url.erase(shape_url.size()-1,1); + // std::cout << "SPText::_buildLayoutInput(): shape-inside: " << shape_url << std::endl; + SPShape *shape = dynamic_cast(document->getObjectById( shape_url )); + if ( shape ) { + + // This code adapted from sp-flowregion.cpp: GetDest() + if (!(shape->_curve)) { + shape->set_shape(); + } + SPCurve *curve = shape->getCurve(); + + if ( curve ) { + Path *temp = new Path; + temp->LoadPathVector( curve->get_pathvector(), shape->transform, true ); + temp->Convert( 0.25 ); // Convert to polyline + Shape* sh = new Shape; + temp->Fill( sh, 0 ); + // for( unsigned i = 0; i < temp->pts.size(); ++i ) { + // std::cout << " ........ " << temp->pts[i].p << std::endl; + // } + // std::cout << " ...... shape: " << sh->numberOfPoints() << std::endl; + Shape *uncross = new Shape; + uncross->ConvertToShape( sh ); + layout.appendWrapShape( uncross ); + } else { + std::cerr << "SPText::_buildLayoutInput(): Failed to get curve." << std::endl; + } + } else { + std::cerr << "SPText::_buildLayoutInput(): Failed to find shape." << std::endl; + } + } + } + if (SP_IS_TEXT(root)) { SP_TEXT(root)->attributes.mergeInto(&optional_attrs, parent_optional_attrs, parent_attrs_offset, true, true); if (SP_TEXT(root)->attributes.getTextLength()->_set) { // set textLength on the entire layout, see note in TNG-Layout.h @@ -503,7 +552,7 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio child_attrs_offset = parent_attrs_offset; } - if (SP_IS_TSPAN(root)) + if (SP_IS_TSPAN(root)) { if (SP_TSPAN(root)->role != SP_TSPAN_ROLE_UNSPECIFIED) { // we need to allow the first line not to have role=line, but still set the source_cookie to the right value SPObject *prev_object = root->getPrev(); @@ -522,13 +571,17 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio // start position. Very confusing. child_attrs_offset--; } - + } + for (SPObject *child = root->firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_STRING(child)) { - Glib::ustring const &string = SP_STRING(child)->string; + SPString *str = dynamic_cast(child); + if (str) { + Glib::ustring const &string = str->string; + // std::cout << " Appending: " << string << std::endl; layout.appendText(string, root->style, child, &optional_attrs, child_attrs_offset + length); length += string.length(); - } /*XML Tree being directly used here while it shouldn't be.*/ else if (!sp_repr_is_meta_element(child->getRepr())) { + } else if (!sp_repr_is_meta_element(child->getRepr())) { + /* ^^^^ XML Tree being directly used here while it shouldn't be.*/ length += _buildLayoutInput(child, optional_attrs, child_attrs_offset + length, in_textpath); } } -- cgit v1.2.3 From f020705fc609f8718b57b9540e7fc2b2dc59b2fe Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 16 Jan 2015 15:47:14 +0100 Subject: Test implementation of 'shape-padding'. (bzr r13858) --- src/sp-text.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/sp-text.cpp') diff --git a/src/sp-text.cpp b/src/sp-text.cpp index fdf57577c..e40661824 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -501,10 +501,18 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio if ( curve ) { Path *temp = new Path; + Path *padded = new Path; temp->LoadPathVector( curve->get_pathvector(), shape->transform, true ); - temp->Convert( 0.25 ); // Convert to polyline + if( style->shape_padding.set ) { + // std::cout << " padding: " << style->shape_padding.computed << std::endl; + temp->OutsideOutline ( padded, style->shape_padding.computed, join_round, butt_straight, 20.0 ); + } else { + // std::cout << " no padding" << std::endl; + padded->Copy( temp ); + } + padded->Convert( 0.25 ); // Convert to polyline Shape* sh = new Shape; - temp->Fill( sh, 0 ); + padded->Fill( sh, 0 ); // for( unsigned i = 0; i < temp->pts.size(); ++i ) { // std::cout << " ........ " << temp->pts[i].p << std::endl; // } @@ -512,6 +520,11 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio Shape *uncross = new Shape; uncross->ConvertToShape( sh ); layout.appendWrapShape( uncross ); + + delete temp; + delete padded; + delete sh; + // delete uncross; } else { std::cerr << "SPText::_buildLayoutInput(): Failed to get curve." << std::endl; } -- cgit v1.2.3