2011-01-30 Simon Fraser <simon.fraser@apple.com>

        Reviewed by Sam Weinig.

        Enhance ShadowBlur to render inset box shadows
        https://bugs.webkit.org/show_bug.cgi?id=51567

        Use ShadowBlur for inset box-shadows with CG. It
        currently lacks a tiled version, but is still much
        faster than CG shadows.

        Test: fast/box-shadow/inset-box-shadow-radius.html

        * platform/graphics/ShadowBlur.cpp:
        * platform/graphics/ShadowBlur.h: New method for inset
        shadows.
        (WebCore::ShadowBlur::drawInsetShadow):

        * platform/graphics/GraphicsContext.cpp: #ifdef out
        fillRectWithRoundedHole() for CG.

        * platform/graphics/cg/GraphicsContextCG.cpp:
        (WebCore::GraphicsContext::fillRectWithRoundedHole): If there's
        a shadow with a radius > 0, use ShadowBlur.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@77110 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e728a61c
2011-01-30 Simon Fraser <simon.fraser@apple.com>
Reviewed by Sam Weinig.
Enhance ShadowBlur to render inset box shadows
https://bugs.webkit.org/show_bug.cgi?id=51567
New test for inset shadow radius, and pixel results updated on tests
whose results are affected by using ShadowBlur rather than CG.
* fast/box-shadow/inset-box-shadow-radius.html: Added.
* platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.checksum: Added.
* platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.png: Added.
* platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.txt: Added.
* platform/mac/fast/box-shadow/inset-expected.checksum:
* platform/mac/fast/box-shadow/inset-expected.png:
* platform/mac/fast/css/shadow-multiple-expected.checksum:
* platform/mac/fast/css/shadow-multiple-expected.png:
2011-01-28 Kenneth Russell <kbr@google.com> 2011-01-28 Kenneth Russell <kbr@google.com>
Reviewed by Chris Marrin. Reviewed by Chris Marrin.
<!DOCTYPE html>
<html>
<head>
<style type="text/css" media="screen">
.wrapper {
outline: 1px solid black;
width: 280px;
height: 280px;
-webkit-box-sizing: border-box;
margin: 4px;
display: inline-block;
}
.box {
position: relative;
width: 280px;
height: 280px;
display: inline-block;
}
.indicator {
position: absolute;
width: 280px;
height: 280px;
-webkit-box-sizing: border-box;
border: 0 solid rgba(0, 255, 0, 0.05);
}
</style>
</head>
<body>
<!-- The extent of the shadow should approximately match the pale green boxes. -->
<div class="wrapper">
<div class="indicator box" style="border-width: 10px"></div>
<div class="box" style="box-shadow: 0 0 10px black inset"></div>
</div>
<div class="wrapper">
<div class="indicator box" style="border-width: 20px"></div>
<div class="box" style="box-shadow: 0 0 20px black inset"></div>
</div>
<br>
<div class="wrapper">
<div class="indicator box" style="border-width: 50px"></div>
<div class="box" style="box-shadow: 0 0 50px black inset"></div>
</div>
<div class="wrapper">
<div class="indicator box" style="border-width: 90px"></div>
<div class="box" style="box-shadow: 0 0 90px black inset"></div>
</div>
</body>
</html>
f2f5929911d4db695f6e5cea09899adf
\ No newline at end of file
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x592
RenderBlock {HTML} at (0,0) size 800x592
RenderBody {BODY} at (8,8) size 784x576
RenderBlock {DIV} at (4,4) size 280x280
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (288,270) size 4x18
text run at (288,270) width 4: " "
RenderBlock {DIV} at (296,4) size 280x280
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (580,270) size 4x18
text run at (580,270) width 4: " "
RenderBR {BR} at (0,0) size 0x0
RenderBlock {DIV} at (4,292) size 280x280
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (288,558) size 4x18
text run at (288,558) width 4: " "
RenderBlock {DIV} at (296,292) size 280x280
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 0x0
layer at (12,12) size 280x280
RenderBlock (positioned) {DIV} at (12,12) size 280x280 [border: (10px solid #00FF000C)]
layer at (12,12) size 280x280
RenderBlock (relative positioned) {DIV} at (0,0) size 280x280
layer at (304,12) size 280x280
RenderBlock (positioned) {DIV} at (304,12) size 280x280 [border: (20px solid #00FF000C)]
layer at (304,12) size 280x280
RenderBlock (relative positioned) {DIV} at (0,0) size 280x280
layer at (12,300) size 280x280
RenderBlock (positioned) {DIV} at (12,300) size 280x280 [border: (50px solid #00FF000C)]
layer at (12,300) size 280x280
RenderBlock (relative positioned) {DIV} at (0,0) size 280x280
layer at (304,300) size 280x280
RenderBlock (positioned) {DIV} at (304,300) size 280x280 [border: (90px solid #00FF000C)]
layer at (304,300) size 280x280
RenderBlock (relative positioned) {DIV} at (0,0) size 280x280
922ba5683c7767e6abd3737835212336 2f04453f3108bc8a47b5e6906bb09997
\ No newline at end of file \ No newline at end of file
ec621f0c3fad619a9ce512be72345138 3915900ef91f193c987bdeb2a1e8e030
\ No newline at end of file \ No newline at end of file
2011-01-30 Simon Fraser <simon.fraser@apple.com>
Reviewed by Sam Weinig.
Enhance ShadowBlur to render inset box shadows
https://bugs.webkit.org/show_bug.cgi?id=51567
Use ShadowBlur for inset box-shadows with CG. It
currently lacks a tiled version, but is still much
faster than CG shadows.
Test: fast/box-shadow/inset-box-shadow-radius.html
* platform/graphics/ShadowBlur.cpp:
* platform/graphics/ShadowBlur.h: New method for inset
shadows.
(WebCore::ShadowBlur::drawInsetShadow):
* platform/graphics/GraphicsContext.cpp: #ifdef out
fillRectWithRoundedHole() for CG.
* platform/graphics/cg/GraphicsContextCG.cpp:
(WebCore::GraphicsContext::fillRectWithRoundedHole): If there's
a shadow with a radius > 0, use ShadowBlur.
2011-01-28 Kenneth Russell <kbr@google.com> 2011-01-28 Kenneth Russell <kbr@google.com>
Reviewed by Chris Marrin. Reviewed by Chris Marrin.
...@@ -610,6 +610,7 @@ void GraphicsContext::fillRoundedRect(const RoundedIntRect& rect, const Color& c ...@@ -610,6 +610,7 @@ void GraphicsContext::fillRoundedRect(const RoundedIntRect& rect, const Color& c
fillRoundedRect(rect.rect(), rect.radii().topLeft(), rect.radii().topRight(), rect.radii().bottomLeft(), rect.radii().bottomRight(), color, colorSpace); fillRoundedRect(rect.rect(), rect.radii().topLeft(), rect.radii().topRight(), rect.radii().bottomLeft(), rect.radii().bottomRight(), color, colorSpace);
} }
#if !PLATFORM(CG)
void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const RoundedIntRect& roundedHoleRect, const Color& color, ColorSpace colorSpace) void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const RoundedIntRect& roundedHoleRect, const Color& color, ColorSpace colorSpace)
{ {
if (paintingDisabled()) if (paintingDisabled())
...@@ -635,6 +636,7 @@ void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const Rounded ...@@ -635,6 +636,7 @@ void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const Rounded
setFillRule(oldFillRule); setFillRule(oldFillRule);
setFillColor(oldFillColor, oldFillColorSpace); setFillColor(oldFillColor, oldFillColorSpace);
} }
#endif
void GraphicsContext::setCompositeOperation(CompositeOperator compositeOperation) void GraphicsContext::setCompositeOperation(CompositeOperator compositeOperation)
{ {
......
...@@ -407,6 +407,24 @@ void ShadowBlur::drawRectShadow(GraphicsContext* graphicsContext, const FloatRec ...@@ -407,6 +407,24 @@ void ShadowBlur::drawRectShadow(GraphicsContext* graphicsContext, const FloatRec
drawRectShadowWithTiling(graphicsContext, shadowedRect, radii, 1, shadowTemplateSize); drawRectShadowWithTiling(graphicsContext, shadowedRect, radii, 1, shadowTemplateSize);
} }
void ShadowBlur::drawInsetShadow(GraphicsContext* graphicsContext, const FloatRect& rect, const FloatRect& holeRect, const RoundedIntRect::Radii& holeRadii)
{
// FIXME: add a tiling code path here.
GraphicsContext* shadowContext = beginShadowLayer(graphicsContext, rect);
if (!shadowContext)
return;
Path path;
path.addRect(rect);
path.addRoundedRect(holeRect, holeRadii.topLeft(), holeRadii.topRight(), holeRadii.bottomLeft(), holeRadii.bottomRight());
shadowContext->setFillRule(RULE_EVENODD);
shadowContext->setFillColor(Color(.0f, .0f, .0f, 1.f), ColorSpaceDeviceRGB);
shadowContext->fillPath(path);
endShadowLayer(graphicsContext);
}
void ShadowBlur::drawRectShadowWithoutTiling(GraphicsContext* graphicsContext, const FloatRect& shadowedRect, const RoundedIntRect::Radii& radii, float alpha) void ShadowBlur::drawRectShadowWithoutTiling(GraphicsContext* graphicsContext, const FloatRect& shadowedRect, const RoundedIntRect::Radii& radii, float alpha)
{ {
GraphicsContext* shadowContext = beginShadowLayer(graphicsContext, shadowedRect); GraphicsContext* shadowContext = beginShadowLayer(graphicsContext, shadowedRect);
......
...@@ -49,6 +49,7 @@ public: ...@@ -49,6 +49,7 @@ public:
bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; } bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; }
void drawRectShadow(GraphicsContext*, const FloatRect&, const RoundedIntRect::Radii&); void drawRectShadow(GraphicsContext*, const FloatRect&, const RoundedIntRect::Radii&);
void drawInsetShadow(GraphicsContext*, const FloatRect&, const FloatRect& holeRect, const RoundedIntRect::Radii& holeRadii);
private: private:
GraphicsContext* beginShadowLayer(GraphicsContext*, const FloatRect& layerArea); GraphicsContext* beginShadowLayer(GraphicsContext*, const FloatRect& layerArea);
......
...@@ -745,6 +745,50 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef ...@@ -745,6 +745,50 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
setCGFillColor(context, oldFillColor, oldColorSpace); setCGFillColor(context, oldFillColor, oldColorSpace);
} }
void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const RoundedIntRect& roundedHoleRect, const Color& color, ColorSpace colorSpace)
{
if (paintingDisabled())
return;
CGContextRef context = platformContext();
Path path;
path.addRect(rect);
if (!roundedHoleRect.radii().isZero())
path.addRoundedRect(roundedHoleRect.rect(), roundedHoleRect.radii().topLeft(), roundedHoleRect.radii().topRight(), roundedHoleRect.radii().bottomLeft(), roundedHoleRect.radii().bottomRight());
else
path.addRect(roundedHoleRect.rect());
WindRule oldFillRule = fillRule();
Color oldFillColor = fillColor();
ColorSpace oldFillColorSpace = fillColorSpace();
setFillRule(RULE_EVENODD);
setFillColor(color, colorSpace);
// fillRectWithRoundedHole() assumes that the edges of rect are clipped out, so we only care about shadows cast around inside the hole.
bool drawOwnShadow = hasBlurredShadow(m_state) && !m_state.shadowsIgnoreTransforms;
if (drawOwnShadow) {
float shadowBlur = m_state.shadowsUseLegacyRadius ? radiusToLegacyRadius(m_state.shadowBlur) : m_state.shadowBlur;
// Turn off CG shadows.
CGContextSaveGState(context);
CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0);
ShadowBlur contextShadow(shadowBlur, m_state.shadowOffset, m_state.shadowColor, m_state.shadowColorSpace);
contextShadow.drawInsetShadow(this, rect, roundedHoleRect.rect(), roundedHoleRect.radii());
}
fillPath(path);
if (drawOwnShadow)
CGContextRestoreGState(context);
setFillRule(oldFillRule);
setFillColor(oldFillColor, oldFillColorSpace);
}
void GraphicsContext::clip(const FloatRect& rect) void GraphicsContext::clip(const FloatRect& rect)
{ {
if (paintingDisabled()) if (paintingDisabled())
......
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