image = new QImage(width, height, QImage::Format_RGB32);
image->fill(QColor(Qt::white).rgb());
painter = new QPainter(image);
+ setDirty();
}
DrawingArea::~DrawingArea()
delete image;
}
-int DrawingArea::width() const
-{
- return image->width();
-}
-
-int DrawingArea::height() const
-{
- return image->height();
-}
-
void DrawingArea::setColor(const QColor &color)
{
QPen pen(painter->pen());
void DrawingArea::drawPoint(int x, int y)
{
+ lock();
painter->drawPoint(x, y);
- emit update();
+ setDirty(QRect(x, y, 1, 1));
+ unlock();
}
void DrawingArea::drawLine(int x1, int y1, int x2, int y2)
{
+ lock();
painter->drawLine(x1, y1, x2, y2);
- emit update();
+ if (x1 > x2)
+ std::swap(x1, x2);
+ if (y1 > y2)
+ std::swap(y1, y2);
+ setDirty(QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1));
+ unlock();
+}
+
+void DrawingArea::setDirty()
+{
+ setDirty(QRect(0, 0, width(), height()));
+}
+
+void DrawingArea::setDirty(const QRect &rect)
+{
+ if (dirtyFlag)
+ dirtyRect |= rect;
+ else
+ dirtyRect = rect;
+ dirtyFlag = true;
}
-const QImage &DrawingArea::getImage() const
+void DrawingArea::setClean()
{
- return *image;
+ dirtyFlag = false;
}
#include <QImage>
#include <QObject>
#include <QPainter>
+#include <QRect>
+#include <QSize>
+#include <QMutex>
class DrawingArea: public QObject {
- Q_OBJECT
+/* Q_OBJECT */
public:
static const int DEFAULT_WIDTH = 640;
int width() const;
int height() const;
+ const QSize size() const;
void setColor(const QColor &color);
void setColor(float red, float green, float blue);
void drawPoint(int x, int y);
void drawLine(int x1, int y1, int x2, int y2);
- const QImage &getImage() const;
+ QImage &getImage();
-signals:
- void update();
+ bool isDirty() const;
+ void setDirty();
+ void setDirty(const QRect &rect);
+ void setClean();
+
+ QRect getDirtyRect() const;
+
+ void lock();
+ void unlock();
private:
QImage *image;
QPainter *painter;
-
+ bool dirtyFlag;
+ QRect dirtyRect;
+ QMutex mutex;
};
-#endif // !DRAWING_AREA_H
+inline
+int DrawingArea::width() const
+{
+ return image->width();
+}
+
+inline
+int DrawingArea::height() const
+{
+ return image->height();
+}
+inline
+const QSize DrawingArea::size() const
+{
+ return image->size();
+}
+inline
+QImage &DrawingArea::getImage()
+{
+ return *image;
+}
+inline
+bool DrawingArea::isDirty() const
+{
+ return dirtyFlag;
+}
+
+inline
+QRect DrawingArea::getDirtyRect() const
+{
+ return dirtyRect;
+}
+
+inline
+void DrawingArea::lock()
+{
+ mutex.lock();
+}
+
+inline
+void DrawingArea::unlock()
+{
+ mutex.unlock();
+}
+
+#endif // !DRAWING_AREA_H
#include "DrawingWindow.h"
#include <QPainter>
+#include <QPaintEvent>
#include <iostream>
-DrawingWindow::DrawingWindow(const DrawingArea &a)
+DrawingWindow::DrawingWindow(DrawingArea &a)
: QWidget()
, drawingArea(a)
+ , pixmap(a.size())
{
initialize();
}
-DrawingWindow::DrawingWindow(QWidget *parent, const DrawingArea &a)
+DrawingWindow::DrawingWindow(QWidget *parent, DrawingArea &a)
: QWidget(parent)
, drawingArea(a)
+ , pixmap(a.size())
{
initialize();
}
DrawingWindow::DrawingWindow(QWidget *parent, Qt::WindowFlags flags,
- const DrawingArea &a)
+ DrawingArea &a)
: QWidget(parent, flags)
, drawingArea(a)
+ , pixmap(a.size())
{
initialize();
}
-void DrawingWindow::paintEvent(QPaintEvent *)
+void DrawingWindow::paintEvent(QPaintEvent *ev)
{
- std::cerr << "paint!\n";
+ QRect rect = ev->rect();
+ drawingArea.lock();
+ if (drawingArea.isDirty()) {
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.drawImage(drawingArea.getDirtyRect(),
+ drawingArea.getImage(),
+ drawingArea.getDirtyRect());
+ drawingArea.setClean();
+ rect |= drawingArea.getDirtyRect();
+ }
+ drawingArea.unlock();
QPainter painter(this);
- painter.drawImage(0, 0, drawingArea.getImage());
+ painter.drawPixmap(0, 0, pixmap);
+}
+
+void DrawingWindow::timerEvent(QTimerEvent *ev)
+{
+ if (ev->timerId() == timer.timerId()) {
+ update();
+ } else {
+ QWidget::timerEvent(ev);
+ }
}
void DrawingWindow::initialize()
setFocusPolicy(Qt::StrongFocus);
setFixedSize(drawingArea.getImage().size());
setAttribute(Qt::WA_OpaquePaintEvent);
- connect(&drawingArea, SIGNAL(update()), this, SLOT(update()));
-
+ timer.start(50, this);
}
#define DRAWING_WINDOW_H
#include "DrawingArea.h"
+#include <QPixmap>
+#include <QTimer>
#include <QWidget>
class DrawingWindow: public QWidget {
+/* Q_OBJECT */
+
public:
- DrawingWindow(const DrawingArea &a);
- DrawingWindow(QWidget *parent, const DrawingArea &a);
- DrawingWindow(QWidget *parent, Qt::WindowFlags flags,
- const DrawingArea &a);
+ DrawingWindow(DrawingArea &a);
+ DrawingWindow(QWidget *parent, DrawingArea &a);
+ DrawingWindow(QWidget *parent, Qt::WindowFlags flags, DrawingArea &a);
protected:
- void paintEvent(QPaintEvent *e);
+ void paintEvent(QPaintEvent *ev);
+ void timerEvent(QTimerEvent *ev);
private:
- const DrawingArea &drawingArea;
+ DrawingArea &drawingArea;
+ QPixmap pixmap;
+ QBasicTimer timer;
void initialize();
};
#include <QApplication>
-
#include <DrawingArea.h>
#include <DrawingThread.h>
#include <DrawingWindow.h>
int c = 0;
int y = 0;
+ int h = a.height();
+ int w = a.width();
+ int count = 10;
while (1) {
- std::cerr << "loooooooooooooooooooooop "
- << y << " (" << c << ")\n";
+// std::cerr << "loooooooooooooooooooooop "
+// << y << " (" << c << ")\n";
a.setColor(c, c, c);
for (int yy = y; yy < y + 10; yy++)
- for (int x = 0; x < a.width(); x++)
+ for (int x = 0; x < w; x++)
a.drawPoint(x, yy);
- if ((y += 10) >= a.height()) {
+ if ((y += 10) >= h) {
y = 0;
c = !c;
+ if (!--count) break;
+ std::cerr << "loooooooooooooooooooooop "
+ << y << " (" << c << ")\n";
}
- sleep(1);
}
return 0;
}
CONFIG += qt debug
+QMAKE_CFLAGS += -O2
+QMAKE_CXXFLAGS += -O2
+
+QMAKE_CFLAGS += -pg
+QMAKE_CXXFLAGS += -pg
+QMAKE_LFLAGS += -pg
+
HEADERS += DrawingArea.h \
DrawingThread.h \
DrawingWindow.h