[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 ®ion)
--- 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