Title: [93136] trunk/Source/WebCore
Revision
93136
Author
[email protected]
Date
2011-08-16 11:45:35 -0700 (Tue, 16 Aug 2011)

Log Message

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.

Patch by Alexei Svitkine <[email protected]> on 2011-08-16
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):

Modified Paths

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();
 };
 
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to