/* * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. * Copyright (C) 2007-2009 Torch Mobile Inc. * Copyright (C) 2010 Patrick Gansterer * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "Image.h" #include "BitmapImage.h" #include "GraphicsContext.h" #include "ImageDecoder.h" #include "NotImplemented.h" #include "PlatformString.h" #include "SharedBuffer.h" #include "TransformationMatrix.h" #include "WinceGraphicsExtras.h" #include #include namespace WebCore { NativeImagePtr ImageFrame::asNewNativeImage() const { return SharedBitmap::create(m_backingStore, m_size, hasAlpha()); } bool FrameData::clear(bool clearMetaData) { if (clearMetaData) m_haveMetadata = false; if (m_frame) { m_frame = 0; return true; } return false; } bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size) { if (!bmp) return false; BITMAP bmpInfo; GetObject(bmp, sizeof(BITMAP), &bmpInfo); ASSERT(bmpInfo.bmBitsPixel == 32); int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight; OwnPtr hdc(CreateCompatibleDC(0)); HGDIOBJ hOldBmp = SelectObject(hdc.get(), bmp); { GraphicsContext gc(hdc.get()); IntSize imageSize = BitmapImage::size(); if (size) drawFrameMatchingSourceSize(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), IntSize(*size), ColorSpaceDeviceRGB, CompositeCopy); else draw(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0, 0, imageSize.width(), imageSize.height()), ColorSpaceDeviceRGB, CompositeCopy); } SelectObject(hdc.get(), hOldBmp); return true; } void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext* ctxt, const FloatRect& dstRect, const IntSize& srcSize, ColorSpace styleColorSpace, CompositeOperator compositeOp) { int frames = frameCount(); for (int i = 0; i < frames; ++i) { RefPtr bmp = frameAtIndex(i); if (!bmp || bmp->height() != static_cast(srcSize.height()) || bmp->width() != static_cast(srcSize.width())) continue; size_t currentFrame = m_currentFrame; m_currentFrame = i; draw(ctxt, dstRect, FloatRect(0, 0, srcSize.width(), srcSize.height()), styleColorSpace, compositeOp); m_currentFrame = currentFrame; return; } // No image of the correct size was found, fallback to drawing the current frame IntSize imageSize = BitmapImage::size(); draw(ctxt, dstRect, FloatRect(0, 0, imageSize.width(), imageSize.height()), styleColorSpace, compositeOp); } void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRectIn, ColorSpace styleColorSpace, CompositeOperator compositeOp) { if (!m_source.initialized()) return; if (mayFillWithSolidColor()) fillWithSolidColor(ctxt, dstRect, solidColor(), styleColorSpace, compositeOp); else { IntRect intSrcRect(srcRectIn); RefPtr bmp = frameAtIndex(m_currentFrame); if (bmp->width() != m_source.size().width()) { double scaleFactor = static_cast(bmp->width()) / m_source.size().width(); intSrcRect.setX(stableRound(srcRectIn.x() * scaleFactor)); intSrcRect.setWidth(stableRound(srcRectIn.width() * scaleFactor)); intSrcRect.setY(stableRound(srcRectIn.y() * scaleFactor)); intSrcRect.setHeight(stableRound(srcRectIn.height() * scaleFactor)); } bmp->draw(ctxt, enclosingIntRect(dstRect), intSrcRect, styleColorSpace, compositeOp); } startAnimation(); } void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) { notImplemented(); } void BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) { RefPtr bmp = nativeImageForCurrentFrame(); if (!bmp) return; bmp->drawPattern(ctxt, tileRectIn, patternTransform, phase, styleColorSpace, op, destRect, m_source.size()); } void BitmapImage::checkForSolidColor() { if (m_checkedForSolidColor) return; if (frameCount() != 1) { m_isSolidColor = false; m_checkedForSolidColor = true; return; } RefPtr bmp = frameAtIndex(0); if (!bmp || !bmp->validHeight()) { m_isSolidColor = false; return; } if (bmp->width() != 1 || bmp->validHeight() != 1) { m_isSolidColor = false; m_checkedForSolidColor = true; return; } m_isSolidColor = true; if (bmp->is16bit()) { unsigned short c = ((unsigned short *)bmp->bytes())[0]; int r = (c >> 7) & 0xF8; int g = (c >> 2) & 0xF8; int b = (c << 3) & 0xF8; if (bmp->usesTransparentColor() && bmp->transparentColor() == RGB(r, g, b)) m_solidColor = Color(r, g, b, 0); else m_solidColor = Color(r, g, b); } else { unsigned c = ((unsigned *)bmp->bytes())[0]; m_solidColor = Color(c); } if (bmp->validHeight() == bmp->height()) m_checkedForSolidColor = true; } } // namespace WebCore