Code

Position of baseline anchor is now dependent of the text alignment
authorDiederik van Lierop <mailat-signdiedenrezidotnl>
Sun, 13 Dec 2009 13:00:22 +0000 (14:00 +0100)
committerDiederik van Lierop <mailat-signdiedenrezidotnl>
Sun, 13 Dec 2009 13:00:22 +0000 (14:00 +0100)
src/libnrtype/Layout-TNG-OutIter.cpp
src/libnrtype/Layout-TNG.h
src/selcue.cpp
src/sp-text.cpp

index 0fc061bfc38f0c33f763edd37fc3a912ae634b80..f4e8e4031f6cc84cc958e4324d474663dc136fd1 100644 (file)
@@ -221,6 +221,31 @@ Geom::Point Layout::characterAnchorPoint(iterator const &it) const
     }
 }
 
+boost::optional<Geom::Point> Layout::baselineAnchorPoint() const
+{
+    iterator pos = this->begin();
+    Geom::Point left_pt = this->characterAnchorPoint(pos);
+    pos.thisEndOfLine();
+    Geom::Point right_pt = this->characterAnchorPoint(pos);
+    Geom::Point mid_pt = (left_pt + right_pt)/2;
+
+    switch (this->paragraphAlignment(pos)) {
+        case LEFT:
+        case FULL:
+            return left_pt;
+            break;
+        case CENTER:
+            return mid_pt;
+            break;
+        case RIGHT:
+            return right_pt;
+            break;
+        default:
+            return boost::optional<Geom::Point>();
+            break;
+    }
+}
+
 Geom::Point Layout::chunkAnchorPoint(iterator const &it) const
 {
     unsigned chunk_index;
@@ -705,7 +730,7 @@ bool Layout::iterator::nextLineCursor(int n)
     unsigned line_index = _parent_layout->_characters[_char_index].chunk(_parent_layout).in_line;
     if (line_index == _parent_layout->_lines.size() - 1) 
         return false; // nowhere to go
-               else
+    else
         n = MIN (n, static_cast<int>(_parent_layout->_lines.size() - 1 - line_index));
     if (_parent_layout->_lines[line_index + n].in_shape != _parent_layout->_lines[line_index].in_shape) {
         // switching between shapes: adjust the stored x to compensate
@@ -728,7 +753,7 @@ bool Layout::iterator::prevLineCursor(int n)
         line_index = _parent_layout->_characters[_char_index].chunk(_parent_layout).in_line;
     if (line_index == 0) 
         return false; // nowhere to go
-               else 
+    else
         n = MIN (n, static_cast<int>(line_index));
     if (_parent_layout->_lines[line_index - n].in_shape != _parent_layout->_lines[line_index].in_shape) {
         // switching between shapes: adjust the stored x to compensate
index 19680b140a56a0cfc2c7b3ba9fea7c2c400c6118..8cd26edefd7aa0e063e49c9ba4a484a307652348 100644 (file)
@@ -480,6 +480,10 @@ public:
     /** For latin text, the left side of the character, on the baseline */
     Geom::Point characterAnchorPoint(iterator const &it) const;
 
+    /** For left aligned text, the leftmost end of the baseline
+    For rightmost text, the rightmost... you probably got it by now ;-)*/
+    boost::optional<Geom::Point> baselineAnchorPoint() const;
+
     /** This is that value to apply to the x,y attributes of tspan role=line
     elements, and hence it takes alignment into account. */
     Geom::Point chunkAnchorPoint(iterator const &it) const;
index 714daaa7ea980da371a87faa0c8d07d09fd5c8ae..8756524dd6b37c01078f93f0c96ae3d82414057d 100644 (file)
@@ -181,18 +181,20 @@ void Inkscape::SelCue::_newTextBaselines()
         if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { // visualize baseline
             Inkscape::Text::Layout const *layout = te_get_layout(item);
             if (layout != NULL && layout->outputExists()) {
-                Geom::Point a = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item);
-                baseline_point = sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRL,
-                                                    "mode", SP_CTRL_MODE_XOR,
-                                                    "size", 4.0,
-                                                    "filled", 0,
-                                                    "stroked", 1,
-                                                    "stroke_color", 0x000000ff,
-                                                    NULL);
-
-                sp_canvas_item_show(baseline_point);
-                SP_CTRL(baseline_point)->moveto(a);
-                sp_canvas_item_move_to_z(baseline_point, 0);
+                boost::optional<Geom::Point> pt = layout->baselineAnchorPoint();
+                if (pt) {
+                    baseline_point = sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRL,
+                        "mode", SP_CTRL_MODE_XOR,
+                        "size", 4.0,
+                        "filled", 0,
+                        "stroked", 1,
+                        "stroke_color", 0x000000ff,
+                        NULL);
+
+                    sp_canvas_item_show(baseline_point);
+                    SP_CTRL(baseline_point)->moveto((*pt) * sp_item_i2d_affine(item));
+                    sp_canvas_item_move_to_z(baseline_point, 0);
+                }
             }
         }
 
index 87c67c646184e847aa74dc7a4b000d6f50a05d89..423922b80c991a11207973b3ab800b1185a18ee3 100644 (file)
@@ -431,30 +431,13 @@ sp_text_description(SPItem *item)
 static void sp_text_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/)
 {
     // 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)
+    // of this point depending on the text alignment (left vs. right)
     Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) item);
-    if(layout != NULL) {
-        int type = target ? int(Inkscape::SNAPTARGET_TEXT_BASELINE) : int(Inkscape::SNAPSOURCE_TEXT_BASELINE);
-
-        Inkscape::Text::Layout::iterator pos = layout->begin();
-        Inkscape::Text::Layout::Alignment text_alignment = layout->paragraphAlignment(pos);
-
-        Geom::Point left_pt = layout->characterAnchorPoint(pos) * sp_item_i2d_affine(item);
-               pos.thisEndOfLine();
-               Geom::Point right_pt = layout->characterAnchorPoint(pos) * sp_item_i2d_affine(item);
-               Geom::Point mid_pt = (left_pt + right_pt)/2;
-
-        switch (text_alignment) {
-                       case Inkscape::Text::Layout::LEFT:
-                       case Inkscape::Text::Layout::FULL:
-                               p.push_back(std::make_pair(left_pt, type));
-                               break;
-                       case Inkscape::Text::Layout::CENTER:
-                               p.push_back(std::make_pair(mid_pt, type));
-                               break;
-                       default: //RIGHT
-                               p.push_back(std::make_pair(right_pt, type));
-                               break;
+    if (layout != NULL && layout->outputExists()) {
+        boost::optional<Geom::Point> pt = layout->baselineAnchorPoint();
+        if (pt) {
+            int type = target ? int(Inkscape::SNAPTARGET_TEXT_BASELINE) : int(Inkscape::SNAPSOURCE_TEXT_BASELINE);
+            p.push_back(std::make_pair((*pt) * sp_item_i2d_affine(item), type));
         }
     }
 }