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) 2007 Ryan Leavengood <leavengood (at) gmail.com> 6 * Copyright (C) 2008 Andrea Anzani <andrea.anzani (at) gmail.com> 7 * Copyright (C) 2010 Stephan Amus <superstippi (at) 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 "SharedBuffer.h" 43 #include "TransformationMatrix.h" 44 #include <Application.h> 45 #include <Bitmap.h> 46 #include <View.h> 47 48 // This function loads resources from WebKit 49 Vector<char> loadResourceIntoArray(const char*); 50 51 52 namespace WebCore { 53 54 bool FrameData::clear(bool clearMetadata) 55 { 56 if (clearMetadata) 57 m_haveMetadata = false; 58 59 if (m_frame) { 60 delete m_frame; 61 m_frame = 0; 62 m_duration = 0.0f; 63 m_hasAlpha = true; 64 return true; 65 } 66 67 return false; 68 } 69 70 WTF::PassRefPtr<Image> Image::loadPlatformResource(const char* name) 71 { 72 Vector<char> array = loadResourceIntoArray(name); 73 WTF::PassRefPtr<BitmapImage> image = BitmapImage::create(); 74 RefPtr<SharedBuffer> buffer = SharedBuffer::create(array.data(), array.size()); 75 image->setData(buffer, true); 76 77 return image; 78 } 79 80 void BitmapImage::initPlatformData() 81 { 82 } 83 84 void BitmapImage::invalidatePlatformData() 85 { 86 } 87 88 // Drawing Routines 89 void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op) 90 { 91 if (!m_source.initialized()) 92 return; 93 94 // Spin the animation to the correct frame before we try to draw it, so we 95 // don't draw an old frame and then immediately need to draw a newer one, 96 // causing flicker and wasting CPU. 97 startAnimation(); 98 99 BBitmap* image = nativeImageForCurrentFrame(); 100 if (!image || !image->IsValid()) // If the image hasn't fully loaded. 101 return; 102 103 if (mayFillWithSolidColor()) { 104 fillWithSolidColor(ctxt, dst, solidColor(), styleColorSpace, op); 105 return; 106 } 107 108 ctxt->save(); 109 ctxt->setCompositeOperation(op); 110 111 BRect srcRect(src); 112 BRect dstRect(dst); 113 114 // Test using example site at 115 // http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html 116 ctxt->platformContext()->SetDrawingMode(B_OP_ALPHA); 117 ctxt->platformContext()->DrawBitmapAsync(image, srcRect, dstRect); 118 ctxt->restore(); 119 120 if (imageObserver()) 121 imageObserver()->didDraw(this); 122 } 123 124 void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace, CompositeOperator op, const FloatRect& dstRect) 125 { 126 BBitmap* image = nativeImageForCurrentFrame(); 127 if (!image || !image->IsValid()) // If the image hasn't fully loaded. 128 return; 129 130 // Figure out if the image has any alpha transparency, we can use faster drawing if not 131 bool hasAlpha = false; 132 133 uint8* bits = reinterpret_cast<uint8*>(image->Bits()); 134 uint32 width = image->Bounds().IntegerWidth() + 1; 135 uint32 height = image->Bounds().IntegerHeight() + 1; 136 137 uint32 bytesPerRow = image->BytesPerRow(); 138 for (uint32 y = 0; y < height && !hasAlpha; y++) { 139 uint8* p = bits; 140 for (uint32 x = 0; x < width && !hasAlpha; x++) { 141 hasAlpha = p[3] < 255; 142 p += 4; 143 } 144 bits += bytesPerRow; 145 } 146 147 context->save(); 148 if (hasAlpha) 149 context->platformContext()->SetDrawingMode(B_OP_ALPHA); 150 else 151 context->platformContext()->SetDrawingMode(B_OP_COPY); 152 context->clip(enclosingIntRect(dstRect)); 153 float currentW = phase.x(); 154 BRect bTileRect(tileRect); 155 while (currentW < dstRect.x() + dstRect.width()) { 156 float currentH = phase.y(); 157 while (currentH < dstRect.y() + dstRect.height()) { 158 BRect bDstRect(currentW, currentH, currentW + width - 1, currentH + height - 1); 159 context->platformContext()->DrawBitmapAsync(image, bTileRect, bDstRect); 160 currentH += height; 161 } 162 currentW += width; 163 } 164 context->restore(); 165 166 if (imageObserver()) 167 imageObserver()->didDraw(this); 168 } 169 170 void BitmapImage::checkForSolidColor() 171 { 172 m_isSolidColor = false; 173 m_checkedForSolidColor = true; 174 175 if (frameCount() > 1) 176 return; 177 178 BBitmap* image = getBBitmap(); 179 if (!image || !image->Bounds().IsValid() 180 || image->Bounds().IntegerWidth() > 0 || image->Bounds().IntegerHeight() > 0) { 181 return; 182 } 183 184 m_isSolidColor = true; 185 uint8* bits = reinterpret_cast<uint8*>(image->Bits()); 186 m_solidColor = Color(bits[2], bits[1], bits[0], bits[3]); 187 } 188 189 BBitmap* BitmapImage::getBBitmap() const 190 { 191 return const_cast<BitmapImage*>(this)->frameAtIndex(0); 192 } 193 194 } // namespace WebCore 195 196