Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1184)

Side by Side Diff: ui/native_theme/native_theme_win.cc

Issue 2182083002: Remove BitmapPlatformDevice from NativeThemeWin (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Switch back to initialization-via-construction once Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/native_theme/native_theme_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
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 "third_party/skia/include/core/SkSurface.h"
27 #include "ui/base/material_design/material_design_controller.h" 28 #include "ui/base/material_design/material_design_controller.h"
28 #include "ui/display/win/dpi.h" 29 #include "ui/display/win/dpi.h"
29 #include "ui/gfx/color_palette.h" 30 #include "ui/gfx/color_palette.h"
30 #include "ui/gfx/color_utils.h" 31 #include "ui/gfx/color_utils.h"
31 #include "ui/gfx/gdi_util.h" 32 #include "ui/gfx/gdi_util.h"
32 #include "ui/gfx/geometry/rect.h" 33 #include "ui/gfx/geometry/rect.h"
33 #include "ui/gfx/geometry/rect_conversions.h" 34 #include "ui/gfx/geometry/rect_conversions.h"
34 #include "ui/gfx/skia_util.h" 35 #include "ui/gfx/skia_util.h"
35 #include "ui/native_theme/common_theme.h" 36 #include "ui/native_theme/common_theme.h"
36 37
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 case kScrollbarHorizontalGripper: 278 case kScrollbarHorizontalGripper:
278 case kScrollbarVerticalGripper: 279 case kScrollbarVerticalGripper:
279 needs_paint_indirect = !GetThemeHandle(SCROLLBAR) || 280 needs_paint_indirect = !GetThemeHandle(SCROLLBAR) ||
280 base::win::GetVersion() == base::win::VERSION_XP; 281 base::win::GetVersion() == base::win::VERSION_XP;
281 break; 282 break;
282 default: 283 default:
283 break; 284 break;
284 } 285 }
285 } 286 }
286 287
288 skia::ScopedPlatformPaint paint(canvas);
289 HDC surface = paint.GetPlatformSurface();
287 if (needs_paint_indirect) 290 if (needs_paint_indirect)
288 PaintIndirect(canvas, part, state, rect, extra); 291 PaintIndirect(canvas, surface, part, state, rect, extra);
289 else 292 else
290 PaintDirect(canvas, part, state, rect, extra); 293 PaintDirect(canvas, surface, part, state, rect, extra);
291 } 294 }
292 295
293 NativeThemeWin::NativeThemeWin() 296 NativeThemeWin::NativeThemeWin()
294 : draw_theme_(NULL), 297 : draw_theme_(NULL),
295 draw_theme_ex_(NULL), 298 draw_theme_ex_(NULL),
296 get_theme_color_(NULL), 299 get_theme_color_(NULL),
297 get_theme_content_rect_(NULL), 300 get_theme_content_rect_(NULL),
298 get_theme_part_size_(NULL), 301 get_theme_part_size_(NULL),
299 open_theme_(NULL), 302 open_theme_(NULL),
300 close_theme_(NULL), 303 close_theme_(NULL),
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 canvas->drawLine(position_x, rect.y(), position_x, rect.bottom(), paint); 372 canvas->drawLine(position_x, rect.y(), position_x, rect.bottom(), paint);
370 } 373 }
371 374
372 void NativeThemeWin::PaintMenuBackground(SkCanvas* canvas, 375 void NativeThemeWin::PaintMenuBackground(SkCanvas* canvas,
373 const gfx::Rect& rect) const { 376 const gfx::Rect& rect) const {
374 SkPaint paint; 377 SkPaint paint;
375 paint.setColor(GetSystemColor(NativeTheme::kColorId_MenuBackgroundColor)); 378 paint.setColor(GetSystemColor(NativeTheme::kColorId_MenuBackgroundColor));
376 canvas->drawRect(gfx::RectToSkRect(rect), paint); 379 canvas->drawRect(gfx::RectToSkRect(rect), paint);
377 } 380 }
378 381
379 void NativeThemeWin::PaintDirect(SkCanvas* canvas, 382 void NativeThemeWin::PaintDirect(SkCanvas* destination_canvas,
383 HDC hdc,
380 Part part, 384 Part part,
381 State state, 385 State state,
382 const gfx::Rect& rect, 386 const gfx::Rect& rect,
383 const ExtraParams& extra) const { 387 const ExtraParams& extra) const {
384 skia::ScopedPlatformPaint scoped_platform_paint(canvas);
385 HDC hdc = scoped_platform_paint.GetPlatformSurface();
386
387 switch (part) { 388 switch (part) {
388 case kCheckbox: 389 case kCheckbox:
389 PaintCheckbox(hdc, part, state, rect, extra.button); 390 PaintCheckbox(hdc, part, state, rect, extra.button);
390 return; 391 return;
391 case kInnerSpinButton: 392 case kInnerSpinButton:
392 PaintSpinButton(hdc, part, state, rect, extra.inner_spin); 393 PaintSpinButton(hdc, part, state, rect, extra.inner_spin);
393 return; 394 return;
394 case kMenuList: 395 case kMenuList:
395 PaintMenuList(hdc, state, rect, extra.menu_list); 396 PaintMenuList(hdc, state, rect, extra.menu_list);
396 return; 397 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 PaintScrollbarArrow(hdc, part, state, rect, extra.scrollbar_arrow); 432 PaintScrollbarArrow(hdc, part, state, rect, extra.scrollbar_arrow);
432 return; 433 return;
433 case kScrollbarHorizontalThumb: 434 case kScrollbarHorizontalThumb:
434 case kScrollbarVerticalThumb: 435 case kScrollbarVerticalThumb:
435 case kScrollbarHorizontalGripper: 436 case kScrollbarHorizontalGripper:
436 case kScrollbarVerticalGripper: 437 case kScrollbarVerticalGripper:
437 PaintScrollbarThumb(hdc, part, state, rect, extra.scrollbar_thumb); 438 PaintScrollbarThumb(hdc, part, state, rect, extra.scrollbar_thumb);
438 return; 439 return;
439 case kScrollbarHorizontalTrack: 440 case kScrollbarHorizontalTrack:
440 case kScrollbarVerticalTrack: 441 case kScrollbarVerticalTrack:
441 PaintScrollbarTrack(canvas, hdc, part, state, rect, 442 PaintScrollbarTrack(destination_canvas, hdc, part, state, rect,
442 extra.scrollbar_track); 443 extra.scrollbar_track);
443 return; 444 return;
444 case kScrollbarCorner: 445 case kScrollbarCorner:
445 canvas->drawColor(SK_ColorWHITE, SkXfermode::kSrc_Mode); 446 destination_canvas->drawColor(SK_ColorWHITE, SkXfermode::kSrc_Mode);
446 return; 447 return;
447 case kTabPanelBackground: 448 case kTabPanelBackground:
448 PaintTabPanelBackground(hdc, rect); 449 PaintTabPanelBackground(hdc, rect);
449 return; 450 return;
450 case kTextField: 451 case kTextField:
451 PaintTextField(hdc, part, state, rect, extra.text_field); 452 PaintTextField(hdc, part, state, rect, extra.text_field);
452 return; 453 return;
453 case kTrackbarThumb: 454 case kTrackbarThumb:
454 case kTrackbarTrack: 455 case kTrackbarTrack:
455 PaintTrackbar(canvas, hdc, part, state, rect, extra.trackbar); 456 PaintTrackbar(destination_canvas, hdc, part, state, rect, extra.trackbar);
456 return; 457 return;
457 case kWindowResizeGripper: 458 case kWindowResizeGripper:
458 PaintWindowResizeGripper(hdc, rect); 459 PaintWindowResizeGripper(hdc, rect);
459 return; 460 return;
460 case kSliderTrack: 461 case kSliderTrack:
461 case kSliderThumb: 462 case kSliderThumb:
462 case kMaxPart: 463 case kMaxPart:
463 NOTREACHED(); 464 NOTREACHED();
464 } 465 }
465 } 466 }
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 case NativeTheme::kColorId_CallToActionColor: 666 case NativeTheme::kColorId_CallToActionColor:
666 return kCallToActionColorInvert; 667 return kCallToActionColorInvert;
667 default: 668 default:
668 return color_utils::InvertColor(GetAuraColor(color_id, this)); 669 return color_utils::InvertColor(GetAuraColor(color_id, this));
669 } 670 }
670 } 671 }
671 672
672 return GetAuraColor(color_id, this); 673 return GetAuraColor(color_id, this);
673 } 674 }
674 675
675 void NativeThemeWin::PaintIndirect(SkCanvas* canvas, 676 void NativeThemeWin::PaintIndirect(SkCanvas* destination_canvas,
677 HDC destination_hdc,
676 Part part, 678 Part part,
677 State state, 679 State state,
678 const gfx::Rect& rect, 680 const gfx::Rect& rect,
679 const ExtraParams& extra) const { 681 const ExtraParams& extra) const {
680 // TODO(asvitkine): This path is pretty inefficient - for each paint operation 682 // TODO(asvitkine): This path is pretty inefficient - for each paint operation
681 // it creates a new offscreen bitmap Skia canvas. This can 683 // it creates a new offscreen bitmap Skia canvas. This can
682 // be sped up by doing it only once per part/state and 684 // be sped up by doing it only once per part/state and
683 // keeping a cache of the resulting bitmaps. 685 // keeping a cache of the resulting bitmaps.
684 686
685 // Create an offscreen canvas that is backed by an HDC. 687 // Create an offscreen canvas that is backed by an HDC.
686 sk_sp<skia::BitmapPlatformDevice> device( 688 base::win::ScopedCreateDC offscreen_hdc(
687 skia::BitmapPlatformDevice::Create( 689 skia::CreateOffscreenSurface(rect.width(), rect.height()));
688 rect.width(), rect.height(), false, NULL)); 690 sk_sp<SkSurface> offscreen_surface =
689 DCHECK(device); 691 skia::MapPlatformSurface(offscreen_hdc.Get());
690 SkCanvas offscreen_canvas(device.get()); 692 DCHECK(offscreen_surface);
691 DCHECK(skia::SupportsPlatformPaint(&offscreen_canvas)); 693 SkCanvas* offscreen_canvas = offscreen_surface->getCanvas();
694 DCHECK(offscreen_canvas);
692 695
693 // Some of the Windows theme drawing operations do not write correct alpha 696 // 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 697 // 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. 698 // especially a problem on Windows XP or when using the Classic theme.
696 // 699 //
697 // To work-around this, mark all pixels with a placeholder value, to detect 700 // 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 701 // 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. 702 // pixels that have alpha 0 to opaque and placeholders to fully-transparent.
700 const SkColor placeholder = SkColorSetARGB(1, 0, 0, 0); 703 const SkColor placeholder = SkColorSetARGB(1, 0, 0, 0);
701 offscreen_canvas.clear(placeholder); 704 offscreen_canvas->clear(placeholder);
702 705
703 // Offset destination rects to have origin (0,0). 706 // Offset destination rects to have origin (0,0).
704 gfx::Rect adjusted_rect(rect.size()); 707 gfx::Rect adjusted_rect(rect.size());
705 ExtraParams adjusted_extra(extra); 708 ExtraParams adjusted_extra(extra);
706 switch (part) { 709 switch (part) {
707 case kProgressBar: 710 case kProgressBar:
708 adjusted_extra.progress_bar.value_rect_x = 0; 711 adjusted_extra.progress_bar.value_rect_x = 0;
709 adjusted_extra.progress_bar.value_rect_y = 0; 712 adjusted_extra.progress_bar.value_rect_y = 0;
710 break; 713 break;
711 case kScrollbarHorizontalTrack: 714 case kScrollbarHorizontalTrack:
712 case kScrollbarVerticalTrack: 715 case kScrollbarVerticalTrack:
713 adjusted_extra.scrollbar_track.track_x = 0; 716 adjusted_extra.scrollbar_track.track_x = 0;
714 adjusted_extra.scrollbar_track.track_y = 0; 717 adjusted_extra.scrollbar_track.track_y = 0;
715 break; 718 break;
716 default: 719 default:
717 break; 720 break;
718 } 721 }
719 // Draw the theme controls using existing HDC-drawing code. 722 // Draw the theme controls using existing HDC-drawing code.
720 PaintDirect(&offscreen_canvas, part, state, adjusted_rect, adjusted_extra); 723 PaintDirect(offscreen_canvas, offscreen_hdc.Get(), part, state,
724 adjusted_rect, adjusted_extra);
721 725
722 SkBitmap bitmap = skia::ReadPixels(&offscreen_canvas); 726 SkBitmap offscreen_bitmap = skia::MapPlatformBitmap(offscreen_hdc.Get());
723 727
724 // Post-process the pixels to fix up the alpha values (see big comment above). 728 // Post-process the pixels to fix up the alpha values (see big comment above).
725 const SkPMColor placeholder_value = SkPreMultiplyColor(placeholder); 729 const SkPMColor placeholder_value = SkPreMultiplyColor(placeholder);
726 const int pixel_count = rect.width() * rect.height(); 730 const int pixel_count = rect.width() * rect.height();
727 SkPMColor* pixels = bitmap.getAddr32(0, 0); 731 SkPMColor* pixels = offscreen_bitmap.getAddr32(0, 0);
728 for (int i = 0; i < pixel_count; i++) { 732 for (int i = 0; i < pixel_count; i++) {
729 if (pixels[i] == placeholder_value) { 733 if (pixels[i] == placeholder_value) {
730 // Pixel wasn't touched - make it fully transparent. 734 // Pixel wasn't touched - make it fully transparent.
731 pixels[i] = SkPackARGB32(0, 0, 0, 0); 735 pixels[i] = SkPackARGB32(0, 0, 0, 0);
732 } else if (SkGetPackedA32(pixels[i]) == 0) { 736 } else if (SkGetPackedA32(pixels[i]) == 0) {
733 // Pixel was touched but has incorrect alpha of 0, make it fully opaque. 737 // Pixel was touched but has incorrect alpha of 0, make it fully opaque.
734 pixels[i] = SkPackARGB32(0xFF, 738 pixels[i] = SkPackARGB32(0xFF,
735 SkGetPackedR32(pixels[i]), 739 SkGetPackedR32(pixels[i]),
736 SkGetPackedG32(pixels[i]), 740 SkGetPackedG32(pixels[i]),
737 SkGetPackedB32(pixels[i])); 741 SkGetPackedB32(pixels[i]));
738 } 742 }
739 } 743 }
740 744
741 // Draw the offscreen bitmap to the destination canvas. 745 destination_canvas->drawBitmap(offscreen_bitmap, rect.x(), rect.y());
742 canvas->drawBitmap(bitmap, rect.x(), rect.y());
743 } 746 }
744 747
745 HRESULT NativeThemeWin::GetThemePartSize(ThemeName theme_name, 748 HRESULT NativeThemeWin::GetThemePartSize(ThemeName theme_name,
746 HDC hdc, 749 HDC hdc,
747 int part_id, 750 int part_id,
748 int state_id, 751 int state_id,
749 RECT* rect, 752 RECT* rect,
750 int ts, 753 int ts,
751 SIZE* size) const { 754 SIZE* size) const {
752 HANDLE handle = GetThemeHandle(theme_name); 755 HANDLE handle = GetThemeHandle(theme_name);
(...skipping 1326 matching lines...) Expand 10 before | Expand all | Expand 10 after
2079 break; 2082 break;
2080 case LAST: 2083 case LAST:
2081 NOTREACHED(); 2084 NOTREACHED();
2082 break; 2085 break;
2083 } 2086 }
2084 theme_handles_[theme_name] = handle; 2087 theme_handles_[theme_name] = handle;
2085 return handle; 2088 return handle;
2086 } 2089 }
2087 2090
2088 } // namespace ui 2091 } // namespace ui
OLDNEW
« no previous file with comments | « ui/native_theme/native_theme_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698