Allow opacity to apply to custom scrollbars

https://bugs.webkit.org/show_bug.cgi?id=120104

Source/WebCore:

Reviewed by David Hyatt.

Opacity was ignored custom scrollbar pseudoelements because custom scrollbar
renderers never create layers, and opacity is normally handled by the RenderLayer code.

Fix by having RenderScrollbarTheme and RenderScrollbarPart do the transparency
layers necessary for opacity. RenderScrollbarPart handles opacity for individual
parts.

Because ScrollbarThemeComposite::paint() renders the parts on after another (with
no nesting), opacity handling for the entire scrollbar needs special-casing.
This is done by willPaintScrollbar()/didPaintScrollbar() on the theme.
RenderScrollbarTheme consults the opacity the scrollbar (which we get from
the ScrollbarBGPart renderer) to decide whether to set up a transparency layer.

Test: scrollbars/scrollbar-parts-opacity.html

* platform/ScrollbarThemeComposite.cpp:
(WebCore::ScrollbarThemeComposite::paint):
* platform/ScrollbarThemeComposite.h:
(WebCore::ScrollbarThemeComposite::willPaintScrollbar):
(WebCore::ScrollbarThemeComposite::didPaintScrollbar):
* rendering/RenderScrollbar.cpp:
(WebCore::RenderScrollbar::opacity):
* rendering/RenderScrollbar.h:
* rendering/RenderScrollbarPart.cpp:
(WebCore::RenderScrollbarPart::paintIntoRect):
* rendering/RenderScrollbarTheme.cpp:
(WebCore::RenderScrollbarTheme::willPaintScrollbar):
(WebCore::RenderScrollbarTheme::didPaintScrollbar):
* rendering/RenderScrollbarTheme.h:

LayoutTests:

Reviewed by David Hyatt.

Ref test for custom scrollbars with opacity on the bar itself,
and on the thumb.

* scrollbars/scrollbar-parts-opacity-expected.html: Added.
* scrollbars/scrollbar-parts-opacity.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@154400 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent a10ca744
2013-08-21 Simon Fraser <simon.fraser@apple.com>
Allow opacity to apply to custom scrollbars
https://bugs.webkit.org/show_bug.cgi?id=120104
Reviewed by David Hyatt.
Ref test for custom scrollbars with opacity on the bar itself,
and on the thumb.
* scrollbars/scrollbar-parts-opacity-expected.html: Added.
* scrollbars/scrollbar-parts-opacity.html: Added.
2013-08-21 Robert Hogan <robert@webkit.org>
REGRESSION(r127163): Respect clearance set on ancestors when placing floats
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
}
.bar-background {
position: absolute;
background-color: green;
opacity: 0.75;
}
.bar-background.vertical {
left: 340px;
width: 60px;
height: 340px;
}
.bar-background.horizontal {
top: 340px;
height: 60px;
width: 340px;
}
.thumb {
position: absolute;
background-color: navy;
opacity: 0.5;
}
.vertical > .thumb {
width: 60px;
height: 145px;
}
.horizontal > .thumb {
width: 145px;
height: 60px;
}
.backdrop {
position: absolute;
top: 100px;
left: 100px;
height: 400px;
width: 400px;
background-color: gray;
}
.backdrop.vertical {
width: 150px;
}
.backdrop.horizontal {
height: 150px;
}
</style>
</head>
<body>
<div class="backdrop vertical"></div>
<div class="backdrop horizontal"></div>
<div class="bar-background vertical">
<div class="thumb"></div>
</div>
<div class="bar-background horizontal">
<div class="thumb"></div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
}
::-webkit-scrollbar {
width: 60px;
height: 60px;
background-color: green;
opacity: 0.75;
}
::-webkit-scrollbar-thumb {
background-color: navy;
opacity: 0.5;
}
.overflow {
position: absolute;
height: 400px;
width: 400px;
overflow: scroll;
}
.contents {
height: 800px;
width: 800px;
}
.backdrop {
position: absolute;
top: 100px;
left: 100px;
height: 400px;
width: 400px;
background-color: gray;
}
.vertical {
width: 150px;
}
.horizontal {
height: 150px;
}
</style>
</head>
<body>
<div class="backdrop vertical"></div>
<div class="backdrop horizontal"></div>
<div class="composited overflow">
<div class="contents"></div>
</div>
</body>
</html>
2013-08-21 Simon Fraser <simon.fraser@apple.com>
Allow opacity to apply to custom scrollbars
https://bugs.webkit.org/show_bug.cgi?id=120104
Reviewed by David Hyatt.
Opacity was ignored custom scrollbar pseudoelements because custom scrollbar
renderers never create layers, and opacity is normally handled by the RenderLayer code.
Fix by having RenderScrollbarTheme and RenderScrollbarPart do the transparency
layers necessary for opacity. RenderScrollbarPart handles opacity for individual
parts.
Because ScrollbarThemeComposite::paint() renders the parts on after another (with
no nesting), opacity handling for the entire scrollbar needs special-casing.
This is done by willPaintScrollbar()/didPaintScrollbar() on the theme.
RenderScrollbarTheme consults the opacity the scrollbar (which we get from
the ScrollbarBGPart renderer) to decide whether to set up a transparency layer.
Test: scrollbars/scrollbar-parts-opacity.html
* platform/ScrollbarThemeComposite.cpp:
(WebCore::ScrollbarThemeComposite::paint):
* platform/ScrollbarThemeComposite.h:
(WebCore::ScrollbarThemeComposite::willPaintScrollbar):
(WebCore::ScrollbarThemeComposite::didPaintScrollbar):
* rendering/RenderScrollbar.cpp:
(WebCore::RenderScrollbar::opacity):
* rendering/RenderScrollbar.h:
* rendering/RenderScrollbarPart.cpp:
(WebCore::RenderScrollbarPart::paintIntoRect):
* rendering/RenderScrollbarTheme.cpp:
(WebCore::RenderScrollbarTheme::willPaintScrollbar):
(WebCore::RenderScrollbarTheme::didPaintScrollbar):
* rendering/RenderScrollbarTheme.h:
2013-08-21 Robert Hogan <robert@webkit.org>
REGRESSION(r127163): Respect clearance set on ancestors when placing floats
......@@ -75,6 +75,8 @@ bool ScrollbarThemeComposite::paint(ScrollbarThemeClient* scrollbar, GraphicsCon
scrollMask |= ForwardTrackPart;
}
willPaintScrollbar(graphicsContext, scrollbar);
// Paint the scrollbar background (only used by custom CSS scrollbars).
paintScrollbarBackground(graphicsContext, scrollbar);
......@@ -105,6 +107,7 @@ bool ScrollbarThemeComposite::paint(ScrollbarThemeClient* scrollbar, GraphicsCon
if (scrollMask & ThumbPart)
paintThumb(graphicsContext, scrollbar, thumbRect);
didPaintScrollbar(graphicsContext, scrollbar);
return true;
}
......
......@@ -55,6 +55,9 @@ public:
virtual int minimumThumbLength(ScrollbarThemeClient*);
virtual void willPaintScrollbar(GraphicsContext*, ScrollbarThemeClient*) { }
virtual void didPaintScrollbar(GraphicsContext*, ScrollbarThemeClient*) { }
virtual void paintScrollbarBackground(GraphicsContext*, ScrollbarThemeClient*) { }
virtual void paintTrackBackground(GraphicsContext*, ScrollbarThemeClient*, const IntRect&) { }
virtual void paintTrackPiece(GraphicsContext*, ScrollbarThemeClient*, const IntRect&, ScrollbarPart) { }
......
......@@ -357,4 +357,13 @@ int RenderScrollbar::minimumThumbLength()
return orientation() == HorizontalScrollbar ? partRenderer->width() : partRenderer->height();
}
float RenderScrollbar::opacity()
{
RenderScrollbarPart* partRenderer = m_parts.get(ScrollbarBGPart);
if (!partRenderer)
return 1;
return partRenderer->style()->opacity();
}
}
......@@ -59,6 +59,8 @@ public:
virtual bool isOverlayScrollbar() const { return false; }
float opacity();
private:
virtual void setParent(ScrollView*);
virtual void setEnabled(bool);
......
......@@ -181,9 +181,18 @@ void RenderScrollbarPart::paintIntoRect(GraphicsContext* graphicsContext, const
setWidth(rect.width());
setHeight(rect.height());
if (graphicsContext->paintingDisabled())
if (graphicsContext->paintingDisabled() || !style()->opacity())
return;
// We don't use RenderLayers for scrollbar parts, so we need to handle opacity here.
// Opacity for ScrollbarBGPart is handled by RenderScrollbarTheme::willPaintScrollbar().
bool needsTransparencyLayer = m_part != ScrollbarBGPart && style()->opacity() < 1;
if (needsTransparencyLayer) {
graphicsContext->save();
graphicsContext->clip(rect);
graphicsContext->beginTransparencyLayer(style()->opacity());
}
// Now do the paint.
PaintInfo paintInfo(graphicsContext, pixelSnappedIntRect(rect), PaintPhaseBlockBackground, PaintBehaviorNormal);
paint(paintInfo, paintOffset);
......@@ -195,6 +204,11 @@ void RenderScrollbarPart::paintIntoRect(GraphicsContext* graphicsContext, const
paint(paintInfo, paintOffset);
paintInfo.phase = PaintPhaseOutline;
paint(paintInfo, paintOffset);
if (needsTransparencyLayer) {
graphicsContext->endTransparencyLayer();
graphicsContext->restore();
}
}
RenderObject* RenderScrollbarPart::rendererOwningScrollbar() const
......
......@@ -107,6 +107,25 @@ IntRect RenderScrollbarTheme::constrainTrackRectToTrackPieces(ScrollbarThemeClie
return result;
}
void RenderScrollbarTheme::willPaintScrollbar(GraphicsContext* context, ScrollbarThemeClient* scrollbar)
{
float opacity = toRenderScrollbar(scrollbar)->opacity();
if (opacity != 1) {
context->save();
context->clip(scrollbar->frameRect());
context->beginTransparencyLayer(opacity);
}
}
void RenderScrollbarTheme::didPaintScrollbar(GraphicsContext* context, ScrollbarThemeClient* scrollbar)
{
float opacity = toRenderScrollbar(scrollbar)->opacity();
if (opacity != 1) {
context->endTransparencyLayer();
context->restore();
}
}
void RenderScrollbarTheme::paintScrollCorner(ScrollView*, GraphicsContext* context, const IntRect& cornerRect)
{
// FIXME: Implement.
......
......@@ -67,6 +67,9 @@ protected:
virtual IntRect backButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool painting = false);
virtual IntRect forwardButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool painting = false);
virtual IntRect trackRect(ScrollbarThemeClient*, bool painting = false);
virtual void willPaintScrollbar(GraphicsContext*, ScrollbarThemeClient*) OVERRIDE;
virtual void didPaintScrollbar(GraphicsContext*, ScrollbarThemeClient*) OVERRIDE;
virtual void paintScrollbarBackground(GraphicsContext*, ScrollbarThemeClient*);
virtual void paintTrackBackground(GraphicsContext*, ScrollbarThemeClient*, const IntRect&);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment