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
GetRebarGradientColors(int width,int x1,int x2,SkColor * c1,SkColor * c2)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
GetDarkLineColor(SkColor * dark_color)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