From 59d17755b0c2baf4018d3ed687c7dd4df77f0c40 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sun, 13 Dec 2009 14:00:22 +0100 Subject: [PATCH] Position of baseline anchor is now dependent of the text alignment --- src/libnrtype/Layout-TNG-OutIter.cpp | 29 ++++++++++++++++++++++++++-- src/libnrtype/Layout-TNG.h | 4 ++++ src/selcue.cpp | 26 +++++++++++++------------ src/sp-text.cpp | 29 ++++++---------------------- 4 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 0fc061bfc..f4e8e4031 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -221,6 +221,31 @@ Geom::Point Layout::characterAnchorPoint(iterator const &it) const } } +boost::optional 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(); + 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(_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(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 diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 19680b140..8cd26edef 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -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 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; diff --git a/src/selcue.cpp b/src/selcue.cpp index 714daaa7e..8756524dd 100644 --- a/src/selcue.cpp +++ b/src/selcue.cpp @@ -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 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); + } } } diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 87c67c646..423922b80 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -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 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)); } } } -- 2.30.2