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 * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> 6 * Copyright (C) 2008 Andrea Anzani <andrea.anzani@gmail.com> 7 * Copyright (C) 2010 Stephan AÃmus <superstippi@gmx.de> 8 * 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 28 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include "config.h" 34#include "Image.h" 35 36#include "BitmapImage.h" 37#include "FloatRect.h" 38#include "GraphicsContext.h" 39#include "ImageObserver.h" 40#include "NotImplemented.h" 41#include "PlatformString.h" 42#include "TransformationMatrix.h" 43#include <Application.h> 44#include <Bitmap.h> 45#include <View.h> 46 47// This function loads resources from WebKit 48Vector<char> loadResourceIntoArray(const char*); 49 50 51namespace WebCore { 52 53bool FrameData::clear(bool clearMetadata) 54{ 55 if (clearMetadata) 56 m_haveMetadata = false; 57 58 if (m_frame) { 59 delete m_frame; 60 m_frame = 0; 61 m_duration = 0.0f; 62 m_hasAlpha = true; 63 return true; 64 } 65 66 return false; 67} 68 69WTF::PassRefPtr<Image> Image::loadPlatformResource(const char* name) 70{ 71 Vector<char> array = loadResourceIntoArray(name); 72 WTF::PassRefPtr<BitmapImage> image = BitmapImage::create(); 73 RefPtr<SharedBuffer> buffer = SharedBuffer::create(array.data(), array.size()); 74 image->setData(buffer, true); 75 76 return image; 77} 78 79void BitmapImage::initPlatformData() 80{ 81} 82 83void BitmapImage::invalidatePlatformData() 84{ 85} 86 87// Drawing Routines 88void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op) 89{ 90 if (!m_source.initialized()) 91 return; 92 93 // Spin the animation to the correct frame before we try to draw it, so we 94 // don't draw an old frame and then immediately need to draw a newer one, 95 // causing flicker and wasting CPU. 96 startAnimation(); 97 98 BBitmap* image = nativeImageForCurrentFrame(); 99 if (!image || !image->IsValid()) // If the image hasn't fully loaded. 100 return; 101 102 if (mayFillWithSolidColor()) { 103 fillWithSolidColor(ctxt, dst, solidColor(), styleColorSpace, op); 104 return; 105 } 106 107 ctxt->save(); 108 ctxt->setCompositeOperation(op); 109 110 BRect srcRect(src); 111 BRect dstRect(dst); 112 113 // Test using example site at 114 // http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html 115 ctxt->platformContext()->SetDrawingMode(B_OP_ALPHA); 116 ctxt->platformContext()->DrawBitmapAsync(image, srcRect, dstRect); 117 ctxt->restore(); 118 119 if (imageObserver()) 120 imageObserver()->didDraw(this); 121} 122 123void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& srcPoint, ColorSpace, CompositeOperator op, const FloatRect& dstRect) 124{ 125 BBitmap* image = nativeImageForCurrentFrame(); 126 if (!image || !image->IsValid()) // If the image hasn't fully loaded. 127 return; 128 129 // Figure out if the image has any alpha transparency, we can use faster drawing if not 130 bool hasAlpha = false; 131 132 uint8* bits = reinterpret_cast<uint8*>(image->Bits()); 133 uint32 width = image->Bounds().IntegerWidth() + 1; 134 uint32 height = image->Bounds().IntegerHeight() + 1; 135 136 uint32 bytesPerRow = image->BytesPerRow(); 137 for (uint32 y = 0; y < height && !hasAlpha; y++) { 138 uint8* p = bits; 139 for (uint32 x = 0; x < width && !hasAlpha; x++) { 140 hasAlpha = p[3] < 255; 141 p += 4; 142 } 143 bits += bytesPerRow; 144 } 145 146 context->save(); 147 if (hasAlpha) 148 context->platformContext()->SetDrawingMode(B_OP_ALPHA); 149 else 150 context->platformContext()->SetDrawingMode(B_OP_COPY); 151 context->clip(enclosingIntRect(dstRect)); 152 float currentW = phase.x(); 153 BRect bTileRect(tileRect); 154 while (currentW < dstRect.x() + dstRect.width()) { 155 float currentH = phase.y(); 156 while (currentH < dstRect.y() + dstRect.height()) { 157 BRect bDstRect(currentW, currentH, currentW + width - 1, currentH + height - 1); 158 context->platformContext()->DrawBitmapAsync(image, bTileRect, bDstRect); 159 currentH += height; 160 } 161 currentW += width; 162 } 163 context->restore(); 164 165 if (imageObserver()) 166 imageObserver()->didDraw(this); 167} 168 169void BitmapImage::checkForSolidColor() 170{ 171 m_isSolidColor = false; 172 m_checkedForSolidColor = true; 173 174 if (frameCount() > 1) 175 return; 176 177 BBitmap* image = getBBitmap(); 178 if (!image || !image->Bounds().IsValid() 179 || image->Bounds().IntegerWidth() > 0 || image->Bounds().IntegerHeight() > 0) { 180 return; 181 } 182 183 m_isSolidColor = true; 184 uint8* bits = reinterpret_cast<uint8*>(image->Bits()); 185 m_solidColor = Color(bits[2], bits[1], bits[0], bits[3]); 186} 187 188BBitmap* BitmapImage::getBBitmap() const 189{ 190 return const_cast<BitmapImage*>(this)->frameAtIndex(0); 191} 192 193} // namespace WebCore 194 195