Jürgen Spitzmüller wrote:
Abdelrazak Younes wrote:
Very clear, thanks a lot!
Jurgen, Jose, do you want to wait for 1.5.1 or shall I commit this now
as I reckon most Mac/PPC user will complain about the speed?
I have extensively tested this and I could not see any drawing problem.
I reckon that the improved speed would be sensible in some X11
installation too. Another solution would be to enclosed the caching
between #ifdef Q_WS_MAC.
Could you post again a patch with all changes that are needed against trunk?
Attached.
It's an important improvement for the Mac users, but since it's probably a
rather big change,
No, not very big and the good thing is that is all located in the same
method.
some testing would surely be good (that would speak for
putting it in soon after a minor 1.5.x release).
Please test it then. Dov already tested it with RTL language and didn't
see any problem at all. I repeat myself but the only side effect that
could happen is that some characters are cropped to the left or to the
right. But I am pretty sure now that I took all possible cases into account.
I take it that wide() will be killed in a second step?
Yes.
Abdel.
Index: frontends/qt4/GuiApplication.cpp
===================================================================
--- frontends/qt4/GuiApplication.cpp (revision 18971)
+++ frontends/qt4/GuiApplication.cpp (working copy)
@@ -41,6 +41,7 @@
#include <QFileOpenEvent>
#include <QLocale>
#include <QLibraryInfo>
+#include <QPixmapCache>
#include <QTextCodec>
#include <QTimer>
#include <QTranslator>
@@ -137,6 +138,10 @@
LoaderQueue::setPriority(10,100);
guiApp = this;
+
+ // Set the cache to 5120 kilobytes which corresponds to screen size of
+ // 1280 by 1024 pixels with a color depth of 32 bits.
+ QPixmapCache::setCacheLimit(5120);
}
Index: frontends/qt4/QLPainter.cpp
===================================================================
--- frontends/qt4/QLPainter.cpp (revision 18971)
+++ frontends/qt4/QLPainter.cpp (working copy)
@@ -11,8 +11,6 @@
#include <config.h>
-#include <QTextLayout>
-
#include "QLPainter.h"
#include "GuiApplication.h"
@@ -28,12 +26,29 @@
#include "support/unicode.h"
+#include <QPixmapCache>
+#include <QTextLayout>
+
using std::endl;
using std::string;
namespace lyx {
namespace frontend {
+namespace {
+
+QString generateStringSignature(QString const & str, Font const & f)
+{
+ QString sig = str;
+ sig.append(QChar(static_cast<short>(f.family())));
+ sig.append(QChar(static_cast<short>(f.series())));
+ sig.append(QChar(static_cast<short>(f.realShape())));
+ sig.append(QChar(static_cast<short>(f.size())));
+ return sig;
+}
+
+} // anon namespace
+
QLPainter::QLPainter(QPaintDevice * device)
: QPainter(device), Painter()
{
@@ -244,14 +259,12 @@
int textwidth;
if (f.realShape() != Font::SMALLCAPS_SHAPE) {
- setQPainterPen(f.realColor());
- if (font() != fi.font)
- setFont(fi.font);
- // We need to draw the text as LTR as we use our own bidi code.
- setLayoutDirection(Qt::LeftToRight);
+ // Here we use the font width cache instead of
+ // textwidth = fontMetrics().width(str);
+ // because the above is awfully expensive on MacOSX
+ textwidth = fi.metrics->width(s);
+
if (isDrawingEnabled()) {
- LYXERR(Debug::PAINTING) << "draw " <<
std::string(str.toUtf8())
- << " at " << x << "," << y << std::endl;
// Qt4 does not display a glyph whose codepoint is the
// same as that of a soft-hyphen (0x00ad), unless it
// occurs at a line-break. As a kludge, we force Qt to
@@ -265,13 +278,43 @@
line.setPosition(QPointF(0, -line.ascent()));
adsymbol.endLayout();
line.draw(this, QPointF(x, y));
- } else
- drawText(x, y, str);
+ } else {
+ QPixmap pm;
+ QString key = generateStringSignature(str, f);
+ // Warning: Left bearing is in general
negative! Only the case
+ // where left bearing is negative is of
interest WRT the the
+ // pixmap width and the text x-position.
+ // Only the left bearing of the first character
is important as we
+ // always write from left to right, even for
right-to-left languages.
+ int const lb =
std::min(fi.metrics->lbearing(s[0]), 0);
+ int const mA = fi.metrics->maxAscent();
+ if (!QPixmapCache::find(key, pm)) {
+ // Only the right bearing of the last
character is important as we
+ // always write from left to right,
even for right-to-left languages.
+ int const rb =
fi.metrics->rbearing(s[s.size()-1]);
+ int const w = textwidth + rb - lb;
+ int const mD = fi.metrics->maxDescent();
+ int const h = mA + mD;
+ pm = QPixmap(w, h);
+ pm.fill(Qt::transparent);
+ QLPainter p(&pm);
+ p.setQPainterPen(f.realColor());
+ if (p.font() != fi.font)
+ p.setFont(fi.font);
+ // We need to draw the text as LTR as
we use our own bidi code.
+ p.setLayoutDirection(Qt::LeftToRight);
+ p.drawText(-lb, mA, str);
+ QPixmapCache::insert(key, pm);
+
+ LYXERR(Debug::PAINTING) << "draw " <<
std::string(str.toUtf8())
+ << " at " << x << "," << y <<
std::endl;
+ LYXERR(Debug::PAINTING) << "h=" << h <<
" mA=" << mA << " mD=" << mD
+ << " w=" << w << " lb=" << lb
<< " tw=" << textwidth
+ << " rb=" << rb << endl;
+ }
+ drawPixmap(x + lb, y - mA, pm);
+ }
}
- // Here we use the font width cache instead of
- // textwidth = fontMetrics().width(str);
- // because the above is awfully expensive on MacOSX
- textwidth = fi.metrics->width(str);
} else {
textwidth = smallCapsText(x, y, str, f);
}