summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/views/theme_helpers.cc
blob: 833f49c28bb95083c1fad1a8cd6ba9ec9860b5f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/theme_helpers.h"

#include <atlbase.h>
#include <atlapp.h>
#include <atltheme.h>

#include "base/logging.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/size.h"

void GetRebarGradientColors(int width, int x1, int x2,
                            SkColor* c1, SkColor* c2) {
  DCHECK(c1 && c2) <<
      "ThemeHelpers::GetRebarGradientColors - c1 or c2 is NULL!";

  // To get the colors we need, we draw a horizontal gradient using
  // DrawThemeBackground, then extract the pixel values from and return
  // those so calling code can use them to create gradient brushes for use in
  // rendering in other directions.

  gfx::Canvas canvas(gfx::Size(width, 1), ui::SCALE_FACTOR_100P, true);

  // Render the Rebar gradient into the DIB
  CTheme theme;
  if (theme.IsThemingSupported())
    theme.OpenThemeData(NULL, L"REBAR");
  // On Windows XP+, if using a Theme, we can ask the theme to render the
  // gradient for us.
  if (!theme.IsThemeNull()) {
    skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas());
    HDC dc = scoped_platform_paint.GetPlatformSurface();
    RECT rect = { 0, 0, width, 1 };
    theme.DrawThemeBackground(dc, 0, 0, &rect, NULL);
  } else {
    // On Windows 2000 or Windows XP+ with the Classic theme selected, we need
    // to build our own gradient using system colors.
    SkColor grad_colors[2];
    COLORREF hl_ref = ::GetSysColor(COLOR_3DHILIGHT);
    grad_colors[0] = SkColorSetRGB(GetRValue(hl_ref), GetGValue(hl_ref),
                                   GetBValue(hl_ref));
    COLORREF face_ref = ::GetSysColor(COLOR_3DFACE);
    grad_colors[1] = SkColorSetRGB(GetRValue(face_ref), GetGValue(face_ref),
                                   GetBValue(face_ref));
    SkPoint grad_points[2];
    grad_points[0].set(SkIntToScalar(0), SkIntToScalar(0));
    grad_points[1].set(SkIntToScalar(width), SkIntToScalar(0));
    SkShader* gradient_shader = SkGradientShader::CreateLinear(
        grad_points, grad_colors, NULL, 2, SkShader::kRepeat_TileMode);
    SkPaint paint;
    paint.setShader(gradient_shader);
    // Shader created with a ref count of 1, release as the paint now owns
    // the gradient.
    gradient_shader->unref();
    paint.setStyle(SkPaint::kFill_Style);
    canvas.sk_canvas()->drawRectCoords(
        SkIntToScalar(0), SkIntToScalar(0),
        SkIntToScalar(width), SkIntToScalar(1), paint);
  }

  // Extract the color values from the selected pixels
  // The | in the following operations forces the alpha to 0xFF. This is
  // needed as windows sets the alpha to 0 when it renders.
  SkDevice* device = skia::GetTopDevice(*canvas.sk_canvas());
  const SkBitmap& bitmap = device->accessBitmap(false);
  SkAutoLockPixels lock(bitmap);

  *c1 = 0xFF000000 | bitmap.getColor(x1, 0);
  *c2 = 0xFF000000 | bitmap.getColor(x2, 0);
}

void GetDarkLineColor(SkColor* dark_color) {
  DCHECK(dark_color) << "ThemeHelpers::DarkColor - dark_color is NULL!";

  CTheme theme;
  if (theme.IsThemingSupported())
    theme.OpenThemeData(NULL, L"REBAR");

  // Note: the alpha values were chosen scientifically according to what looked
  //       best to me at the time! --beng
  if (!theme.IsThemeNull()) {
    *dark_color = SkColorSetARGB(60, 0, 0, 0);
  } else {
    COLORREF shadow_ref = ::GetSysColor(COLOR_3DSHADOW);
    *dark_color = SkColorSetARGB(175,
                                 GetRValue(shadow_ref),
                                 GetGValue(shadow_ref),
                                 GetBValue(shadow_ref));
  }
}