Hello,

FYI, I think I have solved the speed issue under Mac (which will allow us to get rid of the wide() thing). This is not really a bug but it surely is a regression WRT 1.4. But, as 1.5.0 is supposedly soon (today?), I propose to postpone the fix to 1.5.1.
Opinions?
I don't want to steal the focus so I can wait but I'd still be interested in some testing from interested parties.

1) Mac users: Stefan, Bennett, would you mind give it a try?
2) RTL users: I took into account the right bearing of the last character in a word (this is especially important when 'f' is this last character for example). But I am no sure if and how we should correct that for RTL language. I guess Dov or Stefan would be interested in this second point.

Abdel.


Author: younes
Date: Mon Jul  2 17:06:51 2007
New Revision: 18960

URL: http://www.lyx.org/trac/changeset/18960
Log:
Optimize text drawing by using a pixmap cache.

* QApplication::QApplication sets the QPixmapCache maximum size to 5 megs.

* QLPainter
- generateStringSignature(): used for the key used in the QPixmapCache cache.
  - text(): use QPixmapCache instead of drawing the text each time.


Modified:

lyx-devel/branches/personal/younes/mvc/src/frontends/qt4/GuiApplication.cpp
    lyx-devel/branches/personal/younes/mvc/src/frontends/qt4/QLPainter.cpp

Modified: lyx-devel/branches/personal/younes/mvc/src/frontends/qt4/GuiApplication.cpp URL: http://www.lyx.org/trac/file/lyx-devel/branches/personal/younes/mvc/src/frontends/qt4/GuiApplication.cpp?rev=18960
==============================================================================
--- lyx-devel/branches/personal/younes/mvc/src/frontends/qt4/GuiApplication.cpp (original) +++ lyx-devel/branches/personal/younes/mvc/src/frontends/qt4/GuiApplication.cpp Mon Jul 2 17:06:51 2007
@@ -137,6 +137,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);
 }



Modified: lyx-devel/branches/personal/younes/mvc/src/frontends/qt4/QLPainter.cpp URL: http://www.lyx.org/trac/file/lyx-devel/branches/personal/younes/mvc/src/frontends/qt4/QLPainter.cpp?rev=18960
==============================================================================
--- lyx-devel/branches/personal/younes/mvc/src/frontends/qt4/QLPainter.cpp (original) +++ lyx-devel/branches/personal/younes/mvc/src/frontends/qt4/QLPainter.cpp Mon Jul 2 17:06:51 2007
@@ -33,6 +33,20 @@

 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 +258,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 +277,36 @@
                                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);
+                               // FIXME 1: we should probably also use 
fi.metrics->lbearing(s[0])
+                               // FIXME 2: on RTL string should that be 
rbearing(s[0])?
+                               int const w = textwidth + 
fi.metrics->rbearing(s[s.size()-1]);
+                               int const mA = fi.metrics->maxAscent();
+                               int const mD = fi.metrics->maxDescent();
+                               int const h = mA + mD;
+                               if (!QPixmapCache::find(key, pm)) {
+
+                                       LYXERR(Debug::PAINTING) << "draw " << 
std::string(str.toUtf8())
+                                               << " at " << x << "," << y << 
std::endl;
+                                       LYXERR(Debug::PAINTING) << "h=" << h << "  
w=" << w
+ << " mA=" << fi.metrics->maxAscent() << " mD=" << fi.metrics->maxDescent() << endl;
+
+                                       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(0, mA, str);
+                                       QPixmapCache::insert(key, pm);
+                               }
+                               drawPixmap(x, 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);
        }



Reply via email to