#include "support/lassert.h"
#include "support/debug.h"
+#include <algorithm>
+
#include <QPixmapCache>
#include <QTextLayout>
pen.setColor(col);
switch (ls) {
- case line_solid: pen.setStyle(Qt::SolidLine); break;
- case line_onoffdash: pen.setStyle(Qt::DotLine); break;
+ case line_solid:
+ case line_solid_aliased:
+ pen.setStyle(Qt::SolidLine); break;
+ case line_onoffdash:
+ pen.setStyle(Qt::DotLine); break;
}
pen.setWidth(lw);
setQPainterPen(computeColor(col), ls, lw);
bool const do_antialiasing = renderHints() & TextAntialiasing
- && x1 != x2 && y1 != y2;
+ && x1 != x2 && y1 != y2 && ls != line_solid_aliased;
setRenderHint(Antialiasing, do_antialiasing);
drawLine(x1, y1, x2, y2);
setRenderHint(Antialiasing, false);
if (np > points.size())
points.resize(2 * np);
+ // Note: the proper way to not get blurry vertical and horizontal lines is
+ // to add 0.5 to all coordinates.
bool antialias = false;
for (int i = 0; i < np; ++i) {
points[i].setX(xp[i]);
QColor const color = computeColor(col);
setQPainterPen(color, ls, lw);
bool const text_is_antialiased = renderHints() & TextAntialiasing;
- setRenderHint(Antialiasing, antialias && text_is_antialiased);
+ setRenderHint(Antialiasing,
+ antialias && text_is_antialiased && ls != line_solid_aliased);
if (fs == fill_none) {
drawPolyline(points.data(), np);
} else {
QColor const color = computeColor(col);
setQPainterPen(color, ls, lw);
bool const text_is_antialiased = renderHints() & TextAntialiasing;
- setRenderHint(Antialiasing, text_is_antialiased);
+ setRenderHint(Antialiasing, text_is_antialiased && ls != line_solid_aliased);
drawPath(bpath);
if (fs != fill_none)
fillPath(bpath, QBrush(color));
void GuiPainter::text(int x, int y, docstring const & s, FontInfo const & f)
{
- text(x, y, s, f, false, 0.0, 0.0);
+ text(x, y, s, f, Auto, 0.0, 0.0);
}
-void GuiPainter::do_drawText(int x, int y, QString str, bool rtl, FontInfo const & f, QFont ff)
+void GuiPainter::do_drawText(int x, int y, QString str,
+ GuiPainter::Direction const dir,
+ FontInfo const & f, QFont ff)
{
setQPainterPen(computeColor(f.realColor()));
if (font() != ff)
/* Use unicode override characters to enforce drawing direction
* Source: http://www.iamcal.com/understanding-bidirectional-text/
*/
- if (rtl)
+ if (dir == RtL)
// Right-to-left override: forces to draw text right-to-left
str = QChar(0x202E) + str;
- else
+ else if (dir == LtR)
// Left-to-right override: forces to draw text left-to-right
str = QChar(0x202D) + str;
drawText(x, y, str);
* Keep it here for now, in case it can be helpful
*/
//This is much stronger than setLayoutDirection.
- int flag = rtl ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight;
- drawText(x + (rtl ? textwidth : 0), y - fm.maxAscent(), 0, 0,
+ int flag = 0;
+ if (dir == RtL)
+ flag = Qt::TextForceRightToLeft;
+ else if (dir == LtR)
+ flag = Qt::TextForceLeftToRight;
+ drawText(x + ((dir == RtL) ? textwidth : 0), y - fm.maxAscent(), 0, 0,
flag | Qt::TextDontClip,
str);
#endif
void GuiPainter::text(int x, int y, docstring const & s,
- FontInfo const & f, bool const rtl,
+ FontInfo const & f, Direction const dir,
double const wordspacing, double const tw)
{
//LYXERR0("text: x=" << x << ", s=" << s);
int textwidth = 0;
if (tw == 0.0)
// Note that we have to take in account space stretching (word spacing)
- textwidth = fm.width(s) + count(s.begin(), s.end(), ' ') * wordspacing;
+ textwidth = fm.width(s) +
+ static_cast<int>(fm.countExpanders(s) * wordspacing);
else
textwidth = static_cast<int>(tw);
#endif
pm.fill(Qt::transparent);
GuiPainter p(&pm, pixelRatio());
- p.do_drawText(-lb, mA, str, rtl, f, ff);
+ p.do_drawText(-lb, mA, str, dir, f, ff);
QPixmapCache::insert(key, pm);
//LYXERR(Debug::PAINTING, "h=" << h << " mA=" << mA << " mD=" << mD
// << " w=" << w << " lb=" << lb << " tw=" << textwidth
return;
}
- // don't use the pixmap cache,
- do_drawText(x, y, str, rtl, f, ff);
+ // don't use the pixmap cache
+ setQPainterPen(computeColor(f.realColor()));
+ if (dir != Auto) {
+ shared_ptr<QTextLayout const> ptl =
+ fm.getTextLayout(s, dir == RtL, wordspacing);
+ ptl->draw(this, QPointF(x, y - fm.maxAscent()));
+ }
+ else {
+ if (font() != ff)
+ setFont(ff);
+ drawText(x, y, str);
+ }
//LYXERR(Debug::PAINTING, "draw " << string(str.toUtf8())
// << " at " << x << "," << y);
}
void GuiPainter::text(int x, int y, docstring const & str, Font const & f,
double const wordspacing, double const tw)
{
- text(x, y, str, f.fontInfo(), f.isVisibleRightToLeft(), wordspacing, tw);
+ text(x, y, str, f.fontInfo(), f.isVisibleRightToLeft() ? RtL : LtR,
+ wordspacing, tw);
}
{
GuiFontMetrics const & fm = getFontMetrics(f.fontInfo());
FontInfo fi = f.fontInfo();
- bool const rtl = f.isVisibleRightToLeft();
+ Direction const dir = f.isVisibleRightToLeft() ? RtL : LtR;
// dimensions
int const ascent = fm.maxAscent();
int const height = fm.maxAscent() + fm.maxDescent();
- int xmin = fm.pos2x(str, from, rtl, wordspacing);
- int xmax = fm.pos2x(str, to, rtl, wordspacing);
+ int xmin = fm.pos2x(str, from, dir == RtL, wordspacing);
+ int xmax = fm.pos2x(str, to, dir == RtL, wordspacing);
if (xmin > xmax)
swap(xmin, xmax);
fi.setPaintColor(other);
QRegion const clip(x + xmin, y - ascent, xmax - xmin, height);
setClipRegion(clip);
- text(x, y, str, fi, rtl, wordspacing, tw);
+ text(x, y, str, fi, dir, wordspacing, tw);
// Then the part in normal color
// Note that in Qt5, it is not possible to use Qt::UniteClip,
fi.setPaintColor(orig);
QRegion region(viewport());
setClipRegion(region - clip);
- text(x, y, str, fi, rtl, wordspacing, tw);
+ text(x, y, str, fi, dir, wordspacing, tw);
setClipping(false);
}