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_.
This commit is contained in:
Jean-Marc Lasgouttes 2016-12-07 12:16:41 +01:00
parent e0024231d3
commit 57c3a94730
7 changed files with 36 additions and 55 deletions

View File

@ -71,10 +71,6 @@ Other changes are only clean-ups.
The helper version should return a Row::Element instead of an InsetTable. 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 ** Set inset position during metrics phase
In order to do that, a no-paint drawing will be initiated after every 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 painting when not inside in drawParagraph
+ remove Cursor::inCoordCache? + 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 ** Paint directly to screen
Instead of using an intermediary pixmap. I have no idea of how Instead of using an intermediary pixmap. I have no idea of how

View File

@ -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); Row::const_iterator cit = tm.findRowElement(row, pos(), boundary(), dummy);
// Handle the case of empty row // Handle the case of empty row
if (cit == row.end()) { if (cit == row.end()) {
if (paragraph().isRTL(buffer()->params())) if (row.isRTL())
right_pos = row.pos(); right_pos = row.pos();
else else
left_pos = row.pos() - 1; 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) bool Cursor::posVisToNewRow(bool movingLeft)
{ {
Paragraph const & par = paragraph();
Buffer const & buf = *buffer();
Row const & row = textRow(); 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 // Inside a table, determining whether to move to the next or
// previous row should be done based on the table's direction. // previous row should be done based on the table's direction.

View File

@ -164,7 +164,8 @@ Row::Row()
sel_beg(-1), sel_end(-1), sel_beg(-1), sel_end(-1),
begin_margin_sel(false), end_margin_sel(false), begin_margin_sel(false), end_margin_sel(false),
changed_(false), crc_(0), 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 the paragraph itself is RTL, reverse everything
if (rtl_par) if (rtl_par)
reverse(elements_.begin(), elements_.end()); reverse(elements_.begin(), elements_.end());
rtl_ = rtl_par;
} }
} // namespace lyx } // namespace lyx

View File

@ -264,6 +264,8 @@ public:
* This should be called once the row is completely built. * This should be called once the row is completely built.
*/ */
void reverseRTL(bool rtl_par); void reverseRTL(bool rtl_par);
///
bool isRTL() const { return rtl_; }
friend std::ostream & operator<<(std::ostream & os, Row const & row); friend std::ostream & operator<<(std::ostream & os, Row const & row);
@ -320,6 +322,8 @@ private:
bool flushed_; bool flushed_;
/// Row dimension. /// Row dimension.
Dimension dim_; Dimension dim_;
/// true when this row lives in a right-to-left paragraph
bool rtl_;
}; };

View File

@ -26,7 +26,6 @@
#include "Row.h" #include "Row.h"
#include "MetricsInfo.h" #include "MetricsInfo.h"
#include "Paragraph.h" #include "Paragraph.h"
#include "ParagraphMetrics.h"
#include "ParagraphParameters.h" #include "ParagraphParameters.h"
#include "TextMetrics.h" #include "TextMetrics.h"
#include "VSpace.h" #include "VSpace.h"
@ -58,11 +57,11 @@ using frontend::FontMetrics;
RowPainter::RowPainter(PainterInfo & pi, RowPainter::RowPainter(PainterInfo & pi,
Text const & text, Row const & row, int x, int y) Text const & text, Row const & row, int x, int y)
: pi_(pi), text_(text), : pi_(pi), text_(text),
text_metrics_(pi_.base.bv->textMetrics(&text)), tm_(pi_.base.bv->textMetrics(&text)),
pars_(text.paragraphs()), pars_(text.paragraphs()),
row_(row), par_(text.paragraphs()[row.pit()]), row_(row), par_(text.paragraphs()[row.pit()]),
pm_(text_metrics_.parMetrics(row.pit())), change_(pi_.change_), change_(pi_.change_),
xo_(x), yo_(y), width_(text_metrics_.width()) xo_(x), yo_(y)
{ {
x_ = row_.left_margin + xo_; x_ = row_.left_margin + xo_;
@ -260,7 +259,7 @@ void RowPainter::paintChangeBar() const
if (start == end || !par_.isChanged(start, end)) if (start == end || !par_.isChanged(start, end))
return; return;
int const height = text_metrics_.isLastRow(row_) int const height = tm_.isLastRow(row_)
? row_.ascent() ? row_.ascent()
: row_.height(); : row_.height();
@ -280,7 +279,7 @@ void RowPainter::paintAppendix() const
y += 2 * defaultRowHeight(); y += 2 * defaultRowHeight();
pi_.pain.line(1, y, 1, yo_ + row_.height(), Color_appendix); 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; return;
depth_type prev_depth = 0; depth_type prev_depth = 0;
if (!text_metrics_.isFirstRow(row_)) { if (!tm_.isFirstRow(row_)) {
pit_type pit2 = row_.pit(); pit_type pit2 = row_.pit();
if (row_.pos() == 0) if (row_.pos() == 0)
--pit2; --pit2;
@ -300,7 +299,7 @@ void RowPainter::paintDepthBar() const
} }
depth_type next_depth = 0; depth_type next_depth = 0;
if (!text_metrics_.isLastRow(row_)) { if (!tm_.isLastRow(row_)) {
pit_type pit2 = row_.pit(); pit_type pit2 = row_.pit();
if (row_.endpos() >= pars_[pit2].size()) if (row_.endpos() >= pars_[pit2].size())
++pit2; ++pit2;
@ -340,13 +339,13 @@ void RowPainter::paintAppendixStart(int y) const
docstring const label = _("Appendix"); docstring const label = _("Appendix");
theFontMetrics(pb_font).rectText(label, w, a, d); 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; int const text_end = text_start + w;
pi_.pain.rectText(text_start, y + d, label, pb_font, Color_none, Color_none); 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(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()) if (str.empty())
return; return;
bool const is_rtl = text_.isRTL(par_);
Layout const & layout = par_.layout(); Layout const & layout = par_.layout();
FontInfo const font = labelFont(); FontInfo const font = labelFont();
FontMetrics const & fm = theFontMetrics(font); FontMetrics const & fm = theFontMetrics(font);
double x = x_; double x = x_;
if (is_rtl) if (row_.isRTL())
x = width_ - row_.right_margin + fm.width(layout.labelsep); x = tm_.width() - row_.right_margin + fm.width(layout.labelsep);
else else
x = x_ - fm.width(layout.labelsep) - fm.width(str); x = x_ - fm.width(layout.labelsep) - fm.width(str);
@ -412,7 +410,6 @@ void RowPainter::paintLabel() const
void RowPainter::paintTopLevelLabel() const void RowPainter::paintTopLevelLabel() const
{ {
BufferParams const & bparams = pi_.base.bv->buffer().params(); BufferParams const & bparams = pi_.base.bv->buffer().params();
bool const is_rtl = text_.isRTL(par_);
ParagraphParameters const & pparams = par_.params(); ParagraphParameters const & pparams = par_.params();
Layout const & layout = par_.layout(); Layout const & layout = par_.layout();
FontInfo const font = labelFont(); FontInfo const font = labelFont();
@ -437,10 +434,10 @@ void RowPainter::paintTopLevelLabel() const
double x = x_; double x = x_;
if (layout.labeltype == LABEL_CENTERED) { 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; x -= fm.width(str) / 2;
} else if (is_rtl) { } else if (row_.isRTL()) {
x = width_ - row_.right_margin - fm.width(str); x = tm_.width() - row_.right_margin - fm.width(str);
} }
pi_.pain.text(int(x), yo_ - maxdesc - labeladdon, str, font); 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 void RowPainter::paintLast() const
{ {
bool const is_rtl = text_.isRTL(par_);
int const endlabel = getEndLabel(row_.pit(), text_); int const endlabel = getEndLabel(row_.pit(), text_);
// paint imaginary end-of-paragraph character // 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. // If needed, move the box a bit to avoid overlapping with text.
int x = 0; int x = 0;
if (is_rtl) { if (row_.isRTL()) {
int const normal_x = nestMargin() + changebarMargin(); int const normal_x = nestMargin() + changebarMargin();
x = min(normal_x, row_.left_margin - size - Inset::TEXT_TO_INSET_OFFSET); x = min(normal_x, row_.left_margin - size - Inset::TEXT_TO_INSET_OFFSET);
} else { } else {
int const normal_x = width_ - row_.right_margin int const normal_x = tm_.width() - row_.right_margin
- size - Inset::TEXT_TO_INSET_OFFSET; - size - Inset::TEXT_TO_INSET_OFFSET;
x = max(normal_x, row_.width()); x = max(normal_x, row_.width());
} }
@ -536,7 +532,7 @@ void RowPainter::paintLast() const
FontInfo const font = labelFont(); FontInfo const font = labelFont();
FontMetrics const & fm = theFontMetrics(font); FontMetrics const & fm = theFontMetrics(font);
docstring const & str = par_.layout().endlabelstring(); 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); pi_.pain.text(int(x), yo_, str, font);
break; break;
} }
@ -611,10 +607,9 @@ void RowPainter::paintSelection() const
int const y1 = yo_ - row_.ascent(); int const y1 = yo_ - row_.ascent();
int const y2 = y1 + row_.height(); int const y2 = y1 + row_.height();
bool const rtl = text_.isRTL(par_);
// draw the margins // 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, pi_.pain.fillRectangle(int(xo_), y1, row_.left_margin, y2 - y1,
Color_selection); Color_selection);
@ -651,9 +646,9 @@ void RowPainter::paintSelection() const
x += e.full_width(); 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, 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); Color_selection);
} }

View File

@ -29,7 +29,6 @@ class Language;
class PainterInfo; class PainterInfo;
class Paragraph; class Paragraph;
class ParagraphList; class ParagraphList;
class ParagraphMetrics;
class Text; class Text;
class TextMetrics; class TextMetrics;
@ -79,7 +78,7 @@ private:
/// Text for the row /// Text for the row
Text const & text_; Text const & text_;
TextMetrics const & text_metrics_; TextMetrics const & tm_;
ParagraphList const & pars_; ParagraphList const & pars_;
/// The row to paint /// The row to paint
@ -87,7 +86,6 @@ private:
/// Row's paragraph /// Row's paragraph
Paragraph const & par_; Paragraph const & par_;
ParagraphMetrics const & pm_;
/// row changed? (change tracking) /// row changed? (change tracking)
Change const change_; Change const change_;
@ -96,7 +94,6 @@ private:
double const xo_; double const xo_;
int const yo_; // current baseline int const yo_; // current baseline
double x_; double x_;
int width_;
}; };
} // namespace lyx } // namespace lyx

View File

@ -563,7 +563,7 @@ LyXAlignment TextMetrics::getAlign(Paragraph const & par, Row const & row) const
// justification on screen' setting. // justification on screen' setting.
if ((row.flushed() && !forced_block) if ((row.flushed() && !forced_block)
|| !bv_->buffer().params().justification) || !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; return align;
@ -620,7 +620,7 @@ void TextMetrics::computeRowMetrics(Row & row, int width) const
switch (getAlign(par, row)) { switch (getAlign(par, row)) {
case LYX_ALIGN_BLOCK: case LYX_ALIGN_BLOCK:
// Expand expanding characters by a total of w // 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 // Justification failed and the text is RTL: align to the right
row.left_margin += w; row.left_margin += w;
row.dimension().wid += w; row.dimension().wid += w;
@ -1988,15 +1988,14 @@ void TextMetrics::drawParagraph(PainterInfo & pi, pit_type const pit, int const
rp.paintAppendix(); rp.paintAppendix();
rp.paintDepthBar(); rp.paintDepthBar();
rp.paintChangeBar(); rp.paintChangeBar();
bool const is_rtl = text_->isRTL(text_->getPar(pit)); if (i == 0 && !row.isRTL())
if (i == 0 && !is_rtl)
rp.paintFirst(); rp.paintFirst();
if (i == nrows - 1 && is_rtl) if (i == nrows - 1 && row.isRTL())
rp.paintLast(); rp.paintLast();
rp.paintText(); rp.paintText();
if (i == nrows - 1 && !is_rtl) if (i == nrows - 1 && !row.isRTL())
rp.paintLast(); rp.paintLast();
if (i == 0 && is_rtl) if (i == 0 && row.isRTL())
rp.paintFirst(); rp.paintFirst();
rp.paintTooLargeMarks(row_x + row.left_x() < 0, rp.paintTooLargeMarks(row_x + row.left_x() < 0,
row_x + row.right_x() > bv_->workWidth()); row_x + row.right_x() > bv_->workWidth());