From 57c3a94730ed587ac8261bd67532d2ae08c98ced Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Wed, 7 Dec 2016 12:16:41 +0100 Subject: [PATCH] Add RtL information to Row This allows to somewhat simplify the text and avoid some uses of Paragraph (in the long term, RowPainter should not have to access these things). At the same time do a small cleanup to RowPainter: rename text_metrics_ to tm_, remove pm_ and width_. --- development/PAINTING_ANALYSIS | 14 ----------- src/Cursor.cpp | 6 ++--- src/Row.cpp | 4 +++- src/Row.h | 4 ++++ src/RowPainter.cpp | 45 ++++++++++++++++------------------- src/RowPainter.h | 5 +--- src/TextMetrics.cpp | 13 +++++----- 7 files changed, 36 insertions(+), 55 deletions(-) diff --git a/development/PAINTING_ANALYSIS b/development/PAINTING_ANALYSIS index c287710ef8..e53b4b23df 100644 --- a/development/PAINTING_ANALYSIS +++ b/development/PAINTING_ANALYSIS @@ -71,10 +71,6 @@ Other changes are only clean-ups. The helper version should return a Row::Element instead of an InsetTable. -** Remember rtl status in the row object - -This will avoid to pass a Paragraph object to methods that do not need it. - ** Set inset position during metrics phase In order to do that, a no-paint drawing will be initiated after every @@ -90,16 +86,6 @@ application would do. + remove painting when not inside in drawParagraph + remove Cursor::inCoordCache? -** Use Row for MathData - -It may not be so difficult. Implement x2pos and pos2x from -the TM:cursorX and TM::getPosNearX, and use them for both text and -math. - -Will the strings display OK if drawing string-wise? - -Then it would be possible to streamline drawing with disabled painter. - ** Paint directly to screen Instead of using an intermediary pixmap. I have no idea of how diff --git a/src/Cursor.cpp b/src/Cursor.cpp index 14d4a6ae48..f22b3f1099 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -790,7 +790,7 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos) const Row::const_iterator cit = tm.findRowElement(row, pos(), boundary(), dummy); // Handle the case of empty row if (cit == row.end()) { - if (paragraph().isRTL(buffer()->params())) + if (row.isRTL()) right_pos = row.pos(); else left_pos = row.pos() - 1; @@ -864,10 +864,8 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos) const bool Cursor::posVisToNewRow(bool movingLeft) { - Paragraph const & par = paragraph(); - Buffer const & buf = *buffer(); Row const & row = textRow(); - bool par_is_LTR = !par.isRTL(buf.params()); + bool par_is_LTR = !row.isRTL(); // Inside a table, determining whether to move to the next or // previous row should be done based on the table's direction. diff --git a/src/Row.cpp b/src/Row.cpp index 53f04ddb03..eab4df51ba 100644 --- a/src/Row.cpp +++ b/src/Row.cpp @@ -164,7 +164,8 @@ Row::Row() sel_beg(-1), sel_end(-1), begin_margin_sel(false), end_margin_sel(false), changed_(false), crc_(0), - pit_(0), pos_(0), end_(0), right_boundary_(false), flushed_(false) + pit_(0), pos_(0), end_(0), + right_boundary_(false), flushed_(false), rtl_(false) {} @@ -565,6 +566,7 @@ void Row::reverseRTL(bool const rtl_par) // If the paragraph itself is RTL, reverse everything if (rtl_par) reverse(elements_.begin(), elements_.end()); + rtl_ = rtl_par; } } // namespace lyx diff --git a/src/Row.h b/src/Row.h index 961b6ebb98..695c81a95e 100644 --- a/src/Row.h +++ b/src/Row.h @@ -264,6 +264,8 @@ public: * This should be called once the row is completely built. */ void reverseRTL(bool rtl_par); + /// + bool isRTL() const { return rtl_; } friend std::ostream & operator<<(std::ostream & os, Row const & row); @@ -320,6 +322,8 @@ private: bool flushed_; /// Row dimension. Dimension dim_; + /// true when this row lives in a right-to-left paragraph + bool rtl_; }; diff --git a/src/RowPainter.cpp b/src/RowPainter.cpp index fabfcddf2a..91dfb63e4d 100644 --- a/src/RowPainter.cpp +++ b/src/RowPainter.cpp @@ -26,7 +26,6 @@ #include "Row.h" #include "MetricsInfo.h" #include "Paragraph.h" -#include "ParagraphMetrics.h" #include "ParagraphParameters.h" #include "TextMetrics.h" #include "VSpace.h" @@ -58,11 +57,11 @@ using frontend::FontMetrics; RowPainter::RowPainter(PainterInfo & pi, Text const & text, Row const & row, int x, int y) : pi_(pi), text_(text), - text_metrics_(pi_.base.bv->textMetrics(&text)), + tm_(pi_.base.bv->textMetrics(&text)), pars_(text.paragraphs()), row_(row), par_(text.paragraphs()[row.pit()]), - pm_(text_metrics_.parMetrics(row.pit())), change_(pi_.change_), - xo_(x), yo_(y), width_(text_metrics_.width()) + change_(pi_.change_), + xo_(x), yo_(y) { x_ = row_.left_margin + xo_; @@ -260,7 +259,7 @@ void RowPainter::paintChangeBar() const if (start == end || !par_.isChanged(start, end)) return; - int const height = text_metrics_.isLastRow(row_) + int const height = tm_.isLastRow(row_) ? row_.ascent() : row_.height(); @@ -280,7 +279,7 @@ void RowPainter::paintAppendix() const y += 2 * defaultRowHeight(); pi_.pain.line(1, y, 1, yo_ + row_.height(), Color_appendix); - pi_.pain.line(width_ - 2, y, width_ - 2, yo_ + row_.height(), Color_appendix); + pi_.pain.line(tm_.width() - 2, y, tm_.width() - 2, yo_ + row_.height(), Color_appendix); } @@ -292,7 +291,7 @@ void RowPainter::paintDepthBar() const return; depth_type prev_depth = 0; - if (!text_metrics_.isFirstRow(row_)) { + if (!tm_.isFirstRow(row_)) { pit_type pit2 = row_.pit(); if (row_.pos() == 0) --pit2; @@ -300,7 +299,7 @@ void RowPainter::paintDepthBar() const } depth_type next_depth = 0; - if (!text_metrics_.isLastRow(row_)) { + if (!tm_.isLastRow(row_)) { pit_type pit2 = row_.pit(); if (row_.endpos() >= pars_[pit2].size()) ++pit2; @@ -340,13 +339,13 @@ void RowPainter::paintAppendixStart(int y) const docstring const label = _("Appendix"); theFontMetrics(pb_font).rectText(label, w, a, d); - int const text_start = int(xo_ + (width_ - w) / 2); + int const text_start = int(xo_ + (tm_.width() - w) / 2); int const text_end = text_start + w; pi_.pain.rectText(text_start, y + d, label, pb_font, Color_none, Color_none); pi_.pain.line(int(xo_ + 1), y, text_start, y, Color_appendix); - pi_.pain.line(text_end, y, int(xo_ + width_ - 2), y, Color_appendix); + pi_.pain.line(text_end, y, int(xo_ + tm_.width() - 2), y, Color_appendix); } @@ -394,14 +393,13 @@ void RowPainter::paintLabel() const if (str.empty()) return; - bool const is_rtl = text_.isRTL(par_); Layout const & layout = par_.layout(); FontInfo const font = labelFont(); FontMetrics const & fm = theFontMetrics(font); double x = x_; - if (is_rtl) - x = width_ - row_.right_margin + fm.width(layout.labelsep); + if (row_.isRTL()) + x = tm_.width() - row_.right_margin + fm.width(layout.labelsep); else x = x_ - fm.width(layout.labelsep) - fm.width(str); @@ -412,7 +410,6 @@ void RowPainter::paintLabel() const void RowPainter::paintTopLevelLabel() const { BufferParams const & bparams = pi_.base.bv->buffer().params(); - bool const is_rtl = text_.isRTL(par_); ParagraphParameters const & pparams = par_.params(); Layout const & layout = par_.layout(); FontInfo const font = labelFont(); @@ -437,10 +434,10 @@ void RowPainter::paintTopLevelLabel() const double x = x_; if (layout.labeltype == LABEL_CENTERED) { - x = row_.left_margin + (width_ - row_.left_margin - row_.right_margin) / 2; + x = row_.left_margin + (tm_.width() - row_.left_margin - row_.right_margin) / 2; x -= fm.width(str) / 2; - } else if (is_rtl) { - x = width_ - row_.right_margin - fm.width(str); + } else if (row_.isRTL()) { + x = tm_.width() - row_.right_margin - fm.width(str); } pi_.pain.text(int(x), yo_ - maxdesc - labeladdon, str, font); } @@ -480,7 +477,6 @@ static int getEndLabel(pit_type p, Text const & text) void RowPainter::paintLast() const { - bool const is_rtl = text_.isRTL(par_); int const endlabel = getEndLabel(row_.pit(), text_); // paint imaginary end-of-paragraph character @@ -516,11 +512,11 @@ void RowPainter::paintLast() const // If needed, move the box a bit to avoid overlapping with text. int x = 0; - if (is_rtl) { + if (row_.isRTL()) { int const normal_x = nestMargin() + changebarMargin(); x = min(normal_x, row_.left_margin - size - Inset::TEXT_TO_INSET_OFFSET); } else { - int const normal_x = width_ - row_.right_margin + int const normal_x = tm_.width() - row_.right_margin - size - Inset::TEXT_TO_INSET_OFFSET; x = max(normal_x, row_.width()); } @@ -536,7 +532,7 @@ void RowPainter::paintLast() const FontInfo const font = labelFont(); FontMetrics const & fm = theFontMetrics(font); docstring const & str = par_.layout().endlabelstring(); - double const x = is_rtl ? x_ - fm.width(str) : x_; + double const x = row_.isRTL() ? x_ - fm.width(str) : x_; pi_.pain.text(int(x), yo_, str, font); break; } @@ -611,10 +607,9 @@ void RowPainter::paintSelection() const int const y1 = yo_ - row_.ascent(); int const y2 = y1 + row_.height(); - bool const rtl = text_.isRTL(par_); // draw the margins - if (rtl ? row_.end_margin_sel : row_.begin_margin_sel) + if (row_.isRTL() ? row_.end_margin_sel : row_.begin_margin_sel) pi_.pain.fillRectangle(int(xo_), y1, row_.left_margin, y2 - y1, Color_selection); @@ -651,9 +646,9 @@ void RowPainter::paintSelection() const x += e.full_width(); } - if (rtl ? row_.begin_margin_sel : row_.end_margin_sel) + if (row_.isRTL() ? row_.begin_margin_sel : row_.end_margin_sel) pi_.pain.fillRectangle(int(x), y1, - int(xo_ + text_metrics_.width()) - int(x), y2 - y1, + int(xo_ + tm_.width()) - int(x), y2 - y1, Color_selection); } diff --git a/src/RowPainter.h b/src/RowPainter.h index ca719bd228..99f0c8c515 100644 --- a/src/RowPainter.h +++ b/src/RowPainter.h @@ -29,7 +29,6 @@ class Language; class PainterInfo; class Paragraph; class ParagraphList; -class ParagraphMetrics; class Text; class TextMetrics; @@ -79,7 +78,7 @@ private: /// Text for the row Text const & text_; - TextMetrics const & text_metrics_; + TextMetrics const & tm_; ParagraphList const & pars_; /// The row to paint @@ -87,7 +86,6 @@ private: /// Row's paragraph Paragraph const & par_; - ParagraphMetrics const & pm_; /// row changed? (change tracking) Change const change_; @@ -96,7 +94,6 @@ private: double const xo_; int const yo_; // current baseline double x_; - int width_; }; } // namespace lyx diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 65d9424a9f..c337e8f81f 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -563,7 +563,7 @@ LyXAlignment TextMetrics::getAlign(Paragraph const & par, Row const & row) const // justification on screen' setting. if ((row.flushed() && !forced_block) || !bv_->buffer().params().justification) - align = text_->isRTL(par) ? LYX_ALIGN_RIGHT : LYX_ALIGN_LEFT; + align = row.isRTL() ? LYX_ALIGN_RIGHT : LYX_ALIGN_LEFT; } return align; @@ -620,7 +620,7 @@ void TextMetrics::computeRowMetrics(Row & row, int width) const switch (getAlign(par, row)) { case LYX_ALIGN_BLOCK: // Expand expanding characters by a total of w - if (!row.setExtraWidth(w) && text_->isRTL(par)) { + if (!row.setExtraWidth(w) && row.isRTL()) { // Justification failed and the text is RTL: align to the right row.left_margin += w; row.dimension().wid += w; @@ -1988,15 +1988,14 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const rp.paintAppendix(); rp.paintDepthBar(); rp.paintChangeBar(); - bool const is_rtl = text_->isRTL(text_->getPar(pit)); - if (i == 0 && !is_rtl) + if (i == 0 && !row.isRTL()) rp.paintFirst(); - if (i == nrows - 1 && is_rtl) + if (i == nrows - 1 && row.isRTL()) rp.paintLast(); rp.paintText(); - if (i == nrows - 1 && !is_rtl) + if (i == nrows - 1 && !row.isRTL()) rp.paintLast(); - if (i == 0 && is_rtl) + if (i == 0 && row.isRTL()) rp.paintFirst(); rp.paintTooLargeMarks(row_x + row.left_x() < 0, row_x + row.right_x() > bv_->workWidth());