1231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block/* 2231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2006 Dirk Mueller <mueller@kde.org> 3231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2006 Zack Rusin <zack@kde.org> 4231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org> 5231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> 6231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2008 Andrea Anzani <andrea.anzani@gmail.com> 78a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block * Copyright (C) 2010 Stephan Aßmus <superstippi@gmx.de> 8231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 9231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * All rights reserved. 10231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 11231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Redistribution and use in source and binary forms, with or without 12231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * modification, are permitted provided that the following conditions 13231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * are met: 14231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 1. Redistributions of source code must retain the above copyright 15231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * notice, this list of conditions and the following disclaimer. 16231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 2. Redistributions in binary form must reproduce the above copyright 17231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * notice, this list of conditions and the following disclaimer in the 18231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * documentation and/or other materials provided with the distribution. 19231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 20231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 21231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 24231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 28231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block */ 32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "config.h" 34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Image.h" 35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "BitmapImage.h" 37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "FloatRect.h" 38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "GraphicsContext.h" 398a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "ImageObserver.h" 40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "NotImplemented.h" 41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "PlatformString.h" 42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "SharedBuffer.h" 438a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "TransformationMatrix.h" 44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <Application.h> 45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <Bitmap.h> 46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <View.h> 47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// This function loads resources from WebKit 49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockVector<char> loadResourceIntoArray(const char*); 50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocknamespace WebCore { 53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool FrameData::clear(bool clearMetadata) 55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (clearMetadata) 57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_haveMetadata = false; 58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_frame) { 60231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block delete m_frame; 61231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_frame = 0; 62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_duration = 0.0f; 63231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_hasAlpha = true; 64231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 65231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 66231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockWTF::PassRefPtr<Image> Image::loadPlatformResource(const char* name) 71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 72231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Vector<char> array = loadResourceIntoArray(name); 73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block WTF::PassRefPtr<BitmapImage> image = BitmapImage::create(); 74231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RefPtr<SharedBuffer> buffer = SharedBuffer::create(array.data(), array.size()); 75231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block image->setData(buffer, true); 76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 77231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return image; 78231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 79231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid BitmapImage::initPlatformData() 81231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 83231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 84231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid BitmapImage::invalidatePlatformData() 85231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 86231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 87231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 88231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Drawing Routines 89643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op) 90231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 918a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (!m_source.initialized()) 928a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return; 938a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 948a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // Spin the animation to the correct frame before we try to draw it, so we 958a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // don't draw an old frame and then immediately need to draw a newer one, 968a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // causing flicker and wasting CPU. 97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block startAnimation(); 98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block BBitmap* image = nativeImageForCurrentFrame(); 100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!image || !image->IsValid()) // If the image hasn't fully loaded. 101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (mayFillWithSolidColor()) { 104643ca7872b450ea4efacab6188849e5aac2ba161Steve Block fillWithSolidColor(ctxt, dst, solidColor(), styleColorSpace, op); 105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ctxt->save(); 109231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ctxt->setCompositeOperation(op); 110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block BRect srcRect(src); 112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block BRect dstRect(dst); 113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Test using example site at 115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html 116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ctxt->platformContext()->SetDrawingMode(B_OP_ALPHA); 1178a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block ctxt->platformContext()->DrawBitmapAsync(image, srcRect, dstRect); 118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ctxt->restore(); 1198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (imageObserver()) 1218a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block imageObserver()->didDraw(this); 122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 124dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace, CompositeOperator op, const FloatRect& dstRect) 125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block BBitmap* image = nativeImageForCurrentFrame(); 127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!image || !image->IsValid()) // If the image hasn't fully loaded. 128231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return; 129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block // Figure out if the image has any alpha transparency, we can use faster drawing if not 1318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block bool hasAlpha = false; 1328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block uint8* bits = reinterpret_cast<uint8*>(image->Bits()); 1348a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block uint32 width = image->Bounds().IntegerWidth() + 1; 1358a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block uint32 height = image->Bounds().IntegerHeight() + 1; 1368a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1378a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block uint32 bytesPerRow = image->BytesPerRow(); 1388a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block for (uint32 y = 0; y < height && !hasAlpha; y++) { 1398a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block uint8* p = bits; 1408a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block for (uint32 x = 0; x < width && !hasAlpha; x++) { 1418a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block hasAlpha = p[3] < 255; 1428a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block p += 4; 1438a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 1448a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block bits += bytesPerRow; 1458a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 146231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 147231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->save(); 1488a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (hasAlpha) 1498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block context->platformContext()->SetDrawingMode(B_OP_ALPHA); 1508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block else 1518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block context->platformContext()->SetDrawingMode(B_OP_COPY); 152231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->clip(enclosingIntRect(dstRect)); 1538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block float currentW = phase.x(); 1548a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block BRect bTileRect(tileRect); 1558a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block while (currentW < dstRect.x() + dstRect.width()) { 1568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block float currentH = phase.y(); 1578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block while (currentH < dstRect.y() + dstRect.height()) { 1588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block BRect bDstRect(currentW, currentH, currentW + width - 1, currentH + height - 1); 1598a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block context->platformContext()->DrawBitmapAsync(image, bTileRect, bDstRect); 1608a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block currentH += height; 161231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 1628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block currentW += width; 163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 164231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->restore(); 1658a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1668a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (imageObserver()) 1678a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block imageObserver()->didDraw(this); 168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 169231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid BitmapImage::checkForSolidColor() 171231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 172231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_isSolidColor = false; 173231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_checkedForSolidColor = true; 1748a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1758a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (frameCount() > 1) 1768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return; 1778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1788a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block BBitmap* image = getBBitmap(); 1798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (!image || !image->Bounds().IsValid() 1808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block || image->Bounds().IntegerWidth() > 0 || image->Bounds().IntegerHeight() > 0) { 1818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return; 1828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 1838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1848a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block m_isSolidColor = true; 1858a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block uint8* bits = reinterpret_cast<uint8*>(image->Bits()); 1868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block m_solidColor = Color(bits[2], bits[1], bits[0], bits[3]); 187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockBBitmap* BitmapImage::getBBitmap() const 190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return const_cast<BitmapImage*>(this)->frameAtIndex(0); 192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} // namespace WebCore 195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 196