native_theme_base.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/native_theme/native_theme_base.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/effects/SkGradientShader.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ui_base_switches.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/color_utils.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These are the default dimensions of radio buttons and checkboxes.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCheckboxAndRadioWidth = 13;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCheckboxAndRadioHeight = 13;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These sizes match the sizes in Chromium Win.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSliderThumbWidth = 11;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSliderThumbHeight = 21;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderTrackBackgroundColor =
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xe3, 0xdd, 0xd8);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderThumbLightGrey = SkColorSetRGB(0xf4, 0xf2, 0xef);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderThumbDarkGrey = SkColorSetRGB(0xea, 0xe5, 0xe0);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderThumbBorderDarkGrey =
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0x9d, 0x96, 0x8e);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kMenuPopupBackgroundColor = SkColorSetRGB(210, 225, 246);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned int kDefaultScrollbarWidth = 15;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned int kDefaultScrollbarButtonLength = 14;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxTinyColor = SK_ColorGRAY;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxShadowColor = SkColorSetARGB(0x15, 0, 0, 0);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxShadowHoveredColor = SkColorSetARGB(0x1F, 0, 0, 0);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxShadowDisabledColor = SkColorSetARGB(0, 0, 0, 0);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientColors[] = {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xed, 0xed, 0xed),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xde, 0xde, 0xde) };
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientPressedColors[] = {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xe7, 0xe7, 0xe7),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xd7, 0xd7, 0xd7) };
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientHoveredColors[] = {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xf0, 0xf0, 0xf0),
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xe0, 0xe0, 0xe0) };
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientDisabledColors[] = {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetARGB(0x80, 0xed, 0xed, 0xed),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetARGB(0x80, 0xde, 0xde, 0xde) };
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxBorderColor = SkColorSetARGB(0x40, 0, 0, 0);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxBorderHoveredColor = SkColorSetARGB(0x4D, 0, 0, 0);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxBorderDisabledColor = SkColorSetARGB(0x20, 0, 0, 0);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxStrokeColor = SkColorSetARGB(0xB3, 0, 0, 0);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxStrokeDisabledColor = SkColorSetARGB(0x59, 0, 0, 0);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kRadioDotColor = SkColorSetRGB(0x66, 0x66, 0x66);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kRadioDotDisabledColor = SkColorSetARGB(0x80, 0x66, 0x66, 0x66);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get lightness adjusted color.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor BrightenColor(const color_utils::HSL& hsl, SkAlpha alpha,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double lightness_amount) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::HSL adjusted = hsl;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  adjusted.l += lightness_amount;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (adjusted.l > 1.0)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adjusted.l = 1.0;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (adjusted.l < 0.0)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adjusted.l = 0.0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return color_utils::HSLToSkColor(adjusted, alpha);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size NativeThemeBase::GetPartSize(Part part,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       State state,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const ExtraParams& extra) const {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (part) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Please keep these in the order of NativeTheme::Part.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCheckbox:
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kInnerSpinButton:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, 0);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuList:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheck:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheckBackground:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupArrow:
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupBackground:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupGutter:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupSeparator:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuItemBackground:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kProgressBar:
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kPushButton:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kRadio:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, scrollbar_button_length_);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_button_length_, scrollbar_width_);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalThumb:
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This matches Firefox on Linux.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(2 * scrollbar_width_, scrollbar_width_);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalThumb:
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This matches Firefox on Linux.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, 2 * scrollbar_width_);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalTrack:
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(0, scrollbar_width_);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalTrack:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, 0);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalGripper:
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalGripper:
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderTrack:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderThumb:
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // These sizes match the sizes in Chromium Win.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(kSliderThumbWidth, kSliderThumbHeight);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTabPanelBackground:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTextField:
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarThumb:
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarTrack:
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kWindowResizeGripper:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unknown theme part: " << part;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::Paint(SkCanvas* canvas,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            Part part,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            State state,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const gfx::Rect& rect,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const ExtraParams& extra) const {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rect.IsEmpty())
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (part) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Please keep these in the order of NativeTheme::Part.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCheckbox:
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintCheckbox(canvas, state, rect, extra.button);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kInnerSpinButton:
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintInnerSpinButton(canvas, state, rect, extra.inner_spin);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuList:
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintMenuList(canvas, state, rect, extra.menu_list);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheck:
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheckBackground:
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupArrow:
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupBackground:
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PaintMenuPopupBackground(canvas, rect.size(), extra.menu_background);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupGutter:
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupSeparator:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuItemBackground:
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintMenuItemBackground(canvas, state, rect, extra.menu_list);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kProgressBar:
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintProgressBar(canvas, state, rect, extra.progress_bar);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kPushButton:
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintButton(canvas, state, rect, extra.button);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kRadio:
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintRadio(canvas, state, rect, extra.button);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintArrowButton(canvas, rect, part, state);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalThumb:
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalThumb:
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintScrollbarThumb(canvas, part, state, rect);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalTrack:
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalTrack:
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintScrollbarTrack(canvas, part, state, extra.scrollbar_track, rect);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalGripper:
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalGripper:
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Invoked by views scrollbar code, don't care about for non-win
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // implementations, so no NOTIMPLEMENTED.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderTrack:
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintSliderTrack(canvas, state, rect, extra.slider);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderThumb:
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintSliderThumb(canvas, state, rect, extra.slider);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTabPanelBackground:
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTextField:
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintTextField(canvas, state, rect, extra.text_field);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarThumb:
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarTrack:
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kWindowResizeGripper:
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unknown theme part: " << part;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeThemeBase::NativeThemeBase()
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : scrollbar_width_(kDefaultScrollbarWidth),
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scrollbar_button_length_(kDefaultScrollbarButtonLength) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeThemeBase::~NativeThemeBase() {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintArrowButton(
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect, Part direction, State state) const {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int widthMiddle, lengthMiddle;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (direction == kScrollbarUpArrow || direction == kScrollbarDownArrow) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widthMiddle = rect.width() / 2 + 1;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lengthMiddle = rect.height() / 2 + 1;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lengthMiddle = rect.width() / 2 + 1;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widthMiddle = rect.height() / 2 + 1;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calculate button color.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar trackHSV[3];
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(track_color_, trackHSV);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor buttonColor = SaturateAndBrighten(trackHSV, 0, 0.2f);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor backgroundColor = buttonColor;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state == kPressed) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar buttonHSV[3];
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorToHSV(buttonColor, buttonHSV);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buttonColor = SaturateAndBrighten(buttonHSV, 0, -0.1f);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (state == kHovered) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar buttonHSV[3];
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorToHSV(buttonColor, buttonHSV);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buttonColor = SaturateAndBrighten(buttonHSV, 0, 0.05f);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y()
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      + rect.height());
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Paint the background (the area visible behind the rounded corners).
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(backgroundColor);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Paint the button's outline and fill the middle
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath outline;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (direction) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() + 0.5, rect.y() + rect.height() + 0.5);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, -(rect.height() - 2));
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, -2);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 5, 0);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 2);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() + 0.5, rect.y() - 0.5);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 2);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 5, 0);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, -2);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, -(rect.height() - 2));
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() - 0.5, rect.y() + 0.5);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 2, 0);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 5);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-2, 2);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-(rect.width() - 2), 0);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() + rect.width() + 0.5, rect.y() + 0.5);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-(rect.width() - 2), 0);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-2, 2);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 5);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 2, 0);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  outline.close();
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(buttonColor);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(outline, paint);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kStroke_Style);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar thumbHSV[3];
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(thumb_inactive_color_, thumbHSV);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(OutlineColor(trackHSV, thumbHSV));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(outline, paint);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the button is disabled or read-only, the arrow is drawn with the
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // outline color.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state != kDisabled)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorBLACK);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(false);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath path;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The constants in this block of code are hand-tailored to produce good
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // looking arrows without anti-aliasing.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (direction) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle + 2);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(7, 0);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(-4, -4);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle - 3);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(7, 0);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(-4, 4);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.moveTo(rect.x() + lengthMiddle - 3, rect.y() + widthMiddle - 4);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(0, 7);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(4, -4);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.moveTo(rect.x() + lengthMiddle + 1, rect.y() + widthMiddle - 5);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(0, 9);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(-4, -4);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.close();
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(path, paint);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintScrollbarTrack(SkCanvas* canvas,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Part part,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ScrollbarTrackExtraParams& extra_params,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect) const {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(rect.x(), rect.y(), rect.right(), rect.bottom());
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar track_hsv[3];
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(track_color_, track_hsv);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SaturateAndBrighten(track_hsv, 0, 0));
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar thumb_hsv[3];
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(thumb_inactive_color_, thumb_hsv);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(OutlineColor(track_hsv, thumb_hsv));
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawBox(canvas, rect, paint);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintScrollbarThumb(SkCanvas* canvas,
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           Part part,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           State state,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const gfx::Rect& rect) const {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool hovered = state == kHovered;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int midx = rect.x() + rect.width() / 2;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int midy = rect.y() + rect.height() / 2;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool vertical = part == kScrollbarVerticalThumb;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar thumb[3];
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(hovered ? thumb_active_color_ : thumb_inactive_color_, thumb);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SaturateAndBrighten(thumb, 0, 0.02f));
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (vertical)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), midx + 1, rect.y() + rect.height());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), midy + 1);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SaturateAndBrighten(thumb, 0, -0.02f));
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (vertical) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rect.x(), midy + 1, rect.x() + rect.width(), rect.y() + rect.height());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar track[3];
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(track_color_, track);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(OutlineColor(track, thumb));
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawBox(canvas, rect, paint);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rect.height() > 10 && rect.width() > 10) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int grippy_half_width = 2;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int inter_grippy_offset = 3;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (vertical) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawHorizLine(canvas,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx - grippy_half_width,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx + grippy_half_width,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midy - inter_grippy_offset,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    paint);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawHorizLine(canvas,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx - grippy_half_width,
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx + grippy_half_width,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midy,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    paint);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawHorizLine(canvas,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx - grippy_half_width,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx + grippy_half_width,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midy + inter_grippy_offset,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    paint);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawVertLine(canvas,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midx - inter_grippy_offset,
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy - grippy_half_width,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy + grippy_half_width,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   paint);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawVertLine(canvas,
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midx,
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy - grippy_half_width,
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy + grippy_half_width,
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   paint);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawVertLine(canvas,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midx + inter_grippy_offset,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy - grippy_half_width,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy + grippy_half_width,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   paint);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintCheckbox(SkCanvas* canvas,
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    State state,
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const gfx::Rect& rect,
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const ButtonExtraParams& button) const {
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect skrect = PaintCheckboxRadioCommon(canvas, state, rect,
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           SkIntToScalar(2));
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!skrect.isEmpty()) {
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Draw the checkmark / dash.
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkPaint paint;
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setAntiAlias(true);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (state == kDisabled)
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setColor(kCheckboxStrokeDisabledColor);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setColor(kCheckboxStrokeColor);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (button.indeterminate) {
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkPath dash;
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dash.moveTo(skrect.x() + skrect.width() * 0.16,
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  (skrect.y() + skrect.bottom()) / 2);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dash.rLineTo(skrect.width() * 0.68, 0);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setStrokeWidth(SkFloatToScalar(skrect.height() * 0.2));
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas->drawPath(dash, paint);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (button.checked) {
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkPath check;
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      check.moveTo(skrect.x() + skrect.width() * 0.2,
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   skrect.y() + skrect.height() * 0.5);
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      check.rLineTo(skrect.width() * 0.2, skrect.height() * 0.2);
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setStrokeWidth(SkFloatToScalar(skrect.height() * 0.23));
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      check.lineTo(skrect.right() - skrect.width() * 0.2,
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   skrect.y() + skrect.height() * 0.2);
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas->drawPath(check, paint);
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Draws the common elements of checkboxes and radio buttons.
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the rectangle within which any additional decorations should be
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// drawn, or empty if none.
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SkRect NativeThemeBase::PaintCheckboxRadioCommon(
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkScalar borderRadius) const {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect skrect = gfx::RectToSkRect(rect);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the largest square that fits inside the provided rectangle.
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No other browser seems to support non-square widget, so accidentally
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // having non-square sizes is common (eg. amazon and webkit dev tools).
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (skrect.width() != skrect.height()) {
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar size = SkMinScalar(skrect.width(), skrect.height());
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.inset((skrect.width() - size) / 2, (skrect.height() - size) / 2);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the rectangle is too small then paint only a rectangle.  We don't want
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to have to worry about '- 1' and '+ 1' calculations below having overflow
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or underflow.
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (skrect.width() <= 2) {
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxTinyColor);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRect(skrect, paint);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Too small to draw anything more.
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SkRect::MakeEmpty();
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make room for the drop shadow.
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.iset(skrect.x(), skrect.y(), skrect.right() - 1, skrect.bottom() - 1);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw the drop shadow below the widget.
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state != kPressed) {
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setAntiAlias(true);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkRect shadowRect = skrect;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shadowRect.offset(0, 1);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == kDisabled)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     paint.setColor(kCheckboxShadowDisabledColor);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (state == kHovered)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kCheckboxShadowHoveredColor);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kCheckboxShadowColor);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRoundRect(shadowRect, borderRadius, borderRadius, paint);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw the gradient-filled rectangle
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPoint gradient_bounds[3];
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[0].set(skrect.x(), skrect.y());
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[1].set(skrect.x(), skrect.y() + skrect.height() * 0.38);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[2].set(skrect.x(), skrect.bottom());
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkColor* startEndColors;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state == kPressed)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientPressedColors;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (state == kHovered)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientHoveredColors;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (state == kDisabled)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientDisabledColors;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else /* kNormal */
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientColors;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor colors[3] = {startEndColors[0], startEndColors[0], startEndColors[1]};
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<SkShader> shader = skia::AdoptRef(
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkGradientShader::CreateLinear(
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gradient_bounds, colors, NULL, 3, SkShader::kClamp_TileMode, NULL));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint.setShader(shader.get());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRoundRect(skrect, borderRadius, borderRadius, paint);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setShader(NULL);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw the border.
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state == kHovered)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxBorderHoveredColor);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (state == kDisabled)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxBorderDisabledColor);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxBorderColor);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kStroke_Style);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStrokeWidth(SkIntToScalar(1));
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.inset(SkFloatToScalar(.5f), SkFloatToScalar(.5f));
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRoundRect(skrect, borderRadius, borderRadius, paint);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the rectangle excluding the drop shadow for drawing any additional
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // decorations.
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return skrect;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintRadio(SkCanvas* canvas,
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  State state,
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const gfx::Rect& rect,
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const ButtonExtraParams& button) const {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Most of a radio button is the same as a checkbox, except the the rounded
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // square is a circle (i.e. border radius >= 100%).
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkScalar radius = SkFloatToScalar(
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<float>(std::max(rect.width(), rect.height())) / 2);
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect skrect = PaintCheckboxRadioCommon(canvas, state, rect, radius);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!skrect.isEmpty() && button.checked) {
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Draw the dot.
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setAntiAlias(true);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == kDisabled)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kRadioDotDisabledColor);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kRadioDotColor);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.inset(skrect.width() * 0.25, skrect.height() * 0.25);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use drawRoundedRect instead of drawOval to be completely consistent
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // with the border in PaintCheckboxRadioNewCommon.
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRoundRect(skrect, radius, radius, paint);
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintButton(SkCanvas* canvas,
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  State state,
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const gfx::Rect& rect,
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const ButtonExtraParams& button) const {
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRight = rect.right();
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kBottom = rect.bottom();
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect skrect = SkRect::MakeLTRB(rect.x(), rect.y(), kRight, kBottom);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor base_color = button.background_color;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::HSL base_hsl;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::SkColorToHSL(base_color, &base_hsl);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our standard gradient is from 0xdd to 0xf8. This is the amount of
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // increased luminance between those values.
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor light_color(BrightenColor(base_hsl, SkColorGetA(base_color), 0.105));
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the button is too small, fallback to drawing a single, solid color
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rect.width() < 5 || rect.height() < 5) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(base_color);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRect(skrect, paint);
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SK_ColorBLACK);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kLightEnd = state == kPressed ? 1 : 0;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kDarkEnd = !kLightEnd;
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPoint gradient_bounds[2];
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[kLightEnd].iset(rect.x(), rect.y());
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[kDarkEnd].iset(rect.x(), kBottom - 1);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor colors[2];
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  colors[0] = light_color;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  colors[1] = base_color;
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<SkShader> shader = skia::AdoptRef(
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkGradientShader::CreateLinear(
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gradient_bounds, colors, NULL, 2, SkShader::kClamp_TileMode, NULL));
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint.setShader(shader.get());
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRoundRect(skrect, SkIntToScalar(1), SkIntToScalar(1), paint);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setShader(NULL);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (button.has_border) {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int border_alpha = state == kHovered ? 0x80 : 0x55;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (button.is_focused) {
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      border_alpha = 0xff;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(GetSystemColor(kColorId_FocusedBorderColor));
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStrokeWidth(SkIntToScalar(1));
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setAlpha(border_alpha);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.inset(SkFloatToScalar(.5f), SkFloatToScalar(.5f));
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRoundRect(skrect, SkIntToScalar(1), SkIntToScalar(1), paint);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintTextField(SkCanvas* canvas,
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     State state,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const gfx::Rect& rect,
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const TextFieldExtraParams& text) const {
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following drawing code simulates the user-agent css border for
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // text area and text input so that we do not break layout tests. Once we
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have decided the desired looks, we should update the code here and
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the layout test expectations.
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect bounds;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds.set(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint fill_paint;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fill_paint.setStyle(SkPaint::kFill_Style);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fill_paint.setColor(text.background_color);
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRect(bounds, fill_paint);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (text.is_text_area) {
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Draw text area border: 1px solid black
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint stroke_paint;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fill_paint.setStyle(SkPaint::kStroke_Style);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fill_paint.setColor(SK_ColorBLACK);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRect(bounds, fill_paint);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Draw text input and listbox inset border
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   Text Input: 2px inset #eee
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   Listbox: 1px inset #808080
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkColor kLightColor = text.is_listbox ?
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkColorSetRGB(0x80, 0x80, 0x80) : SkColorSetRGB(0xee, 0xee, 0xee);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkColor kDarkColor = text.is_listbox ?
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkColorSetRGB(0x2c, 0x2c, 0x2c) : SkColorSetRGB(0x9a, 0x9a, 0x9a);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kBorderWidth = text.is_listbox ? 1 : 2;
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint dark_paint;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dark_paint.setAntiAlias(true);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dark_paint.setStyle(SkPaint::kFill_Style);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dark_paint.setColor(kDarkColor);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint light_paint;
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    light_paint.setAntiAlias(true);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    light_paint.setStyle(SkPaint::kFill_Style);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    light_paint.setColor(kLightColor);
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int left = rect.x();
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int top = rect.y();
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int right = rect.right();
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int bottom = rect.bottom();
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.incReserve(4);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Top
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(SkIntToScalar(left), SkIntToScalar(top));
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(left + kBorderWidth),
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(top + kBorderWidth));
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right - kBorderWidth),
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(top + kBorderWidth));
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right), SkIntToScalar(top));
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawPath(path, dark_paint);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Bottom
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.reset();
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(SkIntToScalar(left + kBorderWidth),
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(bottom - kBorderWidth));
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom));
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom));
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right - kBorderWidth),
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(bottom - kBorderWidth));
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawPath(path, light_paint);
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Left
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.reset();
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(SkIntToScalar(left), SkIntToScalar(top));
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom));
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(left + kBorderWidth),
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(bottom - kBorderWidth));
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(left + kBorderWidth),
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(top + kBorderWidth));
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawPath(path, dark_paint);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Right
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.reset();
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(SkIntToScalar(right - kBorderWidth),
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(top + kBorderWidth));
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right - kBorderWidth), SkIntToScalar(bottom));
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom));
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right), SkIntToScalar(top));
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawPath(path, light_paint);
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintMenuList(
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MenuListExtraParams& menu_list) const {
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If a border radius is specified, we let the WebCore paint the background
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and the border of the control.
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!menu_list.has_border_radius) {
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ButtonExtraParams button = { 0 };
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    button.background_color = menu_list.background_color;
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    button.has_border = menu_list.has_border;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PaintButton(canvas, state, rect, button);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SK_ColorBLACK);
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath path;
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.moveTo(menu_list.arrow_x, menu_list.arrow_y - 3);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.rLineTo(6, 0);
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.rLineTo(-3, 6);
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.close();
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(path, paint);
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NativeThemeBase::PaintMenuPopupBackground(
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkCanvas* canvas,
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Size& size,
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MenuBackgroundExtraParams& menu_background) const {
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawColor(kMenuPopupBackgroundColor, SkXfermode::kSrc_Mode);
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintMenuItemBackground(
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MenuListExtraParams& menu_list) const {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By default don't draw anything over the normal background.
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintSliderTrack(SkCanvas* canvas,
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       State state,
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const gfx::Rect& rect,
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const SliderExtraParams& slider) const {
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidX = rect.x() + rect.width() / 2;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidY = rect.y() + rect.height() / 2;
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(kSliderTrackBackgroundColor);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect skrect;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (slider.vertical) {
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(std::max(rect.x(), kMidX - 2),
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               rect.y(),
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::min(rect.right(), kMidX + 2),
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               rect.bottom());
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(),
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::max(rect.y(), kMidY - 2),
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               rect.right(),
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::min(rect.bottom(), kMidY + 2));
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRect(skrect, paint);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintSliderThumb(SkCanvas* canvas,
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       State state,
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const gfx::Rect& rect,
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const SliderExtraParams& slider) const {
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool hovered = (state == kHovered) || slider.in_drag;
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidX = rect.x() + rect.width() / 2;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidY = rect.y() + rect.height() / 2;
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(hovered ? SK_ColorWHITE : kSliderThumbLightGrey);
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (slider.vertical)
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), kMidX + 1, rect.bottom());
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), rect.right(), kMidY + 1);
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(hovered ? kSliderThumbLightGrey : kSliderThumbDarkGrey);
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (slider.vertical)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(kMidX + 1, rect.y(), rect.right(), rect.bottom());
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), kMidY + 1, rect.right(), rect.bottom());
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(kSliderThumbBorderDarkGrey);
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawBox(canvas, rect, paint);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rect.height() > 10 && rect.width() > 10) {
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY, paint);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY - 3, paint);
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY + 3, paint);
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintInnerSpinButton(SkCanvas* canvas,
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const InnerSpinButtonExtraParams& spin_button) const {
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (spin_button.read_only)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state = kDisabled;
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State north_state = state;
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State south_state = state;
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (spin_button.spin_up)
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    south_state = south_state != kDisabled ? kNormal : kDisabled;
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    north_state = north_state != kDisabled ? kNormal : kDisabled;
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect half = rect;
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  half.set_height(rect.height() / 2);
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PaintArrowButton(canvas, half, kScrollbarUpArrow, north_state);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  half.set_y(rect.y() + rect.height() / 2);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PaintArrowButton(canvas, half, kScrollbarDownArrow, south_state);
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintProgressBar(SkCanvas* canvas,
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProgressBarExtraParams& progress_bar) const {
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia* bar_image = rb.GetImageSkiaNamed(IDR_PROGRESS_BAR);
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia* left_border_image = rb.GetImageSkiaNamed(
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDR_PROGRESS_BORDER_LEFT);
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia* right_border_image = rb.GetImageSkiaNamed(
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDR_PROGRESS_BORDER_RIGHT);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float tile_scale = static_cast<float>(rect.height()) /
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bar_image->height();
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int new_tile_width = static_cast<int>(bar_image->width() * tile_scale);
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float tile_scale_x = static_cast<float>(new_tile_width) /
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bar_image->width();
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawTiledImage(canvas, *bar_image, 0, 0, tile_scale_x, tile_scale,
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rect.x(), rect.y(), rect.width(), rect.height());
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (progress_bar.value_rect_width) {
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::ImageSkia* value_image = rb.GetImageSkiaNamed(IDR_PROGRESS_VALUE);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_tile_width = static_cast<int>(value_image->width() * tile_scale);
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tile_scale_x = static_cast<float>(new_tile_width) /
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        value_image->width();
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DrawTiledImage(canvas, *value_image, 0, 0, tile_scale_x, tile_scale,
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_x,
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_y,
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_width,
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_height);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int dest_left_border_width = static_cast<int>(left_border_image->width() *
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tile_scale);
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawImageInt(canvas, *left_border_image, 0, 0, left_border_image->width(),
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      left_border_image->height(), rect.x(), rect.y(), dest_left_border_width,
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rect.height());
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int dest_right_border_width = static_cast<int>(right_border_image->width() *
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tile_scale);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int dest_x = rect.right() - dest_right_border_width;
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawImageInt(canvas, *right_border_image, 0, 0, right_border_image->width(),
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               right_border_image->height(), dest_x, rect.y(),
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               dest_right_border_width, rect.height());
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeThemeBase::IntersectsClipRectInt(SkCanvas* canvas,
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            int x, int y, int w, int h) const {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect clip;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return canvas->getClipBounds(&clip) &&
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w),
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     SkIntToScalar(y + h));
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawImageInt(
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* sk_canvas, const gfx::ImageSkia& image,
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int src_x, int src_y, int src_w, int src_h,
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int dest_x, int dest_y, int dest_w, int dest_h) const {
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pkotwicz): Do something better and don't infer device
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scale factor from canvas scale.
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkMatrix m = sk_canvas->getTotalMatrix();
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale(
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkScalarAbs(m.getScaleX()));
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sk_canvas, device_scale_factor));
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->DrawImageInt(image, src_x, src_y, src_w, src_h,
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dest_x, dest_y, dest_w, dest_h, true);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawTiledImage(SkCanvas* sk_canvas,
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::ImageSkia& image,
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int src_x, int src_y, float tile_scale_x, float tile_scale_y,
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int dest_x, int dest_y, int w, int h) const {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pkotwicz): Do something better and don't infer device
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scale factor from canvas scale.
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkMatrix m = sk_canvas->getTotalMatrix();
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale(
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkScalarAbs(m.getScaleX()));
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sk_canvas, device_scale_factor));
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->TileImageInt(image, src_x, src_y, tile_scale_x,
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tile_scale_y, dest_x, dest_y, w, h);
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor NativeThemeBase::SaturateAndBrighten(SkScalar* hsv,
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             SkScalar saturate_amount,
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             SkScalar brighten_amount) const {
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar color[3];
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color[0] = hsv[0];
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color[1] = Clamp(hsv[1] + saturate_amount, 0.0, 1.0);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color[2] = Clamp(hsv[2] + brighten_amount, 0.0, 1.0);
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SkHSVToColor(color);
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawVertLine(SkCanvas* canvas,
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int x,
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int y1,
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int y2,
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const SkPaint& paint) const {
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(x, y1, x + 1, y2 + 1);
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawHorizLine(SkCanvas* canvas,
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int x1,
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int x2,
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int y,
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const SkPaint& paint) const {
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(x1, y, x2 + 1, y + 1);
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawBox(SkCanvas* canvas,
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const gfx::Rect& rect,
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const SkPaint& paint) const {
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int right = rect.x() + rect.width() - 1;
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int bottom = rect.y() + rect.height() - 1;
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawHorizLine(canvas, rect.x(), right, rect.y(), paint);
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawVertLine(canvas, right, rect.y(), bottom, paint);
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawHorizLine(canvas, rect.x(), right, bottom, paint);
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawVertLine(canvas, rect.x(), rect.y(), bottom, paint);
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkScalar NativeThemeBase::Clamp(SkScalar value,
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SkScalar min,
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SkScalar max) const {
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::min(std::max(value, min), max);
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor NativeThemeBase::OutlineColor(SkScalar* hsv1, SkScalar* hsv2) const {
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GTK Theme engines have way too much control over the layout of
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the scrollbar. We might be able to more closely approximate its
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // look-and-feel, if we sent whole images instead of just colors
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the browser to the renderer. But even then, some themes
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // would just break.
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // So, instead, we don't even try to 100% replicate the look of
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the native scrollbar. We render our own version, but we make
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sure to pick colors that blend in nicely with the system GTK
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // theme. In most cases, we can just sample a couple of pixels
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the system scrollbar and use those colors to draw our
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scrollbar.
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This works fine for the track color and the overall thumb
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // color. But it fails spectacularly for the outline color used
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // around the thumb piece.  Not all themes have a clearly defined
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // outline. For some of them it is partially transparent, and for
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // others the thickness is very unpredictable.
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // So, instead of trying to approximate the system theme, we
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead try to compute a reasonable looking choice based on the
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // known color of the track and the thumb piece. This is difficult
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when trying to deal both with high- and low-contrast themes,
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and both with positive and inverted themes.
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following code has been tested to look OK with all of the
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default GTK themes.
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar min_diff = Clamp((hsv1[1] + hsv2[1]) * 1.2f, 0.28f, 0.5f);
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar diff = Clamp(fabs(hsv1[2] - hsv2[2]) / 2, min_diff, 0.5f);
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (hsv1[2] + hsv2[2] > 1.0)
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    diff = -diff;
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SaturateAndBrighten(hsv2, -0.2f, diff);
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
1076