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.
** 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

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);
// 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.

View File

@ -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

View File

@ -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_;
};

View File

@ -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);
}

View File

@ -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

View File

@ -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());