ganeswidgets/src/hgqtquadrenderer.cpp
changeset 2 49c70dcc3f17
child 5 4fa04caf0f43
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ganeswidgets/src/hgqtquadrenderer.cpp	Fri May 14 16:57:01 2010 +0300
@@ -0,0 +1,319 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:    
+*
+*/
+
+#include "hgqtquadrenderer.h"
+#include "hgquad.h"
+#include "hgtransformedquad.h"
+#include "trace.h"
+#include "hgimage.h"
+
+#include <qvector2d>
+#include <qpolygon>
+#include <qmatrix4x4>
+#include <qpainter>
+#include <qpixmapcache>
+
+
+class HgQtImage : public HgImage
+{
+public:    
+    HgQtImage(HgQtQuadRenderer* renderer)
+    {
+        
+    }
+
+    ~HgQtImage()
+    {
+    }
+
+    int width() const
+    {
+        return mPixmap.width();
+    }
+
+    int height() const
+    {
+        return mPixmap.height();
+    }
+
+    int mirrorImageWidth() const
+    {
+        return width();
+    }
+
+    int mirrorImageHeight() const
+    {
+        return height();
+    }
+
+    void setImage(const QImage& image)
+    {
+        mPixmap = QPixmap::fromImage(image);
+        //mMirrorPixmap = QPixmap();
+    }
+    
+    void setPixmap(const QPixmap& pixmap)
+    {
+        mPixmap = pixmap;
+        //mMirrorPixmap = QPixmap();
+    }
+    
+    void releaseImage()
+    {
+        //mPixmap = QPixmap();
+        //mMirrorPixmap = QPixmap();
+    }
+    
+    QImage getQImage() const
+    {
+        return mPixmap.toImage();
+    }
+        
+    const QPixmap& pixmap() const
+    {
+        return mPixmap;
+    }
+    
+    const QPixmap& mirrorPixmap(QPainter* painter)
+    {
+
+        return mPixmap;
+/*        
+        if (mPixmap.isNull())
+            return mPixmap;
+
+        if (mMirrorPixmap.isNull())
+        {
+            QImage img = mPixmap.toImage();
+            QImage mirrorImage = img.scaled(QSize(img.width()/3,img.height()/3)).convertToFormat(QImage::Format_ARGB32);
+            
+            // apply gradient to alpha channel so that mirror image looks like
+            // it fades under the floor
+            for (int i = 0; i < mirrorImage.height(); i++)
+            {
+                qreal t = qreal(i) / qreal(mirrorImage.height());
+                int a = (int)(t * 255.0);
+                uchar* scanline = mirrorImage.scanLine(i);
+                for (int j = 0; j < mirrorImage.width(); j++)
+                {
+                    scanline[j*4+0] /= 3;
+                    scanline[j*4+1] /= 3;
+                    scanline[j*4+2] /= 3;
+                    scanline[j*4+3] = 255;
+                }        
+            }
+            
+            mMirrorPixmap = QPixmap::fromImage(mirrorImage);
+            
+            QPaintDevice* device = painter->device();
+            painter->end();
+
+            mMirrorPixmap = mPixmap.scaled(100,100);
+            int w = mMirrorPixmap.width();
+            int h = mMirrorPixmap.height();
+            //QPainter p;
+            painter->begin(&mMirrorPixmap);
+            painter->fillRect(0,0,w, h, QColor::fromRgbF(0, 0, 0, 0.5f));
+            painter->end();
+
+            painter->begin(device);
+        
+        }
+        
+        
+        return mMirrorPixmap;*/
+    }
+
+    QPixmap mPixmap;
+};
+
+class HgQtQuad : public HgTransformedQuad
+{
+public:
+    
+    HgQtQuad(HgQtQuadRenderer* renderer) : HgTransformedQuad(-1), mRenderer(renderer)
+    {
+        
+    }
+
+    ~HgQtQuad()
+    {
+        
+    }
+
+    void draw(QPainter* painter, const QRectF& rect)    
+    {
+        if (!quad()->visible())
+            return;
+                
+        HgQtImage* image = (HgQtImage*)quad()->image();        
+        if (image == NULL)
+            image = mRenderer->defaultImage();
+        
+        if (image == NULL)
+            return;
+        
+        if (image->pixmap().isNull())
+            image = mRenderer->defaultImage();
+        
+        drawImage(painter, image, rect);                      
+    }
+
+    
+private:
+
+    void computeWarpMatrix(QTransform& tm, int pxWidth, int pxHeight, const QVector2D* points)
+    {
+        QPolygonF poly;
+
+        poly << points[0].toPointF();
+        poly << points[1].toPointF();
+        poly << points[2].toPointF();
+        poly << points[3].toPointF();
+
+        QPolygonF img;
+
+        img.append(QPointF(0,pxHeight));
+        img.append(QPointF(pxWidth,pxHeight));
+        img.append(QPointF(pxWidth,0));
+        img.append(QPointF(0,0));
+
+        QTransform::quadToQuad(img, poly, tm);
+    }
+    
+    void drawImage(QPainter* painter, HgQtImage* image, const QRectF& rect)
+    {
+        const QPixmap& pixmap = image->pixmap();
+        
+        if (pixmap.isNull())            
+            return;
+        
+        const QVector2D* points = mTransformedPoints;
+        if (mRenderer->isReflection() && quad()->mirrorImageEnabled())
+            points = mMirroredPoints;
+        
+        QPolygonF poly;
+        poly << points[0].toPointF();
+        poly << points[1].toPointF();
+        poly << points[2].toPointF();
+        poly << points[3].toPointF();        
+        QRectF bounds = poly.boundingRect();
+        if (!(bounds.intersects(rect) || rect.contains(bounds))) {
+            return;
+        }
+        
+        computeWarpMatrix(mTransform, image->width(), image->height(), points);
+        
+        QTransform base = painter->transform(); 
+        painter->setTransform(mTransform * base);    
+        painter->drawPixmap(QPointF(0,0), pixmap);
+        painter->setTransform(base);
+    }
+
+    HgQtQuadRenderer* mRenderer;
+    QTransform mTransform;
+    QTransform mMirrorTransform;
+};
+
+
+HgQtQuadRenderer::HgQtQuadRenderer(int maxQuads) : 
+    HgTransformedQuadRenderer(maxQuads),
+    mDefaultQtImage(NULL)
+{
+    // initialize base class to the end.
+    init(maxQuads);
+    QImage image(QSize(200,200), QImage::Format_RGB16);
+    image.fill(0xFFFFFFFF);
+    setDefaultImage(image);
+    
+    QPixmapCache::setCacheLimit(2048);
+}
+
+HgQtQuadRenderer::~HgQtQuadRenderer()
+{
+    delete mDefaultQtImage;
+}
+
+void HgQtQuadRenderer::drawQuads(QPainter* painter, const QRectF& rect, 
+    const QMatrix4x4& viewMatrix, const QMatrix4x4& projectionMatrix,
+    Qt::Orientation orientation, 
+    const QTransform& sceneTransform)
+{
+
+    transformQuads(viewMatrix, projectionMatrix, 
+        QPointF(rect.width()/2, rect.height()/2), QSizeF(rect.width(), rect.height()));
+    
+    // save old transform
+    QTransform temp = painter->transform();
+
+    if (mReflectionsEnabled) 
+    {
+        mIsReflection = true;
+
+        drawTransformedQuads(painter, rect);
+    
+        drawFloor(painter, rect);
+    }
+    
+    mIsReflection = false;
+    
+    drawTransformedQuads(painter, rect);
+        
+    painter->setTransform(temp);
+    
+}
+
+HgImage* HgQtQuadRenderer::createNativeImage()
+{    
+    return new HgQtImage(this);   
+}
+
+HgQtImage* HgQtQuadRenderer::defaultImage()
+{
+    return mDefaultQtImage;
+}
+
+void HgQtQuadRenderer::setDefaultImage(QImage defaultImage)
+{
+    HgQuadRenderer::setDefaultImage(defaultImage);
+    
+    delete mDefaultQtImage;
+    mDefaultQtImage = 0;
+    
+    mDefaultQtImage = static_cast<HgQtImage*>(createNativeImage());
+    mDefaultQtImage->setImage(mDefaultImage);
+
+}
+
+HgTransformedQuad* HgQtQuadRenderer::createNativeQuad()
+{
+    return new HgQtQuad(this);
+}
+
+bool HgQtQuadRenderer::isReflection() const
+{
+    return mIsReflection;
+}
+
+void HgQtQuadRenderer::drawFloor(QPainter* painter, const QRectF& rect)
+{
+    QRectF floorRect(0, rect.height()/2, rect.width(), rect.height()/2);
+    QBrush brush(QColor::fromRgbF(0,0,0,0.5f));
+    painter->setBrush(brush);
+    painter->drawRect(floorRect);
+}
+