From d26076c00288c835cd67d95723c8fed4a96a3784 Mon Sep 17 00:00:00 2001 From: Nathan Lee <2431820-nathanal@users.noreply.gitlab.com> Date: Mon, 3 Jun 2019 23:38:12 +1000 Subject: [PATCH 1/2] Crashfix deleting path with invisible text on path Fixes https://gitlab.com/inkscape/inbox/issues/491 --- src/object/sp-tspan.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/object/sp-tspan.cpp b/src/object/sp-tspan.cpp index 7a0db5687d..76c9b1a3a0 100644 --- a/src/object/sp-tspan.cpp +++ b/src/object/sp-tspan.cpp @@ -482,13 +482,29 @@ void sp_textpath_to_text(SPObject *tp) SPObject *text = tp->parent; Geom::OptRect bbox = SP_ITEM(text)->geometricBounds(SP_ITEM(text)->i2doc_affine()); - + Geom::Point xy; if (!bbox) { - return; + // Text is not shown on canvas at all + // Copied from Layout::fitToPathAlign + Path *path = dynamic_cast(tp)->originalPath; + SVGLength const startOffset = dynamic_cast(tp)->startOffset; + double offset = 0.0; + if (startOffset._set) { + if (startOffset.unit == SVGLength::PERCENT) + offset = startOffset.computed * path->Length(); + else + offset = startOffset.computed; + } + int unused = 0; + Path::cut_position *cut_pos = path->CurvilignToPosition(1, &offset, unused); + Geom::Point midpoint; + Geom::Point tangent; + path->PointAndTangentAt(cut_pos[0].piece, cut_pos[0].t, midpoint, tangent); + xy = midpoint; + } else { + xy = bbox->min(); + xy *= tp->document->getDocumentScale().inverse(); // Convert to user-units. } - - Geom::Point xy = bbox->min(); - xy *= tp->document->getDocumentScale().inverse(); // Convert to user-units. // make a list of textpath children std::vector tp_reprs; -- GitLab From 91dc0a4a88c4379971252de5cec319b5f5ad1b5e Mon Sep 17 00:00:00 2001 From: Nathan Lee <2431820-nathanal@users.noreply.gitlab.com> Date: Mon, 3 Jun 2019 23:54:15 +1000 Subject: [PATCH 2/2] Change TextPath to Text positioning Uses originalPath instead of bounding-box. Make positioning consistent with text that is not visible (too long for path). --- src/object/sp-tspan.cpp | 51 +++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/src/object/sp-tspan.cpp b/src/object/sp-tspan.cpp index 76c9b1a3a0..1649367d31 100644 --- a/src/object/sp-tspan.cpp +++ b/src/object/sp-tspan.cpp @@ -480,31 +480,6 @@ SPItem *sp_textpath_get_path_item(SPTextPath *tp) void sp_textpath_to_text(SPObject *tp) { SPObject *text = tp->parent; - - Geom::OptRect bbox = SP_ITEM(text)->geometricBounds(SP_ITEM(text)->i2doc_affine()); - Geom::Point xy; - if (!bbox) { - // Text is not shown on canvas at all - // Copied from Layout::fitToPathAlign - Path *path = dynamic_cast(tp)->originalPath; - SVGLength const startOffset = dynamic_cast(tp)->startOffset; - double offset = 0.0; - if (startOffset._set) { - if (startOffset.unit == SVGLength::PERCENT) - offset = startOffset.computed * path->Length(); - else - offset = startOffset.computed; - } - int unused = 0; - Path::cut_position *cut_pos = path->CurvilignToPosition(1, &offset, unused); - Geom::Point midpoint; - Geom::Point tangent; - path->PointAndTangentAt(cut_pos[0].piece, cut_pos[0].t, midpoint, tangent); - xy = midpoint; - } else { - xy = bbox->min(); - xy *= tp->document->getDocumentScale().inverse(); // Convert to user-units. - } // make a list of textpath children std::vector tp_reprs; @@ -522,15 +497,27 @@ void sp_textpath_to_text(SPObject *tp) text->getRepr()->addChild(copy, nullptr); // fixme: copy id } + // set x/y on text (to be near where it was when on path) + // Copied from Layout::fitToPathAlign + Path *path = dynamic_cast(tp)->originalPath; + SVGLength const startOffset = dynamic_cast(tp)->startOffset; + double offset = 0.0; + if (startOffset._set) { + if (startOffset.unit == SVGLength::PERCENT) + offset = startOffset.computed * path->Length(); + else + offset = startOffset.computed; + } + int unused = 0; + Path::cut_position *cut_pos = path->CurvilignToPosition(1, &offset, unused); + Geom::Point midpoint; + Geom::Point tangent; + path->PointAndTangentAt(cut_pos[0].piece, cut_pos[0].t, midpoint, tangent); + sp_repr_set_svg_double(text->getRepr(), "x", midpoint[Geom::X]); + sp_repr_set_svg_double(text->getRepr(), "y", midpoint[Geom::Y]); + //remove textpath tp->deleteObject(); - - // set x/y on text (to be near where it was when on path) - /* fixme: Yuck, is this really the right test? */ - if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) { - sp_repr_set_svg_double(text->getRepr(), "x", xy[Geom::X]); - sp_repr_set_svg_double(text->getRepr(), "y", xy[Geom::Y]); - } } -- GitLab