diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index 4d74701d3fa2fdc13fa5c12be46d3ade846553a5..5bcddb21994f28d46495d87cbb29010750632b6f 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,22 @@ +2011-01-30 Simon Fraser + + 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 Reviewed by Chris Marrin. diff --git a/LayoutTests/fast/box-shadow/inset-box-shadow-radius.html b/LayoutTests/fast/box-shadow/inset-box-shadow-radius.html new file mode 100644 index 0000000000000000000000000000000000000000..e62601606a95fd248471884843b2a9fe5666b379 --- /dev/null +++ b/LayoutTests/fast/box-shadow/inset-box-shadow-radius.html @@ -0,0 +1,56 @@ + + + + + + + + +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+ + + diff --git a/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.checksum b/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.checksum new file mode 100644 index 0000000000000000000000000000000000000000..5dd208adb381af04f978f58b8c269987838a2d7f --- /dev/null +++ b/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.checksum @@ -0,0 +1 @@ +f2f5929911d4db695f6e5cea09899adf \ No newline at end of file diff --git a/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.png b/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..94ad7c45fe0132650bb8e02efe09ef6a37cc2f6c Binary files /dev/null and b/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.png differ diff --git a/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.txt b/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..0947dfed7a44d1577be7cb1cca9aaafcc31dc78e --- /dev/null +++ b/LayoutTests/platform/mac/fast/box-shadow/inset-box-shadow-radius-expected.txt @@ -0,0 +1,37 @@ +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 diff --git a/LayoutTests/platform/mac/fast/box-shadow/inset-expected.checksum b/LayoutTests/platform/mac/fast/box-shadow/inset-expected.checksum index f9195354608fc296239abf742cd353df6331e9bb..85fffb8276fc3bae9377531d6a47e23d80c65480 100644 --- a/LayoutTests/platform/mac/fast/box-shadow/inset-expected.checksum +++ b/LayoutTests/platform/mac/fast/box-shadow/inset-expected.checksum @@ -1 +1 @@ -922ba5683c7767e6abd3737835212336 \ No newline at end of file +2f04453f3108bc8a47b5e6906bb09997 \ No newline at end of file diff --git a/LayoutTests/platform/mac/fast/box-shadow/inset-expected.png b/LayoutTests/platform/mac/fast/box-shadow/inset-expected.png index d09573899d46f8545d64698e130802f1d0fbdd77..f9175c5c269aade7997cfaa56245fc4950fcce24 100644 Binary files a/LayoutTests/platform/mac/fast/box-shadow/inset-expected.png and b/LayoutTests/platform/mac/fast/box-shadow/inset-expected.png differ diff --git a/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.checksum b/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.checksum index 706fb928b54f49582b6154dac40c74079716e945..88f49a3e8a5d9f0cc496f5d7d482e7d010f5df18 100644 --- a/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.checksum +++ b/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.checksum @@ -1 +1 @@ -ec621f0c3fad619a9ce512be72345138 \ No newline at end of file +3915900ef91f193c987bdeb2a1e8e030 \ No newline at end of file diff --git a/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.png b/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.png index a55fd628d9e26305dad4bad8593bd2601e09297c..4ce88a568ec245539c47321942c340ac12f9132e 100644 Binary files a/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.png and b/LayoutTests/platform/mac/fast/css/shadow-multiple-expected.png differ diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 592bbc6cc2572df79130edec48f6f2bb676cdca5..0bc971466488945c41c23991e4f57a3e48578c5a 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,28 @@ +2011-01-30 Simon Fraser + + 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 Reviewed by Chris Marrin. diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp index 20971e72acf8846ce79948b7d96f9e70a4a17aea..298a89d674498afc6d1622e6b30319dccb3f1400 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.cpp +++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp @@ -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); } +#if !PLATFORM(CG) void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const RoundedIntRect& roundedHoleRect, const Color& color, ColorSpace colorSpace) { if (paintingDisabled()) @@ -635,6 +636,7 @@ void GraphicsContext::fillRectWithRoundedHole(const IntRect& rect, const Rounded setFillRule(oldFillRule); setFillColor(oldFillColor, oldFillColorSpace); } +#endif void GraphicsContext::setCompositeOperation(CompositeOperator compositeOperation) { diff --git a/Source/WebCore/platform/graphics/ShadowBlur.cpp b/Source/WebCore/platform/graphics/ShadowBlur.cpp index c6033d96b3d2567c4092dbd0ee259b3c06761b35..ac9e775c5be2355a29cbc101514f726dca591197 100644 --- a/Source/WebCore/platform/graphics/ShadowBlur.cpp +++ b/Source/WebCore/platform/graphics/ShadowBlur.cpp @@ -407,6 +407,24 @@ void ShadowBlur::drawRectShadow(GraphicsContext* graphicsContext, const FloatRec 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) { GraphicsContext* shadowContext = beginShadowLayer(graphicsContext, shadowedRect); diff --git a/Source/WebCore/platform/graphics/ShadowBlur.h b/Source/WebCore/platform/graphics/ShadowBlur.h index a93eb4d86f61ed9982536e8635daed494c735995..e96c9920724a29ef076e7672d094ababa18c66d9 100644 --- a/Source/WebCore/platform/graphics/ShadowBlur.h +++ b/Source/WebCore/platform/graphics/ShadowBlur.h @@ -49,6 +49,7 @@ public: bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; } void drawRectShadow(GraphicsContext*, const FloatRect&, const RoundedIntRect::Radii&); + void drawInsetShadow(GraphicsContext*, const FloatRect&, const FloatRect& holeRect, const RoundedIntRect::Radii& holeRadii); private: GraphicsContext* beginShadowLayer(GraphicsContext*, const FloatRect& layerArea); diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index cbf467d13ef3d94994a6f23e684e8433f195c1e6..b4acd0f27938aec3e80d664dcf37b7ad3bf4ef1c 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -745,6 +745,50 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef 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) { if (paintingDisabled())