summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_main.cc5
-rw-r--r--chrome/browser/chromeos/native_theme_chromeos.cc76
-rw-r--r--chrome/browser/chromeos/native_theme_chromeos.h6
-rw-r--r--chrome/browser/renderer_preferences_util.cc2
-rw-r--r--chrome/chrome.gyp1
-rw-r--r--chrome/chrome_common.gypi2
-rw-r--r--chrome/common/gfx_resource_provider.cc16
-rw-r--r--chrome/common/gfx_resource_provider.h20
-rw-r--r--chrome/renderer/renderer_main.cc5
-rw-r--r--gfx/gfx.gyp8
-rw-r--r--gfx/gfx_module.cc21
-rw-r--r--gfx/gfx_module.h34
-rw-r--r--gfx/gfx_resources.grd22
-rw-r--r--gfx/native_theme_linux.cc570
-rw-r--r--gfx/native_theme_linux.h149
-rw-r--r--gfx/rect.cc8
-rw-r--r--gfx/rect.h4
-rw-r--r--webkit/glue/webthemeengine_impl_linux.cc100
-rw-r--r--webkit/support/platform_support_gtk.cc11
-rw-r--r--webkit/tools/test_shell/test_shell.gypi2
-rw-r--r--webkit/tools/test_shell/test_shell.h4
-rw-r--r--webkit/tools/test_shell/test_shell_gtk.cc4
-rw-r--r--webkit/tools/test_shell/test_shell_mac.mm4
-rw-r--r--webkit/tools/test_shell/test_shell_main.cc6
-rw-r--r--webkit/tools/test_shell/test_shell_win.cc9
25 files changed, 951 insertions, 138 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index c18f2a8d..fea615c 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -76,6 +76,7 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/env_vars.h"
+#include "chrome/common/gfx_resource_provider.h"
#include "chrome/common/hi_res_timer_manager.h"
#include "chrome/common/json_pref_store.h"
#include "chrome/common/jstemplate_builder.h"
@@ -85,6 +86,7 @@
#include "chrome/common/pref_names.h"
#include "chrome/common/result_codes.h"
#include "chrome/installer/util/google_update_settings.h"
+#include "gfx/gfx_module.h"
#include "grit/app_locale_settings.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
@@ -1507,8 +1509,9 @@ int BrowserMain(const MainFunctionParams& parameters) {
#endif
#endif
- // Configure the network module so it has access to resources.
+ // Configure modules that need access to resources.
net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
+ gfx::GfxModule::SetResourceProvider(chrome::GfxResourceProvider);
// Register our global network handler for chrome:// and
// chrome-extension:// URLs.
diff --git a/chrome/browser/chromeos/native_theme_chromeos.cc b/chrome/browser/chromeos/native_theme_chromeos.cc
index c0cd025..c8bc6da 100644
--- a/chrome/browser/chromeos/native_theme_chromeos.cc
+++ b/chrome/browser/chromeos/native_theme_chromeos.cc
@@ -4,8 +4,6 @@
#include "chrome/browser/chromeos/native_theme_chromeos.h"
-#include <limits>
-
#include "app/resource_bundle.h"
#include "base/logging.h"
#include "gfx/insets.h"
@@ -15,67 +13,6 @@
#include "grit/theme_resources.h"
#include "third_party/skia/include/core/SkShader.h"
-namespace {
-
-bool IntersectsClipRectInt(
- skia::PlatformCanvas* canvas, int x, int y, int w, int h) {
- SkRect clip;
- return canvas->getClipBounds(&clip) &&
- clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w),
- SkIntToScalar(y + h));
-}
-
-void DrawBitmapInt(
- skia::PlatformCanvas* canvas, const SkBitmap& bitmap,
- int src_x, int src_y, int src_w, int src_h,
- int dest_x, int dest_y, int dest_w, int dest_h) {
- DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() &&
- src_y + src_h < std::numeric_limits<int16_t>::max());
- if (src_w <= 0 || src_h <= 0 || dest_w <= 0 || dest_h <= 0) {
- NOTREACHED() << "Attempting to draw bitmap to/from an empty rect!";
- return;
- }
-
- if (!IntersectsClipRectInt(canvas, dest_x, dest_y, dest_w, dest_h))
- return;
-
- SkRect dest_rect = { SkIntToScalar(dest_x),
- SkIntToScalar(dest_y),
- SkIntToScalar(dest_x + dest_w),
- SkIntToScalar(dest_y + dest_h) };
-
- if (src_w == dest_w && src_h == dest_h) {
- // Workaround for apparent bug in Skia that causes image to occasionally
- // shift.
- SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h };
- canvas->drawBitmapRect(bitmap, &src_rect, dest_rect);
- return;
- }
-
- // Make a bitmap shader that contains the bitmap we want to draw. This is
- // basically what SkCanvas.drawBitmap does internally, but it gives us
- // more control over quality and will use the mipmap in the source image if
- // it has one, whereas drawBitmap won't.
- SkShader* shader = SkShader::CreateBitmapShader(bitmap,
- SkShader::kRepeat_TileMode,
- SkShader::kRepeat_TileMode);
- SkMatrix shader_scale;
- shader_scale.setScale(SkFloatToScalar(static_cast<float>(dest_w) / src_w),
- SkFloatToScalar(static_cast<float>(dest_h) / src_h));
- shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y));
- shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y));
- shader->setLocalMatrix(shader_scale);
-
- // The rect will be filled by the bitmap.
- SkPaint p;
- p.setFilterBitmap(true);
- p.setShader(shader);
- shader->unref();
- canvas->drawRect(dest_rect, p);
-}
-
-}
-
/* static */
gfx::NativeThemeLinux* gfx::NativeThemeLinux::instance() {
// The global NativeThemeChromeos instance.
@@ -89,7 +26,7 @@ NativeThemeChromeos::NativeThemeChromeos() {
NativeThemeChromeos::~NativeThemeChromeos() {
}
-gfx::Size NativeThemeChromeos::GetSize(Part part) const {
+gfx::Size NativeThemeChromeos::GetPartSize(Part part) const {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
int scrollbar_width = rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND)->width();
int width = 0, height = 0;
@@ -124,11 +61,13 @@ gfx::Size NativeThemeChromeos::GetSize(Part part) const {
width = scrollbar_width;
height = scrollbar_width;
break;
+ default:
+ return NativeThemeLinux::GetPartSize(part);
}
return gfx::Size(width, height);
}
-void NativeThemeChromeos::PaintTrack(skia::PlatformCanvas* canvas,
+void NativeThemeChromeos::PaintScrollbarTrack(skia::PlatformCanvas* canvas,
Part part, State state,
const ScrollbarTrackExtraParams& extra_params, const gfx::Rect& rect) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
@@ -174,11 +113,11 @@ void NativeThemeChromeos::PaintTrack(skia::PlatformCanvas* canvas,
}
}
-void NativeThemeChromeos::PaintThumb(skia::PlatformCanvas* canvas,
+void NativeThemeChromeos::PaintScrollbarThumb(skia::PlatformCanvas* canvas,
Part part, State state, const gfx::Rect& rect) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
int resource_id = IDR_SCROLL_THUMB;
- if (state == kHover)
+ if (state == kHovered)
resource_id++;
else if (state == kPressed)
resource_id += 2;
@@ -225,7 +164,7 @@ void NativeThemeChromeos::PaintArrowButton(skia::PlatformCanvas* canvas,
int resource_id =
(part == kScrollbarUpArrow || part == kScrollbarLeftArrow) ?
IDR_SCROLL_ARROW_UP : IDR_SCROLL_ARROW_DOWN;
- if (state == kHover)
+ if (state == kHovered)
resource_id++;
else if (state == kPressed)
resource_id += 2;
@@ -255,4 +194,3 @@ SkBitmap* NativeThemeChromeos::GetHorizontalBitmapNamed(int resource_id) {
}
return NULL;
}
-
diff --git a/chrome/browser/chromeos/native_theme_chromeos.h b/chrome/browser/chromeos/native_theme_chromeos.h
index d501f682e..fe92c91 100644
--- a/chrome/browser/chromeos/native_theme_chromeos.h
+++ b/chrome/browser/chromeos/native_theme_chromeos.h
@@ -17,14 +17,14 @@ class NativeThemeChromeos : public gfx::NativeThemeLinux {
virtual ~NativeThemeChromeos();
// Scrollbar painting overrides
- virtual gfx::Size GetSize(Part part) const;
- virtual void PaintTrack(skia::PlatformCanvas* canvas,
+ virtual gfx::Size GetPartSize(Part part) const;
+ virtual void PaintScrollbarTrack(skia::PlatformCanvas* canvas,
Part part, State state,
const ScrollbarTrackExtraParams& extra_params,
const gfx::Rect& rect);
virtual void PaintArrowButton(skia::PlatformCanvas* canvas,
const gfx::Rect& rect, Part direction, State state);
- virtual void PaintThumb(skia::PlatformCanvas* canvas,
+ virtual void PaintScrollbarThumb(skia::PlatformCanvas* canvas,
Part part, State state, const gfx::Rect& rect);
SkBitmap* GetHorizontalBitmapNamed(int resource_id);
diff --git a/chrome/browser/renderer_preferences_util.cc b/chrome/browser/renderer_preferences_util.cc
index 2c021c8..e487b93 100644
--- a/chrome/browser/renderer_preferences_util.cc
+++ b/chrome/browser/renderer_preferences_util.cc
@@ -31,7 +31,7 @@ void UpdateFromSystemSettings(RendererPreferences* prefs, Profile* profile) {
prefs->inactive_selection_fg_color =
provider->get_inactive_selection_fg_color();
#else
- prefs->focus_ring_color = SkColorSetARGB(255, 229, 151, 0);
+ prefs->focus_ring_color = SkColorSetRGB(0x50, 0x7A, 0xD5);
prefs->active_selection_bg_color = SkColorSetRGB(0xDC, 0xE4, 0xFA);
prefs->active_selection_fg_color = SK_ColorBLACK;
prefs->inactive_selection_bg_color = SkColorSetRGB(0xF7, 0xF7, 0xF7);
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 9145889..05ff5f4 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1833,6 +1833,7 @@
'<(grit_out_dir)/renderer_resources.pak',
'<(grit_out_dir)/theme_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/app/app_resources/app_resources.pak',
+ '<(SHARED_INTERMEDIATE_DIR)/gfx/gfx_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/net/net_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/webkit/webkit_chromium_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/webkit/webkit_resources.pak',
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index dfec0d6..7d8d62d 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -77,6 +77,8 @@
'common/font_config_ipc_linux.h',
'common/geoposition.cc',
'common/geoposition.h',
+ 'common/gfx_resource_provider.cc',
+ 'common/gfx_resource_provider.h',
'common/gpu_create_command_buffer_config.cc',
'common/gpu_create_command_buffer_config.h',
'common/gpu_feature_flags.cc',
diff --git a/chrome/common/gfx_resource_provider.cc b/chrome/common/gfx_resource_provider.cc
new file mode 100644
index 0000000..f508c28
--- /dev/null
+++ b/chrome/common/gfx_resource_provider.cc
@@ -0,0 +1,16 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/gfx_resource_provider.h"
+
+#include "app/resource_bundle.h"
+#include "base/string_piece.h"
+
+namespace chrome {
+
+base::StringPiece GfxResourceProvider(int key) {
+ return ResourceBundle::GetSharedInstance().GetRawDataResource(key);
+}
+
+} // namespace chrome
diff --git a/chrome/common/gfx_resource_provider.h b/chrome/common/gfx_resource_provider.h
new file mode 100644
index 0000000..41b67b8
--- /dev/null
+++ b/chrome/common/gfx_resource_provider.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_GFX_RESOURCE_PROVIDER_H_
+#define CHROME_COMMON_GFX_RESOURCE_PROVIDER_H_
+#pragma once
+
+namespace base {
+class StringPiece;
+}
+
+namespace chrome {
+
+// This is called indirectly by the gfx theme code to access resources.
+base::StringPiece GfxResourceProvider(int key);
+
+} // namespace chrome
+
+#endif // CHROME_COMMON_GFX_RESOURCE_PROVIDER_H_
diff --git a/chrome/renderer/renderer_main.cc b/chrome/renderer/renderer_main.cc
index 970aa3e..b6cdd6c 100644
--- a/chrome/renderer/renderer_main.cc
+++ b/chrome/renderer/renderer_main.cc
@@ -21,6 +21,7 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_counters.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/gfx_resource_provider.h"
#include "chrome/common/hi_res_timer_manager.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/main_function_params.h"
@@ -29,6 +30,7 @@
#include "chrome/renderer/renderer_main_platform_delegate.h"
#include "chrome/renderer/render_process_impl.h"
#include "chrome/renderer/render_thread.h"
+#include "gfx/gfx_module.h"
#include "grit/generated_resources.h"
#include "net/base/net_module.h"
#include "ui/base/system_monitor/system_monitor.h"
@@ -213,8 +215,9 @@ int RendererMain(const MainFunctionParams& parameters) {
InitCrashReporter();
#endif
- // Configure the network module so it has access to resources.
+ // Configure modules that need access to resources.
net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
+ gfx::GfxModule::SetResourceProvider(chrome::GfxResourceProvider);
// This function allows pausing execution using the --renderer-startup-dialog
// flag allowing us to attach a debugger.
diff --git a/gfx/gfx.gyp b/gfx/gfx.gyp
index 824e9b0..ac512f3 100644
--- a/gfx/gfx.gyp
+++ b/gfx/gfx.gyp
@@ -7,7 +7,7 @@
'chromium_code': 1,
'grit_info_cmd': ['python', '../tools/grit/grit_info.py',
'<@(grit_defines)'],
- 'grit_cmd': ['python', '../tools/grit/grit.py'],
+ 'grit_cmd': ['python', '../tools/grit/grit.py'],
'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/gfx',
},
'targets': [
@@ -110,6 +110,8 @@
'font.cc',
'gfx_paths.cc',
'gfx_paths.h',
+ 'gfx_module.cc',
+ 'gfx_module.h',
'insets.cc',
'insets.h',
'native_widget_types.h',
@@ -158,7 +160,7 @@
'include_dirs': [
'..',
'<(DEPTH)/third_party/wtl/include',
- ],
+ ],
}],
['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
'dependencies': [
@@ -218,7 +220,7 @@
}],
],
},
-
+
],
}
diff --git a/gfx/gfx_module.cc b/gfx/gfx_module.cc
new file mode 100644
index 0000000..882efad
--- /dev/null
+++ b/gfx/gfx_module.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gfx/gfx_module.h"
+
+namespace gfx {
+
+static GfxModule::ResourceProvider resource_provider = NULL;
+
+// static
+void GfxModule::SetResourceProvider(ResourceProvider func) {
+ resource_provider = func;
+}
+
+// static
+base::StringPiece GfxModule::GetResource(int key) {
+ return resource_provider ? resource_provider(key) : base::StringPiece();
+}
+
+} // namespace gfx
diff --git a/gfx/gfx_module.h b/gfx/gfx_module.h
new file mode 100644
index 0000000..91f8963
--- /dev/null
+++ b/gfx/gfx_module.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GFX_MODULE_H_
+#define GFX_MODULE_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/string_piece.h"
+
+namespace gfx {
+
+// Defines global initializers and associated methods for the gfx module.
+// See net/base/net_module.h for more details.
+class GfxModule {
+ public:
+ typedef base::StringPiece (*ResourceProvider)(int key);
+
+ // Set the function to call when the gfx module needs resources
+ static void SetResourceProvider(ResourceProvider func);
+
+ // Call the resource provider (if one exists) to get the specified resource.
+ // Returns an empty string if the resource does not exist or if there is no
+ // resource provider.
+ static base::StringPiece GetResource(int key);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(GfxModule);
+};
+
+} // namespace gfx
+
+#endif // GFX_MODULE_H_
diff --git a/gfx/gfx_resources.grd b/gfx/gfx_resources.grd
index 060545f..357679d 100644
--- a/gfx/gfx_resources.grd
+++ b/gfx/gfx_resources.grd
@@ -11,7 +11,27 @@
</outputs>
<release seq="1">
<includes>
- <include name="IDR_BITMAP_BRUSH_IMAGE" file="bitmap_brush_image.png" type="BINDATA" />
+ <if expr="os.find('win') != -1">
+ <!-- IDR_BITMAP_BRUSH_IMAGE is for canvas_direct2d_unittest on win -->
+ <include name="IDR_BITMAP_BRUSH_IMAGE" file="resources\bitmap_brush_image.png" type="BINDATA" />
+ </if>
+
+ <if expr="os == 'linux2' or os.find('bsd') != -1 or os == 'sunos5'">
+ <include name="IDR_LINUX_CHECKBOX_DISABLED_INDETERMINATE" file="resources\linux-checkbox-disabled-indeterminate.png" type="BINDATA" />
+ <include name="IDR_LINUX_CHECKBOX_DISABLED_OFF" file="resources\linux-checkbox-disabled-off.png" type="BINDATA" />
+ <include name="IDR_LINUX_CHECKBOX_DISABLED_ON" file="resources\linux-checkbox-disabled-on.png" type="BINDATA" />
+ <include name="IDR_LINUX_CHECKBOX_INDETERMINATE" file="resources\linux-checkbox-indeterminate.png" type="BINDATA" />
+ <include name="IDR_LINUX_CHECKBOX_OFF" file="resources\linux-checkbox-off.png" type="BINDATA" />
+ <include name="IDR_LINUX_CHECKBOX_ON" file="resources\linux-checkbox-on.png" type="BINDATA" />
+ <include name="IDR_LINUX_RADIO_DISABLED_OFF" file="resources\linux-radio-disabled-off.png" type="BINDATA" />
+ <include name="IDR_LINUX_RADIO_DISABLED_ON" file="resources\linux-radio-disabled-on.png" type="BINDATA" />
+ <include name="IDR_LINUX_RADIO_OFF" file="resources\linux-radio-off.png" type="BINDATA" />
+ <include name="IDR_LINUX_RADIO_ON" file="resources\linux-radio-on.png" type="BINDATA" />
+ <include name="IDR_PROGRESS_BAR" file="resources\linux-progress-bar.png" type="BINDATA" />
+ <include name="IDR_PROGRESS_BORDER_LEFT" file="resources\linux-progress-border-left.png" type="BINDATA" />
+ <include name="IDR_PROGRESS_BORDER_RIGHT" file="resources\linux-progress-border-right.png" type="BINDATA" />
+ <include name="IDR_PROGRESS_VALUE" file="resources\linux-progress-value.png" type="BINDATA" />
+ </if>
</includes>
</release>
</grit>
diff --git a/gfx/native_theme_linux.cc b/gfx/native_theme_linux.cc
index 4768f19..b2087fe 100644
--- a/gfx/native_theme_linux.cc
+++ b/gfx/native_theme_linux.cc
@@ -4,9 +4,16 @@
#include "gfx/native_theme_linux.h"
+#include <limits>
+
#include "base/logging.h"
+#include "gfx/codec/png_codec.h"
+#include "gfx/color_utils.h"
+#include "gfx/gfx_module.h"
#include "gfx/size.h"
#include "gfx/rect.h"
+#include "grit/gfx_resources.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
namespace gfx {
@@ -16,6 +23,21 @@ unsigned int NativeThemeLinux::thumb_inactive_color_ = 0xeaeaea;
unsigned int NativeThemeLinux::thumb_active_color_ = 0xf4f4f4;
unsigned int NativeThemeLinux::track_color_ = 0xd3d3d3;
+// These are the default dimensions of radio buttons and checkboxes.
+static const int kCheckboxAndRadioWidth = 13;
+static const int kCheckboxAndRadioHeight = 13;
+
+// These sizes match the sizes in Chromium Win.
+static const int kSliderThumbWidth = 11;
+static const int kSliderThumbHeight = 21;
+
+static const SkColor kSliderTrackBackgroundColor =
+ SkColorSetRGB(0xe3, 0xdd, 0xd8);
+static const SkColor kSliderThumbLightGrey = SkColorSetRGB(0xf4, 0xf2, 0xef);
+static const SkColor kSliderThumbDarkGrey = SkColorSetRGB(0xea, 0xe5, 0xe0);
+static const SkColor kSliderThumbBorderDarkGrey =
+ SkColorSetRGB(0x9d, 0x96, 0x8e);
+
#if !defined(OS_CHROMEOS)
// Chromeos has a different look.
// static
@@ -26,13 +48,44 @@ NativeThemeLinux* NativeThemeLinux::instance() {
}
#endif
+// Get lightness adjusted color.
+static SkColor BrightenColor(const color_utils::HSL& hsl, SkAlpha alpha,
+ double lightness_amount) {
+ color_utils::HSL adjusted = hsl;
+ adjusted.l += lightness_amount;
+ if (adjusted.l > 1.0)
+ adjusted.l = 1.0;
+ if (adjusted.l < 0.0)
+ adjusted.l = 0.0;
+
+ return color_utils::HSLToSkColor(adjusted, alpha);
+}
+
+static SkBitmap* GfxGetBitmapNamed(int key) {
+ base::StringPiece data = GfxModule::GetResource(key);
+ if (!data.size()) {
+ NOTREACHED() << "Unable to load image resource " << key;
+ return NULL;
+ }
+
+ SkBitmap bitmap;
+ if (!gfx::PNGCodec::Decode(
+ reinterpret_cast<const unsigned char*>(data.data()),
+ data.size(), &bitmap)) {
+ NOTREACHED() << "Unable to decode image resource " << key;
+ return NULL;
+ }
+
+ return new SkBitmap(bitmap);
+}
+
NativeThemeLinux::NativeThemeLinux() {
}
NativeThemeLinux::~NativeThemeLinux() {
}
-gfx::Size NativeThemeLinux::GetSize(Part part) const {
+gfx::Size NativeThemeLinux::GetPartSize(Part part) const {
switch (part) {
case kScrollbarDownArrow:
case kScrollbarUpArrow:
@@ -51,6 +104,20 @@ gfx::Size NativeThemeLinux::GetSize(Part part) const {
return gfx::Size(0, scrollbar_width_);
case kScrollbarVerticalTrack:
return gfx::Size(scrollbar_width_, 0);
+ case kCheckbox:
+ case kRadio:
+ return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight);
+ case kSliderThumb:
+ // These sizes match the sizes in Chromium Win.
+ return gfx::Size(kSliderThumbWidth, kSliderThumbHeight);
+ case kInnerSpinButton:
+ return gfx::Size(scrollbar_width_, 0);
+ case kPushButton:
+ case kTextField:
+ case kMenuList:
+ case kSliderTrack:
+ case kProgressBar:
+ return gfx::Size(); // No default size.
}
return gfx::Size();
}
@@ -77,7 +144,7 @@ void NativeThemeLinux::PaintArrowButton(
SkScalar buttonHSV[3];
SkColorToHSV(buttonColor, buttonHSV);
buttonColor = SaturateAndBrighten(buttonHSV, 0, -0.1);
- } else if (state == kHover) {
+ } else if (state == kHovered) {
SkScalar buttonHSV[3];
SkColorToHSV(buttonColor, buttonHSV);
buttonColor = SaturateAndBrighten(buttonHSV, 0, 0.05);
@@ -195,20 +262,47 @@ void NativeThemeLinux::Paint(skia::PlatformCanvas* canvas,
break;
case kScrollbarHorizontalThumb:
case kScrollbarVerticalThumb:
- PaintThumb(canvas, part, state, rect);
+ PaintScrollbarThumb(canvas, part, state, rect);
break;
case kScrollbarHorizontalTrack:
case kScrollbarVerticalTrack:
- PaintTrack(canvas, part, state, extra.scrollbar_track, rect);
+ PaintScrollbarTrack(canvas, part, state, extra.scrollbar_track, rect);
+ break;
+ case kCheckbox:
+ PaintCheckbox(canvas, state, rect, extra.button);
+ break;
+ case kRadio:
+ PaintRadio(canvas, state, rect, extra.button);
+ break;
+ case kPushButton:
+ PaintButton(canvas, state, rect, extra.button);
+ break;
+ case kTextField:
+ PaintTextField(canvas, state, rect, extra.text_field);
+ break;
+ case kMenuList:
+ PaintMenuList(canvas, state, rect, extra.menu_list);
+ break;
+ case kSliderTrack:
+ PaintSliderTrack(canvas, state, rect, extra.slider);
+ break;
+ case kSliderThumb:
+ PaintSliderThumb(canvas, state, rect, extra.slider);
+ break;
+ case kInnerSpinButton:
+ PaintInnerSpinButton(canvas, state, rect, extra.inner_spin);
+ break;
+ case kProgressBar:
+ PaintProgressBar(canvas, state, rect, extra.progress_bar);
break;
}
}
-void NativeThemeLinux::PaintTrack(skia::PlatformCanvas* canvas,
- Part part,
- State state,
- const ScrollbarTrackExtraParams& extra_params,
- const gfx::Rect& rect) {
+void NativeThemeLinux::PaintScrollbarTrack(skia::PlatformCanvas* canvas,
+ Part part,
+ State state,
+ const ScrollbarTrackExtraParams& extra_params,
+ const gfx::Rect& rect) {
SkPaint paint;
SkIRect skrect;
@@ -225,11 +319,11 @@ void NativeThemeLinux::PaintTrack(skia::PlatformCanvas* canvas,
DrawBox(canvas, rect, paint);
}
-void NativeThemeLinux::PaintThumb(skia::PlatformCanvas* canvas,
- Part part,
- State state,
- const gfx::Rect& rect) {
- const bool hovered = state == kHover;
+void NativeThemeLinux::PaintScrollbarThumb(skia::PlatformCanvas* canvas,
+ Part part,
+ State state,
+ const gfx::Rect& rect) {
+ const bool hovered = state == kHovered;
const int midx = rect.x() + rect.width() / 2;
const int midy = rect.y() + rect.height() / 2;
const bool vertical = part == kScrollbarVerticalThumb;
@@ -304,6 +398,376 @@ void NativeThemeLinux::PaintThumb(skia::PlatformCanvas* canvas,
}
}
+void NativeThemeLinux::PaintCheckbox(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& button) {
+ static SkBitmap* image_disabled_indeterminate = GfxGetBitmapNamed(
+ IDR_LINUX_CHECKBOX_DISABLED_INDETERMINATE);
+ static SkBitmap* image_indeterminate = GfxGetBitmapNamed(
+ IDR_LINUX_CHECKBOX_INDETERMINATE);
+ static SkBitmap* image_disabled_on = GfxGetBitmapNamed(
+ IDR_LINUX_CHECKBOX_DISABLED_ON);
+ static SkBitmap* image_on = GfxGetBitmapNamed(IDR_LINUX_CHECKBOX_ON);
+ static SkBitmap* image_disabled_off = GfxGetBitmapNamed(
+ IDR_LINUX_CHECKBOX_DISABLED_OFF);
+ static SkBitmap* image_off = GfxGetBitmapNamed(IDR_LINUX_CHECKBOX_OFF);
+
+ SkBitmap* image = NULL;
+ if (button.indeterminate) {
+ image = state == kDisabled ? image_disabled_indeterminate
+ : image_indeterminate;
+ } else if (button.checked) {
+ image = state == kDisabled ? image_disabled_on : image_on;
+ } else {
+ image = state == kDisabled ? image_disabled_off : image_off;
+ }
+
+ gfx::Rect bounds = rect.Center(gfx::Size(image->width(), image->height()));
+ DrawBitmapInt(canvas, *image, 0, 0, image->width(), image->height(),
+ bounds.x(), bounds.y(), bounds.width(), bounds.height());
+}
+
+void NativeThemeLinux::PaintRadio(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& button) {
+ static SkBitmap* image_disabled_on = GfxGetBitmapNamed(
+ IDR_LINUX_RADIO_DISABLED_ON);
+ static SkBitmap* image_on = GfxGetBitmapNamed(IDR_LINUX_RADIO_ON);
+ static SkBitmap* image_disabled_off = GfxGetBitmapNamed(
+ IDR_LINUX_RADIO_DISABLED_OFF);
+ static SkBitmap* image_off = GfxGetBitmapNamed(IDR_LINUX_RADIO_OFF);
+
+ SkBitmap* image = NULL;
+ if (state == kDisabled)
+ image = button.checked ? image_disabled_on : image_disabled_off;
+ else
+ image = button.checked ? image_on : image_off;
+
+ gfx::Rect bounds = rect.Center(gfx::Size(image->width(), image->height()));
+ DrawBitmapInt(canvas, *image, 0, 0, image->width(), image->height(),
+ bounds.x(), bounds.y(), bounds.width(), bounds.height());
+}
+
+void NativeThemeLinux::PaintButton(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& button) {
+ SkPaint paint;
+ SkRect skrect;
+ const int kRight = rect.right();
+ const int kBottom = rect.bottom();
+ SkColor base_color = button.background_color;
+
+ color_utils::HSL base_hsl;
+ color_utils::SkColorToHSL(base_color, &base_hsl);
+
+ // Our standard gradient is from 0xdd to 0xf8. This is the amount of
+ // increased luminance between those values.
+ SkColor light_color(BrightenColor(base_hsl, SkColorGetA(base_color), 0.105));
+
+ // If the button is too small, fallback to drawing a single, solid color
+ if (rect.width() < 5 || rect.height() < 5) {
+ paint.setColor(base_color);
+ skrect.set(rect.x(), rect.y(), kRight, kBottom);
+ canvas->drawRect(skrect, paint);
+ return;
+ }
+
+ const int kBorderAlpha = state == kHovered ? 0x80 : 0x55;
+ paint.setARGB(kBorderAlpha, 0, 0, 0);
+ canvas->drawLine(rect.x() + 1, rect.y(), kRight - 1, rect.y(), paint);
+ canvas->drawLine(kRight - 1, rect.y() + 1, kRight - 1, kBottom - 1, paint);
+ canvas->drawLine(rect.x() + 1, kBottom - 1, kRight - 1, kBottom - 1, paint);
+ canvas->drawLine(rect.x(), rect.y() + 1, rect.x(), kBottom - 1, paint);
+
+ paint.setColor(SK_ColorBLACK);
+ const int kLightEnd = state == kPressed ? 1 : 0;
+ const int kDarkEnd = !kLightEnd;
+ SkPoint gradient_bounds[2];
+ gradient_bounds[kLightEnd].set(SkIntToScalar(rect.x()),
+ SkIntToScalar(rect.y()));
+ gradient_bounds[kDarkEnd].set(SkIntToScalar(rect.x()),
+ SkIntToScalar(kBottom - 1));
+ SkColor colors[2];
+ colors[0] = light_color;
+ colors[1] = base_color;
+
+ SkShader* shader = SkGradientShader::CreateLinear(
+ gradient_bounds, colors, NULL, 2, SkShader::kClamp_TileMode, NULL);
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setShader(shader);
+ shader->unref();
+
+ skrect.set(rect.x() + 1, rect.y() + 1, kRight - 1, kBottom - 1);
+ canvas->drawRect(skrect, paint);
+
+ paint.setShader(NULL);
+ paint.setColor(BrightenColor(base_hsl, SkColorGetA(base_color), -0.0588));
+ canvas->drawPoint(rect.x() + 1, rect.y() + 1, paint);
+ canvas->drawPoint(kRight - 2, rect.y() + 1, paint);
+ canvas->drawPoint(rect.x() + 1, kBottom - 2, paint);
+ canvas->drawPoint(kRight - 2, kBottom - 2, paint);
+}
+
+void NativeThemeLinux::PaintTextField(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const TextFieldExtraParams& text) {
+ // The following drawing code simulates the user-agent css border for
+ // text area and text input so that we do not break layout tests. Once we
+ // have decided the desired looks, we should update the code here and
+ // the layout test expectations.
+ SkRect bounds;
+ bounds.set(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1);
+
+ SkPaint fill_paint;
+ fill_paint.setStyle(SkPaint::kFill_Style);
+ fill_paint.setColor(text.background_color);
+ canvas->drawRect(bounds, fill_paint);
+
+ if (text.is_text_area) {
+ // Draw text area border: 1px solid black
+ SkPaint stroke_paint;
+ fill_paint.setStyle(SkPaint::kStroke_Style);
+ fill_paint.setColor(SK_ColorBLACK);
+ canvas->drawRect(bounds, fill_paint);
+ } else {
+ // Draw text input and listbox inset border
+ // Text Input: 2px inset #eee
+ // Listbox: 1px inset #808080
+ const SkColor kLightColor = text.is_listbox ?
+ SkColorSetRGB(0x80, 0x80, 0x80) : SkColorSetRGB(0xee, 0xee, 0xee);
+ const SkColor kDarkColor = text.is_listbox ?
+ SkColorSetRGB(0x2c, 0x2c, 0x2c) : SkColorSetRGB(0x9a, 0x9a, 0x9a);
+ const int kBorderWidth = text.is_listbox ? 1 : 2;
+
+ SkPaint dark_paint;
+ dark_paint.setAntiAlias(true);
+ dark_paint.setStyle(SkPaint::kFill_Style);
+ dark_paint.setColor(kDarkColor);
+
+ SkPaint light_paint;
+ light_paint.setAntiAlias(true);
+ light_paint.setStyle(SkPaint::kFill_Style);
+ light_paint.setColor(kLightColor);
+
+ int left = rect.x();
+ int top = rect.y();
+ int right = rect.right();
+ int bottom = rect.bottom();
+
+ SkPath path;
+ path.incReserve(4);
+
+ // Top
+ path.moveTo(SkIntToScalar(left), SkIntToScalar(top));
+ path.lineTo(SkIntToScalar(left + kBorderWidth),
+ SkIntToScalar(top + kBorderWidth));
+ path.lineTo(SkIntToScalar(right - kBorderWidth),
+ SkIntToScalar(top + kBorderWidth));
+ path.lineTo(SkIntToScalar(right), SkIntToScalar(top));
+ canvas->drawPath(path, dark_paint);
+
+ // Bottom
+ path.reset();
+ path.moveTo(SkIntToScalar(left + kBorderWidth),
+ SkIntToScalar(bottom - kBorderWidth));
+ path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom));
+ path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom));
+ path.lineTo(SkIntToScalar(right - kBorderWidth),
+ SkIntToScalar(bottom - kBorderWidth));
+ canvas->drawPath(path, light_paint);
+
+ // Left
+ path.reset();
+ path.moveTo(SkIntToScalar(left), SkIntToScalar(top));
+ path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom));
+ path.lineTo(SkIntToScalar(left + kBorderWidth),
+ SkIntToScalar(bottom - kBorderWidth));
+ path.lineTo(SkIntToScalar(left + kBorderWidth),
+ SkIntToScalar(top + kBorderWidth));
+ canvas->drawPath(path, dark_paint);
+
+ // Right
+ path.reset();
+ path.moveTo(SkIntToScalar(right - kBorderWidth),
+ SkIntToScalar(top + kBorderWidth));
+ path.lineTo(SkIntToScalar(right - kBorderWidth), SkIntToScalar(bottom));
+ path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom));
+ path.lineTo(SkIntToScalar(right), SkIntToScalar(top));
+ canvas->drawPath(path, light_paint);
+ }
+}
+
+void NativeThemeLinux::PaintMenuList(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const MenuListExtraParams& menu_list) {
+ ButtonExtraParams button = { 0 };
+ button.background_color = menu_list.background_color;
+ PaintButton(canvas, state, rect, button);
+
+ SkPaint paint;
+ paint.setColor(SK_ColorBLACK);
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kFill_Style);
+
+ SkPath path;
+ path.moveTo(menu_list.arrow_x, menu_list.arrow_y - 3);
+ path.rLineTo(6, 0);
+ path.rLineTo(-3, 6);
+ path.close();
+ canvas->drawPath(path, paint);
+}
+
+void NativeThemeLinux::PaintSliderTrack(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const SliderExtraParams& slider) {
+ const int kMidX = rect.x() + rect.width() / 2;
+ const int kMidY = rect.y() + rect.height() / 2;
+
+ SkPaint paint;
+ paint.setColor(kSliderTrackBackgroundColor);
+
+ SkRect skrect;
+ if (slider.vertical) {
+ skrect.set(std::max(rect.x(), kMidX - 2),
+ rect.y(),
+ std::min(rect.right(), kMidX + 2),
+ rect.bottom());
+ } else {
+ skrect.set(rect.x(),
+ std::max(rect.y(), kMidY - 2),
+ rect.right(),
+ std::min(rect.bottom(), kMidY + 2));
+ }
+ canvas->drawRect(skrect, paint);
+}
+
+void NativeThemeLinux::PaintSliderThumb(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const SliderExtraParams& slider) {
+ const bool hovered = (state == kHovered) || slider.in_drag;
+ const int kMidX = rect.x() + rect.width() / 2;
+ const int kMidY = rect.y() + rect.height() / 2;
+
+ SkPaint paint;
+ paint.setColor(hovered ? SK_ColorWHITE : kSliderThumbLightGrey);
+
+ SkIRect skrect;
+ if (slider.vertical)
+ skrect.set(rect.x(), rect.y(), kMidX + 1, rect.bottom());
+ else
+ skrect.set(rect.x(), rect.y(), rect.right(), kMidY + 1);
+
+ canvas->drawIRect(skrect, paint);
+
+ paint.setColor(hovered ? kSliderThumbLightGrey : kSliderThumbDarkGrey);
+
+ if (slider.vertical)
+ skrect.set(kMidX + 1, rect.y(), rect.right(), rect.bottom());
+ else
+ skrect.set(rect.x(), kMidY + 1, rect.right(), rect.bottom());
+
+ canvas->drawIRect(skrect, paint);
+
+ paint.setColor(kSliderThumbBorderDarkGrey);
+ DrawBox(canvas, rect, paint);
+
+ if (rect.height() > 10 && rect.width() > 10) {
+ DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY, paint);
+ DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY - 3, paint);
+ DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY + 3, paint);
+ }
+}
+
+void NativeThemeLinux::PaintInnerSpinButton(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const InnerSpinButtonExtraParams& spin_button) {
+ if (spin_button.read_only)
+ state = kDisabled;
+
+ State north_state = state;
+ State south_state = state;
+ if (spin_button.spin_up)
+ south_state = south_state != kDisabled ? kNormal : kDisabled;
+ else
+ north_state = north_state != kDisabled ? kNormal : kDisabled;
+
+ gfx::Rect half = rect;
+ half.set_height(rect.height() / 2);
+ PaintArrowButton(canvas, half, kScrollbarUpArrow, north_state);
+
+ half.set_y(rect.y() + rect.height() / 2);
+ PaintArrowButton(canvas, half, kScrollbarDownArrow, south_state);
+}
+
+void NativeThemeLinux::PaintProgressBar(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ProgressBarExtraParams& progress_bar) {
+ static SkBitmap* bar_image = GfxGetBitmapNamed(IDR_PROGRESS_BAR);
+ static SkBitmap* value_image = GfxGetBitmapNamed(IDR_PROGRESS_VALUE);
+ static SkBitmap* left_border_image = GfxGetBitmapNamed(
+ IDR_PROGRESS_BORDER_LEFT);
+ static SkBitmap* right_border_image = GfxGetBitmapNamed(
+ IDR_PROGRESS_BORDER_RIGHT);
+
+ double tile_scale = static_cast<double>(rect.height()) /
+ bar_image->height();
+
+ int new_tile_width = static_cast<int>(bar_image->width() * tile_scale);
+ double tile_scale_x = static_cast<double>(new_tile_width) /
+ bar_image->width();
+
+ DrawTiledImage(canvas, *bar_image, 0, 0, tile_scale_x, tile_scale,
+ rect.x(), rect.y(), rect.width(), rect.height());
+
+ if (progress_bar.value_rect_width) {
+
+ new_tile_width = static_cast<int>(value_image->width() * tile_scale);
+ tile_scale_x = static_cast<double>(new_tile_width) /
+ value_image->width();
+
+ DrawTiledImage(canvas, *value_image, 0, 0, tile_scale_x, tile_scale,
+ progress_bar.value_rect_x,
+ progress_bar.value_rect_y,
+ progress_bar.value_rect_width,
+ progress_bar.value_rect_height);
+ }
+
+ int dest_left_border_width = static_cast<int>(left_border_image->width() *
+ tile_scale);
+ SkRect dest_rect = {
+ SkIntToScalar(rect.x()),
+ SkIntToScalar(rect.y()),
+ SkIntToScalar(rect.x() + dest_left_border_width),
+ SkIntToScalar(rect.bottom())
+ };
+ canvas->drawBitmapRect(*left_border_image, NULL, dest_rect);
+
+ int dest_right_border_width = static_cast<int>(right_border_image->width() *
+ tile_scale);
+ dest_rect.set(SkIntToScalar(rect.right() - dest_right_border_width),
+ SkIntToScalar(rect.y()),
+ SkIntToScalar(rect.right()),
+ SkIntToScalar(rect.bottom()));
+ canvas->drawBitmapRect(*right_border_image, NULL, dest_rect);
+}
+
+bool NativeThemeLinux::IntersectsClipRectInt(
+ skia::PlatformCanvas* canvas, int x, int y, int w, int h) {
+ SkRect clip;
+ return canvas->getClipBounds(&clip) &&
+ clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w),
+ SkIntToScalar(y + h));
+}
+
void NativeThemeLinux::DrawVertLine(SkCanvas* canvas,
int x,
int y1,
@@ -335,6 +799,84 @@ void NativeThemeLinux::DrawBox(SkCanvas* canvas,
DrawVertLine(canvas, rect.x(), rect.y(), bottom, paint);
}
+void NativeThemeLinux::DrawBitmapInt(
+ skia::PlatformCanvas* canvas, const SkBitmap& bitmap,
+ int src_x, int src_y, int src_w, int src_h,
+ int dest_x, int dest_y, int dest_w, int dest_h) {
+ DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() &&
+ src_y + src_h < std::numeric_limits<int16_t>::max());
+ if (src_w <= 0 || src_h <= 0 || dest_w <= 0 || dest_h <= 0) {
+ NOTREACHED() << "Attempting to draw bitmap to/from an empty rect!";
+ return;
+ }
+
+ if (!IntersectsClipRectInt(canvas, dest_x, dest_y, dest_w, dest_h))
+ return;
+
+ SkRect dest_rect = { SkIntToScalar(dest_x),
+ SkIntToScalar(dest_y),
+ SkIntToScalar(dest_x + dest_w),
+ SkIntToScalar(dest_y + dest_h) };
+
+ if (src_w == dest_w && src_h == dest_h) {
+ // Workaround for apparent bug in Skia that causes image to occasionally
+ // shift.
+ SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h };
+ canvas->drawBitmapRect(bitmap, &src_rect, dest_rect);
+ return;
+ }
+
+ // Make a bitmap shader that contains the bitmap we want to draw. This is
+ // basically what SkCanvas.drawBitmap does internally, but it gives us
+ // more control over quality and will use the mipmap in the source image if
+ // it has one, whereas drawBitmap won't.
+ SkShader* shader = SkShader::CreateBitmapShader(bitmap,
+ SkShader::kRepeat_TileMode,
+ SkShader::kRepeat_TileMode);
+ SkMatrix shader_scale;
+ shader_scale.setScale(SkFloatToScalar(static_cast<float>(dest_w) / src_w),
+ SkFloatToScalar(static_cast<float>(dest_h) / src_h));
+ shader_scale.preTranslate(SkIntToScalar(-src_x), SkIntToScalar(-src_y));
+ shader_scale.postTranslate(SkIntToScalar(dest_x), SkIntToScalar(dest_y));
+ shader->setLocalMatrix(shader_scale);
+
+ // The rect will be filled by the bitmap.
+ SkPaint p;
+ p.setFilterBitmap(true);
+ p.setShader(shader);
+ shader->unref();
+ canvas->drawRect(dest_rect, p);
+}
+
+void NativeThemeLinux::DrawTiledImage(SkCanvas* canvas,
+ const SkBitmap& bitmap,
+ int src_x, int src_y, double tile_scale_x, double tile_scale_y,
+ int dest_x, int dest_y, int w, int h) const {
+ SkShader* shader = SkShader::CreateBitmapShader(bitmap,
+ SkShader::kRepeat_TileMode,
+ SkShader::kRepeat_TileMode);
+ if (tile_scale_x != 1.0 || tile_scale_y != 1.0) {
+ SkMatrix shader_scale;
+ shader_scale.setScale(SkDoubleToScalar(tile_scale_x),
+ SkDoubleToScalar(tile_scale_y));
+ shader->setLocalMatrix(shader_scale);
+ }
+
+ SkPaint paint;
+ paint.setShader(shader);
+ paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
+
+ // CreateBitmapShader returns a Shader with a reference count of one, we
+ // need to unref after paint takes ownership of the shader.
+ shader->unref();
+ canvas->save();
+ canvas->translate(SkIntToScalar(dest_x - src_x),
+ SkIntToScalar(dest_y - src_y));
+ canvas->clipRect(SkRect::MakeXYWH(src_x, src_y, w, h));
+ canvas->drawPaint(paint);
+ canvas->restore();
+}
+
SkScalar NativeThemeLinux::Clamp(SkScalar value,
SkScalar min,
SkScalar max) const {
diff --git a/gfx/native_theme_linux.h b/gfx/native_theme_linux.h
index 4a79da3..0837d2a 100644
--- a/gfx/native_theme_linux.h
+++ b/gfx/native_theme_linux.h
@@ -28,13 +28,22 @@ class NativeThemeLinux {
kScrollbarHorizontalThumb,
kScrollbarVerticalThumb,
kScrollbarHorizontalTrack,
- kScrollbarVerticalTrack
+ kScrollbarVerticalTrack,
+ kCheckbox,
+ kRadio,
+ kPushButton,
+ kTextField,
+ kMenuList,
+ kSliderTrack,
+ kSliderThumb,
+ kInnerSpinButton,
+ kProgressBar,
};
// The state of the part.
enum State {
kDisabled,
- kHover,
+ kHovered,
kNormal,
kPressed,
};
@@ -47,15 +56,58 @@ class NativeThemeLinux {
int track_height;
};
+ struct ButtonExtraParams {
+ bool checked;
+ bool indeterminate; // Whether the button state is indeterminate.
+ bool is_default; // Whether the button is default button.
+ SkColor background_color;
+ };
+
+ struct TextFieldExtraParams {
+ bool is_text_area;
+ bool is_listbox;
+ SkColor background_color;
+ };
+
+ struct MenuListExtraParams {
+ int arrow_x;
+ int arrow_y;
+ SkColor background_color;
+ };
+
+ struct SliderExtraParams {
+ bool vertical;
+ bool in_drag;
+ };
+
+ struct InnerSpinButtonExtraParams {
+ bool spin_up;
+ bool read_only;
+ };
+
+ struct ProgressBarExtraParams {
+ bool determinate;
+ int value_rect_x;
+ int value_rect_y;
+ int value_rect_width;
+ int value_rect_height;
+ };
+
union ExtraParams {
ScrollbarTrackExtraParams scrollbar_track;
+ ButtonExtraParams button;
+ MenuListExtraParams menu_list;
+ SliderExtraParams slider;
+ TextFieldExtraParams text_field;
+ InnerSpinButtonExtraParams inner_spin;
+ ProgressBarExtraParams progress_bar;
};
// Gets our singleton instance.
static NativeThemeLinux* instance();
// Return the size of the part.
- virtual gfx::Size GetSize(Part part) const;
+ virtual gfx::Size GetPartSize(Part part) const;
// Paint the part to the canvas.
virtual void Paint(skia::PlatformCanvas* canvas,
Part part,
@@ -71,23 +123,87 @@ class NativeThemeLinux {
NativeThemeLinux();
virtual ~NativeThemeLinux();
- // Draw the arrow.
+ // Draw the arrow. Used by scrollbar and inner spin button.
virtual void PaintArrowButton(
skia::PlatformCanvas* gc,
const gfx::Rect& rect,
Part direction,
State state);
- // Paint the track. Done before the thumb so that it can contain alpha.
- virtual void PaintTrack(skia::PlatformCanvas* canvas,
- Part part,
- State state,
- const ScrollbarTrackExtraParams& extra_params,
- const gfx::Rect& rect);
- // Draw the thumb over the track.
- virtual void PaintThumb(skia::PlatformCanvas* canvas,
- Part part,
- State state,
- const gfx::Rect& rect);
+ // Paint the scrollbar track. Done before the thumb so that it can contain
+ // alpha.
+ virtual void PaintScrollbarTrack(skia::PlatformCanvas* canvas,
+ Part part,
+ State state,
+ const ScrollbarTrackExtraParams& extra_params,
+ const gfx::Rect& rect);
+ // Draw the scrollbar thumb over the track.
+ virtual void PaintScrollbarThumb(skia::PlatformCanvas* canvas,
+ Part part,
+ State state,
+ const gfx::Rect& rect);
+ // Draw the checkbox.
+ virtual void PaintCheckbox(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& button);
+ // Draw the radio.
+ virtual void PaintRadio(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& button);
+ // Draw the push button.
+ virtual void PaintButton(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& button);
+ // Draw the text field.
+ virtual void PaintTextField(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const TextFieldExtraParams& text);
+ // Draw the menu list.
+ virtual void PaintMenuList(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const MenuListExtraParams& menu_list);
+ // Draw the slider track.
+ virtual void PaintSliderTrack(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const SliderExtraParams& slider);
+ // Draw the slider thumb.
+ virtual void PaintSliderThumb(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const SliderExtraParams& slider);
+ // Draw the inner spin button.
+ virtual void PaintInnerSpinButton(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const InnerSpinButtonExtraParams& spin_button);
+ // Draw the progress bar.
+ virtual void PaintProgressBar(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ProgressBarExtraParams& progress_bar);
+
+ protected:
+ bool IntersectsClipRectInt(skia::PlatformCanvas* canvas,
+ int x, int y, int w, int h);
+
+ void DrawBitmapInt(skia::PlatformCanvas* canvas, const SkBitmap& bitmap,
+ int src_x, int src_y, int src_w, int src_h,
+ int dest_x, int dest_y, int dest_w, int dest_h);
+
+ void DrawTiledImage(SkCanvas* canvas,
+ const SkBitmap& bitmap,
+ int src_x, int src_y,
+ double tile_scale_x, double tile_scale_y,
+ int dest_x, int dest_y, int w, int h) const;
+
+ SkColor SaturateAndBrighten(SkScalar* hsv,
+ SkScalar saturate_amount,
+ SkScalar brighten_amount) const;
private:
void DrawVertLine(SkCanvas* canvas,
@@ -106,9 +222,6 @@ class NativeThemeLinux {
SkScalar Clamp(SkScalar value,
SkScalar min,
SkScalar max) const;
- SkColor SaturateAndBrighten(SkScalar* hsv,
- SkScalar saturate_amount,
- SkScalar brighten_amount) const;
SkColor OutlineColor(SkScalar* hsv1, SkScalar* hsv2) const;
static unsigned int scrollbar_width_;
diff --git a/gfx/rect.cc b/gfx/rect.cc
index e9c666c..a1a72cb 100644
--- a/gfx/rect.cc
+++ b/gfx/rect.cc
@@ -234,6 +234,14 @@ Point Rect::CenterPoint() const {
return Point(x() + (width() + 1) / 2, y() + (height() + 1) / 2);
}
+Rect Rect::Center(const gfx::Size& size) const {
+ int new_width = std::min(width(), size.width());
+ int new_height = std::min(height(), size.height());
+ int new_x = x() + (width() - new_width) / 2;
+ int new_y = y() + (height() - new_height) / 2;
+ return Rect(new_x, new_y, new_width, new_height);
+}
+
bool Rect::SharesEdgeWith(const gfx::Rect& rect) const {
return (y() == rect.y() && height() == rect.height() &&
(x() == rect.right() || right() == rect.x())) ||
diff --git a/gfx/rect.h b/gfx/rect.h
index e305b9b..b4c9a0b 100644
--- a/gfx/rect.h
+++ b/gfx/rect.h
@@ -164,6 +164,10 @@ class Rect {
// Returns the center of this rectangle.
Point CenterPoint() const;
+ // Return a rectangle that has the same center point but with a size capped
+ // at given |size|.
+ Rect Center(const gfx::Size& size) const;
+
// Returns true if this rectangle shares an entire edge (i.e., same width or
// same height) with the given rectangle, and the rectangles do not overlap.
bool SharesEdgeWith(const gfx::Rect& rect) const;
diff --git a/webkit/glue/webthemeengine_impl_linux.cc b/webkit/glue/webthemeengine_impl_linux.cc
index 518166e..067b203 100644
--- a/webkit/glue/webthemeengine_impl_linux.cc
+++ b/webkit/glue/webthemeengine_impl_linux.cc
@@ -38,6 +38,24 @@ static gfx::NativeThemeLinux::Part NativeThemePart(
return gfx::NativeThemeLinux::kScrollbarHorizontalTrack;
case WebKit::WebThemeEngine::PartScrollbarVerticalTrack:
return gfx::NativeThemeLinux::kScrollbarVerticalTrack;
+ case WebKit::WebThemeEngine::PartCheckbox:
+ return gfx::NativeThemeLinux::kCheckbox;
+ case WebKit::WebThemeEngine::PartRadio:
+ return gfx::NativeThemeLinux::kRadio;
+ case WebKit::WebThemeEngine::PartButton:
+ return gfx::NativeThemeLinux::kPushButton;
+ case WebKit::WebThemeEngine::PartTextField:
+ return gfx::NativeThemeLinux::kTextField;
+ case WebKit::WebThemeEngine::PartMenuList:
+ return gfx::NativeThemeLinux::kMenuList;
+ case WebKit::WebThemeEngine::PartSliderTrack:
+ return gfx::NativeThemeLinux::kSliderTrack;
+ case WebKit::WebThemeEngine::PartSliderThumb:
+ return gfx::NativeThemeLinux::kSliderThumb;
+ case WebKit::WebThemeEngine::PartInnerSpinButton:
+ return gfx::NativeThemeLinux::kInnerSpinButton;
+ case WebKit::WebThemeEngine::PartProgressBar:
+ return gfx::NativeThemeLinux::kProgressBar;
default:
return gfx::NativeThemeLinux::kScrollbarDownArrow;
}
@@ -49,7 +67,7 @@ static gfx::NativeThemeLinux::State NativeThemeState(
case WebKit::WebThemeEngine::StateDisabled:
return gfx::NativeThemeLinux::kDisabled;
case WebKit::WebThemeEngine::StateHover:
- return gfx::NativeThemeLinux::kHover;
+ return gfx::NativeThemeLinux::kHovered;
case WebKit::WebThemeEngine::StateNormal:
return gfx::NativeThemeLinux::kNormal;
case WebKit::WebThemeEngine::StatePressed:
@@ -64,21 +82,79 @@ static void GetNativeThemeExtraParams(
WebKit::WebThemeEngine::State state,
const WebKit::WebThemeEngine::ExtraParams* extra_params,
gfx::NativeThemeLinux::ExtraParams* native_theme_extra_params) {
- if (part == WebKit::WebThemeEngine::PartScrollbarHorizontalTrack ||
- part == WebKit::WebThemeEngine::PartScrollbarVerticalTrack) {
- native_theme_extra_params->scrollbar_track.track_x =
- extra_params->scrollbarTrack.trackX;
- native_theme_extra_params->scrollbar_track.track_y =
- extra_params->scrollbarTrack.trackY;
- native_theme_extra_params->scrollbar_track.track_width =
- extra_params->scrollbarTrack.trackWidth;
- native_theme_extra_params->scrollbar_track.track_height =
- extra_params->scrollbarTrack.trackHeight;
+ switch (part) {
+ case WebKit::WebThemeEngine::PartScrollbarHorizontalTrack:
+ case WebKit::WebThemeEngine::PartScrollbarVerticalTrack:
+ native_theme_extra_params->scrollbar_track.track_x =
+ extra_params->scrollbarTrack.trackX;
+ native_theme_extra_params->scrollbar_track.track_y =
+ extra_params->scrollbarTrack.trackY;
+ native_theme_extra_params->scrollbar_track.track_width =
+ extra_params->scrollbarTrack.trackWidth;
+ native_theme_extra_params->scrollbar_track.track_height =
+ extra_params->scrollbarTrack.trackHeight;
+ break;
+ case WebKit::WebThemeEngine::PartCheckbox:
+ native_theme_extra_params->button.checked = extra_params->button.checked;
+ native_theme_extra_params->button.indeterminate =
+ extra_params->button.indeterminate;
+ break;
+ case WebKit::WebThemeEngine::PartRadio:
+ native_theme_extra_params->button.checked = extra_params->button.checked;
+ break;
+ case WebKit::WebThemeEngine::PartButton:
+ native_theme_extra_params->button.is_default =
+ extra_params->button.isDefault;
+ native_theme_extra_params->button.background_color =
+ extra_params->button.backgroundColor;
+ break;
+ case WebKit::WebThemeEngine::PartTextField:
+ native_theme_extra_params->text_field.is_text_area =
+ extra_params->textField.isTextArea;
+ native_theme_extra_params->text_field.is_listbox =
+ extra_params->textField.isListbox;
+ native_theme_extra_params->text_field.background_color =
+ extra_params->textField.backgroundColor;
+ break;
+ case WebKit::WebThemeEngine::PartMenuList:
+ native_theme_extra_params->menu_list.arrow_x =
+ extra_params->menuList.arrowX;
+ native_theme_extra_params->menu_list.arrow_y =
+ extra_params->menuList.arrowY;
+ native_theme_extra_params->menu_list.background_color =
+ extra_params->menuList.backgroundColor;
+ break;
+ case WebKit::WebThemeEngine::PartSliderTrack:
+ case WebKit::WebThemeEngine::PartSliderThumb:
+ native_theme_extra_params->slider.vertical =
+ extra_params->slider.vertical;
+ native_theme_extra_params->slider.in_drag = extra_params->slider.inDrag;
+ break;
+ case WebKit::WebThemeEngine::PartInnerSpinButton:
+ native_theme_extra_params->inner_spin.spin_up =
+ extra_params->innerSpin.spinUp;
+ native_theme_extra_params->inner_spin.read_only =
+ extra_params->innerSpin.readOnly;
+ break;
+ case WebKit::WebThemeEngine::PartProgressBar:
+ native_theme_extra_params->progress_bar.determinate =
+ extra_params->progressBar.determinate;
+ native_theme_extra_params->progress_bar.value_rect_x =
+ extra_params->progressBar.valueRectX;
+ native_theme_extra_params->progress_bar.value_rect_y =
+ extra_params->progressBar.valueRectY;
+ native_theme_extra_params->progress_bar.value_rect_width =
+ extra_params->progressBar.valueRectWidth;
+ native_theme_extra_params->progress_bar.value_rect_height =
+ extra_params->progressBar.valueRectHeight;
+ break;
+ default:
+ break; // Parts that have no extra params get here.
}
}
WebKit::WebSize WebThemeEngineImpl::getSize(WebKit::WebThemeEngine::Part part) {
- return gfx::NativeThemeLinux::instance()->GetSize(NativeThemePart(part));
+ return gfx::NativeThemeLinux::instance()->GetPartSize(NativeThemePart(part));
}
void WebThemeEngineImpl::paint(
diff --git a/webkit/support/platform_support_gtk.cc b/webkit/support/platform_support_gtk.cc
index 2ab9627..4defd31 100644
--- a/webkit/support/platform_support_gtk.cc
+++ b/webkit/support/platform_support_gtk.cc
@@ -11,6 +11,7 @@
#include "base/path_service.h"
#include "base/string16.h"
#include "base/string_piece.h"
+#include "gfx/gfx_module.h"
#include "grit/webkit_resources.h"
namespace {
@@ -18,6 +19,13 @@ namespace {
// Data resources on linux. This is a pointer to the mmapped resources file.
app::DataPack* g_resource_data_pack = NULL;
+base::StringPiece TestResourceProvider(int resource_id) {
+ base::StringPiece res;
+ if (g_resource_data_pack)
+ g_resource_data_pack->GetStringPiece(resource_id, &res);
+ return res;
+}
+
}
namespace webkit_support {
@@ -37,6 +45,9 @@ void AfterInitialize(bool unit_test_mode) {
data_path = data_path.Append("DumpRenderTree.pak");
if (!g_resource_data_pack->Load(data_path))
LOG(FATAL) << "failed to load DumpRenderTree.pak";
+
+ // Config the modules that need access to a limited set of resources.
+ gfx::GfxModule::SetResourceProvider(TestResourceProvider);
}
void BeforeShutdown() {
diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi
index e20e687..93fb40e 100644
--- a/webkit/tools/test_shell/test_shell.gypi
+++ b/webkit/tools/test_shell/test_shell.gypi
@@ -176,6 +176,7 @@
'action_name': 'test_shell_repack',
'variables': {
'pak_inputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/gfx/gfx_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/net/net_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/test_shell/test_shell_resources.pak',
'<(SHARED_INTERMEDIATE_DIR)/webkit/webkit_chromium_resources.pak',
@@ -331,6 +332,7 @@
],
}, { # OS != "mac"
'dependencies': [
+ '<(DEPTH)/gfx/gfx.gyp:gfx_resources',
'<(DEPTH)/net/net.gyp:net_resources',
'<(DEPTH)/webkit/support/webkit_support.gyp:webkit_resources',
'<(DEPTH)/webkit/support/webkit_support.gyp:webkit_strings',
diff --git a/webkit/tools/test_shell/test_shell.h b/webkit/tools/test_shell/test_shell.h
index 9da615b..a3e441f 100644
--- a/webkit/tools/test_shell/test_shell.h
+++ b/webkit/tools/test_shell/test_shell.h
@@ -360,8 +360,8 @@ public:
// Show the "attach to me" dialog, for debugging test shell startup.
static void ShowStartupDebuggingDialog();
- // This is called indirectly by the network layer to access resources.
- static base::StringPiece NetResourceProvider(int key);
+ // This is called indirectly by the modules that need access resources.
+ static base::StringPiece ResourceProvider(int key);
TestShellDevToolsAgent* dev_tools_agent() {
return dev_tools_agent_.get();
diff --git a/webkit/tools/test_shell/test_shell_gtk.cc b/webkit/tools/test_shell/test_shell_gtk.cc
index 4a04610..7c9b0cc 100644
--- a/webkit/tools/test_shell/test_shell_gtk.cc
+++ b/webkit/tools/test_shell/test_shell_gtk.cc
@@ -626,7 +626,7 @@ void TestShell::ShowStartupDebuggingDialog() {
}
// static
-base::StringPiece TestShell::NetResourceProvider(int key) {
+base::StringPiece TestShell::ResourceProvider(int key) {
base::StringPiece res;
g_resource_data_pack->GetStringPiece(key, &res);
return res;
@@ -655,7 +655,7 @@ base::StringPiece GetDataResource(int resource_id) {
resource_id = IDR_TEXTAREA_RESIZER_TESTSHELL;
break;
}
- return TestShell::NetResourceProvider(resource_id);
+ return TestShell::ResourceProvider(resource_id);
}
} // namespace webkit_glue
diff --git a/webkit/tools/test_shell/test_shell_mac.mm b/webkit/tools/test_shell/test_shell_mac.mm
index f669663..9378bea 100644
--- a/webkit/tools/test_shell/test_shell_mac.mm
+++ b/webkit/tools/test_shell/test_shell_mac.mm
@@ -654,7 +654,7 @@ void TestShell::ShowStartupDebuggingDialog() {
[alert runModal];
}
-base::StringPiece TestShell::NetResourceProvider(int key) {
+base::StringPiece TestShell::ResourceProvider(int key) {
base::StringPiece res;
g_resource_data_pack->GetStringPiece(key, &res);
return res;
@@ -721,7 +721,7 @@ base::StringPiece GetDataResource(int resource_id) {
case IDR_INPUT_SPEECH:
case IDR_INPUT_SPEECH_RECORDING:
case IDR_INPUT_SPEECH_WAITING:
- return TestShell::NetResourceProvider(resource_id);
+ return TestShell::ResourceProvider(resource_id);
default:
break;
diff --git a/webkit/tools/test_shell/test_shell_main.cc b/webkit/tools/test_shell/test_shell_main.cc
index 7f8dfab..916986f 100644
--- a/webkit/tools/test_shell/test_shell_main.cc
+++ b/webkit/tools/test_shell/test_shell_main.cc
@@ -22,6 +22,7 @@
#include "base/string_number_conversions.h"
#include "base/sys_info.h"
#include "base/utf_string_conversions.h"
+#include "gfx/gfx_module.h"
#include "net/base/cookie_monster.h"
#include "net/base/net_module.h"
#include "net/base/net_util.h"
@@ -202,8 +203,9 @@ int main(int argc, char* argv[]) {
// Load ICU data tables
icu_util::Initialize();
- // Config the network module so it has access to a limited set of resources.
- net::NetModule::SetResourceProvider(TestShell::NetResourceProvider);
+ // Config the modules that need access to a limited set of resources.
+ net::NetModule::SetResourceProvider(TestShell::ResourceProvider);
+ gfx::GfxModule::SetResourceProvider(TestShell::ResourceProvider);
platform.InitializeGUI();
diff --git a/webkit/tools/test_shell/test_shell_win.cc b/webkit/tools/test_shell/test_shell_win.cc
index b235981..a7c4d94 100644
--- a/webkit/tools/test_shell/test_shell_win.cc
+++ b/webkit/tools/test_shell/test_shell_win.cc
@@ -138,11 +138,6 @@ static base::StringPiece GetRawDataResource(HMODULE module, int resource_id) {
: base::StringPiece();
}
-// This is called indirectly by the network layer to access resources.
-base::StringPiece NetResourceProvider(int key) {
- return GetRawDataResource(::GetModuleHandle(NULL), key);
-}
-
} // namespace
// Initialize static member variable
@@ -739,7 +734,7 @@ void TestShell::ShowStartupDebuggingDialog() {
}
// static
-base::StringPiece TestShell::NetResourceProvider(int key) {
+base::StringPiece TestShell::ResourceProvider(int key) {
return GetRawDataResource(::GetModuleHandle(NULL), key);
}
@@ -806,7 +801,7 @@ base::StringPiece GetDataResource(int resource_id) {
case IDR_INPUT_SPEECH:
case IDR_INPUT_SPEECH_RECORDING:
case IDR_INPUT_SPEECH_WAITING:
- return NetResourceProvider(resource_id);
+ return TestShell::ResourceProvider(resource_id);
default:
break;