Index: third_party/WebKit/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp |
=================================================================== |
--- third_party/WebKit/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp (revision 51794) |
+++ third_party/WebKit/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp (working copy) |
@@ -33,6 +33,8 @@ |
#include "PlatformContextSkia.h" |
#include "PlatformMouseEvent.h" |
+#include "RenderTheme.h" |
+#include "RenderThemeChromiumLinux.h" |
#include "Scrollbar.h" |
#include "TransformationMatrix.h" |
@@ -73,6 +75,70 @@ |
drawVertLine(canvas, rect.x(), rect.y(), bottom, paint); |
} |
+static SkColor saturateAndBrighten(SkScalar* hsv, |
+ SkScalar saturateAmount, |
+ SkScalar brightenAmount) |
+{ |
+ SkScalar color[3]; |
+ color[0] = hsv[0]; |
+ |
+ color[1] = hsv[1] + saturateAmount; |
+ if (color[1] > 1.0) |
+ color[1] = 1.0; |
+ else if (color[1] < 0.0) |
+ color[1] = 0.0; |
+ |
+ color[2] = hsv[2] + brightenAmount; |
+ if (color[2] > 1.0) |
+ color[2] = 1.0; |
+ else if (color[2] < 0.0) |
+ color[2] = 0.0; |
+ |
+ return SkHSVToColor(color); |
+} |
+ |
+static SkColor outlineColor(SkScalar* hsv1, SkScalar* hsv2) { |
+ // GTK Theme engines have way too much control over the layout of the |
+ // scrollbar. We might be able to more closely approximate its look-and-feel, |
+ // if we sent whole images instead of just colors from the browser to the |
+ // renderer. But even then, some themes would just break. |
+ // |
+ // So, instead, we don't even try to 100% replicate the look of the native |
+ // scrollbar. We render our own version, but we make sure to pick colors that |
+ // blend in nicely with the system GTK theme. In most cases, we can just |
+ // sample a couple of pixels from the system scrollbar and use those colors |
+ // to draw our scrollbar. |
+ // |
+ // This works fine for the track color and the overall thumb color. But it |
+ // fails spectacularly for the outline color used around the thumb piece. |
+ // Not all themes have a clearly defined outline. For some of them it is |
+ // partially transparent, and for others the thickness is very unpredictable. |
+ // |
+ // So, instead of trying to approximate the system theme, we instead try to |
+ // compute a reasonable looking choice based on the known color of the track |
+ // and the thumb piece. This is difficult when trying to deal both with high- |
+ // and low-contrast themes, and both with positive and inverted themes. |
+ // |
+ // The following code has been tested to look OK with all of the default GTK |
+ // themes. |
+ SkScalar min_diff = (hsv1[1] + hsv2[1])*1.2; |
+ if (min_diff < 0.2) |
+ min_diff = 0.2; |
+ else if (min_diff > 0.5) |
+ min_diff = 0.5; |
+ |
+ SkScalar diff = fabs(hsv1[2] - hsv2[2])/2; |
+ if (diff < min_diff) |
+ diff = min_diff; |
+ else if (diff > 0.5) |
+ diff = 0.5; |
+ |
+ if (hsv1[2] + hsv2[2] > 1.0) |
+ diff = -diff; |
+ |
+ return saturateAndBrighten(hsv2, -0.2, diff); |
+} |
+ |
IntRect ScrollbarThemeChromium::trackRect(Scrollbar* scrollbar, bool) |
{ |
IntSize bs = buttonSize(scrollbar); |
@@ -89,10 +155,16 @@ |
SkIRect skrect; |
skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); |
- paint.setARGB(0xff, 0xe3, 0xdd, 0xd8); |
+ SkScalar track_hsv[3]; |
+ SkColorToHSV(RenderThemeChromiumLinux::trackColor(), track_hsv); |
+ paint.setColor(saturateAndBrighten(track_hsv, 0, 0)); |
canvas->drawIRect(skrect, paint); |
- paint.setARGB(0xff, 0xc5, 0xba, 0xb0); |
+ SkScalar thumb_hsv[3]; |
+ SkColorToHSV(RenderThemeChromiumLinux::thumbInactiveColor(), |
+ thumb_hsv); |
+ |
+ paint.setColor(outlineColor(track_hsv, thumb_hsv)); |
drawBox(canvas, rect, paint); |
} |
@@ -109,11 +181,14 @@ |
const bool vertical = scrollbar->orientation() == VerticalScrollbar; |
SkCanvas* const canvas = gc->platformContext()->canvas(); |
+ SkScalar thumb[3]; |
+ SkColorToHSV(hovered |
+ ? RenderThemeChromiumLinux::thumbActiveColor() |
+ : RenderThemeChromiumLinux::thumbInactiveColor(), |
+ thumb); |
+ |
SkPaint paint; |
- if (hovered) |
- paint.setARGB(0xff, 0xff, 0xff, 0xff); |
- else |
- paint.setARGB(0xff, 0xf4, 0xf2, 0xef); |
+ paint.setColor(saturateAndBrighten(thumb, 0, 0.02)); |
SkIRect skrect; |
if (vertical) |
@@ -123,10 +198,7 @@ |
canvas->drawIRect(skrect, paint); |
- if (hovered) |
- paint.setARGB(0xff, 0xf4, 0xf2, 0xef); |
- else |
- paint.setARGB(0xff, 0xea, 0xe5, 0xe0); |
+ paint.setColor(saturateAndBrighten(thumb, 0, -0.02)); |
if (vertical) |
skrect.set(midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); |
@@ -135,11 +207,12 @@ |
canvas->drawIRect(skrect, paint); |
- paint.setARGB(0xff, 0x9d, 0x96, 0x8e); |
+ SkScalar track[3]; |
+ SkColorToHSV(RenderThemeChromiumLinux::trackColor(), track); |
+ paint.setColor(outlineColor(track, thumb)); |
drawBox(canvas, rect, paint); |
if (rect.height() > 10 && rect.width() > 10) { |
- paint.setARGB(0xff, 0x9d, 0x96, 0x8e); |
const int grippyHalfWidth = 2; |
const int interGrippyOffset = 3; |
if (vertical) { |