From 41ed8679e8e8d31ced13cb0a3334dc0a8313a351 Mon Sep 17 00:00:00 2001 From: "fsamuel@chromium.org" Date: Fri, 23 Sep 2011 21:39:52 +0000 Subject: [PATCH] Refactor paintOverhangAreas to allow non-Mac Chromium platforms to reuse code https://bugs.webkit.org/show_bug.cgi?id=68648 Reviewed by Dimitri Glazkov. Source/WebCore: No new tests because there's no change in functionality (yet). * platform/chromium/ScrollbarThemeChromium.cpp: (WebCore::ScrollbarThemeChromium::ScrollbarThemeChromium): (WebCore::ScrollbarThemeChromium::~ScrollbarThemeChromium): (WebCore::ScrollbarThemeChromium::paintOverhangAreas): * platform/chromium/ScrollbarThemeChromium.h: * platform/chromium/ScrollbarThemeChromiumMac.h: * platform/chromium/ScrollbarThemeChromiumMac.mm: (WebCore::ScrollbarThemeChromiumMac::ScrollbarThemeChromiumMac): Source/WebKit/chromium: * features.gypi: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95860 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 18 +++ .../platform/chromium/ScrollbarThemeChromium.cpp | 143 +++++++++++++++++++++ .../platform/chromium/ScrollbarThemeChromium.h | 12 ++ .../platform/chromium/ScrollbarThemeChromiumMac.h | 5 - .../platform/chromium/ScrollbarThemeChromiumMac.mm | 127 ------------------ Source/WebKit/chromium/ChangeLog | 9 ++ Source/WebKit/chromium/features.gypi | 3 + 7 files changed, 185 insertions(+), 132 deletions(-) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index c0387c2..d46d2bc 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,21 @@ +2011-09-23 Fady Samuel + + Refactor paintOverhangAreas to allow non-Mac Chromium platforms to reuse code + https://bugs.webkit.org/show_bug.cgi?id=68648 + + Reviewed by Dimitri Glazkov. + + No new tests because there's no change in functionality (yet). + + * platform/chromium/ScrollbarThemeChromium.cpp: + (WebCore::ScrollbarThemeChromium::ScrollbarThemeChromium): + (WebCore::ScrollbarThemeChromium::~ScrollbarThemeChromium): + (WebCore::ScrollbarThemeChromium::paintOverhangAreas): + * platform/chromium/ScrollbarThemeChromium.h: + * platform/chromium/ScrollbarThemeChromiumMac.h: + * platform/chromium/ScrollbarThemeChromiumMac.mm: + (WebCore::ScrollbarThemeChromiumMac::ScrollbarThemeChromiumMac): + 2011-09-23 Ojan Vafai remove physical flex-flow values to match the updated spec diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromium.cpp b/Source/WebCore/platform/chromium/ScrollbarThemeChromium.cpp index 24b3e18..6cc4d3d 100644 --- a/Source/WebCore/platform/chromium/ScrollbarThemeChromium.cpp +++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromium.cpp @@ -28,6 +28,11 @@ #include "ScrollbarThemeChromium.h" #include "PlatformMouseEvent.h" + +#if ENABLE(RUBBER_BANDING) +#include "ScrollView.h" +#endif + #include "ScrollableArea.h" #include "Scrollbar.h" #include "ScrollbarThemeComposite.h" @@ -39,6 +44,144 @@ namespace WebCore { +#if ENABLE(RUBBER_BANDING) +ScrollbarThemeChromium::ScrollbarThemeChromium() +{ + static bool initialized = false; + if (!initialized) { + initialized = true; + // Load the linen pattern image used for overhang drawing. + RefPtr patternImage = Image::loadPlatformResource("overhangPattern"); + m_overhangPattern = Pattern::create(patternImage, true, true); + } +} + +ScrollbarThemeChromium::~ScrollbarThemeChromium() +{ +} + +void ScrollbarThemeChromium::paintOverhangAreas(ScrollView* view, GraphicsContext* context, const IntRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect& dirtyRect) +{ + // The extent of each shadow in pixels. + const int kShadowSize = 4; + // Offset of negative one pixel to make the gradient blend with the toolbar's bottom border. + const int kToolbarShadowOffset = -1; + const struct { + float stop; + Color color; + } kShadowColors[] = { + { 0.000, Color(0, 0, 0, 255) }, + { 0.125, Color(0, 0, 0, 57) }, + { 0.375, Color(0, 0, 0, 41) }, + { 0.625, Color(0, 0, 0, 18) }, + { 0.875, Color(0, 0, 0, 6) }, + { 1.000, Color(0, 0, 0, 0) } + }; + const unsigned kNumShadowColors = sizeof(kShadowColors) / sizeof(kShadowColors[0]); + + const bool hasHorizontalOverhang = !horizontalOverhangRect.isEmpty(); + const bool hasVerticalOverhang = !verticalOverhangRect.isEmpty(); + // Prefer non-additive shadows, but degrade to additive shadows if there is vertical overhang. + const bool useAdditiveShadows = hasVerticalOverhang; + + GraphicsContextStateSaver stateSaver(*context); + + context->setFillPattern(m_overhangPattern); + 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) { + int toolbarShadowHeight = kShadowSize; + RefPtr gradient; + IntRect shadowRect = horizontalOverhangRect; + shadowRect.setHeight(kShadowSize); + if (scrollOffset.height() < 0) { + if (useAdditiveShadows) { + toolbarShadowHeight = std::min(horizontalOverhangRect.height(), kShadowSize); + } else if (horizontalOverhangRect.height() < 2 * kShadowSize + kToolbarShadowOffset) { + // Split the overhang area between the web content shadow and toolbar shadow if it's too small. + shadowRect.setHeight((horizontalOverhangRect.height() + 1) / 2); + toolbarShadowHeight = horizontalOverhangRect.height() - shadowRect.height() - kToolbarShadowOffset; + } + shadowRect.setY(horizontalOverhangRect.maxY() - shadowRect.height()); + gradient = Gradient::create(FloatPoint(0, shadowRect.maxY()), FloatPoint(0, shadowRect.maxY() - kShadowSize)); + shadowCornerOrigin.setY(shadowRect.maxY()); + shadowCornerOffset.setY(-kShadowSize); + } else { + gradient = Gradient::create(FloatPoint(0, shadowRect.y()), FloatPoint(0, shadowRect.maxY())); + shadowCornerOrigin.setY(shadowRect.y()); + } + if (hasVerticalOverhang) { + 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 a drop-shadow from the toolbar. + if (scrollOffset.height() < 0) { + shadowRect.setY(kToolbarShadowOffset); + shadowRect.setHeight(toolbarShadowHeight); + gradient = Gradient::create(FloatPoint(0, shadowRect.y()), FloatPoint(0, shadowRect.y() + kShadowSize)); + 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; + IntRect shadowRect = verticalOverhangRect; + shadowRect.setWidth(kShadowSize); + if (scrollOffset.width() < 0) { + shadowRect.setX(verticalOverhangRect.maxX() - shadowRect.width()); + gradient = Gradient::create(FloatPoint(shadowRect.maxX(), 0), FloatPoint(shadowRect.x(), 0)); + } else + 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)); + + // Draw a drop-shadow from the toolbar. + shadowRect = verticalOverhangRect; + shadowRect.setY(kToolbarShadowOffset); + shadowRect.setHeight(kShadowSize); + gradient = Gradient::create(FloatPoint(0, shadowRect.y()), FloatPoint(0, shadowRect.maxY())); + 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::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)); + } +} +#endif + bool ScrollbarThemeChromium::hasThumb(Scrollbar* scrollbar) { // This method is just called as a paint-time optimization to see if diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromium.h b/Source/WebCore/platform/chromium/ScrollbarThemeChromium.h index 1178125..179c34e 100644 --- a/Source/WebCore/platform/chromium/ScrollbarThemeChromium.h +++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromium.h @@ -40,6 +40,13 @@ namespace WebCore { // This class contains the scrollbar code which is shared between Chromium // Windows and Linux. class ScrollbarThemeChromium : public ScrollbarThemeComposite { +#if ENABLE(RUBBER_BANDING) + public: + ScrollbarThemeChromium(); + virtual ~ScrollbarThemeChromium(); + virtual void paintOverhangAreas(ScrollView*, GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect); +#endif + protected: virtual bool hasButtons(Scrollbar*) { return true; } virtual bool hasThumb(Scrollbar*); @@ -52,6 +59,11 @@ namespace WebCore { virtual void paintTickmarks(GraphicsContext*, Scrollbar*, const IntRect&); virtual IntSize buttonSize(Scrollbar*) = 0; + +#if ENABLE(RUBBER_BANDING) + private: + RefPtr m_overhangPattern; +#endif }; } // namespace WebCore diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.h b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.h index cc9a308..ed84f32 100644 --- a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.h +++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.h @@ -62,8 +62,6 @@ public: 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*); @@ -82,9 +80,6 @@ protected: private: void paintGivenTickmarks(GraphicsContext*, Scrollbar*, const IntRect&, const Vector&); - -private: - RefPtr m_overhangPattern; }; } diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm index 472343d..c2dd0d3 100644 --- a/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm +++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm @@ -194,10 +194,6 @@ ScrollbarThemeChromiumMac::ScrollbarThemeChromiumMac() if (!initialized) { initialized = true; - // Load the linen pattern image used for overhang drawing. - RefPtr patternImage = Image::loadPlatformResource("overhangPattern"); - m_overhangPattern = Pattern::create(patternImage, true, true); - [ScrollbarPrefsObserver registerAsObserver]; preferencesChanged(); } @@ -676,127 +672,4 @@ void ScrollbarThemeChromiumMac::paintGivenTickmarks(GraphicsContext* context, Sc } } -void ScrollbarThemeChromiumMac::paintOverhangAreas(ScrollView* view, GraphicsContext* context, const IntRect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect& dirtyRect) -{ - // The extent of each shadow in pixels. - const int kShadowSize = 4; - // Offset of negative one pixel to make the gradient blend with the toolbar's bottom border. - const int kToolbarShadowOffset = -1; - const struct { - float stop; - Color color; - } kShadowColors[] = { - { 0.000, Color(0, 0, 0, 255) }, - { 0.125, Color(0, 0, 0, 57) }, - { 0.375, Color(0, 0, 0, 41) }, - { 0.625, Color(0, 0, 0, 18) }, - { 0.875, Color(0, 0, 0, 6) }, - { 1.000, Color(0, 0, 0, 0) } - }; - const unsigned kNumShadowColors = sizeof(kShadowColors)/sizeof(kShadowColors[0]); - - const bool hasHorizontalOverhang = !horizontalOverhangRect.isEmpty(); - const bool hasVerticalOverhang = !verticalOverhangRect.isEmpty(); - // Prefer non-additive shadows, but degrade to additive shadows if there is vertical overhang. - const bool useAdditiveShadows = hasVerticalOverhang; - - GraphicsContextStateSaver stateSaver(*context); - - context->setFillPattern(m_overhangPattern); - 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) { - int toolbarShadowHeight = kShadowSize; - RefPtr gradient; - IntRect shadowRect = horizontalOverhangRect; - shadowRect.setHeight(kShadowSize); - if (scrollOffset.height() < 0) { - if (useAdditiveShadows) { - toolbarShadowHeight = std::min(horizontalOverhangRect.height(), kShadowSize); - } else if (horizontalOverhangRect.height() < 2 * kShadowSize + kToolbarShadowOffset) { - // Split the overhang area between the web content shadow and toolbar shadow if it's too small. - shadowRect.setHeight((horizontalOverhangRect.height() + 1) / 2); - toolbarShadowHeight = horizontalOverhangRect.height() - shadowRect.height() - kToolbarShadowOffset; - } - shadowRect.setY(horizontalOverhangRect.maxY() - shadowRect.height()); - gradient = Gradient::create(FloatPoint(0, shadowRect.maxY()), FloatPoint(0, shadowRect.maxY() - kShadowSize)); - shadowCornerOrigin.setY(shadowRect.maxY()); - shadowCornerOffset.setY(-kShadowSize); - } else { - gradient = Gradient::create(FloatPoint(0, shadowRect.y()), FloatPoint(0, shadowRect.maxY())); - shadowCornerOrigin.setY(shadowRect.y()); - } - if (hasVerticalOverhang) { - 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 a drop-shadow from the toolbar. - if (scrollOffset.height() < 0) { - shadowRect.setY(kToolbarShadowOffset); - shadowRect.setHeight(toolbarShadowHeight); - gradient = Gradient::create(FloatPoint(0, shadowRect.y()), FloatPoint(0, shadowRect.y() + kShadowSize)); - 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; - IntRect shadowRect = verticalOverhangRect; - shadowRect.setWidth(kShadowSize); - if (scrollOffset.width() < 0) { - shadowRect.setX(verticalOverhangRect.maxX() - shadowRect.width()); - gradient = Gradient::create(FloatPoint(shadowRect.maxX(), 0), FloatPoint(shadowRect.x(), 0)); - } else { - 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)); - - // Draw a drop-shadow from the toolbar. - shadowRect = verticalOverhangRect; - shadowRect.setY(kToolbarShadowOffset); - shadowRect.setHeight(kShadowSize); - gradient = Gradient::create(FloatPoint(0, shadowRect.y()), FloatPoint(0, shadowRect.maxY())); - 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::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)); - } -} - - } diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog index 119cfb6..9c199c0 100644 --- a/Source/WebKit/chromium/ChangeLog +++ b/Source/WebKit/chromium/ChangeLog @@ -1,3 +1,12 @@ +2011-09-23 Fady Samuel + + Refactor paintOverhangAreas to allow non-Mac Chromium platforms to reuse code + https://bugs.webkit.org/show_bug.cgi?id=68648 + + Reviewed by Dimitri Glazkov. + + * features.gypi: + 2011-09-23 Elliot Poger update layout_tests to account for new default of use_skia=1 diff --git a/Source/WebKit/chromium/features.gypi b/Source/WebKit/chromium/features.gypi index c7c078c..fbb2e5a 100644 --- a/Source/WebKit/chromium/features.gypi +++ b/Source/WebKit/chromium/features.gypi @@ -140,6 +140,9 @@ }], ['touchui==1', { 'enable_touch_icon_loading': 1, + 'feature_defines': [ + 'ENABLE_RUBBER_BANDING=1', + ], }], # Mac OS X uses Accelerate.framework FFT by default instead of FFmpeg. ['OS!="mac"', { -- 2.7.4