Use the new antialiasing property for canvas painting
authorCharles Yin <charles.yin@nokia.com>
Mon, 27 Aug 2012 01:36:42 +0000 (11:36 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 27 Aug 2012 23:14:17 +0000 (01:14 +0200)
Change-Id: I76f21d055696978f2f6936006eea038dd73cce6c
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
src/quick/items/context2d/qquickcanvascontext.cpp
src/quick/items/context2d/qquickcanvascontext_p.h
src/quick/items/context2d/qquickcanvasitem.cpp
src/quick/items/context2d/qquickcontext2d.cpp
src/quick/items/context2d/qquickcontext2d_p.h
src/quick/items/context2d/qquickcontext2dtexture.cpp
src/quick/items/context2d/qquickcontext2dtexture_p.h
src/quick/items/context2d/qquickcontext2dtile.cpp
src/quick/items/context2d/qquickcontext2dtile_p.h
tests/auto/quick/qquickcanvasitem/data/CanvasComponent.qml

index 39f178b..e40b689 100644 (file)
@@ -53,13 +53,14 @@ QQuickCanvasContext::~QQuickCanvasContext()
 {
 }
 
-void QQuickCanvasContext::prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth)
+void QQuickCanvasContext::prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing)
 {
     Q_UNUSED(canvasSize);
     Q_UNUSED(tileSize);
     Q_UNUSED(canvasWindow);
     Q_UNUSED(dirtyRect);
     Q_UNUSED(smooth);
+    Q_UNUSED(antialiasing);
 }
 
 void QQuickCanvasContext::flush()
index 37ce698..66b1fc8 100644 (file)
@@ -67,7 +67,7 @@ public:
     // Init (ignore options if necessary)
     virtual void init(QQuickCanvasItem *canvasItem, const QVariantMap &args) = 0;
 
-    virtual void prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth);
+    virtual void prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing);
     virtual void flush();
 
     virtual void setV8Engine(QV8Engine *engine) = 0;
index 4eb8f62..5a29928 100644 (file)
@@ -647,7 +647,7 @@ void QQuickCanvasItem::updatePolish()
     Q_D(QQuickCanvasItem);
 
     if (d->contextInitialized)
-        d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth);
+        d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, d->antialiasing);
 
     if (d->animationCallbacks.size() > 0 && isVisible()) {
         QMap<int, v8::Persistent<v8::Function> > animationCallbacks = d->animationCallbacks;
@@ -691,6 +691,11 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
     if (!node)
         node = new QSGSimpleTextureNode;
 
+    if (d->smooth)
+        node->setFiltering(QSGTexture::Linear);
+    else
+        node->setFiltering(QSGTexture::Nearest);
+
     if (d->renderStrategy == QQuickCanvasItem::Cooperative)
         d->context->flush();
 
index 981e075..cb7f44a 100644 (file)
@@ -3397,7 +3397,7 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args
     m_texture->setTileSize(canvasItem->tileSize());
     m_texture->setCanvasSize(canvasItem->canvasSize().toSize());
     m_texture->setSmooth(canvasItem->smooth());
-
+    m_texture->setAntialiasing(canvasItem->antialiasing());
     m_thread = QThread::currentThread();
 
     QThread *renderThread = m_thread;
@@ -3426,16 +3426,17 @@ void QQuickContext2D::init(QQuickCanvasItem *canvasItem, const QVariantMap &args
     reset();
 }
 
-void QQuickContext2D::prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth)
+void QQuickContext2D::prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing)
 {
-    QMetaObject::invokeMethod(m_texture,
-                                                               "canvasChanged",
-                                                               Qt::AutoConnection,
-                                                               Q_ARG(QSize, canvasSize),
-                                                               Q_ARG(QSize, tileSize),
-                                                               Q_ARG(QRect, canvasWindow),
-                                                               Q_ARG(QRect, dirtyRect),
-                                                               Q_ARG(bool, smooth));
+    QMetaObject::invokeMethod(m_texture
+                                                , "canvasChanged"
+                                                , Qt::AutoConnection
+                                                , Q_ARG(QSize, canvasSize)
+                                                , Q_ARG(QSize, tileSize)
+                                                , Q_ARG(QRect, canvasWindow)
+                                                , Q_ARG(QRect, dirtyRect)
+                                                , Q_ARG(bool, smooth)
+                                                , Q_ARG(bool, antialiasing));
 }
 
 void QQuickContext2D::flush()
index 295be05..b9621dd 100644 (file)
@@ -169,7 +169,7 @@ public:
 
     QStringList contextNames() const;
     void init(QQuickCanvasItem *canvasItem, const QVariantMap &args);
-    void prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth);
+    void prepare(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing);
     void flush();
     void sync();
     QThread *thread() const {return m_thread;}
index a315d30..169c03b 100644 (file)
@@ -93,7 +93,8 @@ QQuickContext2DTexture::QQuickContext2DTexture()
     , m_dirtyCanvas(false)
     , m_canvasWindowChanged(false)
     , m_dirtyTexture(false)
-    , m_smooth(false)
+    , m_smooth(true)
+    , m_antialiasing(false)
     , m_tiledCanvas(false)
     , m_painting(false)
 {
@@ -141,6 +142,11 @@ void QQuickContext2DTexture::setSmooth(bool smooth)
     m_smooth = smooth;
 }
 
+void QQuickContext2DTexture::setAntialiasing(bool antialiasing)
+{
+    m_antialiasing = antialiasing;
+}
+
 void QQuickContext2DTexture::setItem(QQuickCanvasItem* item)
 {
     m_item = item;
@@ -174,7 +180,7 @@ bool QQuickContext2DTexture::setDirtyRect(const QRect &r)
     return doDirty;
 }
 
-void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth)
+void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing)
 {
     QSize ts = tileSize;
     if (ts.width() > canvasSize.width())
@@ -198,6 +204,7 @@ void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize&
         setDirtyRect(dirtyRect);
 
     setSmooth(smooth);
+    setAntialiasing(antialiasing);
 }
 
 void QQuickContext2DTexture::paintWithoutTiles(QQuickContext2DCommandBuffer *ccb)
@@ -213,12 +220,16 @@ void QQuickContext2DTexture::paintWithoutTiles(QQuickContext2DCommandBuffer *ccb
 
     QPainter p;
     p.begin(device);
+    if (m_antialiasing)
+        p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, true);
+    else
+        p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, false);
+
     if (m_smooth)
-        p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
-                               | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+        p.setRenderHint(QPainter::SmoothPixmapTransform, true);
     else
-        p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
-                                 | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, false);
+        p.setRenderHint(QPainter::SmoothPixmapTransform, false);
+
     p.setCompositionMode(QPainter::CompositionMode_SourceOver);
 
     ccb->replay(&p, m_state);
@@ -262,7 +273,7 @@ void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb)
             QQuickContext2D::State oldState = m_state;
             foreach (QQuickContext2DTile* tile, m_tiles) {
                 if (tile->dirty()) {
-                    ccb->replay(tile->createPainter(m_smooth), oldState);
+                    ccb->replay(tile->createPainter(m_smooth, m_antialiasing), oldState);
                     tile->drawFinished();
                     tile->markDirty(false);
                 }
@@ -444,7 +455,7 @@ bool QQuickContext2DFBOTexture::doMultisampling() const
         extensionsChecked = true;
     }
 
-    return multisamplingSupported  && m_smooth;
+    return multisamplingSupported  && m_antialiasing;
 }
 
 void QQuickContext2DFBOTexture::grabImage(const QRectF& rf)
index 6841855..3730021 100644 (file)
@@ -77,6 +77,7 @@ public:
     bool setTileSize(const QSize &size);
     bool setCanvasWindow(const QRect& canvasWindow);
     void setSmooth(bool smooth);
+    void setAntialiasing(bool antialiasing);
     bool setDirtyRect(const QRect &dirtyRect);
     bool canvasDestroyed();
 
@@ -86,7 +87,7 @@ Q_SIGNALS:
 public Q_SLOTS:
     void markDirtyTexture();
     void setItem(QQuickCanvasItem* item);
-    void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth);
+    void canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing);
     void paint(QQuickContext2DCommandBuffer *ccb);
     virtual void grabImage(const QRectF& region = QRectF()) = 0;
 
@@ -115,6 +116,7 @@ protected:
     uint m_canvasWindowChanged : 1;
     uint m_dirtyTexture : 1;
     uint m_smooth : 1;
+    uint m_antialiasing : 1;
     uint m_tiledCanvas : 1;
     uint m_painting : 1;
 };
index 046300a..71aa0c9 100644 (file)
@@ -60,7 +60,7 @@ QQuickContext2DTile::~QQuickContext2DTile()
         m_painter.end();
 }
 
-QPainter* QQuickContext2DTile::createPainter(bool smooth)
+QPainter* QQuickContext2DTile::createPainter(bool smooth, bool antialiasing)
 {
     if (m_painter.isActive())
         m_painter.end();
@@ -78,12 +78,16 @@ QPainter* QQuickContext2DTile::createPainter(bool smooth)
             v = 150;
         m_painter.fillRect(QRect(0, 0, m_rect.width(), m_rect.height()), QColor(v, v, v, 255));
 #endif
+
+        if (antialiasing)
+            m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, true);
+        else
+            m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, false);
+
         if (smooth)
-            m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
-                                   | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+            m_painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
         else
-            m_painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing
-                                     | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, false);
+            m_painter.setRenderHint(QPainter::SmoothPixmapTransform, false);
 
         m_painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
         m_painter.translate(-m_rect.left(), -m_rect.top());
index 2e6d61c..11f3618 100644 (file)
@@ -64,7 +64,7 @@ public:
     QRect rect() const {return m_rect;}
 
     virtual void setRect(const QRect& r) = 0;
-    virtual QPainter* createPainter(bool smooth = false);
+    virtual QPainter* createPainter(bool smooth, bool antialiasing);
     virtual void drawFinished() {}
 
 protected:
index 12c1c89..b9e8d75 100644 (file)
@@ -6,7 +6,6 @@ Component {
         Canvas {
             id:c
              width:100;height:100
-             smooth:false //this line is needed for some tests (smooth painting can change the colors and alpha channel values)
              onPaint :{} //this line is needed for some tests (make sure onPaint handler always called
              property alias paintCount:spyPaint.count
              property alias paintedCount:spyPainted.count