summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp')
-rw-r--r--WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp87
1 files changed, 75 insertions, 12 deletions
diff --git a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
index 64f58c4..3a1a652 100644
--- a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
+++ b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
@@ -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,60 @@ static void drawBox(SkCanvas* canvas, const IntRect& rect, const SkPaint& paint)
drawVertLine(canvas, rect.x(), rect.y(), bottom, paint);
}
+static SkScalar clamp(SkScalar value, SkScalar min, SkScalar max)
+{
+ return std::min(std::max(value, min), max);
+}
+
+static SkColor saturateAndBrighten(SkScalar* hsv,
+ SkScalar saturateAmount,
+ SkScalar brightenAmount)
+{
+ SkScalar color[3];
+ color[0] = hsv[0];
+ color[1] = clamp(hsv[1] + saturateAmount, 0.0, 1.0);
+ color[2] = clamp(hsv[2] + brightenAmount, 0.0, 1.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 minDiff = clamp((hsv1[1] + hsv2[1]) * 1.2, 0.2, 0.5);
+ SkScalar diff = clamp(fabs(hsv1[2] - hsv2[2]) / 2, minDiff, 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 +145,16 @@ void ScrollbarThemeChromiumLinux::paintTrackPiece(GraphicsContext* gc, Scrollbar
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 +171,14 @@ void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
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 +188,7 @@ void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
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 +197,12 @@ void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
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) {