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