The branch, str-metrics, has been updated.

- Log -----------------------------------------------------------------

commit df57a9a3f74e25e7a1e03bcdc08f7ebb33c1c76e
Author: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date:   Fri Oct 18 11:42:26 2013 +0200

    Some fixes related to RTL text
    
     * rewrite Row::reverseRTL so that it works in RTL paragraphs with mixed 
LTR/RTL text;
    
     * fix handling of boundary situations in Row::Elements::x2pos;
    
     * fix handling of boundary situations in TextMetrics::getColumnNearX;
    
     * make sure to always use Font::isVisibleRightToLeft instead of 
Font::isRightToLeft;
    
     * in cursorX, return the old pixel value when KEEP_OLD_METRICS_CODE is 
true;
    
     * Improve debug messages.

diff --git a/00README_STR_METRICS_BRANCH b/00README_STR_METRICS_BRANCH
index 18c68ca..e38d4b6 100644
--- a/00README_STR_METRICS_BRANCH
+++ b/00README_STR_METRICS_BRANCH
@@ -24,21 +24,26 @@ What is done:
   useless workarounds which disable kerning and ligatures.
 
 
-Next steps needed:
+Next steps:
 
 * check what happens with arabic and/or hebrew text. There may be some
   problems related to compose characters. I suspect that some code is
   needed in FontMetrics::width.
 
-Next possible steps:
-
 * Get rid of old code in cursorX and getColumnNearX; it has been
   kept for comparison purpose, guarded with KEEP_OLD_METRICS_CODE in
   order to check computations.
 
+* rename getColumnNearX to getPosNearX or x2pos (and change code
+  accordingly). It does not make sense to return a position relative
+  to the start of row, since nobody needs this.
+
 * Re-implement row painting using row elements. This is not difficult
   in principle, but the code is intricate and needs some careful
-  analysis.
+  analysis. First thing that needs to be done is to break row elements
+  with the same criterions. Currently TextMetrics::breakRow does not
+  consider on-the-fly spellchecking and selection changes, but it is
+  not clear to me that it is required.
 
 * Profile and see how performance can be improved.
 
@@ -56,4 +61,7 @@ Other differences (aka real bugs)
 
 * there are still difference in what breaks words. In particular,
   RowPainter breaks strings at: selection end, spellchecking
-  extremity.
+  extremities.
+
+* when clicking in the right margin, GetColumnNearX does not return
+  the same value as before.
diff --git a/src/Row.cpp b/src/Row.cpp
index d784979..d074d73 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -64,27 +64,26 @@ pos_type Row::Element::x2pos(double &x, bool const low) 
const
        FontMetrics const & fm = theFontMetrics(font);
        double last_w = 0;
        double w = 0;
-       size_t i = 1;
+       size_t i = 0;
        // non-STRING element only contain one position
        if (type != STRING) {
-               i = 0;
                w = width();
        } else {
                // FIXME: implement dichotomy search?
-               for ( ; i <= str.size() ; ++i) {
+               for ( ; i < str.size() ; ++i) {
                        last_w = w;
-                       w = fm.width(str.substr(0,i));
-                       if (w > x2) {
-                               --i;
+                       w = fm.width(str.substr(0, i + 1));
+                       if (w > x2)
                                break;
-                       }
                }
                // if (i == str.size())
                //      lyxerr << " NOT FOUND ";
        }
 
+       if (i == str.size())
+               x2 = w;
        // round to the closest side
-       if (!low && (x2 - last_w > w - x2)) {
+       else if (!low && (x2 - last_w > w - x2)) {
                x2 = w;
                ++i;
        } else
@@ -214,6 +213,7 @@ ostream & operator<<(ostream & os, Row const & row)
        os << " pos: " << row.pos_ << " end: " << row.end_
           << " x: " << row.x
           << " width: " << row.dim_.wid
+          << " right_margin: " << row.right_margin
           << " ascent: " << row.dim_.asc
           << " descent: " << row.dim_.des
           << " separator: " << row.separator
@@ -382,24 +382,25 @@ void Row::shorten_if_needed(pos_type const keep, int 
const w)
 }
 
 
-void Row::reverseRTL()
+void Row::reverseRTL(bool const rtl_par)
 {
        pos_type i = 0;
        pos_type const end = elements_.size();
        while (i < end) {
-               // skip LtR elements
-               while (i < end && !elements_[i].font.isRightToLeft())
-                       ++i;
-               if (i >= end)
-                       break;
-
-               // look for a RTL sequence
+               // gather a sequence of elements with the same direction
+               bool const rtl = elements_[i].font.isVisibleRightToLeft();
                pos_type j = i;
-               while (j < end && elements_[j].font.isRightToLeft())
+               while (j < end && elements_[j].font.isVisibleRightToLeft() == 
rtl)
                        ++j;
-               reverse(elements_.begin() + i, elements_.begin() + j);
+               // if the direction is not the same as the paragraph
+               // direction, the sequence has to be reverted.
+               if (rtl != rtl_par)
+                       reverse(elements_.begin() + i, elements_.begin() + j);
                i = j;
        }
+       // If the paragraph itself is RTL, reverse everything
+       if (rtl_par)
+               reverse(elements_.begin(), elements_.end());
 }
 
 } // namespace lyx
diff --git a/src/Row.h b/src/Row.h
index 4f2bd74..0a45aa0 100644
--- a/src/Row.h
+++ b/src/Row.h
@@ -186,6 +186,10 @@ public:
        ///
        bool empty() const { return elements_.empty(); }
        ///
+       Element & front() { return elements_.front(); }
+       ///
+       Element const & front() const { return elements_.front(); }
+       ///
        Element & back() { return elements_.back(); }
        ///
        Element const & back() const { return elements_.back(); }
@@ -212,7 +216,7 @@ public:
         * Find sequences of right-to-left elements and reverse them.
         * This should be called once the row is completely built.
         */
-       void reverseRTL();
+       void reverseRTL(bool rtl_par);
 
        friend std::ostream & operator<<(std::ostream & os, Row const & row);
 
diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp
index 8684625..7192d1e 100644
--- a/src/TextMetrics.cpp
+++ b/src/TextMetrics.cpp
@@ -15,7 +15,7 @@
  * Full author contact details are available in file CREDITS.
  */
 
-//#define KEEP_OLD_METRICS_CODE 1
+#define KEEP_OLD_METRICS_CODE 1
 
 #include <config.h>
 
@@ -810,8 +810,8 @@ void TextMetrics::breakRow(Row & row, int const 
right_margin, pit_type const pit
        int const width = max_width_ - right_margin;
        pos_type const body_pos = par.beginOfBody();
        row.clear();
-       row.dimension().wid = leftMargin(max_width_, pit, pos);
-       row.x = row.width();
+       row.x = leftMargin(max_width_, pit, pos);
+       row.dimension().wid = row.x;
        row.right_margin = right_margin;
 
        if (pos >= end || row.width() > width) {
@@ -929,7 +929,7 @@ void TextMetrics::breakRow(Row & row, int const 
right_margin, pit_type const pit
                row.pop_back();
 
        // make sure that the RTL elements are in reverse ordering
-       row.reverseRTL();
+       row.reverseRTL(text_->isRTL(par));
 
        row.dimension().wid += right_margin;
 }
@@ -1130,11 +1130,16 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit,
 
        pos_type pos = row.pos();
        boundary = false;
-       if (row.x >= x || row.empty())
+       if (row.empty())
                x = row.x;
-       else if (x >= row.width() - row.right_margin) {
+       else if (x < row.x) {
+               pos = row.front().font.isVisibleRightToLeft() ?
+                       row.front().endpos : row.front().pos;
+               x = row.x;
+       } else if (x > row.width() - row.right_margin) {
+               pos = row.back().font.isVisibleRightToLeft() ?
+                       row.back().pos : row.back().endpos;
                x = row.width() - row.right_margin;
-               pos = row.back().endpos;
        } else {
                double w = row.x;
                Row::const_iterator cit = row.begin();
@@ -1296,7 +1301,7 @@ pos_type TextMetrics::getColumnNearX(pit_type const pit,
 
        if (abs(x2 - x) > 0.1 || boundary != boundary
            || c != pos) {
-               lyxerr << "getColumnNearX: new=(x=" << x - xo << ", b=" << 
boundary << ", p=" << pos << "), "
+               lyxerr << "getColumnNearX(" << x_orig << "): new=(x=" << x - xo 
<< ", b=" << boundary << ", p=" << pos << "), "
                       << "old=(x=" << x2 - xo << ", b=" << boundary2 << ", p=" 
<< c << "), " << row;
        }
 
@@ -1625,7 +1630,7 @@ int TextMetrics::cursorX(CursorSlice const & sl,
        int const boundary_corr = (boundary && pos) ? -1 : 0;
 
        if (row.empty()
-           || (row.begin()->font.isRightToLeft()
+           || (row.begin()->font.isVisibleRightToLeft()
                && pos == row.begin()->endpos))
                return int(x);
 
@@ -1640,12 +1645,13 @@ int TextMetrics::cursorX(CursorSlice const & sl,
        }
 
        if (cit == row.end()
-           && (row.back().font.isRightToLeft() || pos != row.back().endpos))
-               lyxerr << "NOT FOUND!"
-                      << "pos=" << pos << "(" << boundary_corr << ")" << "\n"
-                      << row;
+           && (row.back().font.isVisibleRightToLeft() || pos != 
row.back().endpos))
+               LYXERR0("cursorX(" << pos - boundary_corr
+                       << ", " << boundary_corr << "): NOT FOUND! " << row);
 
-#ifdef KEEP_OLD_METRICS_CODE
+#ifndef KEEP_OLD_METRICS_CODE
+       return int(x);
+#else
        Paragraph const & par = text_->paragraphs()[pit];
 
        // Correct position in front of big insets
@@ -1782,19 +1788,17 @@ int TextMetrics::cursorX(CursorSlice const & sl,
        }
 
        if (abs(x2 - x) > 0.01) {
-               lyxerr << "cursorX: x2=" << x2 << ", x=" << x;
+               lyxerr << "cursorX(" << pos - boundary_corr << ", " << 
boundary_corr
+                      << "): old=" << x2 << ", new=" << x;
                if (cit == row.end())
-                       lyxerr << "Element not found for "
-                              << pos - boundary_corr << "(" << boundary_corr 
<< ")";
+                       lyxerr << "Element not found\n";
                else
-                       lyxerr << " in [" << cit->pos << "/"
-                              << pos - boundary_corr << "(" << boundary_corr 
<< ")"
-                              << "/" << cit->endpos << "] of " << *cit << "\n";
+                       lyxerr << " found in " << *cit << "\n";
                lyxerr << row <<endl;
        }
-#endif
 
-       return int(x);
+       return int(x2);
+#endif
 }
 
 

-----------------------------------------------------------------------

Summary of changes:
 00README_STR_METRICS_BRANCH |   18 +++++++++++----
 src/Row.cpp                 |   37 +++++++++++++++++----------------
 src/Row.h                   |    6 ++++-
 src/TextMetrics.cpp         |   48 +++++++++++++++++++++++-------------------
 4 files changed, 63 insertions(+), 46 deletions(-)


hooks/post-receive
-- 
Repository for new features

Reply via email to