Diff
Modified: trunk/Source/WebCore/ChangeLog (93135 => 93136)
--- trunk/Source/WebCore/ChangeLog 2011-08-16 18:44:01 UTC (rev 93135)
+++ trunk/Source/WebCore/ChangeLog 2011-08-16 18:45:35 UTC (rev 93136)
@@ -1,3 +1,31 @@
+2011-08-16 Alexei Svitkine <[email protected]>
+
+ Chromium Mac: Rubber banding gutter drawing
+ https://bugs.webkit.org/show_bug.cgi?id=66226
+
+ Make ScrollView::paintOverhangAreas() use the ScrollbarTheme::nativeTheme() to
+ draw the overhang areas.
+ Move default implementation to ScrollbarThemeComposite::paintOverhangAreas().
+ Add a different implementation for Chromium Mac.
+
+ Reviewed by Dimitri Glazkov.
+
+ No new tests since this is just refactoring code and adding a Chromium-specific path for overhang drawing.
+
+ * platform/ScrollView.cpp:
+ (WebCore::ScrollView::wheelEvent):
+ * platform/ScrollbarTheme.h:
+ (WebCore::ScrollbarTheme::paintOverhangAreas):
+ * platform/ScrollbarThemeComposite.cpp:
+ (WebCore::ScrollbarThemeComposite::paintOverhangAreas):
+ * platform/ScrollbarThemeComposite.h:
+ * platform/chromium/ScrollbarThemeChromiumMac.h:
+ * platform/chromium/ScrollbarThemeChromiumMac.mm:
+ (WebCore::ScrollbarThemeChromiumMac::ScrollbarThemeChromiumMac):
+ (WebCore::scrollbarStateToThemeState):
+ (WebCore::ScrollbarThemeChromiumMac::paintTickmarks):
+ (WebCore::ScrollbarThemeChromiumMac::paintOverhangAreas):
+
2011-08-12 Wyatt Carss <[email protected]>
Programmatically set selection should not have direction on Mac
Modified: trunk/Source/WebCore/platform/ScrollView.cpp (93135 => 93136)
--- trunk/Source/WebCore/platform/ScrollView.cpp 2011-08-16 18:44:01 UTC (rev 93135)
+++ trunk/Source/WebCore/platform/ScrollView.cpp 2011-08-16 18:45:35 UTC (rev 93136)
@@ -1086,17 +1086,9 @@
}
}
-void ScrollView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect&)
+void ScrollView::paintOverhangAreas(GraphicsContext* context, const IntRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect& dirtyRect)
{
- // FIXME: This should be checking the dirty rect.
-
- context->setFillColor(Color::white, ColorSpaceDeviceRGB);
- if (!horizontalOverhangRect.isEmpty())
- context->fillRect(horizontalOverhangRect);
-
- context->setFillColor(Color::white, ColorSpaceDeviceRGB);
- if (!verticalOverhangRect.isEmpty())
- context->fillRect(verticalOverhangRect);
+ ScrollbarTheme::nativeTheme()->paintOverhangAreas(this, context, horizontalOverhangRect, verticalOverhangRect, dirtyRect);
}
bool ScrollView::isPointInScrollbarCorner(const IntPoint& windowPoint)
Modified: trunk/Source/WebCore/platform/ScrollbarTheme.h (93135 => 93136)
--- trunk/Source/WebCore/platform/ScrollbarTheme.h 2011-08-16 18:44:01 UTC (rev 93135)
+++ trunk/Source/WebCore/platform/ScrollbarTheme.h 2011-08-16 18:45:35 UTC (rev 93136)
@@ -82,6 +82,8 @@
virtual void paintScrollCorner(ScrollView*, GraphicsContext* context, const IntRect& cornerRect) { defaultPaintScrollCorner(context, cornerRect); }
static void defaultPaintScrollCorner(GraphicsContext* context, const IntRect& cornerRect) { context->fillRect(cornerRect, Color::white, ColorSpaceDeviceRGB); }
+ virtual void paintOverhangAreas(ScrollView*, GraphicsContext*, const IntRect&, const IntRect&, const IntRect&) { }
+
virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&) { return false; }
virtual bool shouldSnapBackToDragOrigin(Scrollbar*, const PlatformMouseEvent&) { return false; }
virtual bool shouldDragDocumentInsteadOfThumb(Scrollbar*, const PlatformMouseEvent&) { return false; }
Modified: trunk/Source/WebCore/platform/ScrollbarThemeComposite.cpp (93135 => 93136)
--- trunk/Source/WebCore/platform/ScrollbarThemeComposite.cpp 2011-08-16 18:44:01 UTC (rev 93135)
+++ trunk/Source/WebCore/platform/ScrollbarThemeComposite.cpp 2011-08-16 18:45:35 UTC (rev 93136)
@@ -315,4 +315,15 @@
context->fillRect(cornerRect, Color::white, ColorSpaceDeviceRGB);
}
+void ScrollbarThemeComposite::paintOverhangAreas(ScrollView*, GraphicsContext* context, const IntRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect& dirtyRect)
+{
+ context->setFillColor(Color::white, ColorSpaceDeviceRGB);
+ if (!horizontalOverhangRect.isEmpty())
+ context->fillRect(intersection(horizontalOverhangRect, dirtyRect));
+
+ context->setFillColor(Color::white, ColorSpaceDeviceRGB);
+ if (!verticalOverhangRect.isEmpty())
+ context->fillRect(intersection(verticalOverhangRect, dirtyRect));
}
+
+}
Modified: trunk/Source/WebCore/platform/ScrollbarThemeComposite.h (93135 => 93136)
--- trunk/Source/WebCore/platform/ScrollbarThemeComposite.h 2011-08-16 18:44:01 UTC (rev 93135)
+++ trunk/Source/WebCore/platform/ScrollbarThemeComposite.h 2011-08-16 18:45:35 UTC (rev 93136)
@@ -44,6 +44,7 @@
virtual int trackLength(Scrollbar*);
virtual void paintScrollCorner(ScrollView*, GraphicsContext*, const IntRect& cornerRect);
+ virtual void paintOverhangAreas(ScrollView*, GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect);
protected:
virtual bool hasButtons(Scrollbar*) = 0;
Modified: trunk/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.h (93135 => 93136)
--- trunk/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.h 2011-08-16 18:44:01 UTC (rev 93135)
+++ trunk/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.h 2011-08-16 18:45:35 UTC (rev 93136)
@@ -40,6 +40,8 @@
ScrollbarThemeChromiumMac();
virtual ~ScrollbarThemeChromiumMac();
+ void preferencesChanged();
+
virtual bool paint(Scrollbar*, GraphicsContext* context, const IntRect& damageRect);
virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar);
@@ -58,6 +60,8 @@
void setNewPainterForScrollbar(Scrollbar*, WKScrollbarPainterRef);
WKScrollbarPainterRef painterForScrollbar(Scrollbar*);
+ virtual void paintOverhangAreas(ScrollView*, GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect);
+
protected:
virtual bool hasButtons(Scrollbar*);
virtual bool hasThumb(Scrollbar*);
@@ -73,8 +77,8 @@
virtual void paintTickmarks(GraphicsContext*, Scrollbar*, const IntRect&);
-public:
- void preferencesChanged();
+private:
+ RefPtr<Pattern> m_overhangPattern;
};
}
Modified: trunk/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm (93135 => 93136)
--- trunk/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm 2011-08-16 18:44:01 UTC (rev 93135)
+++ trunk/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm 2011-08-16 18:45:35 UTC (rev 93136)
@@ -27,7 +27,9 @@
#include "config.h"
#include "ScrollbarThemeChromiumMac.h"
+#include "BitmapImage.h"
#include "FrameView.h"
+#include "Gradient.h"
#include "ImageBuffer.h"
#include "LocalCurrentGraphicsContext.h"
#include "PlatformBridge.h"
@@ -44,6 +46,13 @@
#include "skia/ext/skia_utils_mac.h"
#endif
+
+// Undocumented Lion method to get the pattern for the over-scroll area.
+@interface NSColor (LionSekretAPI)
++ (NSImage*)_linenPatternImage;
+@end
+
+
// FIXME: There are repainting problems due to Aqua scroll bar buttons' visual overflow.
using namespace std;
@@ -185,6 +194,21 @@
static bool initialized;
if (!initialized) {
initialized = true;
+
+ // Load the linen pattern image used for overhang drawing if available.
+ if ([NSColor respondsToSelector:@selector(_linenPatternImage)]) {
+ NSImage* image = [NSColor _linenPatternImage];
+ if (image) {
+ NSData* tiffData = [image TIFFRepresentation];
+ if (tiffData) {
+ CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)tiffData, NULL);
+ CGImageRef cgImage = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
+ RefPtr<Image> patternImage = BitmapImage::create(cgImage);
+ m_overhangPattern = Pattern::create(patternImage, true, true);
+ }
+ }
+ }
+
[ScrollbarPrefsObserver registerAsObserver];
preferencesChanged();
}
@@ -436,7 +460,8 @@
}
}
-static PlatformBridge::ThemePaintState scrollbarStateToThemeState(Scrollbar* scrollbar) {
+static PlatformBridge::ThemePaintState scrollbarStateToThemeState(Scrollbar* scrollbar)
+{
if (!scrollbar->enabled())
return PlatformBridge::StateDisabled;
if (!scrollbar->scrollableArea()->isActive())
@@ -598,7 +623,8 @@
return true;
}
-void ScrollbarThemeChromiumMac::paintTickmarks(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) {
+void ScrollbarThemeChromiumMac::paintTickmarks(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect)
+{
if (scrollbar->orientation() != VerticalScrollbar)
return;
@@ -643,4 +669,99 @@
context->restore();
}
+void ScrollbarThemeChromiumMac::paintOverhangAreas(ScrollView* view, GraphicsContext* context, const IntRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect& dirtyRect)
+{
+ const int kShadowSize = 5;
+ const struct {
+ float stop;
+ Color color;
+ } kShadowColors[] = {
+ { 0.0, Color(0, 0, 0, 141) },
+ { 0.2, Color(0, 0, 0, 89) },
+ { 0.6, Color(0, 0, 0, 30) },
+ { 1.0, Color(0, 0, 0, 0) }
+ };
+ const unsigned kNumShadowColors = sizeof(kShadowColors)/sizeof(kShadowColors[0]);
+
+ bool hasHorizontalOverhang = !horizontalOverhangRect.isEmpty();
+ bool hasVerticalOverhang = !verticalOverhangRect.isEmpty();
+
+ context->save();
+
+ if (m_overhangPattern.get())
+ context->setFillPattern(m_overhangPattern);
+ else
+ context->setFillColor(Color::darkGray, ColorSpaceDeviceRGB);
+
+ if (hasHorizontalOverhang)
+ context->fillRect(intersection(horizontalOverhangRect, dirtyRect));
+ if (hasVerticalOverhang)
+ context->fillRect(intersection(verticalOverhangRect, dirtyRect));
+
+ IntSize scrollOffset = view->scrollOffset();
+ FloatPoint shadowCornerOrigin;
+ FloatPoint shadowCornerOffset;
+
+ // Draw the shadow for the horizontal overhang.
+ if (hasHorizontalOverhang) {
+ RefPtr<Gradient> gradient;
+ IntRect shadowRect = horizontalOverhangRect;
+ if (scrollOffset.height() < 0) {
+ shadowRect.setY(shadowRect.maxY() - kShadowSize);
+ shadowRect.setHeight(kShadowSize);
+ gradient = Gradient::create(FloatPoint(0, shadowRect.maxY()), FloatPoint(0, shadowRect.y()));
+ shadowCornerOrigin.setY(shadowRect.maxY());
+ shadowCornerOffset.setY(-kShadowSize);
+ } else {
+ shadowRect.setHeight(kShadowSize);
+ gradient = Gradient::create(FloatPoint(0, shadowRect.y()), FloatPoint(0, shadowRect.maxY()));
+ shadowCornerOrigin.setY(shadowRect.y());
+ }
+ if (hasHorizontalOverhang) {
+ shadowRect.setWidth(shadowRect.width() - verticalOverhangRect.width());
+ if (scrollOffset.width() < 0) {
+ shadowRect.setX(shadowRect.x() + verticalOverhangRect.width());
+ shadowCornerOrigin.setX(shadowRect.x());
+ shadowCornerOffset.setX(-kShadowSize);
+ } else {
+ shadowCornerOrigin.setX(shadowRect.maxX());
+ }
+ }
+ for (unsigned i = 0; i < kNumShadowColors; i++)
+ gradient->addColorStop(kShadowColors[i].stop, kShadowColors[i].color);
+ context->setFillGradient(gradient);
+ context->fillRect(intersection(shadowRect, dirtyRect));
+ }
+
+ // Draw the shadow for the vertical overhang.
+ if (hasVerticalOverhang) {
+ RefPtr<Gradient> gradient;
+ IntRect shadowRect = verticalOverhangRect;
+ if (scrollOffset.width() < 0) {
+ shadowRect.setX(shadowRect.maxX() - kShadowSize);
+ shadowRect.setWidth(kShadowSize);
+ gradient = Gradient::create(FloatPoint(shadowRect.maxX(), 0), FloatPoint(shadowRect.x(), 0));
+ } else {
+ shadowRect.setWidth(kShadowSize);
+ gradient = Gradient::create(FloatPoint(shadowRect.x(), 0), FloatPoint(shadowRect.maxX(), 0));
+ }
+ for (unsigned i = 0; i < kNumShadowColors; i++)
+ gradient->addColorStop(kShadowColors[i].stop, kShadowColors[i].color);
+ context->setFillGradient(gradient);
+ context->fillRect(intersection(shadowRect, dirtyRect));
+ }
+
+ // If both rectangles present, draw a radial gradient for the corner.
+ if (hasHorizontalOverhang && hasVerticalOverhang) {
+ RefPtr<Gradient> gradient = Gradient::create(shadowCornerOrigin, 0, shadowCornerOrigin, kShadowSize);
+ for (unsigned i = 0; i < kNumShadowColors; i++)
+ gradient->addColorStop(kShadowColors[i].stop, kShadowColors[i].color);
+ context->setFillGradient(gradient);
+ context->fillRect(FloatRect(shadowCornerOrigin.x() + shadowCornerOffset.x(), shadowCornerOrigin.y() + shadowCornerOffset.y(), kShadowSize, kShadowSize));
+ }
+
+ context->restore();
}
+
+
+}
Modified: trunk/Source/WebCore/platform/mac/ScrollbarThemeMac.h (93135 => 93136)
--- trunk/Source/WebCore/platform/mac/ScrollbarThemeMac.h 2011-08-16 18:44:01 UTC (rev 93135)
+++ trunk/Source/WebCore/platform/mac/ScrollbarThemeMac.h 2011-08-16 18:45:35 UTC (rev 93136)
@@ -39,6 +39,8 @@
ScrollbarThemeMac();
virtual ~ScrollbarThemeMac();
+ void preferencesChanged();
+
virtual void updateEnabledState(Scrollbar*);
virtual bool paint(Scrollbar*, GraphicsContext* context, const IntRect& damageRect);
@@ -76,9 +78,6 @@
virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&);
virtual bool shouldDragDocumentInsteadOfThumb(Scrollbar*, const PlatformMouseEvent&);
-
-public:
- void preferencesChanged();
};
}