[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/work/koffice-essen/kspread/ui
From:       Marijn Kruisselbrink <m.kruisselbrink () student ! tue ! nl>
Date:       2010-12-02 9:26:47
Message-ID: 20101202092647.266CCAC8B1 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1202777 by mkruisselbrink:

and add the real background painting logic to PixmapCachingSheetView; no proper \
cleaning up yet, and I do probably want to rewrite it to use QFuture/QtConcurrent \
instead of threadweaver, but at least it seems to work quite well already

 M  +103 -12   PixmapCachingSheetView.cpp  
 M  +7 -1      PixmapCachingSheetView.h  


--- branches/work/koffice-essen/kspread/ui/PixmapCachingSheetView.cpp \
#1202776:1202777 @@ -29,6 +29,11 @@
 
 #include <kdebug.h>
 
+#ifdef KSPREAD_MT
+#include <ThreadWeaver/Job>
+#include <ThreadWeaver/Weaver>
+#endif
+
 using namespace KSpread;
 
 #define TILESIZE 256
@@ -41,9 +46,76 @@
     QCache<int, QPixmap> tileCache;
     QPointF lastScale;
 
-    QPixmap* getTile(const Sheet* sheet, int x, int y);
+    QPixmap* getTile(const Sheet* sheet, int x, int y, CanvasBase* canvas);
 };
 
+#ifdef KSPREAD_MT
+class TileDrawingJob : public ThreadWeaver::Job
+{
+public:
+    TileDrawingJob(const Sheet* sheet, SheetView* sheetView, CanvasBase* canvas, \
const QPointF& scale, int x, int y); +    ~TileDrawingJob();
+protected:
+    virtual void run();
+private:
+    const Sheet* m_sheet;
+    SheetView* m_sheetView;
+public:
+    CanvasBase* m_canvas;
+    QPointF m_scale;
+    int m_x;
+    int m_y;
+    QImage m_image;
+};
+
+TileDrawingJob::TileDrawingJob(const Sheet *sheet, SheetView* sheetView, CanvasBase* \
canvas, const QPointF& scale, int x, int y) +    : m_sheet(sheet), \
m_sheetView(sheetView), m_canvas(canvas), m_scale(scale), m_x(x), m_y(y) +    , \
m_image(TILESIZE, TILESIZE, QImage::Format_ARGB32) +{
+    kDebug() << "new job for " << x << "," << y << " " << m_scale;
+}
+
+TileDrawingJob::~TileDrawingJob()
+{
+    kDebug() << "end job for " << m_x << "," << m_y << " " << m_scale;
+}
+
+void TileDrawingJob::run()
+{
+    kDebug() << "start draw for " << m_x << "," << m_y << " " << m_scale;
+    m_image.fill(QColor(255, 255, 255, 0).rgba());
+    QPainter pixmapPainter(&m_image);
+    pixmapPainter.setClipRect(m_image.rect());
+    pixmapPainter.scale(m_scale.x(), m_scale.y());
+
+    QRect globalPixelRect(QPoint(m_x * TILESIZE, m_y * TILESIZE), QSize(TILESIZE, \
TILESIZE)); +    QRectF docRect(
+            globalPixelRect.x() / m_scale.x(),
+            globalPixelRect.y() / m_scale.y(),
+            globalPixelRect.width() / m_scale.x(),
+            globalPixelRect.height() / m_scale.y()
+    );
+
+    pixmapPainter.translate(-docRect.x(), -docRect.y());
+
+    double loffset, toffset;
+    const int left = m_sheet->leftColumn(docRect.left(), loffset);
+    const int right = m_sheet->rightColumn(docRect.right());
+    const int top = m_sheet->topRow(docRect.top(), toffset);
+    const int bottom = m_sheet->bottomRow(docRect.bottom());
+    QRect cellRect(left, top, right - left + 1, bottom - top + 1);
+
+    kDebug() << globalPixelRect << docRect;
+    kDebug() << cellRect;
+
+    // TODO
+    m_sheetView->SheetView::paintCells(pixmapPainter, docRect, QPointF(loffset, \
toffset), 0, cellRect); +
+    //m_image.save(QString("/tmp/tile%1_%2.png").arg(m_x).arg(m_y));
+    kDebug() << "end draw for " << m_x << "," << m_y << " " << m_scale;
+}
+#endif
+
 PixmapCachingSheetView::PixmapCachingSheetView(const Sheet* sheet)
     : SheetView(sheet), d(new Private(this))
 {
@@ -55,13 +127,36 @@
     delete d;
 }
 
-QPixmap* PixmapCachingSheetView::Private::getTile(const Sheet* sheet, int x, int y)
+void PixmapCachingSheetView::jobDone(ThreadWeaver::Job *tjob)
 {
+#ifdef KSPREAD_MT
+    TileDrawingJob* job = static_cast<TileDrawingJob*>(tjob);
+    if (job->m_scale == d->lastScale) {
+        int idx = job->m_x << 16 | job->m_y;
+        d->tileCache.insert(idx, new QPixmap(QPixmap::fromImage(job->m_image)));
+        // TODO: figure out what area to repaint
+        job->m_canvas->update();
+    }
+    job->deleteLater();
+#endif
+}
+
+QPixmap* PixmapCachingSheetView::Private::getTile(const Sheet* sheet, int x, int y, \
CanvasBase* canvas) +{
     int idx = x << 16 | y;
     if (tileCache.contains(idx)) return tileCache.object(idx);
 
+#ifdef KSPREAD_MT
+    TileDrawingJob* job = new TileDrawingJob(sheet, q, canvas, lastScale, x, y);
+    QObject::connect(job, SIGNAL(done(ThreadWeaver::Job*)), q, \
SLOT(jobDone(ThreadWeaver::Job*)), Qt::QueuedConnection); +    \
ThreadWeaver::Weaver::instance()->enqueue(job);  QPixmap* pm = new QPixmap(TILESIZE, \
TILESIZE);  pm->fill(QColor(255, 255, 255, 0));
+    tileCache.insert(idx, pm);
+    return pm;
+#else
+    QPixmap* pm = new QPixmap(TILESIZE, TILESIZE);
+    pm->fill(QColor(255, 255, 255, 0));
     QPainter pixmapPainter(pm);
     pixmapPainter.setClipRect(pm->rect());
     pixmapPainter.scale(lastScale.x(), lastScale.y());
@@ -86,17 +181,17 @@
     kDebug() << globalPixelRect << docRect;
     kDebug() << cellRect;
 
-    q->setVisibleRect(cellRect);
-    q->SheetView::paintCells(pixmapPainter, docRect, QPointF(loffset, toffset));
-    //pm->save(QString("/tmp/tile%1.png").arg(idx));
+    q->SheetView::paintCells(pixmapPainter, docRect, QPointF(loffset, toffset), 0, \
cellRect); +    pm->save(QString("/tmp/tile%1.png").arg(idx));
     tileCache.insert(idx, pm);
     return pm;
+#endif
 }
 
-void PixmapCachingSheetView::paintCells(QPainter& painter, const QRectF& paintRect, \
const QPointF& topLeft, const CanvasBase* canvas) +void \
PixmapCachingSheetView::paintCells(QPainter& painter, const QRectF& paintRect, const \
QPointF& topLeft, CanvasBase* canvas, const QRect& visibleRect)  {
     if (!canvas) {
-        SheetView::paintCells(painter, paintRect, topLeft);
+        SheetView::paintCells(painter, paintRect, topLeft, canvas, visibleRect);
         return;
     }
     // paintRect:   the canvas area, that should be painted; in document \
coordinates; @@ -133,19 +228,15 @@
     tiles.setBottom((pixelRect.bottom() + TILESIZE - 1) / TILESIZE);
     kDebug() << paintRect << pixelRect << tiles << topLeft << scale << o;
 
-    QRect savedVisRect = visibleRect();
-
     const Sheet* s = sheet();
     for (int x = tiles.left(); x < tiles.right(); x++) {
         for (int y = tiles.top(); y < tiles.bottom(); y++) {
-            QPixmap *p = d->getTile(s, x, y);
+            QPixmap *p = d->getTile(s, x, y, canvas);
             QPointF pt(x * TILESIZE / scale.x(), y * TILESIZE / scale.y());
             QRectF r(pt, QSizeF(TILESIZE / sx, TILESIZE / sy));
             painter.drawPixmap(r, *p, p->rect());
         }
     }
-
-    setVisibleRect(savedVisRect);
 }
 
 void PixmapCachingSheetView::invalidateRegion(const Region &region)
--- branches/work/koffice-essen/kspread/ui/PixmapCachingSheetView.h #1202776:1202777
@@ -22,6 +22,10 @@
 
 #include "SheetView.h"
 
+namespace ThreadWeaver {
+    class Job;
+}
+
 namespace KSpread {
 
 class PixmapCachingSheetView : public SheetView
@@ -40,7 +44,9 @@
 
     virtual void invalidateRegion(const Region& region);
     virtual void invalidate();
-    virtual void paintCells(QPainter& painter, const QRectF& paintRect, const \
QPointF& topLeft, const CanvasBase* canvas); +    virtual void paintCells(QPainter& \
painter, const QRectF& paintRect, const QPointF& topLeft, CanvasBase* canvas, const \
QRect& visibleRect); +private slots:
+    void jobDone(ThreadWeaver::Job* job);
 private:
     class Private;
     Private * const d;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic