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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/views/theme_helpers.h" 6 7 #include <atlbase.h> 8 #include <atlapp.h> 9 #include <atltheme.h> 10 11 #include "base/logging.h" 12 #include "skia/ext/bitmap_platform_device_win.h" 13 #include "third_party/skia/include/effects/SkGradientShader.h" 14 #include "ui/gfx/canvas_skia.h" 15 16 void GetRebarGradientColors(int width, int x1, int x2, 17 SkColor* c1, SkColor* c2) { 18 DCHECK(c1 && c2) << 19 "ThemeHelpers::GetRebarGradientColors - c1 or c2 is NULL!"; 20 21 // To get the colors we need, we draw a horizontal gradient using 22 // DrawThemeBackground, then extract the pixel values from and return 23 // those so calling code can use them to create gradient brushes for use in 24 // rendering in other directions. 25 26 gfx::CanvasSkia canvas(width, 1, true); 27 28 // Render the Rebar gradient into the DIB 29 CTheme theme; 30 if (theme.IsThemingSupported()) 31 theme.OpenThemeData(NULL, L"REBAR"); 32 // On Windows XP+, if using a Theme, we can ask the theme to render the 33 // gradient for us. 34 if (!theme.IsThemeNull()) { 35 HDC dc = canvas.beginPlatformPaint(); 36 RECT rect = { 0, 0, width, 1 }; 37 theme.DrawThemeBackground(dc, 0, 0, &rect, NULL); 38 canvas.endPlatformPaint(); 39 } else { 40 // On Windows 2000 or Windows XP+ with the Classic theme selected, we need 41 // to build our own gradient using system colors. 42 SkColor grad_colors[2]; 43 COLORREF hl_ref = ::GetSysColor(COLOR_3DHILIGHT); 44 grad_colors[0] = SkColorSetRGB(GetRValue(hl_ref), GetGValue(hl_ref), 45 GetBValue(hl_ref)); 46 COLORREF face_ref = ::GetSysColor(COLOR_3DFACE); 47 grad_colors[1] = SkColorSetRGB(GetRValue(face_ref), GetGValue(face_ref), 48 GetBValue(face_ref)); 49 SkPoint grad_points[2]; 50 grad_points[0].set(SkIntToScalar(0), SkIntToScalar(0)); 51 grad_points[1].set(SkIntToScalar(width), SkIntToScalar(0)); 52 SkShader* gradient_shader = SkGradientShader::CreateLinear( 53 grad_points, grad_colors, NULL, 2, SkShader::kRepeat_TileMode); 54 SkPaint paint; 55 paint.setShader(gradient_shader); 56 // Shader created with a ref count of 1, release as the paint now owns 57 // the gradient. 58 gradient_shader->unref(); 59 paint.setStyle(SkPaint::kFill_Style); 60 canvas.drawRectCoords(SkIntToScalar(0), SkIntToScalar(0), 61 SkIntToScalar(width), SkIntToScalar(1), paint); 62 } 63 64 // Extract the color values from the selected pixels 65 // The | in the following operations forces the alpha to 0xFF. This is 66 // needed as windows sets the alpha to 0 when it renders. 67 skia::BitmapPlatformDevice& device = 68 static_cast<skia::BitmapPlatformDevice&>( 69 canvas.getTopPlatformDevice()); 70 *c1 = 0xFF000000 | device.getColorAt(x1, 0); 71 *c2 = 0xFF000000 | device.getColorAt(x2, 0); 72 } 73 74 void GetDarkLineColor(SkColor* dark_color) { 75 DCHECK(dark_color) << "ThemeHelpers::DarkColor - dark_color is NULL!"; 76 77 CTheme theme; 78 if (theme.IsThemingSupported()) 79 theme.OpenThemeData(NULL, L"REBAR"); 80 81 // Note: the alpha values were chosen scientifically according to what looked 82 // best to me at the time! --beng 83 if (!theme.IsThemeNull()) { 84 *dark_color = SkColorSetARGB(60, 0, 0, 0); 85 } else { 86 COLORREF shadow_ref = ::GetSysColor(COLOR_3DSHADOW); 87 *dark_color = SkColorSetARGB(175, 88 GetRValue(shadow_ref), 89 GetGValue(shadow_ref), 90 GetBValue(shadow_ref)); 91 } 92 } 93