1/* 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 3 * Copyright (C) 2007-2009 Torch Mobile Inc. 4 * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "config.h" 28#include "Image.h" 29 30#include "BitmapImage.h" 31#include "GraphicsContext.h" 32#include "ImageDecoder.h" 33#include "NotImplemented.h" 34#include "SharedBuffer.h" 35#include "TransformationMatrix.h" 36#include "WinceGraphicsExtras.h" 37#include <wtf/OwnPtr.h> 38#include <wtf/text/WTFString.h> 39 40#include <windows.h> 41 42namespace WebCore { 43 44PassNativeImagePtr ImageFrame::asNewNativeImage() const 45{ 46 return SharedBitmap::create(m_backingStore, m_size, hasAlpha()); 47} 48 49bool FrameData::clear(bool clearMetaData) 50{ 51 if (clearMetaData) 52 m_haveMetadata = false; 53 54 if (m_frame) { 55 m_frame = 0; 56 return true; 57 } 58 59 return false; 60} 61 62bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size) 63{ 64 if (!bmp) 65 return false; 66 67 BITMAP bmpInfo; 68 GetObject(bmp, sizeof(BITMAP), &bmpInfo); 69 70 ASSERT(bmpInfo.bmBitsPixel == 32); 71 int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight; 72 73 OwnPtr<HDC> hdc = adoptPtr(CreateCompatibleDC(0)); 74 HGDIOBJ hOldBmp = SelectObject(hdc.get(), bmp); 75 76 { 77 GraphicsContext gc(hdc.get()); 78 79 IntSize imageSize = BitmapImage::size(); 80 if (size) 81 drawFrameMatchingSourceSize(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), IntSize(*size), ColorSpaceDeviceRGB, CompositeCopy); 82 else 83 draw(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0, 0, imageSize.width(), imageSize.height()), ColorSpaceDeviceRGB, CompositeCopy, BlendModeNormal); 84 } 85 86 SelectObject(hdc.get(), hOldBmp); 87 88 return true; 89} 90 91void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext* ctxt, const FloatRect& dstRect, const IntSize& srcSize, ColorSpace styleColorSpace, CompositeOperator compositeOp) 92{ 93 int frames = frameCount(); 94 for (int i = 0; i < frames; ++i) { 95 RefPtr<SharedBitmap> bmp = frameAtIndex(i); 96 if (!bmp || bmp->height() != static_cast<unsigned>(srcSize.height()) || bmp->width() != static_cast<unsigned>(srcSize.width())) 97 continue; 98 99 size_t currentFrame = m_currentFrame; 100 m_currentFrame = i; 101 draw(ctxt, dstRect, FloatRect(0, 0, srcSize.width(), srcSize.height()), styleColorSpace, compositeOp, BlendModeNormal); 102 m_currentFrame = currentFrame; 103 return; 104 } 105 106 // No image of the correct size was found, fallback to drawing the current frame 107 IntSize imageSize = BitmapImage::size(); 108 draw(ctxt, dstRect, FloatRect(0, 0, imageSize.width(), imageSize.height()), styleColorSpace, compositeOp, BlendModeNormal); 109} 110 111void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRectIn, ColorSpace styleColorSpace, CompositeOperator compositeOp, BlendMode blendMode) 112{ 113 if (!m_source.initialized()) 114 return; 115 116 if (mayFillWithSolidColor()) 117 fillWithSolidColor(ctxt, dstRect, solidColor(), styleColorSpace, compositeOp); 118 else { 119 IntRect intSrcRect(srcRectIn); 120 RefPtr<SharedBitmap> bmp = frameAtIndex(m_currentFrame); 121 if (bmp) { 122 if (bmp->width() != m_source.size().width()) { 123 double scaleFactor = static_cast<double>(bmp->width()) / m_source.size().width(); 124 125 intSrcRect.setX(stableRound(srcRectIn.x() * scaleFactor)); 126 intSrcRect.setWidth(stableRound(srcRectIn.width() * scaleFactor)); 127 intSrcRect.setY(stableRound(srcRectIn.y() * scaleFactor)); 128 intSrcRect.setHeight(stableRound(srcRectIn.height() * scaleFactor)); 129 } 130 bmp->draw(ctxt, enclosingIntRect(dstRect), intSrcRect, styleColorSpace, compositeOp, blendMode); 131 } 132 } 133 134 startAnimation(); 135} 136 137void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, 138 const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode) 139{ 140 notImplemented(); 141} 142 143void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const AffineTransform& patternTransform, 144 const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) 145{ 146 RefPtr<SharedBitmap> bmp = nativeImageForCurrentFrame(); 147 if (!bmp) 148 return; 149 150 bmp->drawPattern(ctxt, tileRectIn, patternTransform, phase, styleColorSpace, op, destRect, m_source.size()); 151} 152 153void BitmapImage::checkForSolidColor() 154{ 155 if (m_checkedForSolidColor) 156 return; 157 158 if (frameCount() != 1) { 159 m_isSolidColor = false; 160 m_checkedForSolidColor = true; 161 return; 162 } 163 164 RefPtr<SharedBitmap> bmp = frameAtIndex(0); 165 if (!bmp || !bmp->validHeight()) { 166 m_isSolidColor = false; 167 return; 168 } 169 170 if (bmp->width() != 1 || bmp->validHeight() != 1) { 171 m_isSolidColor = false; 172 m_checkedForSolidColor = true; 173 return; 174 } 175 176 m_isSolidColor = true; 177 178 if (bmp->is16bit()) { 179 unsigned short c = ((unsigned short *)bmp->bytes())[0]; 180 int r = (c >> 7) & 0xF8; 181 int g = (c >> 2) & 0xF8; 182 int b = (c << 3) & 0xF8; 183 if (bmp->usesTransparentColor() && bmp->transparentColor() == RGB(r, g, b)) 184 m_solidColor = Color(r, g, b, 0); 185 else 186 m_solidColor = Color(r, g, b); 187 } else { 188 unsigned c = ((unsigned *)bmp->bytes())[0]; 189 m_solidColor = Color(c); 190 } 191 192 if (bmp->validHeight() == bmp->height()) 193 m_checkedForSolidColor = true; 194} 195 196} // namespace WebCore 197