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 "third_party/skia/include/effects/SkGradientShader.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ui_base_switches.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/color_utils.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h"
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/native_theme/common_theme.h"
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/resources/grit/ui_resources.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These are the default dimensions of radio buttons and checkboxes.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCheckboxAndRadioWidth = 13;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCheckboxAndRadioHeight = 13;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These sizes match the sizes in Chromium Win.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSliderThumbWidth = 11;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSliderThumbHeight = 21;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderTrackBackgroundColor =
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xe3, 0xdd, 0xd8);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderThumbLightGrey = SkColorSetRGB(0xf4, 0xf2, 0xef);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderThumbDarkGrey = SkColorSetRGB(0xea, 0xe5, 0xe0);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderThumbBorderDarkGrey =
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0x9d, 0x96, 0x8e);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const SkColor kTextBorderColor = SkColorSetRGB(0xa9, 0xa9, 0xa9);
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kMenuPopupBackgroundColor = SkColorSetRGB(210, 225, 246);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned int kDefaultScrollbarWidth = 15;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned int kDefaultScrollbarButtonLength = 14;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxTinyColor = SK_ColorGRAY;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxShadowColor = SkColorSetARGB(0x15, 0, 0, 0);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxShadowHoveredColor = SkColorSetARGB(0x1F, 0, 0, 0);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxShadowDisabledColor = SkColorSetARGB(0, 0, 0, 0);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientColors[] = {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xed, 0xed, 0xed),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xde, 0xde, 0xde) };
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientPressedColors[] = {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xe7, 0xe7, 0xe7),
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xd7, 0xd7, 0xd7) };
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientHoveredColors[] = {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xf0, 0xf0, 0xf0),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xe0, 0xe0, 0xe0) };
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientDisabledColors[] = {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetARGB(0x80, 0xed, 0xed, 0xed),
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetARGB(0x80, 0xde, 0xde, 0xde) };
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxBorderColor = SkColorSetARGB(0x40, 0, 0, 0);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxBorderHoveredColor = SkColorSetARGB(0x4D, 0, 0, 0);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxBorderDisabledColor = SkColorSetARGB(0x20, 0, 0, 0);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxStrokeColor = SkColorSetARGB(0xB3, 0, 0, 0);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxStrokeDisabledColor = SkColorSetARGB(0x59, 0, 0, 0);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kRadioDotColor = SkColorSetRGB(0x66, 0x66, 0x66);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kRadioDotDisabledColor = SkColorSetARGB(0x80, 0x66, 0x66, 0x66);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get lightness adjusted color.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor BrightenColor(const color_utils::HSL& hsl, SkAlpha alpha,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double lightness_amount) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::HSL adjusted = hsl;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  adjusted.l += lightness_amount;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (adjusted.l > 1.0)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adjusted.l = 1.0;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (adjusted.l < 0.0)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adjusted.l = 0.0;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return color_utils::HSLToSkColor(adjusted, alpha);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size NativeThemeBase::GetPartSize(Part part,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       State state,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const ExtraParams& extra) const {
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gfx::Size size = CommonThemeGetPartSize(part, state, extra);
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!size.IsEmpty())
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return size;
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (part) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Please keep these in the order of NativeTheme::Part.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCheckbox:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kInnerSpinButton:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, 0);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuList:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheck:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheckBackground:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupArrow:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupBackground:
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupGutter:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupSeparator:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuItemBackground:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kProgressBar:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kPushButton:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kRadio:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, scrollbar_button_length_);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_button_length_, scrollbar_width_);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalThumb:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This matches Firefox on Linux.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(2 * scrollbar_width_, scrollbar_width_);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalThumb:
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This matches Firefox on Linux.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, 2 * scrollbar_width_);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalTrack:
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(0, scrollbar_width_);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalTrack:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, 0);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalGripper:
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalGripper:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderTrack:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderThumb:
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // These sizes match the sizes in Chromium Win.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(kSliderThumbWidth, kSliderThumbHeight);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTabPanelBackground:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTextField:
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarThumb:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarTrack:
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kWindowResizeGripper:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unknown theme part: " << part;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void NativeThemeBase::PaintStateTransition(SkCanvas* canvas,
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           Part part,
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           State startState,
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           State endState,
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           double progress,
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           const gfx::Rect& rect) const {
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (rect.IsEmpty())
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Currently state transition is animation only working for overlay scrollbars
174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // on Aura platforms.
175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  switch (part) {
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case kScrollbarHorizontalThumb:
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case kScrollbarVerticalThumb:
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      PaintScrollbarThumbStateTransition(
179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          canvas, startState, endState, progress, rect);
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      break;
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    default:
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      NOTREACHED() << "Does not support state transition for this part:"
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   << part;
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      break;
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return;
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::Paint(SkCanvas* canvas,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            Part part,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            State state,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const gfx::Rect& rect,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const ExtraParams& extra) const {
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rect.IsEmpty())
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (part) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Please keep these in the order of NativeTheme::Part.
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case kComboboxArrow:
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      CommonThemePaintComboboxArrow(canvas, rect);
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      break;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCheckbox:
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintCheckbox(canvas, state, rect, extra.button);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kInnerSpinButton:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintInnerSpinButton(canvas, state, rect, extra.inner_spin);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuList:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintMenuList(canvas, state, rect, extra.menu_list);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheck:
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheckBackground:
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupArrow:
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupBackground:
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PaintMenuPopupBackground(canvas, rect.size(), extra.menu_background);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupGutter:
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupSeparator:
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuItemBackground:
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintMenuItemBackground(canvas, state, rect, extra.menu_list);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kProgressBar:
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintProgressBar(canvas, state, rect, extra.progress_bar);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kPushButton:
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintButton(canvas, state, rect, extra.button);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kRadio:
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintRadio(canvas, state, rect, extra.button);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (scrollbar_button_length_ > 0)
2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        PaintArrowButton(canvas, rect, part, state);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalThumb:
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalThumb:
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintScrollbarThumb(canvas, part, state, rect);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalTrack:
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalTrack:
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintScrollbarTrack(canvas, part, state, extra.scrollbar_track, rect);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalGripper:
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalGripper:
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Invoked by views scrollbar code, don't care about for non-win
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // implementations, so no NOTIMPLEMENTED.
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case kScrollbarCorner:
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PaintScrollbarCorner(canvas, state, rect);
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderTrack:
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintSliderTrack(canvas, state, rect, extra.slider);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderThumb:
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintSliderThumb(canvas, state, rect, extra.slider);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTabPanelBackground:
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTextField:
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintTextField(canvas, state, rect, extra.text_field);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarThumb:
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarTrack:
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kWindowResizeGripper:
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unknown theme part: " << part;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeThemeBase::NativeThemeBase()
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : scrollbar_width_(kDefaultScrollbarWidth),
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scrollbar_button_length_(kDefaultScrollbarButtonLength) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeThemeBase::~NativeThemeBase() {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintArrowButton(
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect, Part direction, State state) const {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calculate button color.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar trackHSV[3];
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(track_color_, trackHSV);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor buttonColor = SaturateAndBrighten(trackHSV, 0, 0.2f);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor backgroundColor = buttonColor;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state == kPressed) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar buttonHSV[3];
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorToHSV(buttonColor, buttonHSV);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buttonColor = SaturateAndBrighten(buttonHSV, 0, -0.1f);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (state == kHovered) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar buttonHSV[3];
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorToHSV(buttonColor, buttonHSV);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buttonColor = SaturateAndBrighten(buttonHSV, 0, 0.05f);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y()
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      + rect.height());
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Paint the background (the area visible behind the rounded corners).
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(backgroundColor);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Paint the button's outline and fill the middle
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath outline;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (direction) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() + 0.5, rect.y() + rect.height() + 0.5);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, -(rect.height() - 2));
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, -2);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 5, 0);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 2);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() + 0.5, rect.y() - 0.5);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 2);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 5, 0);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, -2);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, -(rect.height() - 2));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() - 0.5, rect.y() + 0.5);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 2, 0);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 5);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-2, 2);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-(rect.width() - 2), 0);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() + rect.width() + 0.5, rect.y() + 0.5);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-(rect.width() - 2), 0);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-2, 2);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 5);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 2, 0);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  outline.close();
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(buttonColor);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(outline, paint);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kStroke_Style);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar thumbHSV[3];
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(thumb_inactive_color_, thumbHSV);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(OutlineColor(trackHSV, thumbHSV));
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(outline, paint);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PaintArrow(canvas, rect, direction, GetArrowColor(state));
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NativeThemeBase::PaintArrow(SkCanvas* gc,
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 const gfx::Rect& rect,
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 Part direction,
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 SkColor color) const {
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int width_middle, length_middle;
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (direction == kScrollbarUpArrow || direction == kScrollbarDownArrow) {
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    width_middle = rect.width() / 2 + 1;
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    length_middle = rect.height() / 2 + 1;
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    length_middle = rect.width() / 2 + 1;
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    width_middle = rect.height() / 2 + 1;
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SkPaint paint;
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  paint.setColor(color);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(false);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath path;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The constants in this block of code are hand-tailored to produce good
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // looking arrows without anti-aliasing.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (direction) {
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      path.moveTo(rect.x() + width_middle - 4, rect.y() + length_middle + 2);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(7, 0);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(-4, -4);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      path.moveTo(rect.x() + width_middle - 4, rect.y() + length_middle - 3);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(7, 0);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(-4, 4);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      path.moveTo(rect.x() + length_middle - 3, rect.y() + width_middle - 4);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(0, 7);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(4, -4);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      path.moveTo(rect.x() + length_middle + 1, rect.y() + width_middle - 5);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(0, 9);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(-4, -4);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.close();
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gc->drawPath(path, paint);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintScrollbarTrack(SkCanvas* canvas,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Part part,
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ScrollbarTrackExtraParams& extra_params,
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect) const {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(rect.x(), rect.y(), rect.right(), rect.bottom());
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar track_hsv[3];
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(track_color_, track_hsv);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SaturateAndBrighten(track_hsv, 0, 0));
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar thumb_hsv[3];
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(thumb_inactive_color_, thumb_hsv);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(OutlineColor(track_hsv, thumb_hsv));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawBox(canvas, rect, paint);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintScrollbarThumb(SkCanvas* canvas,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           Part part,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           State state,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const gfx::Rect& rect) const {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool hovered = state == kHovered;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int midx = rect.x() + rect.width() / 2;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int midy = rect.y() + rect.height() / 2;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool vertical = part == kScrollbarVerticalThumb;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar thumb[3];
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(hovered ? thumb_active_color_ : thumb_inactive_color_, thumb);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SaturateAndBrighten(thumb, 0, 0.02f));
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (vertical)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), midx + 1, rect.y() + rect.height());
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), midy + 1);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SaturateAndBrighten(thumb, 0, -0.02f));
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (vertical) {
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rect.x(), midy + 1, rect.x() + rect.width(), rect.y() + rect.height());
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar track[3];
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(track_color_, track);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(OutlineColor(track, thumb));
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawBox(canvas, rect, paint);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rect.height() > 10 && rect.width() > 10) {
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int grippy_half_width = 2;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int inter_grippy_offset = 3;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (vertical) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawHorizLine(canvas,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx - grippy_half_width,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx + grippy_half_width,
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midy - inter_grippy_offset,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    paint);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawHorizLine(canvas,
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx - grippy_half_width,
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx + grippy_half_width,
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midy,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    paint);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawHorizLine(canvas,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx - grippy_half_width,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx + grippy_half_width,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midy + inter_grippy_offset,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    paint);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawVertLine(canvas,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midx - inter_grippy_offset,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy - grippy_half_width,
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy + grippy_half_width,
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   paint);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawVertLine(canvas,
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midx,
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy - grippy_half_width,
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy + grippy_half_width,
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   paint);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawVertLine(canvas,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midx + inter_grippy_offset,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy - grippy_half_width,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy + grippy_half_width,
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   paint);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void NativeThemeBase::PaintScrollbarCorner(SkCanvas* canvas,
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           State state,
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           const gfx::Rect& rect) const {
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintCheckbox(SkCanvas* canvas,
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    State state,
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const gfx::Rect& rect,
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const ButtonExtraParams& button) const {
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect skrect = PaintCheckboxRadioCommon(canvas, state, rect,
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           SkIntToScalar(2));
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!skrect.isEmpty()) {
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Draw the checkmark / dash.
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkPaint paint;
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setAntiAlias(true);
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (state == kDisabled)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setColor(kCheckboxStrokeDisabledColor);
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setColor(kCheckboxStrokeColor);
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (button.indeterminate) {
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkPath dash;
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dash.moveTo(skrect.x() + skrect.width() * 0.16,
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  (skrect.y() + skrect.bottom()) / 2);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dash.rLineTo(skrect.width() * 0.68, 0);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setStrokeWidth(SkFloatToScalar(skrect.height() * 0.2));
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas->drawPath(dash, paint);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (button.checked) {
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkPath check;
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      check.moveTo(skrect.x() + skrect.width() * 0.2,
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   skrect.y() + skrect.height() * 0.5);
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      check.rLineTo(skrect.width() * 0.2, skrect.height() * 0.2);
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setStrokeWidth(SkFloatToScalar(skrect.height() * 0.23));
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      check.lineTo(skrect.right() - skrect.width() * 0.2,
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   skrect.y() + skrect.height() * 0.2);
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas->drawPath(check, paint);
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Draws the common elements of checkboxes and radio buttons.
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the rectangle within which any additional decorations should be
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// drawn, or empty if none.
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SkRect NativeThemeBase::PaintCheckboxRadioCommon(
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkScalar borderRadius) const {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect skrect = gfx::RectToSkRect(rect);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the largest square that fits inside the provided rectangle.
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No other browser seems to support non-square widget, so accidentally
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // having non-square sizes is common (eg. amazon and webkit dev tools).
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (skrect.width() != skrect.height()) {
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar size = SkMinScalar(skrect.width(), skrect.height());
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.inset((skrect.width() - size) / 2, (skrect.height() - size) / 2);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the rectangle is too small then paint only a rectangle.  We don't want
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to have to worry about '- 1' and '+ 1' calculations below having overflow
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or underflow.
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (skrect.width() <= 2) {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxTinyColor);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRect(skrect, paint);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Too small to draw anything more.
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SkRect::MakeEmpty();
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make room for the drop shadow.
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.iset(skrect.x(), skrect.y(), skrect.right() - 1, skrect.bottom() - 1);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw the drop shadow below the widget.
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state != kPressed) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setAntiAlias(true);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkRect shadowRect = skrect;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shadowRect.offset(0, 1);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == kDisabled)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     paint.setColor(kCheckboxShadowDisabledColor);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (state == kHovered)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kCheckboxShadowHoveredColor);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kCheckboxShadowColor);
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRoundRect(shadowRect, borderRadius, borderRadius, paint);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw the gradient-filled rectangle
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPoint gradient_bounds[3];
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[0].set(skrect.x(), skrect.y());
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[1].set(skrect.x(), skrect.y() + skrect.height() * 0.38);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[2].set(skrect.x(), skrect.bottom());
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkColor* startEndColors;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state == kPressed)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientPressedColors;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (state == kHovered)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientHoveredColors;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (state == kDisabled)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientDisabledColors;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else /* kNormal */
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientColors;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor colors[3] = {startEndColors[0], startEndColors[0], startEndColors[1]};
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<SkShader> shader = skia::AdoptRef(
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkGradientShader::CreateLinear(
627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          gradient_bounds, colors, NULL, 3, SkShader::kClamp_TileMode));
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint.setShader(shader.get());
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRoundRect(skrect, borderRadius, borderRadius, paint);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setShader(NULL);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw the border.
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state == kHovered)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxBorderHoveredColor);
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (state == kDisabled)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxBorderDisabledColor);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxBorderColor);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kStroke_Style);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStrokeWidth(SkIntToScalar(1));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.inset(SkFloatToScalar(.5f), SkFloatToScalar(.5f));
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRoundRect(skrect, borderRadius, borderRadius, paint);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the rectangle excluding the drop shadow for drawing any additional
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // decorations.
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return skrect;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintRadio(SkCanvas* canvas,
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  State state,
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const gfx::Rect& rect,
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const ButtonExtraParams& button) const {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Most of a radio button is the same as a checkbox, except the the rounded
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // square is a circle (i.e. border radius >= 100%).
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkScalar radius = SkFloatToScalar(
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<float>(std::max(rect.width(), rect.height())) / 2);
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect skrect = PaintCheckboxRadioCommon(canvas, state, rect, radius);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!skrect.isEmpty() && button.checked) {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Draw the dot.
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setAntiAlias(true);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == kDisabled)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kRadioDotDisabledColor);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kRadioDotColor);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.inset(skrect.width() * 0.25, skrect.height() * 0.25);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use drawRoundedRect instead of drawOval to be completely consistent
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // with the border in PaintCheckboxRadioNewCommon.
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRoundRect(skrect, radius, radius, paint);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintButton(SkCanvas* canvas,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  State state,
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const gfx::Rect& rect,
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const ButtonExtraParams& button) const {
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRight = rect.right();
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kBottom = rect.bottom();
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect skrect = SkRect::MakeLTRB(rect.x(), rect.y(), kRight, kBottom);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor base_color = button.background_color;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::HSL base_hsl;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::SkColorToHSL(base_color, &base_hsl);
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our standard gradient is from 0xdd to 0xf8. This is the amount of
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // increased luminance between those values.
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor light_color(BrightenColor(base_hsl, SkColorGetA(base_color), 0.105));
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the button is too small, fallback to drawing a single, solid color
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rect.width() < 5 || rect.height() < 5) {
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(base_color);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRect(skrect, paint);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SK_ColorBLACK);
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kLightEnd = state == kPressed ? 1 : 0;
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kDarkEnd = !kLightEnd;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPoint gradient_bounds[2];
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[kLightEnd].iset(rect.x(), rect.y());
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[kDarkEnd].iset(rect.x(), kBottom - 1);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor colors[2];
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  colors[0] = light_color;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  colors[1] = base_color;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<SkShader> shader = skia::AdoptRef(
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkGradientShader::CreateLinear(
714cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          gradient_bounds, colors, NULL, 2, SkShader::kClamp_TileMode));
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint.setShader(shader.get());
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRoundRect(skrect, SkIntToScalar(1), SkIntToScalar(1), paint);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setShader(NULL);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (button.has_border) {
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int border_alpha = state == kHovered ? 0x80 : 0x55;
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (button.is_focused) {
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      border_alpha = 0xff;
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(GetSystemColor(kColorId_FocusedBorderColor));
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStrokeWidth(SkIntToScalar(1));
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setAlpha(border_alpha);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.inset(SkFloatToScalar(.5f), SkFloatToScalar(.5f));
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRoundRect(skrect, SkIntToScalar(1), SkIntToScalar(1), paint);
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintTextField(SkCanvas* canvas,
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     State state,
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const gfx::Rect& rect,
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const TextFieldExtraParams& text) const {
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect bounds;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds.set(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint fill_paint;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fill_paint.setStyle(SkPaint::kFill_Style);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fill_paint.setColor(text.background_color);
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRect(bounds, fill_paint);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Text INPUT, listbox SELECT, and TEXTAREA have consistent borders.
7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // border: 1px solid #a9a9a9
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SkPaint stroke_paint;
7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stroke_paint.setStyle(SkPaint::kStroke_Style);
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stroke_paint.setColor(kTextBorderColor);
7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  canvas->drawRect(bounds, stroke_paint);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintMenuList(
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MenuListExtraParams& menu_list) const {
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If a border radius is specified, we let the WebCore paint the background
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and the border of the control.
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!menu_list.has_border_radius) {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ButtonExtraParams button = { 0 };
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    button.background_color = menu_list.background_color;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    button.has_border = menu_list.has_border;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PaintButton(canvas, state, rect, button);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SK_ColorBLACK);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath path;
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.moveTo(menu_list.arrow_x, menu_list.arrow_y - 3);
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.rLineTo(6, 0);
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.rLineTo(-3, 6);
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.close();
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(path, paint);
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NativeThemeBase::PaintMenuPopupBackground(
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkCanvas* canvas,
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Size& size,
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MenuBackgroundExtraParams& menu_background) const {
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawColor(kMenuPopupBackgroundColor, SkXfermode::kSrc_Mode);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintMenuItemBackground(
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MenuListExtraParams& menu_list) const {
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By default don't draw anything over the normal background.
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintSliderTrack(SkCanvas* canvas,
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       State state,
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const gfx::Rect& rect,
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const SliderExtraParams& slider) const {
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidX = rect.x() + rect.width() / 2;
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidY = rect.y() + rect.height() / 2;
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(kSliderTrackBackgroundColor);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect skrect;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (slider.vertical) {
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(std::max(rect.x(), kMidX - 2),
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               rect.y(),
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::min(rect.right(), kMidX + 2),
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               rect.bottom());
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(),
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::max(rect.y(), kMidY - 2),
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               rect.right(),
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::min(rect.bottom(), kMidY + 2));
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRect(skrect, paint);
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintSliderThumb(SkCanvas* canvas,
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       State state,
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const gfx::Rect& rect,
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const SliderExtraParams& slider) const {
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool hovered = (state == kHovered) || slider.in_drag;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidX = rect.x() + rect.width() / 2;
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidY = rect.y() + rect.height() / 2;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(hovered ? SK_ColorWHITE : kSliderThumbLightGrey);
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (slider.vertical)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), kMidX + 1, rect.bottom());
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), rect.right(), kMidY + 1);
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(hovered ? kSliderThumbLightGrey : kSliderThumbDarkGrey);
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (slider.vertical)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(kMidX + 1, rect.y(), rect.right(), rect.bottom());
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), kMidY + 1, rect.right(), rect.bottom());
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(kSliderThumbBorderDarkGrey);
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawBox(canvas, rect, paint);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rect.height() > 10 && rect.width() > 10) {
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY, paint);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY - 3, paint);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY + 3, paint);
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintInnerSpinButton(SkCanvas* canvas,
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const InnerSpinButtonExtraParams& spin_button) const {
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (spin_button.read_only)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state = kDisabled;
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State north_state = state;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State south_state = state;
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (spin_button.spin_up)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    south_state = south_state != kDisabled ? kNormal : kDisabled;
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    north_state = north_state != kDisabled ? kNormal : kDisabled;
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect half = rect;
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  half.set_height(rect.height() / 2);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PaintArrowButton(canvas, half, kScrollbarUpArrow, north_state);
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  half.set_y(rect.y() + rect.height() / 2);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PaintArrowButton(canvas, half, kScrollbarDownArrow, south_state);
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintProgressBar(SkCanvas* canvas,
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProgressBarExtraParams& progress_bar) const {
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia* bar_image = rb.GetImageSkiaNamed(IDR_PROGRESS_BAR);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia* left_border_image = rb.GetImageSkiaNamed(
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDR_PROGRESS_BORDER_LEFT);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia* right_border_image = rb.GetImageSkiaNamed(
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDR_PROGRESS_BORDER_RIGHT);
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
894ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK(bar_image->width() > 0);
895ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK(rect.width() > 0);
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
897ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  float tile_scale_y = static_cast<float>(rect.height()) / bar_image->height();
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
899ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int dest_left_border_width = left_border_image->width();
900ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int dest_right_border_width = right_border_image->width();
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
902ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Since an implicit float -> int conversion will truncate, we want to make
903ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // sure that if a border is desired, it gets at least one pixel.
904ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (dest_left_border_width > 0) {
905ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dest_left_border_width = dest_left_border_width * tile_scale_y;
906ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dest_left_border_width = std::max(dest_left_border_width, 1);
907ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
908ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (dest_right_border_width > 0) {
909ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dest_right_border_width = dest_right_border_width * tile_scale_y;
910ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dest_right_border_width = std::max(dest_right_border_width, 1);
911ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
912ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
913ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Since the width of the progress bar may not be evenly divisible by the
914ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // tile size, in order to make it look right we may need to draw some of the
915ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // with a width of 1 pixel smaller than the rest of the tiles.
916ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int new_tile_width = static_cast<int>(bar_image->width() * tile_scale_y);
917ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  new_tile_width = std::max(new_tile_width, 1);
918ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
919ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  float tile_scale_x = static_cast<float>(new_tile_width) / bar_image->width();
920ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (rect.width() % new_tile_width == 0) {
921ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DrawTiledImage(canvas, *bar_image, 0, 0, tile_scale_x, tile_scale_y,
922ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        rect.x(), rect.y(),
923ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        rect.width(), rect.height());
924ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  } else {
925ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    int num_tiles = 1 + rect.width() / new_tile_width;
926ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    int overshoot = num_tiles * new_tile_width - rect.width();
927ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Since |overshoot| represents the number of tiles that were too big, draw
928ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // |overshoot| tiles with their width reduced by 1.
929ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    int num_big_tiles = num_tiles - overshoot;
930ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    int num_small_tiles = overshoot;
931ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    int small_width = new_tile_width - 1;
932ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    float small_scale_x = static_cast<float>(small_width) / bar_image->width();
933ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    float big_scale_x = tile_scale_x;
934ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
935ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Rect big_rect = rect;
936ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Rect small_rect = rect;
937ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    big_rect.Inset(0, 0, num_small_tiles*small_width, 0);
938ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    small_rect.Inset(num_big_tiles*new_tile_width, 0, 0, 0);
939ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
940ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DrawTiledImage(canvas, *bar_image, 0, 0, big_scale_x, tile_scale_y,
941ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      big_rect.x(), big_rect.y(), big_rect.width(), big_rect.height());
942ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DrawTiledImage(canvas, *bar_image, 0, 0, small_scale_x, tile_scale_y,
943ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      small_rect.x(), small_rect.y(), small_rect.width(), small_rect.height());
944ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (progress_bar.value_rect_width) {
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::ImageSkia* value_image = rb.GetImageSkiaNamed(IDR_PROGRESS_VALUE);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
948ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    new_tile_width = static_cast<int>(value_image->width() * tile_scale_y);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tile_scale_x = static_cast<float>(new_tile_width) /
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        value_image->width();
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
952ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DrawTiledImage(canvas, *value_image, 0, 0, tile_scale_x, tile_scale_y,
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_x,
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_y,
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_width,
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_height);
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawImageInt(canvas, *left_border_image, 0, 0, left_border_image->width(),
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      left_border_image->height(), rect.x(), rect.y(), dest_left_border_width,
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rect.height());
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int dest_x = rect.right() - dest_right_border_width;
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawImageInt(canvas, *right_border_image, 0, 0, right_border_image->width(),
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               right_border_image->height(), dest_x, rect.y(),
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               dest_right_border_width, rect.height());
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeThemeBase::IntersectsClipRectInt(SkCanvas* canvas,
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            int x, int y, int w, int h) const {
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect clip;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return canvas->getClipBounds(&clip) &&
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w),
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     SkIntToScalar(y + h));
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawImageInt(
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* sk_canvas, const gfx::ImageSkia& image,
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int src_x, int src_y, int src_w, int src_h,
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int dest_x, int dest_y, int dest_w, int dest_h) const {
981f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<gfx::Canvas> canvas(CommonThemeCreateCanvas(sk_canvas));
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->DrawImageInt(image, src_x, src_y, src_w, src_h,
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dest_x, dest_y, dest_w, dest_h, true);
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawTiledImage(SkCanvas* sk_canvas,
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::ImageSkia& image,
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int src_x, int src_y, float tile_scale_x, float tile_scale_y,
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int dest_x, int dest_y, int w, int h) const {
990f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<gfx::Canvas> canvas(CommonThemeCreateCanvas(sk_canvas));
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->TileImageInt(image, src_x, src_y, tile_scale_x,
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tile_scale_y, dest_x, dest_y, w, h);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor NativeThemeBase::SaturateAndBrighten(SkScalar* hsv,
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             SkScalar saturate_amount,
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             SkScalar brighten_amount) const {
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar color[3];
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color[0] = hsv[0];
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color[1] = Clamp(hsv[1] + saturate_amount, 0.0, 1.0);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color[2] = Clamp(hsv[2] + brighten_amount, 0.0, 1.0);
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SkHSVToColor(color);
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkColor NativeThemeBase::GetArrowColor(State state) const {
10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (state != kDisabled)
10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return SK_ColorBLACK;
10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SkScalar track_hsv[3];
10105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SkColorToHSV(track_color_, track_hsv);
10115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SkScalar thumb_hsv[3];
10125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SkColorToHSV(thumb_inactive_color_, thumb_hsv);
10135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return OutlineColor(track_hsv, thumb_hsv);
10145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
10155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawVertLine(SkCanvas* canvas,
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int x,
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int y1,
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int y2,
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const SkPaint& paint) const {
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(x, y1, x + 1, y2 + 1);
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawHorizLine(SkCanvas* canvas,
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int x1,
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int x2,
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int y,
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const SkPaint& paint) const {
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(x1, y, x2 + 1, y + 1);
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawBox(SkCanvas* canvas,
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const gfx::Rect& rect,
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const SkPaint& paint) const {
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int right = rect.x() + rect.width() - 1;
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int bottom = rect.y() + rect.height() - 1;
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawHorizLine(canvas, rect.x(), right, rect.y(), paint);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawVertLine(canvas, right, rect.y(), bottom, paint);
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawHorizLine(canvas, rect.x(), right, bottom, paint);
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawVertLine(canvas, rect.x(), rect.y(), bottom, paint);
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkScalar NativeThemeBase::Clamp(SkScalar value,
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SkScalar min,
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SkScalar max) const {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::min(std::max(value, min), max);
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor NativeThemeBase::OutlineColor(SkScalar* hsv1, SkScalar* hsv2) const {
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GTK Theme engines have way too much control over the layout of
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the scrollbar. We might be able to more closely approximate its
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // look-and-feel, if we sent whole images instead of just colors
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the browser to the renderer. But even then, some themes
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // would just break.
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // So, instead, we don't even try to 100% replicate the look of
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the native scrollbar. We render our own version, but we make
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sure to pick colors that blend in nicely with the system GTK
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // theme. In most cases, we can just sample a couple of pixels
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the system scrollbar and use those colors to draw our
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scrollbar.
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This works fine for the track color and the overall thumb
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // color. But it fails spectacularly for the outline color used
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // around the thumb piece.  Not all themes have a clearly defined
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // outline. For some of them it is partially transparent, and for
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // others the thickness is very unpredictable.
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // So, instead of trying to approximate the system theme, we
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead try to compute a reasonable looking choice based on the
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // known color of the track and the thumb piece. This is difficult
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when trying to deal both with high- and low-contrast themes,
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and both with positive and inverted themes.
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following code has been tested to look OK with all of the
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default GTK themes.
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar min_diff = Clamp((hsv1[1] + hsv2[1]) * 1.2f, 0.28f, 0.5f);
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar diff = Clamp(fabs(hsv1[2] - hsv2[2]) / 2, min_diff, 0.5f);
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (hsv1[2] + hsv2[2] > 1.0)
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    diff = -diff;
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SaturateAndBrighten(hsv2, -0.2f, diff);
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
1091