rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2006 Dirk Mueller <mueller@kde.org> |
| 3 | * Copyright (C) 2006 Zack Rusin <zack@kde.org> |
| 4 | * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org> |
| 5 | * |
| 6 | * All rights reserved. |
| 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without |
| 9 | * modification, are permitted provided that the following conditions |
| 10 | * are met: |
| 11 | * 1. Redistributions of source code must retain the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer. |
| 13 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. |
| 16 | * |
| 17 | * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| 18 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 20 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| 21 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 23 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 24 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 25 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | */ |
| 29 | |
| 30 | #include "config.h" |
| 31 | #include "Image.h" |
| 32 | |
eseidel | 6195285 | 2006-12-29 01:57:44 +0000 | [diff] [blame] | 33 | #include "BitmapImage.h" |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 34 | #include "FloatRect.h" |
ap | c5efe7e | 2006-09-06 17:17:42 +0000 | [diff] [blame] | 35 | #include "PlatformString.h" |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 36 | #include "GraphicsContext.h" |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 37 | #include "AffineTransform.h" |
kevino | 64ee95c | 2007-05-28 00:39:59 +0000 | [diff] [blame] | 38 | #include "NotImplemented.h" |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 39 | |
| 40 | #include <QPixmap> |
| 41 | #include <QPainter> |
| 42 | #include <QImage> |
| 43 | #include <QImageReader> |
staikos | 309162b | 2007-01-23 18:18:19 +0000 | [diff] [blame] | 44 | #if QT_VERSION >= 0x040300 |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 45 | #include <QTransform> |
staikos | 309162b | 2007-01-23 18:18:19 +0000 | [diff] [blame] | 46 | #endif |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 47 | |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 48 | #include <QDebug> |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 49 | |
| 50 | #include <math.h> |
| 51 | |
staikos | cdc883d | 2007-06-22 03:29:41 +0000 | [diff] [blame^] | 52 | // This function loads resources into WebKit |
| 53 | QPixmap loadResourcePixmap(const char*); |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 54 | |
| 55 | namespace WebCore { |
| 56 | |
| 57 | void FrameData::clear() |
| 58 | { |
| 59 | if (m_frame) { |
| 60 | m_frame = 0; |
aroben | 3bad1044 | 2006-08-25 16:46:35 +0000 | [diff] [blame] | 61 | m_duration = 0.0f; |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 62 | m_hasAlpha = true; |
| 63 | } |
| 64 | } |
| 65 | |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 66 | |
| 67 | |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 68 | // ================================================ |
| 69 | // Image Class |
| 70 | // ================================================ |
| 71 | |
ap | 3924f3a | 2006-08-26 09:51:46 +0000 | [diff] [blame] | 72 | Image* Image::loadPlatformResource(const char* name) |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 73 | { |
staikos | cdc883d | 2007-06-22 03:29:41 +0000 | [diff] [blame^] | 74 | BitmapImage* img = new BitmapImage(loadResourcePixmap(name)); |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 75 | return img; |
| 76 | } |
| 77 | |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 78 | |
| 79 | void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, |
| 80 | const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect) |
| 81 | { |
| 82 | notImplemented(); |
| 83 | } |
| 84 | |
staikos | cdc883d | 2007-06-22 03:29:41 +0000 | [diff] [blame^] | 85 | BitmapImage::BitmapImage(const QPixmap &pixmap, ImageObserver *observer) |
| 86 | : Image(observer) |
| 87 | , m_currentFrame(0) |
| 88 | , m_frames(0) |
| 89 | , m_frameTimer(0) |
| 90 | , m_repetitionCount(0) |
| 91 | , m_repetitionsComplete(0) |
| 92 | , m_isSolidColor(false) |
| 93 | , m_animatingImageType(true) |
| 94 | , m_animationFinished(false) |
| 95 | , m_allDataReceived(false) |
| 96 | , m_haveSize(false) |
| 97 | , m_sizeAvailable(false) |
| 98 | , m_decodedSize(0) |
| 99 | { |
| 100 | m_pixmap = new QPixmap(pixmap); |
| 101 | } |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 102 | |
| 103 | void BitmapImage::initPlatformData() |
| 104 | { |
staikos | cdc883d | 2007-06-22 03:29:41 +0000 | [diff] [blame^] | 105 | m_pixmap = 0; |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 106 | } |
| 107 | |
| 108 | void BitmapImage::invalidatePlatformData() |
| 109 | { |
staikos | cdc883d | 2007-06-22 03:29:41 +0000 | [diff] [blame^] | 110 | delete m_pixmap; |
| 111 | m_pixmap = 0; |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 112 | } |
| 113 | |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 114 | // Drawing Routines |
eseidel | 6195285 | 2006-12-29 01:57:44 +0000 | [diff] [blame] | 115 | void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 116 | const FloatRect& src, CompositeOperator op) |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 117 | { |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 118 | QPixmap* image = nativeImageForCurrentFrame(); |
| 119 | if (!image) |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 120 | return; |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 121 | |
| 122 | if (mayFillWithSolidColor()) { |
| 123 | fillWithSolidColor(ctxt, dst, solidColor(), op); |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 124 | return; |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 125 | } |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 126 | |
| 127 | IntSize selfSize = size(); |
| 128 | FloatRect srcRect(src); |
| 129 | FloatRect dstRect(dst); |
| 130 | |
| 131 | ctxt->save(); |
| 132 | |
| 133 | // Set the compositing operation. |
| 134 | ctxt->setCompositeOperation(op); |
| 135 | |
aroben | 8c8a13e | 2006-08-24 18:32:46 +0000 | [diff] [blame] | 136 | QPainter* painter(ctxt->platformContext()); |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 137 | |
| 138 | // Test using example site at |
| 139 | // http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html |
zack | bfb6351 | 2007-01-15 17:19:24 +0000 | [diff] [blame] | 140 | painter->drawPixmap(dst, *image, src); |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 141 | |
| 142 | ctxt->restore(); |
| 143 | |
| 144 | startAnimation(); |
| 145 | } |
| 146 | |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 147 | void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, |
| 148 | const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect) |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 149 | { |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 150 | QPixmap* framePixmap = nativeImageForCurrentFrame(); |
| 151 | if (!framePixmap) // If it's too early we won't have an image yet. |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 152 | return; |
zack | d2a180a | 2007-01-26 08:25:32 +0000 | [diff] [blame] | 153 | |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 154 | QPixmap pixmap = *framePixmap; |
| 155 | QRect tr = QRectF(tileRect).toRect(); |
zack | b9f5486 | 2007-01-26 08:54:19 +0000 | [diff] [blame] | 156 | if (tr.x() || tr.y() || tr.width() != pixmap.width() || tr.height() != pixmap.height()) { |
lars | f6076a4 | 2007-01-17 19:04:39 +0000 | [diff] [blame] | 157 | pixmap = pixmap.copy(tr); |
zack | b9f5486 | 2007-01-26 08:54:19 +0000 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | if (patternTransform.isIdentity()) { |
| 161 | ctxt->save(); |
| 162 | ctxt->setCompositeOperation(op); |
| 163 | QPainter* p = ctxt->platformContext(); |
| 164 | p->setBrushOrigin(phase); |
| 165 | p->drawTiledPixmap(destRect, pixmap); |
| 166 | ctxt->restore(); |
| 167 | } else { |
| 168 | QBrush b(pixmap); |
| 169 | b.setMatrix(patternTransform); |
| 170 | ctxt->save(); |
| 171 | ctxt->setCompositeOperation(op); |
| 172 | QPainter* p = ctxt->platformContext(); |
| 173 | p->setBrushOrigin(phase); |
| 174 | p->fillRect(destRect, b); |
| 175 | ctxt->restore(); |
| 176 | } |
eseidel | 6195285 | 2006-12-29 01:57:44 +0000 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | void BitmapImage::checkForSolidColor() |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 180 | { |
| 181 | // FIXME: It's easy to implement this optimization. Just need to check the RGBA32 buffer to see if it is 1x1. |
| 182 | m_isSolidColor = false; |
| 183 | } |
| 184 | |
zack | d2a180a | 2007-01-26 08:25:32 +0000 | [diff] [blame] | 185 | QPixmap* BitmapImage::getPixmap() const |
| 186 | { |
staikos | cdc883d | 2007-06-22 03:29:41 +0000 | [diff] [blame^] | 187 | if (!m_pixmap) |
| 188 | return const_cast<BitmapImage*>(this)->frameAtIndex(0); |
| 189 | else |
| 190 | return m_pixmap; |
zack | d2a180a | 2007-01-26 08:25:32 +0000 | [diff] [blame] | 191 | } |
| 192 | |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 193 | } |
| 194 | |
eseidel | 6195285 | 2006-12-29 01:57:44 +0000 | [diff] [blame] | 195 | |
rwlbuis | 9802198 | 2006-08-23 21:04:08 +0000 | [diff] [blame] | 196 | // vim: ts=4 sw=4 et |