Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Many of these functions are based on those found in | 5 // Many of these functions are based on those found in |
| 6 // webkit/port/platform/PasteboardWin.cpp | 6 // webkit/port/platform/PasteboardWin.cpp |
| 7 | 7 |
| 8 #include "ui/base/clipboard/clipboard.h" | 8 #include "ui/base/clipboard/clipboard.h" |
| 9 | 9 |
| 10 #include <shlobj.h> | 10 #include <shlobj.h> |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 469 gfx::CanvasSkia canvas(bitmap->bmiHeader.biWidth, bitmap->bmiHeader.biHeight, | 469 gfx::CanvasSkia canvas(bitmap->bmiHeader.biWidth, bitmap->bmiHeader.biHeight, |
| 470 false); | 470 false); |
| 471 { | 471 { |
| 472 skia::ScopedPlatformPaint scoped_platform_paint(&canvas); | 472 skia::ScopedPlatformPaint scoped_platform_paint(&canvas); |
| 473 HDC dc = scoped_platform_paint.GetPlatformSurface(); | 473 HDC dc = scoped_platform_paint.GetPlatformSurface(); |
| 474 ::SetDIBitsToDevice(dc, 0, 0, bitmap->bmiHeader.biWidth, | 474 ::SetDIBitsToDevice(dc, 0, 0, bitmap->bmiHeader.biWidth, |
| 475 bitmap->bmiHeader.biHeight, 0, 0, 0, | 475 bitmap->bmiHeader.biHeight, 0, 0, 0, |
| 476 bitmap->bmiHeader.biHeight, bitmap_bits, bitmap, | 476 bitmap->bmiHeader.biHeight, bitmap_bits, bitmap, |
| 477 DIB_RGB_COLORS); | 477 DIB_RGB_COLORS); |
| 478 } | 478 } |
| 479 // SetDIBitsToDevice doesn't properly set alpha values for bitmaps with | 479 // Windows doesn't really handle alpha channels well in many situations. We |
| 480 // depth < 32bpp so manually fix it up. | 480 // attempt to manually fix the alpha channel here. Since Windows uses |
| 481 if (bitmap->bmiHeader.biBitCount < 32) { | 481 // premultiplied alpha, we scan for instances where (R, G, B) > A. If there |
| 482 const SkBitmap& device_bitmap = canvas.getDevice()->accessBitmap(true); | 482 // are any invalid premultiplied colors in the image, we assume the alpha |
| 483 // channel contains junk and reset the alpha value for all pixels to 255. This | |
| 484 // heuristic will fail on a transparent bitmap containing only black pixels... | |
| 485 const SkBitmap& device_bitmap = canvas.getDevice()->accessBitmap(true); | |
| 486 { | |
| 483 SkAutoLockPixels lock(device_bitmap); | 487 SkAutoLockPixels lock(device_bitmap); |
| 488 bool has_invalid_alpha_channel = false; | |
| 484 for (int x = 0; x < device_bitmap.width(); ++x) { | 489 for (int x = 0; x < device_bitmap.width(); ++x) { |
| 485 for (int y = 0; y < device_bitmap.height(); ++y) { | 490 for (int y = 0; y < device_bitmap.height(); ++y) { |
| 486 *device_bitmap.getAddr32(x, y) = | 491 uint32_t pixel = *device_bitmap.getAddr32(x, y); |
| 487 SkColorSetA(*device_bitmap.getAddr32(x, y), 0xFF); | 492 if (SkColorGetR(pixel) > SkColorGetA(pixel) || |
| 493 SkColorGetG(pixel) > SkColorGetA(pixel) || | |
| 494 SkColorGetB(pixel) > SkColorGetA(pixel)) { | |
| 495 has_invalid_alpha_channel = true; | |
| 496 break; | |
|
tony
2011/09/20 23:26:54
This only breaks out of the inner for loop. You p
dcheng
2011/09/20 23:56:33
Done. Thanks for the catch.
| |
| 497 } | |
| 498 } | |
| 499 } | |
| 500 | |
| 501 if (has_invalid_alpha_channel) { | |
| 502 for (int x = 0; x < device_bitmap.width(); ++x) { | |
| 503 for (int y = 0; y < device_bitmap.height(); ++y) { | |
| 504 *device_bitmap.getAddr32(x, y) = | |
| 505 SkColorSetA(*device_bitmap.getAddr32(x, y), 0xFF); | |
| 506 } | |
| 488 } | 507 } |
| 489 } | 508 } |
| 490 } | 509 } |
| 510 | |
| 491 return canvas.ExtractBitmap(); | 511 return canvas.ExtractBitmap(); |
| 492 } | 512 } |
| 493 | 513 |
| 494 void Clipboard::ReadBookmark(string16* title, std::string* url) const { | 514 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |
| 495 if (title) | 515 if (title) |
| 496 title->clear(); | 516 title->clear(); |
| 497 | 517 |
| 498 if (url) | 518 if (url) |
| 499 url->clear(); | 519 url->clear(); |
| 500 | 520 |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 688 clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass", | 708 clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass", |
| 689 L"ClipboardOwnerWindow", | 709 L"ClipboardOwnerWindow", |
| 690 0, 0, 0, 0, 0, | 710 0, 0, 0, 0, 0, |
| 691 HWND_MESSAGE, | 711 HWND_MESSAGE, |
| 692 0, 0, 0); | 712 0, 0, 0); |
| 693 } | 713 } |
| 694 return clipboard_owner_; | 714 return clipboard_owner_; |
| 695 } | 715 } |
| 696 | 716 |
| 697 } // namespace ui | 717 } // namespace ui |
| OLD | NEW |