Home | History | Annotate | Download | only in qt
      1 /*
      2  * Copyright (C) 2006 Dirk Mueller <mueller (at) kde.org>
      3  * Copyright (C) 2006 Zack Rusin <zack (at) kde.org>
      4  * Copyright (C) 2006 Simon Hausmann <hausmann (at) kde.org>
      5  * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
      6  *
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     21  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     26  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "Image.h"
     33 
     34 #include "AffineTransform.h"
     35 #include "ImageObserver.h"
     36 #include "BitmapImage.h"
     37 #include "FloatRect.h"
     38 #include "PlatformString.h"
     39 #include "GraphicsContext.h"
     40 #include "StillImageQt.h"
     41 #include "qwebsettings.h"
     42 
     43 #include <QPixmap>
     44 #include <QPainter>
     45 #include <QImage>
     46 #include <QImageReader>
     47 #include <QTransform>
     48 
     49 #include <QDebug>
     50 
     51 #include <math.h>
     52 
     53 // This function loads resources into WebKit
     54 static QPixmap loadResourcePixmap(const char *name)
     55 {
     56     QPixmap pixmap;
     57     if (qstrcmp(name, "missingImage") == 0)
     58         pixmap = QWebSettings::webGraphic(QWebSettings::MissingImageGraphic);
     59     else if (qstrcmp(name, "nullPlugin") == 0)
     60         pixmap = QWebSettings::webGraphic(QWebSettings::MissingPluginGraphic);
     61     else if (qstrcmp(name, "urlIcon") == 0)
     62         pixmap = QWebSettings::webGraphic(QWebSettings::DefaultFrameIconGraphic);
     63     else if (qstrcmp(name, "textAreaResizeCorner") == 0)
     64         pixmap = QWebSettings::webGraphic(QWebSettings::TextAreaSizeGripCornerGraphic);
     65     else if (qstrcmp(name, "deleteButton") == 0)
     66         pixmap = QWebSettings::webGraphic(QWebSettings::DeleteButtonGraphic);
     67 
     68     return pixmap;
     69 }
     70 
     71 namespace WebCore {
     72 
     73 bool FrameData::clear(bool clearMetadata)
     74 {
     75     if (clearMetadata)
     76         m_haveMetadata = false;
     77 
     78     if (m_frame) {
     79         delete m_frame;
     80         m_frame = 0;
     81         return true;
     82     }
     83     return false;
     84 }
     85 
     86 
     87 // ================================================
     88 // Image Class
     89 // ================================================
     90 
     91 PassRefPtr<Image> Image::loadPlatformResource(const char* name)
     92 {
     93     return StillImage::create(loadResourcePixmap(name));
     94 }
     95 
     96 void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform,
     97                         const FloatPoint& phase, ColorSpace, CompositeOperator op, const FloatRect& destRect)
     98 {
     99     QPixmap* framePixmap = nativeImageForCurrentFrame();
    100     if (!framePixmap) // If it's too early we won't have an image yet.
    101         return;
    102 
    103     QPixmap pixmap = *framePixmap;
    104     QRect tr = QRectF(tileRect).toRect();
    105     if (tr.x() || tr.y() || tr.width() != pixmap.width() || tr.height() != pixmap.height())
    106         pixmap = pixmap.copy(tr);
    107 
    108     QBrush b(pixmap);
    109     b.setTransform(patternTransform);
    110     ctxt->save();
    111     ctxt->setCompositeOperation(op);
    112     QPainter* p = ctxt->platformContext();
    113     if (!pixmap.hasAlpha() && p->compositionMode() == QPainter::CompositionMode_SourceOver)
    114         p->setCompositionMode(QPainter::CompositionMode_Source);
    115     p->setBrushOrigin(phase);
    116     p->fillRect(destRect, b);
    117     ctxt->restore();
    118 
    119     if (imageObserver())
    120         imageObserver()->didDraw(this);
    121 }
    122 
    123 BitmapImage::BitmapImage(QPixmap* pixmap, ImageObserver* observer)
    124     : Image(observer)
    125     , m_currentFrame(0)
    126     , m_frames(0)
    127     , m_frameTimer(0)
    128     , m_repetitionCount(cAnimationNone)
    129     , m_repetitionCountStatus(Unknown)
    130     , m_repetitionsComplete(0)
    131     , m_isSolidColor(false)
    132     , m_checkedForSolidColor(false)
    133     , m_animationFinished(true)
    134     , m_allDataReceived(true)
    135     , m_haveSize(true)
    136     , m_sizeAvailable(true)
    137     , m_decodedSize(0)
    138     , m_haveFrameCount(true)
    139     , m_frameCount(1)
    140 {
    141     initPlatformData();
    142 
    143     int width = pixmap->width();
    144     int height = pixmap->height();
    145     m_decodedSize = width * height * 4;
    146     m_size = IntSize(width, height);
    147 
    148     m_frames.grow(1);
    149     m_frames[0].m_frame = pixmap;
    150     m_frames[0].m_hasAlpha = pixmap->hasAlpha();
    151     m_frames[0].m_haveMetadata = true;
    152     checkForSolidColor();
    153 }
    154 
    155 void BitmapImage::initPlatformData()
    156 {
    157 }
    158 
    159 void BitmapImage::invalidatePlatformData()
    160 {
    161 }
    162 
    163 // Drawing Routines
    164 void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
    165                        const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op)
    166 {
    167     startAnimation();
    168 
    169     QPixmap* image = nativeImageForCurrentFrame();
    170     if (!image)
    171         return;
    172 
    173     if (mayFillWithSolidColor()) {
    174         fillWithSolidColor(ctxt, dst, solidColor(), styleColorSpace, op);
    175         return;
    176     }
    177 
    178     IntSize selfSize = size();
    179 
    180     ctxt->save();
    181 
    182     // Set the compositing operation.
    183     ctxt->setCompositeOperation(op);
    184 
    185     QPainter* painter(ctxt->platformContext());
    186 
    187     if (!image->hasAlpha() && painter->compositionMode() == QPainter::CompositionMode_SourceOver)
    188         painter->setCompositionMode(QPainter::CompositionMode_Source);
    189 
    190     // Test using example site at
    191     // http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
    192     painter->drawPixmap(dst, *image, src);
    193 
    194     ctxt->restore();
    195 
    196     if (imageObserver())
    197         imageObserver()->didDraw(this);
    198 }
    199 
    200 void BitmapImage::checkForSolidColor()
    201 {
    202     m_isSolidColor = false;
    203     m_checkedForSolidColor = true;
    204 
    205     if (frameCount() > 1)
    206         return;
    207 
    208     QPixmap* framePixmap = frameAtIndex(0);
    209     if (!framePixmap || framePixmap->width() != 1 || framePixmap->height() != 1)
    210         return;
    211 
    212     m_isSolidColor = true;
    213     m_solidColor = QColor::fromRgba(framePixmap->toImage().pixel(0, 0));
    214 }
    215 
    216 #if OS(WINDOWS)
    217 PassRefPtr<BitmapImage> BitmapImage::create(HBITMAP hBitmap)
    218 {
    219     return BitmapImage::create(new QPixmap(QPixmap::fromWinHBITMAP(hBitmap)));
    220 }
    221 #endif
    222 
    223 }
    224 
    225 
    226 // vim: ts=4 sw=4 et
    227