Commit f900fb44 authored by dcheng@chromium.org's avatar dcheng@chromium.org

Properly scope ScopedPlatformPaint so that the native drawing layer and Skia...

Properly scope ScopedPlatformPaint so that the native drawing layer and Skia are in agreement on the state of the pixels. Also fix Windows to not return completely transparent bitmaps when the source image has color depth < 32 bpp.

BUG=86085
TEST=Copy an image from MS Paint and paste it into Gmail using 32bpp for the display color depth.

Review URL: http://codereview.chromium.org/7471008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95668 0039d316-1c4b-4281-b951-d872f2087c98
parent bdae5c11
......@@ -388,10 +388,12 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
gfx::CanvasSkia canvas(gdk_pixbuf_get_width(pixbuf.get()),
gdk_pixbuf_get_height(pixbuf.get()),
false);
skia::ScopedPlatformPaint scoped_platform_paint(&canvas);
cairo_t* context = scoped_platform_paint.GetPlatformSurface();
gdk_cairo_set_source_pixbuf(context, pixbuf.get(), 0.0, 0.0);
cairo_paint(context);
{
skia::ScopedPlatformPaint scoped_platform_paint(&canvas);
cairo_t* context = scoped_platform_paint.GetPlatformSurface();
gdk_cairo_set_source_pixbuf(context, pixbuf.get(), 0.0, 0.0);
cairo_paint(context);
}
return canvas.ExtractBitmap();
}
......
......@@ -247,12 +247,15 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
scoped_nsobject<NSImage> image(
[[NSImage alloc] initWithPasteboard:GetPasteboard()]);
if (image.get()) {
[image setFlipped:YES];
int width = [image size].width;
int height = [image size].height;
if (!image.get())
return SkBitmap();
gfx::CanvasSkia canvas(width, height, false);
[image setFlipped:YES];
int width = [image size].width;
int height = [image size].height;
gfx::CanvasSkia canvas(width, height, false);
{
skia::ScopedPlatformPaint scoped_platform_paint(&canvas);
CGContextRef gc = scoped_platform_paint.GetPlatformSurface();
NSGraphicsContext* cocoa_gc =
......@@ -263,9 +266,8 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
operation:NSCompositeCopy
fraction:1.0];
[NSGraphicsContext restoreGraphicsState];
return canvas.ExtractBitmap();
}
return SkBitmap();
return canvas.ExtractBitmap();
}
void Clipboard::ReadBookmark(string16* title, std::string* url) const {
......
......@@ -438,27 +438,54 @@ SkBitmap Clipboard::ReadImage(Buffer buffer) const {
if (!clipboard.Acquire(GetClipboardWindow()))
return SkBitmap();
HBITMAP source_bitmap = static_cast<HBITMAP>(::GetClipboardData(CF_BITMAP));
if (!source_bitmap)
return SkBitmap();
base::win::ScopedHDC source_dc(::CreateCompatibleDC(NULL));
if (!source_dc)
return SkBitmap();
::SelectObject(source_dc, source_bitmap);
// Get the dimensions of the bitmap.
BITMAPINFO bitmap_info = {};
bitmap_info.bmiHeader.biSize = sizeof(bitmap_info.bmiHeader);
::GetDIBits(source_dc, source_bitmap, 0, 0, 0, &bitmap_info, DIB_RGB_COLORS);
int width = bitmap_info.bmiHeader.biWidth;
int height = bitmap_info.bmiHeader.biHeight;
gfx::CanvasSkia canvas(width, height, false);
skia::ScopedPlatformPaint scoped_platform_paint(&canvas);
HDC destination_dc = scoped_platform_paint.GetPlatformSurface();
::BitBlt(destination_dc, 0, 0, width, height, source_dc, 0, 0, SRCCOPY);
// We use a DIB rather than a DDB here since ::GetObject() with the
// HBITMAP returned from ::GetClipboardData(CF_BITMAP) always reports a color
// depth of 32bpp.
BITMAPINFO* bitmap = static_cast<BITMAPINFO*>(::GetClipboardData(CF_DIB));
int color_table_length = 0;
switch (bitmap->bmiHeader.biBitCount) {
case 1:
case 4:
case 8:
color_table_length = bitmap->bmiHeader.biClrUsed
? bitmap->bmiHeader.biClrUsed
: 1 << bitmap->bmiHeader.biBitCount;
break;
case 16:
case 32:
if (bitmap->bmiHeader.biCompression == BI_BITFIELDS)
color_table_length = 3;
break;
case 24:
break;
default:
NOTREACHED();
}
const void* bitmap_bits = reinterpret_cast<const char*>(bitmap)
+ bitmap->bmiHeader.biSize + color_table_length * sizeof(RGBQUAD);
gfx::CanvasSkia canvas(bitmap->bmiHeader.biWidth, bitmap->bmiHeader.biHeight,
false);
{
skia::ScopedPlatformPaint scoped_platform_paint(&canvas);
HDC dc = scoped_platform_paint.GetPlatformSurface();
::SetDIBitsToDevice(dc, 0, 0, bitmap->bmiHeader.biWidth,
bitmap->bmiHeader.biHeight, 0, 0, 0,
bitmap->bmiHeader.biHeight, bitmap_bits, bitmap,
DIB_RGB_COLORS);
}
// SetDIBitsToDevice doesn't properly set alpha values for bitmaps with
// depth < 32bpp so manually fix it up.
if (bitmap->bmiHeader.biBitCount < 32) {
const SkBitmap& device_bitmap = canvas.getDevice()->accessBitmap(true);
SkAutoLockPixels lock(device_bitmap);
for (int i = 0; i < device_bitmap.height(); ++i) {
for (int j = 0; j < device_bitmap.width(); ++j) {
*device_bitmap.getAddr32(i, j) =
SkColorSetA(*device_bitmap.getAddr32(i, j), 0xFF);
}
}
}
return canvas.ExtractBitmap();
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment