diff options
Diffstat (limited to 'WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp')
-rw-r--r-- | WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp | 87 |
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) { |