Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "ui/native_theme/native_theme_win.h" | 5 #include "ui/native_theme/native_theme_win.h" | 
| 6 | 6 | 
| 7 #include <windows.h> | 7 #include <windows.h> | 
| 8 #include <stddef.h> | 8 #include <stddef.h> | 
| 9 #include <uxtheme.h> | 9 #include <uxtheme.h> | 
| 10 #include <vsstyle.h> | 10 #include <vsstyle.h> | 
| 11 #include <vssym32.h> | 11 #include <vssym32.h> | 
| 12 | 12 | 
| 13 #include "base/logging.h" | 13 #include "base/logging.h" | 
| 14 #include "base/macros.h" | 14 #include "base/macros.h" | 
| 15 #include "base/win/scoped_gdi_object.h" | 15 #include "base/win/scoped_gdi_object.h" | 
| 16 #include "base/win/scoped_hdc.h" | 16 #include "base/win/scoped_hdc.h" | 
| 17 #include "base/win/scoped_select_object.h" | 17 #include "base/win/scoped_select_object.h" | 
| 18 #include "base/win/windows_version.h" | 18 #include "base/win/windows_version.h" | 
| 19 #include "skia/ext/bitmap_platform_device.h" | 19 #include "skia/ext/bitmap_platform_device.h" | 
| 20 #include "skia/ext/platform_canvas.h" | 20 #include "skia/ext/platform_canvas.h" | 
| 21 #include "skia/ext/skia_utils_win.h" | 21 #include "skia/ext/skia_utils_win.h" | 
| 22 #include "third_party/skia/include/core/SkCanvas.h" | 22 #include "third_party/skia/include/core/SkCanvas.h" | 
| 23 #include "third_party/skia/include/core/SkColor.h" | 23 #include "third_party/skia/include/core/SkColor.h" | 
| 24 #include "third_party/skia/include/core/SkColorPriv.h" | 24 #include "third_party/skia/include/core/SkColorPriv.h" | 
| 
 
Peter Kasting
2016/06/29 23:20:01
Maybe can remove this #include now?
 
 | |
| 25 #include "third_party/skia/include/core/SkRefCnt.h" | 25 #include "third_party/skia/include/core/SkRefCnt.h" | 
| 26 #include "third_party/skia/include/core/SkShader.h" | 26 #include "third_party/skia/include/core/SkShader.h" | 
| 27 #include "ui/base/material_design/material_design_controller.h" | 27 #include "ui/base/material_design/material_design_controller.h" | 
| 28 #include "ui/display/win/dpi.h" | 28 #include "ui/display/win/dpi.h" | 
| 29 #include "ui/gfx/color_palette.h" | 29 #include "ui/gfx/color_palette.h" | 
| 30 #include "ui/gfx/color_utils.h" | 30 #include "ui/gfx/color_utils.h" | 
| 31 #include "ui/gfx/gdi_util.h" | 31 #include "ui/gfx/gdi_util.h" | 
| 32 #include "ui/gfx/geometry/rect.h" | 32 #include "ui/gfx/geometry/rect.h" | 
| 33 #include "ui/gfx/geometry/rect_conversions.h" | 33 #include "ui/gfx/geometry/rect_conversions.h" | 
| 34 #include "ui/gfx/skia_util.h" | 34 #include "ui/gfx/skia_util.h" | 
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 248 PaintMenuBackground(canvas, rect); | 248 PaintMenuBackground(canvas, rect); | 
| 249 return; | 249 return; | 
| 250 case kMenuItemBackground: | 250 case kMenuItemBackground: | 
| 251 CommonThemePaintMenuItemBackground(this, canvas, state, rect, | 251 CommonThemePaintMenuItemBackground(this, canvas, state, rect, | 
| 252 extra.menu_item); | 252 extra.menu_item); | 
| 253 return; | 253 return; | 
| 254 default: | 254 default: | 
| 255 break; | 255 break; | 
| 256 } | 256 } | 
| 257 | 257 | 
| 258 bool needs_paint_indirect = false; | 258 PaintDirect(canvas, part, state, rect, extra); | 
| 
 
Peter Kasting
2016/06/29 23:20:01
This is now the only caller of this function.  I w
 
 | |
| 259 if (!skia::SupportsPlatformPaint(canvas)) { | |
| 260 // This block will only get hit with --enable-accelerated-drawing flag. | |
| 261 needs_paint_indirect = true; | |
| 262 } else { | |
| 263 // Scrollbar components on Windows Classic theme (on all Windows versions) | |
| 264 // have particularly problematic alpha values, so always draw them | |
| 265 // indirectly. In addition, scrollbar thumbs and grippers for the Windows XP | |
| 266 // theme (available only on Windows XP) also need their alpha values | |
| 267 // fixed. | |
| 268 switch (part) { | |
| 269 case kScrollbarDownArrow: | |
| 270 case kScrollbarUpArrow: | |
| 271 case kScrollbarLeftArrow: | |
| 272 case kScrollbarRightArrow: | |
| 273 needs_paint_indirect = !GetThemeHandle(SCROLLBAR); | |
| 274 break; | |
| 275 case kScrollbarHorizontalThumb: | |
| 276 case kScrollbarVerticalThumb: | |
| 277 case kScrollbarHorizontalGripper: | |
| 278 case kScrollbarVerticalGripper: | |
| 279 needs_paint_indirect = !GetThemeHandle(SCROLLBAR) || | |
| 280 base::win::GetVersion() == base::win::VERSION_XP; | |
| 281 break; | |
| 282 default: | |
| 283 break; | |
| 284 } | |
| 285 } | |
| 286 | |
| 287 if (needs_paint_indirect) | |
| 288 PaintIndirect(canvas, part, state, rect, extra); | |
| 289 else | |
| 290 PaintDirect(canvas, part, state, rect, extra); | |
| 291 } | 259 } | 
| 292 | 260 | 
| 293 NativeThemeWin::NativeThemeWin() | 261 NativeThemeWin::NativeThemeWin() | 
| 294 : draw_theme_(NULL), | 262 : draw_theme_(NULL), | 
| 295 draw_theme_ex_(NULL), | 263 draw_theme_ex_(NULL), | 
| 296 get_theme_color_(NULL), | 264 get_theme_color_(NULL), | 
| 297 get_theme_content_rect_(NULL), | 265 get_theme_content_rect_(NULL), | 
| 298 get_theme_part_size_(NULL), | 266 get_theme_part_size_(NULL), | 
| 299 open_theme_(NULL), | 267 open_theme_(NULL), | 
| 300 close_theme_(NULL), | 268 close_theme_(NULL), | 
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 665 case NativeTheme::kColorId_CallToActionColor: | 633 case NativeTheme::kColorId_CallToActionColor: | 
| 666 return kCallToActionColorInvert; | 634 return kCallToActionColorInvert; | 
| 667 default: | 635 default: | 
| 668 return color_utils::InvertColor(GetAuraColor(color_id, this)); | 636 return color_utils::InvertColor(GetAuraColor(color_id, this)); | 
| 669 } | 637 } | 
| 670 } | 638 } | 
| 671 | 639 | 
| 672 return GetAuraColor(color_id, this); | 640 return GetAuraColor(color_id, this); | 
| 673 } | 641 } | 
| 674 | 642 | 
| 675 void NativeThemeWin::PaintIndirect(SkCanvas* canvas, | |
| 676 Part part, | |
| 677 State state, | |
| 678 const gfx::Rect& rect, | |
| 679 const ExtraParams& extra) const { | |
| 680 // TODO(asvitkine): This path is pretty inefficient - for each paint operation | |
| 681 // it creates a new offscreen bitmap Skia canvas. This can | |
| 682 // be sped up by doing it only once per part/state and | |
| 683 // keeping a cache of the resulting bitmaps. | |
| 684 | |
| 685 // Create an offscreen canvas that is backed by an HDC. | |
| 686 sk_sp<skia::BitmapPlatformDevice> device( | |
| 687 skia::BitmapPlatformDevice::Create( | |
| 688 rect.width(), rect.height(), false, NULL)); | |
| 689 DCHECK(device); | |
| 690 SkCanvas offscreen_canvas(device.get()); | |
| 691 DCHECK(skia::SupportsPlatformPaint(&offscreen_canvas)); | |
| 692 | |
| 693 // Some of the Windows theme drawing operations do not write correct alpha | |
| 694 // values for fully-opaque pixels; instead the pixels get alpha 0. This is | |
| 695 // especially a problem on Windows XP or when using the Classic theme. | |
| 696 // | |
| 697 // To work-around this, mark all pixels with a placeholder value, to detect | |
| 698 // which pixels get touched by the paint operation. After paint, set any | |
| 699 // pixels that have alpha 0 to opaque and placeholders to fully-transparent. | |
| 700 const SkColor placeholder = SkColorSetARGB(1, 0, 0, 0); | |
| 701 offscreen_canvas.clear(placeholder); | |
| 702 | |
| 703 // Offset destination rects to have origin (0,0). | |
| 704 gfx::Rect adjusted_rect(rect.size()); | |
| 705 ExtraParams adjusted_extra(extra); | |
| 706 switch (part) { | |
| 707 case kProgressBar: | |
| 708 adjusted_extra.progress_bar.value_rect_x = 0; | |
| 709 adjusted_extra.progress_bar.value_rect_y = 0; | |
| 710 break; | |
| 711 case kScrollbarHorizontalTrack: | |
| 712 case kScrollbarVerticalTrack: | |
| 713 adjusted_extra.scrollbar_track.track_x = 0; | |
| 714 adjusted_extra.scrollbar_track.track_y = 0; | |
| 715 break; | |
| 716 default: | |
| 717 break; | |
| 718 } | |
| 719 // Draw the theme controls using existing HDC-drawing code. | |
| 720 PaintDirect(&offscreen_canvas, part, state, adjusted_rect, adjusted_extra); | |
| 721 | |
| 722 SkBitmap bitmap = skia::ReadPixels(&offscreen_canvas); | |
| 723 | |
| 724 // Post-process the pixels to fix up the alpha values (see big comment above). | |
| 725 const SkPMColor placeholder_value = SkPreMultiplyColor(placeholder); | |
| 726 const int pixel_count = rect.width() * rect.height(); | |
| 727 SkPMColor* pixels = bitmap.getAddr32(0, 0); | |
| 728 for (int i = 0; i < pixel_count; i++) { | |
| 729 if (pixels[i] == placeholder_value) { | |
| 730 // Pixel wasn't touched - make it fully transparent. | |
| 731 pixels[i] = SkPackARGB32(0, 0, 0, 0); | |
| 732 } else if (SkGetPackedA32(pixels[i]) == 0) { | |
| 733 // Pixel was touched but has incorrect alpha of 0, make it fully opaque. | |
| 734 pixels[i] = SkPackARGB32(0xFF, | |
| 735 SkGetPackedR32(pixels[i]), | |
| 736 SkGetPackedG32(pixels[i]), | |
| 737 SkGetPackedB32(pixels[i])); | |
| 738 } | |
| 739 } | |
| 740 | |
| 741 // Draw the offscreen bitmap to the destination canvas. | |
| 742 canvas->drawBitmap(bitmap, rect.x(), rect.y()); | |
| 743 } | |
| 744 | |
| 745 HRESULT NativeThemeWin::GetThemePartSize(ThemeName theme_name, | 643 HRESULT NativeThemeWin::GetThemePartSize(ThemeName theme_name, | 
| 746 HDC hdc, | 644 HDC hdc, | 
| 747 int part_id, | 645 int part_id, | 
| 748 int state_id, | 646 int state_id, | 
| 749 RECT* rect, | 647 RECT* rect, | 
| 750 int ts, | 648 int ts, | 
| 751 SIZE* size) const { | 649 SIZE* size) const { | 
| 752 HANDLE handle = GetThemeHandle(theme_name); | 650 HANDLE handle = GetThemeHandle(theme_name); | 
| 753 return (handle && get_theme_part_size_) ? | 651 return (handle && get_theme_part_size_) ? | 
| 754 get_theme_part_size_(handle, hdc, part_id, state_id, rect, ts, size) : | 652 get_theme_part_size_(handle, hdc, part_id, state_id, rect, ts, size) : | 
| (...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2079 break; | 1977 break; | 
| 2080 case LAST: | 1978 case LAST: | 
| 2081 NOTREACHED(); | 1979 NOTREACHED(); | 
| 2082 break; | 1980 break; | 
| 2083 } | 1981 } | 
| 2084 theme_handles_[theme_name] = handle; | 1982 theme_handles_[theme_name] = handle; | 
| 2085 return handle; | 1983 return handle; | 
| 2086 } | 1984 } | 
| 2087 | 1985 | 
| 2088 } // namespace ui | 1986 } // namespace ui | 
| OLD | NEW |