Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
    • Switch to GitLab Next
  • Sign in / Register
  • inkscape inkscape
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 1,526
    • Issues 1,526
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 135
    • Merge requests 135
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • External wiki
    • External wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar

Scheduled maintenance on the database layer will take place on 2022-07-02. We expect GitLab.com to be unavailable for up to 2 hours starting from 06:00 UTC. Kindly follow our status page for updates and read more in our blog post.

  • Inkscape
  • inkscapeinkscape
  • Merge requests
  • !3537

Fix multiline vertical text positioning in browsers.

  • Review changes

  • Download
  • Email patches
  • Plain diff
Merged Nathan Lee requested to merge nathanal/inkscape:inkscape1227_2 into master Sep 26, 2021
  • Overview 6
  • Commits 2
  • Pipelines 9
  • Changes 5

Fix #1227 (closed)

This solution assumes that we should modify the layout so that public functions return x/y values taking this into account.

~~Note: one undocumented change, when Alignment == NONE in chunkAnchorPoint, we no longer add chunk_width * 0.5 to the anchor point's x value. That now matches _getChunkLeftWithAlignment~~Update: looking into uses of NONE, I think Alignment NONE might occur when text is empty, in which case there is no change in behavior.

I'm not sure this is the right approach. An alternate approach that doesn't touch Layout-TNG:

diff --git a/src/object/sp-text.cpp b/src/object/sp-text.cpp
index 935446c54a..6c81c06314 100644
--- a/src/object/sp-text.cpp
+++ b/src/object/sp-text.cpp
@@ -893,6 +893,9 @@ void SPText::rebuildLayout()
                  && tspan->attributes.singleXYCoordinates() ) {
                 Inkscape::Text::Layout::iterator iter = layout.sourceToIterator(tspan);
                 Geom::Point anchor_point = layout.chunkAnchorPoint(iter);
+                if (!is_horizontal()) {
+                    std::swap(anchor_point[Geom::X], anchor_point[Geom::Y]);
+                }
                 tspan->attributes.setFirstXY(anchor_point);
                 // repr needs to be updated but if we do it here we get a loop.
             }

and

diff --git a/src/object/sp-flowtext.cpp b/src/object/sp-flowtext.cpp
index af675eeeb4..1238254634 100644
--- a/src/object/sp-flowtext.cpp
+++ b/src/object/sp-flowtext.cpp
@@ -496,11 +496,16 @@ Inkscape::XML::Node *SPFlowtext::getAsText()
         return nullptr;
     }
 
+    bool horizontal = (style->writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB || style->writing_mode.computed == SP_CSS_WRITING_MODE_RL_TB);
+
     Inkscape::XML::Document *xml_doc = this->document->getReprDoc();
     Inkscape::XML::Node *repr = xml_doc->createElement("svg:text");
     repr->setAttribute("xml:space", "preserve");
     repr->setAttribute("style", this->getRepr()->attribute("style"));
     Geom::Point anchor_point = this->layout.characterAnchorPoint(this->layout.begin());
+    if (!horizontal) {
+        std::swap(anchor_point[Geom::X], anchor_point[Geom::Y]);
+    }
     repr->setAttributeSvgDouble("x", anchor_point[Geom::X]);
     repr->setAttributeSvgDouble("y", anchor_point[Geom::Y]);
 
@@ -515,6 +520,9 @@ Inkscape::XML::Node *SPFlowtext::getAsText()
 
             Inkscape::XML::Node *span_tspan = xml_doc->createElement("svg:tspan");
             Geom::Point anchor_point = this->layout.characterAnchorPoint(it);
+            if (!horizontal) {
+                std::swap(anchor_point[Geom::X], anchor_point[Geom::Y]);
+            }
             // use kerning to simulate justification and whatnot
             Inkscape::Text::Layout::iterator it_span_end = it;
             it_span_end.nextStartOfSpan();
Edited Oct 01, 2021 by Nathan Lee
Assignee
Assign to
Reviewer
Request review from
Time tracking
Source branch: inkscape1227_2