diff options
Diffstat (limited to 'Source/WebCore/platform/graphics/win')
9 files changed, 227 insertions, 66 deletions
diff --git a/Source/WebCore/platform/graphics/win/DIBPixelData.cpp b/Source/WebCore/platform/graphics/win/DIBPixelData.cpp new file mode 100644 index 0000000..e45ba06 --- /dev/null +++ b/Source/WebCore/platform/graphics/win/DIBPixelData.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2011 Brent Fulgham <bfulgham@webkit.org> + * + * 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 INC. ``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 INC. OR + * 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 "DIBPixelData.h" + +namespace WebCore { + +static const WORD bitmapType = 0x4d42; // BMP format +static const WORD bitmapPixelsPerMeter = 2834; // 72 dpi + +DIBPixelData::DIBPixelData(HBITMAP bitmap) +{ + initialize(bitmap); +} + +void DIBPixelData::initialize(HBITMAP bitmap) +{ + BITMAP bmpInfo; + GetObject(bitmap, sizeof(bmpInfo), &bmpInfo); + + m_bitmapBuffer = reinterpret_cast<UInt8*>(bmpInfo.bmBits); + m_bitmapBufferLength = bmpInfo.bmWidthBytes * bmpInfo.bmHeight; + m_size = IntSize(bmpInfo.bmWidth, bmpInfo.bmHeight); + m_bytesPerRow = bmpInfo.bmWidthBytes; + m_bitsPerPixel = bmpInfo.bmBitsPixel; +} + +#ifndef NDEBUG +void DIBPixelData::writeToFile(LPCWSTR filePath) +{ + HANDLE hFile = ::CreateFile(filePath, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + if (INVALID_HANDLE_VALUE == hFile) + return; + + BITMAPFILEHEADER header; + header.bfType = bitmapType; + header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + header.bfReserved1 = 0; + header.bfReserved2 = 0; + header.bfSize = sizeof(BITMAPFILEHEADER); + + BITMAPINFOHEADER info; + info.biSize = sizeof(BITMAPINFOHEADER); + info.biWidth = m_size.width(); + info.biHeight = m_size.height(); + info.biPlanes = 1; + info.biBitCount = m_bitsPerPixel; + info.biCompression = BI_RGB; + info.biSizeImage = bufferLength(); + info.biXPelsPerMeter = bitmapPixelsPerMeter; + info.biYPelsPerMeter = bitmapPixelsPerMeter; + info.biClrUsed = 0; + info.biClrImportant = 0; + + DWORD bytesWritten = 0; + ::WriteFile(hFile, &header, sizeof(header), &bytesWritten, 0); + ::WriteFile(hFile, &info, sizeof(info), &bytesWritten, 0); + ::WriteFile(hFile, buffer(), bufferLength(), &bytesWritten, 0); + + ::CloseHandle(hFile); +} +#endif + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/win/DIBPixelData.h b/Source/WebCore/platform/graphics/win/DIBPixelData.h new file mode 100644 index 0000000..40afa2b --- /dev/null +++ b/Source/WebCore/platform/graphics/win/DIBPixelData.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2011 Brent Fulgham <bfulgham@webkit.org> + * + * 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 INC. ``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 INC. OR + * 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. + */ + +#ifndef DIBPixelData_h +#define DIBPixelData_h + +#include "IntSize.h" +#include <windows.h> + +#if !USE(CG) +// UInt8 is defined in CoreFoundation/CFBase.h +typedef unsigned char UInt8; +#endif + +namespace WebCore { + +class DIBPixelData { + public: + DIBPixelData() + : m_bitmapBuffer(0) + , m_bitmapBufferLength(0) + , m_bytesPerRow(0) + , m_bitsPerPixel(0) + { + } + DIBPixelData(HBITMAP); + + void initialize(HBITMAP); + +#ifndef NDEBUG + void writeToFile(LPCWSTR); +#endif + + UInt8* buffer() const { return m_bitmapBuffer; } + unsigned bufferLength() const { return m_bitmapBufferLength; } + const IntSize& size() const { return m_size; } + unsigned bytesPerRow() const { return m_bytesPerRow; } + unsigned short bitsPerPixel() const { return m_bitsPerPixel; } + + private: + UInt8* m_bitmapBuffer; + unsigned m_bitmapBufferLength; + IntSize m_size; + unsigned m_bytesPerRow; + unsigned short m_bitsPerPixel; +}; + +} // namespace WebCore + +#endif // DIBPixelData_h diff --git a/Source/WebCore/platform/graphics/win/FontCacheWin.cpp b/Source/WebCore/platform/graphics/win/FontCacheWin.cpp index 5382ef7..46f6f11 100644 --- a/Source/WebCore/platform/graphics/win/FontCacheWin.cpp +++ b/Source/WebCore/platform/graphics/win/FontCacheWin.cpp @@ -36,7 +36,7 @@ #include <windows.h> #include <wtf/StdLibExtras.h> #include <wtf/text/StringHash.h> -#if PLATFORM(CG) +#if USE(CG) #include <ApplicationServices/ApplicationServices.h> #include <WebKitSystemInterface/WebKitSystemInterface.h> #endif @@ -48,7 +48,7 @@ namespace WebCore void FontCache::platformInit() { -#if PLATFORM(CG) +#if USE(CG) wkSetUpFontCache(1536 * 1024 * 4); // This size matches Mac. #endif } @@ -471,7 +471,7 @@ static HFONT createGDIFont(const AtomicString& family, LONG desiredWeight, bool matchData.m_chosen.lfUnderline = false; matchData.m_chosen.lfStrikeOut = false; matchData.m_chosen.lfCharSet = DEFAULT_CHARSET; -#if PLATFORM(CG) || PLATFORM(CAIRO) +#if USE(CG) || USE(CAIRO) matchData.m_chosen.lfOutPrecision = OUT_TT_ONLY_PRECIS; #else matchData.m_chosen.lfOutPrecision = OUT_TT_PRECIS; @@ -581,9 +581,9 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD FontPlatformData* result = new FontPlatformData(hfont, fontDescription.computedPixelSize(), synthesizeBold, synthesizeItalic, useGDI); -#if PLATFORM(CG) +#if USE(CG) bool fontCreationFailed = !result->cgFont(); -#elif PLATFORM(CAIRO) +#elif USE(CAIRO) bool fontCreationFailed = !result->scaledFont(); #endif diff --git a/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp b/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp index 301198d..d0b37bd 100644 --- a/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp +++ b/Source/WebCore/platform/graphics/win/FontPlatformDataWin.cpp @@ -41,9 +41,9 @@ FontPlatformData::FontPlatformData(HFONT font, float size, bool bold, bool obliq , m_orientation(Horizontal) , m_textOrientation(TextOrientationVerticalRight) , m_widthVariant(RegularWidth) -#if PLATFORM(CG) +#if USE(CG) , m_cgFont(0) -#elif PLATFORM(CAIRO) +#elif USE(CAIRO) , m_scaledFont(0) #endif , m_isColorBitmapFont(false) diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp index d0bd4e9..cb0c9a7 100644 --- a/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp +++ b/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp @@ -40,25 +40,24 @@ namespace WebCore { static CGContextRef CGContextWithHDC(HDC hdc, bool hasAlpha) { HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)); - BITMAP info; - GetObject(bitmap, sizeof(info), &info); + DIBPixelData pixelData(bitmap); // FIXME: We can get here because we asked for a bitmap that is too big // when we have a tiled layer and we're compositing. In that case // bmBitsPixel will be 0. This seems to be benign, so for now we will // exit gracefully and look at it later: // https://bugs.webkit.org/show_bug.cgi?id=52041 - // ASSERT(info.bmBitsPixel == 32); - if (info.bmBitsPixel != 32) + // ASSERT(bitmapBits.bitsPerPixel() == 32); + if (pixelData.bitsPerPixel() != 32) return 0; CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little | (hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst); - CGContextRef context = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8, - info.bmWidthBytes, deviceRGBColorSpaceRef(), bitmapInfo); + CGContextRef context = CGBitmapContextCreate(pixelData.buffer(), pixelData.size().width(), pixelData.size().height(), 8, + pixelData.bytesPerRow(), deviceRGBColorSpaceRef(), bitmapInfo); // Flip coords - CGContextTranslateCTM(context, 0, info.bmHeight); + CGContextTranslateCTM(context, 0, pixelData.size().height()); CGContextScaleCTM(context, 1, -1); // Put the HDC In advanced mode so it will honor affine transforms. @@ -99,16 +98,14 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo if (dstRect.isEmpty()) return; - HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)); + OwnPtr<HBITMAP> bitmap = adoptPtr(static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP))); + + DIBPixelData pixelData(bitmap.get()); - // Need to make a CGImage out of the bitmap's pixel buffer and then draw - // it into our context. - BITMAP info; - GetObject(bitmap, sizeof(info), &info); - ASSERT(info.bmBitsPixel == 32); + ASSERT(pixelData.bitsPerPixel() == 32); - CGContextRef bitmapContext = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8, - info.bmWidthBytes, deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Little | + CGContextRef bitmapContext = CGBitmapContextCreate(pixelData.buffer(), pixelData.size().width(), pixelData.size().height(), 8, + pixelData.bytesPerRow(), deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Little | (supportAlphaBlend ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst)); CGImageRef image = CGBitmapContextCreateImage(bitmapContext); @@ -118,7 +115,6 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo CGImageRelease(image); CGContextRelease(bitmapContext); ::DeleteDC(hdc); - ::DeleteObject(bitmap); } void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& point) diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp index 7ce7ee9..9f7aece 100644 --- a/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp +++ b/Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp @@ -78,7 +78,7 @@ void GraphicsContext::platformInit(HDC dc, bool hasAlpha) else setPaintingDisabled(true); - m_data = new GraphicsContextPlatformPrivateTopLevel(new PlatformContextCairo(cr)); + m_data = new GraphicsContextPlatformPrivateToplevel(new PlatformContextCairo(cr)); m_data->m_hdc = dc; if (platformContext()->cr()) { // Make sure the context starts in sync with our state. @@ -93,6 +93,33 @@ static void setRGBABitmapAlpha(unsigned char* bytes, size_t length, unsigned cha bytes[i + 3] = level; } +static void drawBitmapToContext(GraphicsContextPlatformPrivate* context, cairo_t* cr, const DIBPixelData& pixelData, const IntSize& translate) +{ + // Need to make a cairo_surface_t out of the bitmap's pixel buffer and then draw + // it into our context. + cairo_surface_t* surface = cairo_image_surface_create_for_data(pixelData.buffer(), + CAIRO_FORMAT_ARGB32, + pixelData.size().width(), + pixelData.size().height(), + pixelData.bytesPerRow()); + + // Flip the target surface so that when we set the srcImage as + // the surface it will draw right-side-up. + cairo_save(cr); + cairo_translate(cr, static_cast<double>(translate.width()), static_cast<double>(translate.height())); + cairo_scale(cr, 1, -1); + cairo_set_source_surface(cr, surface, 0, 0); + + if (context->layers.size()) + cairo_paint_with_alpha(cr, context->layers.last()); + else + cairo_paint(cr); + + // Delete all our junk. + cairo_surface_destroy(surface); + cairo_restore(cr); +} + void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap) { bool createdBitmap = mayCreateBitmap && (!m_data->m_hdc || inTransparencyLayer()); @@ -104,46 +131,26 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo if (dstRect.isEmpty()) return; - HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP)); + OwnPtr<HBITMAP> bitmap = adoptPtr(static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP))); - BITMAP info; - GetObject(bitmap, sizeof(info), &info); - ASSERT(info.bmBitsPixel == 32); + DIBPixelData pixelData(bitmap.get()); + ASSERT(pixelData.bitsPerPixel() == 32); // If this context does not support alpha blending, then it may have // been drawn with GDI functions which always set the alpha channel // to zero. We need to manually set the bitmap to be fully opaque. - unsigned char* bytes = reinterpret_cast<unsigned char*>(info.bmBits); + unsigned char* bytes = reinterpret_cast<unsigned char*>(pixelData.buffer()); if (!supportAlphaBlend) - setRGBABitmapAlpha(bytes, info.bmHeight * info.bmWidthBytes, 255); + setRGBABitmapAlpha(bytes, pixelData.size().height() * pixelData.bytesPerRow(), 255); - // Need to make a cairo_surface_t out of the bitmap's pixel buffer and then draw - // it into our context. - cairo_surface_t* image = cairo_image_surface_create_for_data(bytes, - CAIRO_FORMAT_ARGB32, - info.bmWidth, - info.bmHeight, - info.bmWidthBytes); - - // Scale the target surface to the new image size, and flip it - // so that when we set the srcImage as the surface it will draw - // right-side-up. - cairo_t* cr = platformContext()->cr(); - cairo_save(cr); - cairo_translate(cr, dstRect.x(), dstRect.height() + dstRect.y()); - cairo_scale(cr, 1, -1); - cairo_set_source_surface(cr, image, 0, 0); + drawBitmapToContext(m_data, platformContext()->cr(), pixelData, IntSize(dstRect.x(), dstRect.height() + dstRect.y())); - if (m_data->layers.size()) - cairo_paint_with_alpha(cr, m_data->layers.last()); - else - cairo_paint(cr); - - // Delete all our junk. - cairo_surface_destroy(image); ::DeleteDC(hdc); - ::DeleteObject(bitmap); - cairo_restore(cr); +} + +void GraphicsContext::drawWindowsBitmap(WindowsBitmap* bitmap, const IntPoint& point) +{ + drawBitmapToContext(m_data, platformContext()->cr(), bitmap->windowsDIB(), IntSize(point.x(), bitmap->size().height() + point.y())); } void GraphicsContextPlatformPrivate::syncContext(cairo_t* cr) diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp index f2850e4..28ce55a 100644 --- a/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp +++ b/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp @@ -26,9 +26,9 @@ #include "config.h" #include "GraphicsContext.h" -#if PLATFORM(CG) +#if USE(CG) #include "GraphicsContextPlatformPrivateCG.h" -#elif PLATFORM(CAIRO) +#elif USE(CAIRO) #include "GraphicsContextPlatformPrivateCairo.h" #endif @@ -65,21 +65,20 @@ bool GraphicsContext::shouldIncludeChildWindows() const GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, IntSize size) : m_hdc(0) - , m_size(size) { - BitmapInfo bitmapInfo = BitmapInfo::create(m_size); + BitmapInfo bitmapInfo = BitmapInfo::create(size); - m_bitmap = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, reinterpret_cast<void**>(&m_bitmapBuffer), 0, 0); + void* storage = 0; + m_bitmap = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, &storage, 0, 0); if (!m_bitmap) return; m_hdc = CreateCompatibleDC(hdc); SelectObject(m_hdc, m_bitmap); - BITMAP bmpInfo; - GetObject(m_bitmap, sizeof(bmpInfo), &bmpInfo); - m_bytesPerRow = bmpInfo.bmWidthBytes; - m_bitmapBufferLength = bmpInfo.bmWidthBytes * bmpInfo.bmHeight; + m_pixelData.initialize(m_bitmap); + + ASSERT(storage == m_pixelData.buffer()); SetGraphicsMode(m_hdc, GM_ADVANCED); } diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp index dd3cd32..588146a 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp @@ -30,7 +30,7 @@ #include "WebCoreInstanceHandle.h" #include <windows.h> -#if PLATFORM(CG) +#if USE(CG) #include <CoreGraphics/CGColor.h> #endif diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp index 323ff73..db730ca 100644 --- a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp +++ b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp @@ -39,7 +39,7 @@ #include <winsock2.h> #include <wtf/MathExtras.h> -#if PLATFORM(CG) +#if USE(CG) #include <ApplicationServices/ApplicationServices.h> #include <WebKitSystemInterface/WebKitSystemInterface.h> #endif |