Cleanup Painter text() API

* remove optional arguments to the helpers that use a FontInfo
* add a textwidth argument to the text() methods that are used by rowpainter.

Now textwidth is only computed if a null value was passed to the
text() method. This means that in the use case of rowpainter, no
textwidth needs to be computed.
This commit is contained in:
Jean-Marc Lasgouttes 2016-03-20 20:02:05 +01:00
parent 333f6fcf07
commit 598f7e4a45
5 changed files with 67 additions and 40 deletions

View File

@ -60,6 +60,7 @@ cursor.
* Proposals
* Clean-up of drawing code
The goal is to make painting with drawing disable fast enough that it
@ -81,7 +82,7 @@ paintInset needs to be called.
The only thing we want to do here is to set inset positions (for
text). The other insets still use the painter with drawing disabled.
** Painter::text
** DONE Painter::text
We cannot remove (or make private) the version that uses a
FontInfo because it is used by PainterInfo::draw. Document this and
@ -99,6 +100,26 @@ version.
==> more versions, no optional parameters.
** make Inset::display() more useful
Extending the DisplayType enum would allow to remove special cases
from the code.
The enumeration could be like
: Inline = 0
: BreakBefore = 1 // break row before this inset
: BreakAfter = 2 // break row after this inset
: CanBreakAfter = 4 // optionally break row after this inset
: AlignLeft = 8
: AlignRight = 16
: NoBoundary = 32 // do not allow cursor to go at the end of the row
: //before display inset
: Display = BreakBefore|BreakAfter
A display equation would be Display, other could be Display|AlignLeft
BreakAfter can be used by Newline or separator insets
CanBreakAfter can be used by the optional hyphen InsetSpecialChar.
** Set inset position during metrics phase
In order to do that, a no-paint drawing will be initiated after every

View File

@ -246,13 +246,14 @@ void RowPainter::paintStringAndSel(Row::Element const & e)
Color const col = e.change.changed() ? e.change.color()
: Color_selectiontext;
copy.fontInfo().setPaintColor(col);
pi_.pain.text(int(x_), yo_, e.str, copy, e.extra);
pi_.pain.text(int(x_), yo_, e.str, copy, e.extra, e.full_width());
} else if (!some_sel) {
pi_.pain.text(int(x_), yo_, e.str, e.font, e.extra);
pi_.pain.text(int(x_), yo_, e.str, e.font, e.extra, e.full_width());
} else {
pi_.pain.text(int(x_), yo_, e.str, e.font, Color_selectiontext,
max(row_.sel_beg, e.pos) - e.pos,
min(row_.sel_end, e.endpos) - e.pos, e.extra);
min(row_.sel_end, e.endpos) - e.pos,
e.extra, e.full_width());
}
x_ += e.full_width();
}

View File

@ -133,21 +133,17 @@ public:
virtual void image(int x, int y, int w, int h,
graphics::Image const & image) = 0;
/** draw a character at position x, y (y is the baseline)
*/
virtual void text(int x, int y, char_type c, FontInfo const & f) = 0;
/// draw a string at position x, y (y is the baseline).
virtual void text(int x, int y, docstring const & str, FontInfo const & f) = 0;
/** draw a string at position x, y (y is the baseline). The
* text direction is given by \c rtl.
*/
virtual void text(int x, int y, docstring const & str, FontInfo const & f,
bool rtl = false, double wordspacing = 0.0) = 0;
/// draw a char at position x, y (y is the baseline)
virtual void text(int x, int y, char_type c, FontInfo const & f) = 0;
/** draw a string at position x, y (y is the baseline). The
* text direction is enforced by the \c Font.
*/
virtual void text(int x, int y, docstring const & str, Font const & f,
double wordspacing = 0.0) = 0;
double wordspacing, double textwidth) = 0;
/** draw a string at position x, y (y is the baseline), but
* make sure that the part between \c from and \c to is in
@ -155,7 +151,7 @@ public:
*/
virtual void text(int x, int y, docstring const & str, Font const & f,
Color other, size_type from, size_type to,
double const wordspacing) = 0;
double wordspacing, double textwidth) = 0;
void setDrawingEnabled(bool drawing_enabled)
{ drawing_enabled_ = drawing_enabled; }

View File

@ -333,6 +333,12 @@ void GuiPainter::text(int x, int y, char_type c, FontInfo const & f)
}
void GuiPainter::text(int x, int y, docstring const & s, FontInfo const & f)
{
text(x, y, s, f, false, 0.0, 0.0);
}
void GuiPainter::do_drawText(int x, int y, QString str, bool rtl, FontInfo const & f, QFont ff)
{
setQPainterPen(computeColor(f.realColor()));
@ -370,7 +376,7 @@ void GuiPainter::do_drawText(int x, int y, QString str, bool rtl, FontInfo const
void GuiPainter::text(int x, int y, docstring const & s,
FontInfo const & f, bool const rtl,
double const wordspacing)
double const wordspacing, double const tw)
{
//LYXERR0("text: x=" << x << ", s=" << s);
if (s.empty() || !isDrawingEnabled())
@ -383,7 +389,7 @@ void GuiPainter::text(int x, int y, docstring const & s,
frontend. This is just wrong, because the symbol is no UCS4 character at
all. You can think of this number as the code point of the symbol in a
custom symbol encoding. It works because this char_type is later on again
interpreted as a position in the font again.
interpreted as a position in the font.
The correct solution would be to have extra functions for symbols, but that
would require to duplicate a lot of frontend and mathed support code.
*/
@ -400,11 +406,12 @@ void GuiPainter::text(int x, int y, docstring const & s,
ff.setWordSpacing(wordspacing);
GuiFontMetrics const & fm = getFontMetrics(f);
// Here we use the font width cache instead of
// textwidth = fontMetrics().width(str);
// because the above is awfully expensive on MacOSX
int textwidth = 0;
if (tw == 0.0)
// Note that we have to take in account space stretching (word spacing)
int const textwidth = fm.width(s) + count(s.begin(), s.end(), ' ') * wordspacing;
textwidth = fm.width(s) + count(s.begin(), s.end(), ' ') * wordspacing;
else
textwidth = static_cast<int>(tw);
textDecoration(f, x, y, textwidth);
@ -464,15 +471,15 @@ void GuiPainter::text(int x, int y, docstring const & s,
void GuiPainter::text(int x, int y, docstring const & str, Font const & f,
double const wordspacing)
double const wordspacing, double const tw)
{
text(x, y, str, f.fontInfo(), f.isVisibleRightToLeft(), wordspacing);
text(x, y, str, f.fontInfo(), f.isVisibleRightToLeft(), wordspacing, tw);
}
void GuiPainter::text(int x, int y, docstring const & str, Font const & f,
Color other, size_type const from, size_type const to,
double const wordspacing)
double const wordspacing, double const tw)
{
GuiFontMetrics const & fm = getFontMetrics(f.fontInfo());
FontInfo fi = f.fontInfo();
@ -491,7 +498,7 @@ void GuiPainter::text(int x, int y, docstring const & str, Font const & f,
fi.setPaintColor(other);
QRegion const clip(x + xmin, y - ascent, xmax - xmin, height);
setClipRegion(clip);
text(x, y, str, fi, rtl, wordspacing);
text(x, y, str, fi, rtl, wordspacing, tw);
// Then the part in normal color
// Note that in Qt5, it is not possible to use Qt::UniteClip,
@ -499,7 +506,7 @@ void GuiPainter::text(int x, int y, docstring const & str, Font const & f,
fi.setPaintColor(orig);
QRegion region(viewport());
setClipRegion(region - clip);
text(x, y, str, fi, rtl, wordspacing);
text(x, y, str, fi, rtl, wordspacing, tw);
setClipping(false);
}

View File

@ -105,17 +105,17 @@ public:
virtual void image(int x, int y, int w, int h,
lyx::graphics::Image const & image);
/** draw a string at position x, y (y is the baseline). The
* text direction is given by \c rtl.
*/
virtual void text(int x, int y, docstring const & str, FontInfo const & f,
bool rtl = false, double wordspacing = 0.0);
/// draw a string at position x, y (y is the baseline).
virtual void text(int x, int y, docstring const & str, FontInfo const & f);
/// draw a char at position x, y (y is the baseline)
virtual void text(int x, int y, char_type c, FontInfo const & f);
/** draw a string at position x, y (y is the baseline). The
* text direction is enforced by the \c Font.
*/
virtual void text(int x, int y, docstring const & str, Font const & f,
double wordspacing = 0.0);
double wordspacing, double textwidth);
/** draw a string at position x, y (y is the baseline), but
* make sure that the part between \c from and \c to is in
@ -123,10 +123,7 @@ public:
*/
virtual void text(int x, int y, docstring const & str, Font const & f,
Color other, size_type from, size_type to,
double const wordspacing);
/// draw a char at position x, y (y is the baseline)
virtual void text(int x, int y, char_type c, FontInfo const & f);
double wordspacing, double textwidth);
///
virtual void textDecoration(FontInfo const & f, int x, int y, int width);
@ -186,6 +183,11 @@ private:
// Helper for text() method
void do_drawText(int x, int y, QString str, bool rtl, FontInfo const & f, QFont ff);
// Real text() method
void text(int x, int y, docstring const & s,
FontInfo const & f, bool const rtl,
double const wordspacing, double tw);
QColor current_color_;
Painter::line_style current_ls_;
int current_lw_;