diff options
Diffstat (limited to 'WebCore/platform/graphics/wince/SharedBitmap.cpp')
-rw-r--r-- | WebCore/platform/graphics/wince/SharedBitmap.cpp | 615 |
1 files changed, 0 insertions, 615 deletions
diff --git a/WebCore/platform/graphics/wince/SharedBitmap.cpp b/WebCore/platform/graphics/wince/SharedBitmap.cpp deleted file mode 100644 index 05d1535..0000000 --- a/WebCore/platform/graphics/wince/SharedBitmap.cpp +++ /dev/null @@ -1,615 +0,0 @@ -/* - * Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved. - * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "SharedBitmap.h" - -#include "GDIExtras.h" -#include "GraphicsContext.h" -#include "GraphicsTypes.h" -#include "TransformationMatrix.h" -#include "WinCEGraphicsExtras.h" -#include <wtf/HashSet.h> -#include <wtf/RefCountedLeakCounter.h> -#include <wtf/PassOwnArrayPtr.h> -#include <wtf/OwnPtr.h> - -#include <windows.h> - -namespace WebCore { - -#ifndef NDEBUG -static WTF::RefCountedLeakCounter sharedBitmapLeakCounter("SharedBitmap"); -#endif - - -PassRefPtr<SharedBitmap> SharedBitmap::create(const IntSize& size, BitmapInfo::BitCount bitCount, bool initPixels) -{ - RefPtr<SharedBitmap> resultantBitmap = adoptRef(new SharedBitmap(size, bitCount, initPixels)); - if (resultantBitmap && !resultantBitmap->bytes()) - return 0; - return resultantBitmap.release(); -} - -PassRefPtr<SharedBitmap> SharedBitmap::create(const Vector<unsigned>& data, const IntSize& size, bool hasAlpha) -{ - RefPtr<SharedBitmap> result = create(size, BitmapInfo::BitCount32, false); - if (!result) - return 0; - memcpy(result->bytes(), data.data(), data.size() * sizeof(unsigned)); - result->setHasAlpha(hasAlpha); - return result.release(); -} - -SharedBitmap::SharedBitmap(const IntSize& size, BitmapInfo::BitCount bitCount, bool initPixels) - : m_bmpInfo(BitmapInfo::createBottomUp(size, bitCount)) - , m_locked(false) - , m_usesTransparentColor(false) - , m_transparentColor(RGB(0, 0, 0)) - , m_pixels(0) - , m_hasAlpha(false) - , m_validHeight(abs(size.height())) - , m_hbitmap(0) -{ -#ifndef NDEBUG - sharedBitmapLeakCounter.increment(); -#endif - - unsigned bufferSize = m_bmpInfo.numPixels(); - if (bitCount == BitmapInfo::BitCount16) - bufferSize /= 2; - - m_pixelData = adoptArrayPtr(new unsigned[bufferSize]); - m_pixels = m_pixelData.get(); - - if (initPixels) - resetPixels(); -} - -SharedBitmap::~SharedBitmap() -{ -#ifndef NDEBUG - sharedBitmapLeakCounter.decrement(); -#endif -} - -void SharedBitmap::resetPixels(bool black) -{ - if (!m_pixels) - return; - - unsigned bufferSize = m_bmpInfo.numPixels(); - if (black) { - unsigned bufferSizeInBytes = bufferSize * (is16bit() ? 2 : 4); - memset(m_pixels, 0, bufferSizeInBytes); - return; - } - - if (is16bit()) { - // Fill it with white color - wmemset(static_cast<wchar_t*>(m_pixels), 0xFFFF, bufferSize); - return; - } - - // Make it white but transparent - unsigned* pixel = static_cast<unsigned*>(m_pixels); - const unsigned* bufferEnd = pixel + bufferSize; - while (pixel < bufferEnd) - *pixel++ = 0x00FFFFFF; -} - -static inline unsigned short convert32To16(unsigned pixel) -{ - unsigned short r = static_cast<unsigned short>((pixel & 0x00F80000) >> 8); - unsigned short g = static_cast<unsigned short>((pixel & 0x0000FC00) >> 5); - unsigned short b = static_cast<unsigned short>((pixel & 0x000000F8) >> 3); - return r | g | b; -} - -bool SharedBitmap::to16bit() -{ - if (m_locked) - return false; - if (is16bit()) - return true; - - BitmapInfo newBmpInfo = BitmapInfo::create(m_bmpInfo.size(), BitmapInfo::BitCount16); - - int width = newBmpInfo.width(); - int paddedWidth = newBmpInfo.paddedWidth(); - int bufferSize = paddedWidth * newBmpInfo.height(); - OwnArrayPtr<unsigned> newPixelData(new unsigned[bufferSize / 2]); - void* newPixels = newPixelData.get(); - - if (!newPixels) - return false; - - unsigned short* p16 = static_cast<unsigned short*>(newPixels); - const unsigned* p32 = static_cast<const unsigned*>(m_pixels); - - bool skips = paddedWidth != width; - - const unsigned short* p16end = p16 + bufferSize; - while (p16 < p16end) { - for (unsigned short* p16lineEnd = p16 + width; p16 < p16lineEnd; ) - *p16++ = convert32To16(*p32++); - - if (skips) - *p16++ = 0; - } - - if (m_hbitmap) - m_hbitmap = nullptr; - else - m_pixelData = newPixelData.release(); - - m_pixels = newPixels; - m_bmpInfo = newBmpInfo; - - setHasAlpha(false); - return true; -} - -bool SharedBitmap::freeMemory() -{ - if (m_locked) - return false; - - if (m_hbitmap) { - m_hbitmap = nullptr; - m_pixels = 0; - return true; - } - - if (m_pixels) { - m_pixelData = nullptr; - m_pixels = 0; - return true; - } - - return false; -} - -PassOwnPtr<HBITMAP> SharedBitmap::createHandle(void** pixels, BitmapInfo* bmpInfo, int height, bool use16bit) const -{ - if (!m_pixels) - return 0; - - if (height == -1) - height = this->height(); - *bmpInfo = BitmapInfo::createBottomUp(IntSize(width(), height), (use16bit || is16bit()) ? BitmapInfo::BitCount16 : BitmapInfo::BitCount32); - - OwnPtr<HBITMAP> hbmp = adoptPtr(CreateDIBSection(0, bmpInfo, DIB_RGB_COLORS, pixels, 0, 0)); - - if (!hbmp) - return 0; - - OwnPtr<HDC> bmpDC = adoptPtr(CreateCompatibleDC(0)); - HGDIOBJ hOldBmp = SelectObject(bmpDC.get(), hbmp.get()); - - StretchDIBits(bmpDC.get(), 0, 0, width(), height, 0, 0, width(), height, m_pixels, &m_bmpInfo, DIB_RGB_COLORS, SRCCOPY); - - SelectObject(bmpDC.get(), hOldBmp); - - return hbmp.release(); -} - -bool SharedBitmap::ensureHandle() -{ - if (m_hbitmap) - return true; - - if (!m_pixels) - return false; - - if (m_locked) - return false; - - BitmapInfo bmpInfo; - void* pixels; - m_hbitmap = createHandle(&pixels, &bmpInfo, -1, !hasAlpha()); - - if (!m_hbitmap) - return false; - - m_pixelData = nullptr; - m_pixels = pixels; - m_bmpInfo = bmpInfo; - - return true; -} - -void SharedBitmap::draw(GraphicsContext* ctxt, const IntRect& dstRect, const IntRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp) -{ - if (!m_pixels) - return; - ctxt->drawBitmap(this, dstRect, srcRect, styleColorSpace, compositeOp); -} - -void SharedBitmap::draw(HDC hdc, const IntRect& dstRect, const IntRect& srcRect, CompositeOperator compositeOp) -{ - if (!m_pixels) - return; - - if (dstRect.isEmpty() || srcRect.isEmpty()) - return; - - HBITMAP hbitmap = 0; - OwnPtr<HBITMAP> hTempBitmap; - bool usingHandle = compositeOp == CompositeSourceOver && (hasAlpha() && hasAlphaBlendSupport() || usesTransparentColor()); - - if (usingHandle) { - if (ensureHandle()) - hbitmap = m_hbitmap.get(); - else { - void* pixels; - BitmapInfo bmpInfo; - hTempBitmap = createHandle(&pixels, &bmpInfo, -1, usesTransparentColor()); - hbitmap = hTempBitmap.get(); - } - } - if (!hbitmap) { - // FIXME: handle other composite operation types? - DWORD rop = compositeOp == CompositeCopy ? SRCCOPY - : compositeOp == CompositeXOR ? PATINVERT - : compositeOp == CompositeClear ? WHITENESS - : SRCCOPY; - - StretchDIBits(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), - srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), m_pixels, &m_bmpInfo, DIB_RGB_COLORS, rop); - return; - } - - OwnPtr<HDC> hmemdc = adoptPtr(CreateCompatibleDC(hdc)); - HGDIOBJ hOldBmp = SelectObject(hmemdc.get(), hbitmap); - - if (!usesTransparentColor() && hasAlphaBlendSupport()) { - static const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; - bool success = alphaBlendIfSupported(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), hmemdc.get(), - srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), blend); - ASSERT_UNUSED(success, success); - } else { - TransparentBlt(hdc, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height(), hmemdc.get(), - srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), transparentColor()); - } - - SelectObject(hmemdc.get(), hOldBmp); -} - -PassOwnPtr<HBITMAP> SharedBitmap::clipBitmap(const IntRect& rect, bool useAlpha, BitmapInfo& bmpInfo, void*& pixels) -{ - if (!bytes()) - return 0; - - int oldWidth = width(); - int oldHeight = height(); - int copyWidth = std::min<int>(rect.width(), oldWidth - rect.x()); - int copyHeight = std::min<int>(rect.height(), oldHeight - rect.y()); - if (!copyWidth || !copyHeight) - return 0; - - bmpInfo = BitmapInfo::createBottomUp(IntSize(copyWidth, copyHeight), (useAlpha && is32bit()) ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16); - OwnPtr<HBITMAP> newBmp = adoptPtr(CreateDIBSection(0, &bmpInfo, DIB_RGB_COLORS, &pixels, 0, 0)); - - if (!newBmp) - return 0; - - OwnPtr<HDC> dcNew = adoptPtr(CreateCompatibleDC(0)); - HGDIOBJ tmpNew = SelectObject(dcNew.get(), newBmp.get()); - - StretchDIBits(dcNew.get(), 0, 0, copyWidth, copyHeight, rect.x(), rect.y(), copyWidth, copyHeight, - bytes(), &bitmapInfo(), DIB_RGB_COLORS, SRCCOPY); - - SelectObject(dcNew.get(), tmpNew); - return newBmp.release(); -} - -PassRefPtr<SharedBitmap> SharedBitmap::clipBitmap(const IntRect& rect, bool useAlpha) -{ - int oldWidth = width(); - int oldHeight = height(); - int copyWidth = std::min<int>(rect.width(), oldWidth - rect.x()); - int copyHeight = std::min<int>(rect.height(), oldHeight - rect.y()); - if (!copyWidth || !copyHeight) - return 0; - - RefPtr<SharedBitmap> newBmp = create(IntSize(copyWidth, copyHeight), useAlpha && is32bit() ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16, false); - - if (!newBmp || !newBmp->bytes()) - return 0; - - DCHolder dcNew(newBmp.get()); - - StretchDIBits(dcNew.get(), 0, 0, copyWidth, copyHeight, rect.x(), rect.y(), copyWidth, copyHeight, - bytes(), &bitmapInfo(), DIB_RGB_COLORS, SRCCOPY); - - return newBmp; -} - -static void drawPatternSimple(HDC hdc, const RECT& destRect, HBITMAP hbmp, const POINT& phase) -{ - OwnPtr<HBRUSH> hBrush = adoptPtr(CreatePatternBrush(hbmp)); - if (!hBrush) - return; - - POINT oldOrg; - SetBrushOrgEx(hdc, destRect.left - phase.x, destRect.top - phase.y, &oldOrg); - FillRect(hdc, &destRect, hBrush.get()); - SetBrushOrgEx(hdc, oldOrg.x, oldOrg.y, 0); -} - -static void drawPatternSimple(HDC hdc, const RECT& destRect, const SharedBitmap* bmp, const SIZE& bmpSize, const POINT& phase) -{ - int dstY = destRect.top; - for (int sourceY = phase.y; dstY < destRect.bottom; ) { - int sourceH = std::min<int>(bmpSize.cy - sourceY, destRect.bottom - dstY); - int dstX = destRect.left; - for (int sourceX = phase.x; dstX < destRect.right; ) { - int sourceW = std::min<int>(bmpSize.cx - sourceX, destRect.right - dstX); - - StretchDIBits(hdc, dstX, dstY, sourceW, sourceH, sourceX, sourceY, sourceW, sourceH, - bmp->bytes(), &bmp->bitmapInfo(), DIB_RGB_COLORS, SRCCOPY); - - dstX += sourceW; - sourceX = 0; - } - - dstY += sourceH; - sourceY = 0; - } -} - -static LONG normalizePhase(LONG phase, int limit) -{ - if (!phase || limit < 2) - return 0; - - if (limit == 2) - return phase & 1; - - if (phase < 0) { - phase = -phase; - if (phase > limit) - phase = static_cast<LONG>(static_cast<unsigned>(phase) % static_cast<unsigned>(limit)); - if (phase) - phase = limit - phase; - return phase; - } - - if (phase < limit) - return phase; - - return static_cast<LONG>(static_cast<unsigned>(phase) % static_cast<unsigned>(limit)); -} - -void SharedBitmap::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const AffineTransform& patternTransform, - const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize) -{ - if (!m_pixels) - return; - ctxt->drawBitmapPattern(this, tileRectIn, patternTransform, phase, styleColorSpace, op, destRect, origSourceSize); -} - -void SharedBitmap::drawPattern(HDC hdc, const AffineTransform& transform, const FloatRect& tileRectIn, const AffineTransform& patternTransform, - const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize) -{ - if (!m_pixels) - return; - - if (tileRectIn.width() <= 0 || tileRectIn.height() <= 0) - return; - - bool useAlpha = op == CompositeSourceOver && hasAlpha() && is32bit(); - - int bmpWidth = width(); - int bmpHeight = height(); - - FloatRect tileRect(tileRectIn); - if (bmpWidth != origSourceSize.width()) { - double rate = static_cast<double>(bmpWidth) / origSourceSize.width(); - double temp = tileRect.width() * rate; - tileRect.setX(tileRect.x() * rate); - tileRect.setWidth(temp); - temp = tileRect.height() * rate; - tileRect.setY(tileRect.y() * rate); - tileRect.setHeight(temp); - } - - OwnPtr<HBITMAP> clippedBmp; - - if (tileRect.x() || tileRect.y() || tileRect.width() != bmpWidth || tileRect.height() != bmpHeight) { - BitmapInfo patternBmpInfo; - void* patternPixels; - clippedBmp = clipBitmap(IntRect(tileRect), useAlpha, patternBmpInfo, patternPixels); - if (!clippedBmp) - return; - - bmpWidth = tileRect.width(); - bmpHeight = tileRect.height(); - } - - AffineTransform tf = transform; - tf *= patternTransform; - - FloatRect trRect = tf.mapRect(destRect); - - RECT clipBox; - int clipType = GetClipBox(hdc, &clipBox); - if (clipType == SIMPLEREGION) - trRect.intersect(FloatRect(clipBox.left, clipBox.top, clipBox.right - clipBox.left, clipBox.bottom - clipBox.top)); - else if (clipType == COMPLEXREGION) { - OwnPtr<HRGN> clipRgn = adoptPtr(CreateRectRgn(0, 0, 0, 0)); - if (GetClipRgn(hdc, clipRgn.get()) > 0) { - DWORD regionDataSize = GetRegionData(clipRgn.get(), sizeof(RGNDATA), 0); - if (regionDataSize) { - Vector<RGNDATA> regionData(regionDataSize); - GetRegionData(clipRgn.get(), regionDataSize, regionData.data()); - RECT* rect = reinterpret_cast<RECT*>(regionData[0].Buffer); - for (DWORD i = 0; i < regionData[0].rdh.nCount; ++i, ++rect) - trRect.intersect(FloatRect(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top)); - } - } - } - - if (trRect.width() <= 0 || trRect.height() <= 0) - return; - - trRect.inflate(1); - IntRect visibleDstRect = enclosingIntRect(tf.inverse().mapRect(trRect)); - visibleDstRect.intersect(IntRect(destRect)); - - if (visibleDstRect.width() <= 0 || visibleDstRect.height() <= 0) - return; - - trRect = tf.mapRect(visibleDstRect); - RECT dstRectWin = { - stableRound(trRect.x()), - stableRound(trRect.y()), - stableRound(trRect.right()), - stableRound(trRect.bottom()), - }; - if (dstRectWin.right <= dstRectWin.left || dstRectWin.bottom <= dstRectWin.top) - return; - - SIZE bmpSize = { bmpWidth, bmpHeight }; - - // Relative to destination, in bitmap pixels - POINT phaseWin = { stableRound(visibleDstRect.x() - phase.x()), stableRound(visibleDstRect.y() - phase.y()) }; - phaseWin.x = normalizePhase(phaseWin.x, bmpSize.cx); - phaseWin.y = normalizePhase(phaseWin.y, bmpSize.cy); - - RECT srcRectWin = { - 0, - 0, - stableRound(visibleDstRect.right()) - stableRound(visibleDstRect.x()), - stableRound(visibleDstRect.bottom()) - stableRound(visibleDstRect.y()) - }; - if (srcRectWin.right <= 0 || srcRectWin.bottom <= 0) - return; - - BitmapInfo bmpInfo = BitmapInfo::createBottomUp(IntSize(srcRectWin.right, srcRectWin.bottom), useAlpha ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16); - void* pixels; - OwnPtr<HBITMAP> hbmpTemp = adoptPtr(CreateDIBSection(0, &bmpInfo, DIB_RGB_COLORS, &pixels, 0, 0)); - - if (!hbmpTemp) - return; - - OwnPtr<HDC> hmemdc = adoptPtr(CreateCompatibleDC(hdc)); - HGDIOBJ oldBmp = SelectObject(hmemdc.get(), hbmpTemp.get()); - if (clippedBmp) - drawPatternSimple(hmemdc.get(), srcRectWin, clippedBmp.get(), phaseWin); - else if ((op != CompositeSourceOver || canUseDIBits()) && srcRectWin.right <= bmpSize.cx * 2 && srcRectWin.bottom <= bmpSize.cy * 2) - drawPatternSimple(hmemdc.get(), srcRectWin, this, bmpSize, phaseWin); - else if (ensureHandle()) - drawPatternSimple(hmemdc.get(), srcRectWin, getHandle(), phaseWin); - else { - void* pixels; - BitmapInfo bmpInfo; - OwnPtr<HBITMAP> hbmp = createHandle(&pixels, &bmpInfo, -1, false); - if (hbmp) - drawPatternSimple(hmemdc.get(), srcRectWin, hbmp.get(), phaseWin); - else { - SelectObject(hmemdc.get(), oldBmp); - return; - } - } - - if (useAlpha && hasAlphaBlendSupport()) { - static const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; - bool success = alphaBlendIfSupported(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left, dstRectWin.bottom - dstRectWin.top, - hmemdc.get(), 0, 0, srcRectWin.right, srcRectWin.bottom, blend); - ASSERT_UNUSED(success, success); - } else if (useAlpha && !hasAlphaBlendSupport() || op == CompositeSourceOver && usesTransparentColor()) { - TransparentBlt(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left, - dstRectWin.bottom - dstRectWin.top, hmemdc.get(), 0, 0, srcRectWin.right, srcRectWin.bottom, transparentColor()); - } else { - DWORD bmpOp = op == CompositeCopy ? SRCCOPY - : op == CompositeSourceOver ? SRCCOPY - : op == CompositeXOR ? PATINVERT - : op == CompositeClear ? WHITENESS - : SRCCOPY; // FIXEME: other types? - - StretchDIBits(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left, - dstRectWin.bottom - dstRectWin.top, 0, 0, srcRectWin.right, srcRectWin.bottom, - pixels, &bmpInfo, DIB_RGB_COLORS, bmpOp); - } - SelectObject(hmemdc.get(), oldBmp); -} - -SharedBitmap::DCProvider* SharedBitmap::s_dcProvider = new SharedBitmap::DCProvider; - -HDC SharedBitmap::DCProvider::getDC(SharedBitmap* bmp, unsigned* key) -{ - if (!bmp || !bmp->ensureHandle()) - return 0; - - HDC hdc = CreateCompatibleDC(0); - if (!hdc) - return 0; - - *key = reinterpret_cast<unsigned>(SelectObject(hdc, bmp->getHandle())); - RECT rect = { 0, 0, bmp->width(), bmp->height() }; - OwnPtr<HRGN> clipRgn = adoptPtr(CreateRectRgnIndirect(&rect)); - SelectClipRgn(hdc, clipRgn.get()); - - return hdc; -} - -void SharedBitmap::DCProvider::releaseDC(SharedBitmap*, HDC hdc, unsigned key1) -{ - if (!hdc) - return; - - SelectObject(hdc, reinterpret_cast<HGDIOBJ>(key1)); - DeleteDC(hdc); -} - -void SharedBitmap::clearPixels(const IntRect& rect) -{ - if (!m_pixels) - return; - - IntRect bmpRect(0, 0, width(), height()); - bmpRect.intersect(rect); - if (is16bit()) { - unsigned w = m_bmpInfo.paddedWidth(); - unsigned short* dst = static_cast<unsigned short*>(m_pixels); - dst += bmpRect.y() * w + bmpRect.x(); - int wordsToSet = bmpRect.width(); - const unsigned short* dstEnd = dst + bmpRect.height() * w; - while (dst < dstEnd) { - wmemset(reinterpret_cast<wchar_t*>(dst), 0, wordsToSet); - dst += w; - } - return; - } - - unsigned w = width(); - unsigned* dst = static_cast<unsigned*>(m_pixels); - dst += bmpRect.y() * w + bmpRect.x(); - int wordsToSet = bmpRect.width() * 2; - const unsigned* dstEnd = dst + bmpRect.height() * w; - while (dst < dstEnd) { - wmemset(reinterpret_cast<wchar_t*>(dst), 0, wordsToSet); - dst += w; - } -} - -} // namespace WebCore |