Guillaume Pothier wrote:
Ok, I also tried with --disable-stdlib-debug and I don't notice any difference.
Could you please try this patch? 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); }