Home | History | Annotate | Download | only in qt
      1 /*
      2  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
      3 
      4  This library is free software; you can redistribute it and/or
      5  modify it under the terms of the GNU Library General Public
      6  License as published by the Free Software Foundation; either
      7  version 2 of the License, or (at your option) any later version.
      8 
      9  This library is distributed in the hope that it will be useful,
     10  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  Library General Public License for more details.
     13 
     14  You should have received a copy of the GNU Library General Public License
     15  along with this library; see the file COPYING.LIB.  If not, write to
     16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  Boston, MA 02110-1301, USA.
     18  */
     19 
     20 #include "config.h"
     21 #include "TextureMapperQt.h"
     22 
     23 #include <QtCore/qdebug.h>
     24 #include <QtGui/qpaintengine.h>
     25 #include <QtGui/qpixmap.h>
     26 
     27 #ifdef QT_OPENGL_LIB
     28 # include "opengl/TextureMapperGL.h"
     29 #endif
     30 
     31 namespace WebCore {
     32 
     33 void BitmapTextureQt::destroy()
     34 {
     35     if (m_pixmap.paintingActive())
     36         qFatal("Destroying an active pixmap");
     37     m_pixmap = QPixmap();
     38 }
     39 
     40 void BitmapTextureQt::reset(const IntSize& size, bool isOpaque)
     41 {
     42     BitmapTexture::reset(size, isOpaque);
     43 
     44     if (size.width() > m_pixmap.size().width() || size.height() > m_pixmap.size().height() || m_pixmap.isNull())
     45         m_pixmap = QPixmap(size.width(), size.height());
     46     if (!isOpaque)
     47         m_pixmap.fill(Qt::transparent);
     48 }
     49 
     50 PlatformGraphicsContext* BitmapTextureQt::beginPaint(const IntRect& dirtyRect)
     51 {
     52     m_painter.begin(&m_pixmap);
     53     TextureMapperQt::initialize(&m_painter);
     54     m_painter.setCompositionMode(QPainter::CompositionMode_Clear);
     55     m_painter.fillRect(QRect(dirtyRect), Qt::transparent);
     56     m_painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
     57     return &m_painter;
     58 }
     59 
     60 void BitmapTextureQt::endPaint()
     61 {
     62     m_painter.end();
     63 }
     64 
     65 bool BitmapTextureQt::save(const String& path)
     66 {
     67     return m_pixmap.save(path, "PNG");
     68 }
     69 
     70 void BitmapTextureQt::setContentsToImage(Image* image)
     71 {
     72     if (!image)
     73         return;
     74     const QPixmap* pixmap = image->nativeImageForCurrentFrame();
     75     if (!pixmap)
     76         return;
     77     BitmapTexture::reset(pixmap->size(), !pixmap->hasAlphaChannel());
     78     m_pixmap = *pixmap;
     79 }
     80 
     81 void BitmapTextureQt::pack()
     82 {
     83     if (m_pixmap.isNull())
     84         return;
     85 
     86     m_image = m_pixmap.toImage();
     87     m_pixmap = QPixmap();
     88     m_isPacked = true;
     89 }
     90 
     91 void BitmapTextureQt::unpack()
     92 {
     93     m_isPacked = false;
     94     if (m_image.isNull())
     95         return;
     96 
     97     m_pixmap = QPixmap::fromImage(m_image);
     98     m_image = QImage();
     99 }
    100 
    101 void TextureMapperQt::setClip(const IntRect& rect)
    102 {
    103      QPainter* painter = m_currentSurface ? &m_currentSurface->m_painter : m_painter;
    104      painter->setClipRect(rect);
    105 }
    106 
    107 TextureMapperQt::TextureMapperQt()
    108     : m_currentSurface(0)
    109 {
    110 }
    111 
    112 void TextureMapperQt::setGraphicsContext(GraphicsContext* context)
    113 {
    114     m_painter = context->platformContext();
    115     initialize(m_painter);
    116 }
    117 
    118 void TextureMapperQt::bindSurface(BitmapTexture* surface)
    119 {
    120     if (m_currentSurface == surface)
    121         return;
    122     if (m_currentSurface)
    123         m_currentSurface->m_painter.end();
    124     if (!surface) {
    125         m_currentSurface = 0;
    126         return;
    127     }
    128     BitmapTextureQt* surfaceQt = static_cast<BitmapTextureQt*>(surface);
    129     if (!surfaceQt->m_painter.isActive())
    130         surfaceQt->m_painter.begin(&surfaceQt->m_pixmap);
    131     m_currentSurface = surfaceQt;
    132 }
    133 
    134 
    135 void TextureMapperQt::drawTexture(const BitmapTexture& texture, const IntRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture)
    136 {
    137     const BitmapTextureQt& textureQt = static_cast<const BitmapTextureQt&>(texture);
    138     QPainter* painter = m_painter;
    139     QPixmap pixmap = textureQt.m_pixmap;
    140     if (m_currentSurface)
    141         painter = &m_currentSurface->m_painter;
    142 
    143     if (maskTexture && maskTexture->isValid()) {
    144         const BitmapTextureQt* mask = static_cast<const BitmapTextureQt*>(maskTexture);
    145         QPixmap intermediatePixmap(pixmap.size());
    146         intermediatePixmap.fill(Qt::transparent);
    147         QPainter maskPainter(&intermediatePixmap);
    148         maskPainter.setCompositionMode(QPainter::CompositionMode_Source);
    149         maskPainter.drawPixmap(0, 0, pixmap);
    150         maskPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
    151         maskPainter.drawPixmap(QRect(0, 0, pixmap.width(), pixmap.height()), mask->m_pixmap, mask->sourceRect());
    152         maskPainter.end();
    153         pixmap = intermediatePixmap;
    154     }
    155 
    156     const qreal prevOpacity = painter->opacity();
    157     const QTransform prevTransform = painter->transform();
    158     painter->setOpacity(opacity);
    159     painter->setTransform(matrix, true);
    160     painter->drawPixmap(targetRect, pixmap, textureQt.sourceRect());
    161     painter->setTransform(prevTransform);
    162     painter->setOpacity(prevOpacity);
    163 }
    164 
    165 PassOwnPtr<TextureMapper> TextureMapper::create(GraphicsContext* context)
    166 {
    167 #ifdef QT_OPENGL_LIB
    168     if (context && context->platformContext()->paintEngine()->type() == QPaintEngine::OpenGL2)
    169         return new TextureMapperGL;
    170 #endif
    171     return new TextureMapperQt;
    172 }
    173 
    174 PassRefPtr<BitmapTexture> TextureMapperQt::createTexture()
    175 {
    176     return adoptRef(new BitmapTextureQt());
    177 }
    178 
    179 BitmapTextureQt::BitmapTextureQt()
    180     : m_isPacked(false)
    181 {
    182 
    183 }
    184 
    185 #ifdef QT_OPENGL_LIB
    186 class RGBA32PremultimpliedBufferQt : public RGBA32PremultimpliedBuffer {
    187 public:
    188     virtual PlatformGraphicsContext* beginPaint(const IntRect& rect, bool opaque)
    189     {
    190         // m_image is only using during paint, it's safe to override it.
    191         m_image = QImage(rect.size().width(), rect.size().height(), QImage::Format_ARGB32_Premultiplied);
    192         if (!opaque)
    193             m_image.fill(0);
    194         m_painter.begin(&m_image);
    195         TextureMapperQt::initialize(&m_painter);
    196         m_painter.translate(-rect.x(), -rect.y());
    197         return &m_painter;
    198     }
    199 
    200     virtual void endPaint() { m_painter.end(); }
    201     virtual const void* data() const { return m_image.constBits(); }
    202 
    203 private:
    204     QPainter m_painter;
    205     QImage m_image;
    206 };
    207 
    208 PassRefPtr<RGBA32PremultimpliedBuffer> RGBA32PremultimpliedBuffer::create()
    209 {
    210     return adoptRef(new RGBA32PremultimpliedBufferQt());
    211 }
    212 
    213 #endif
    214 };
    215