REGRESSION (r107836): fast/box-shadow/spread.html and fast/writing-mode/box-shadow...
authormitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Feb 2012 03:32:07 +0000 (03:32 +0000)
committermitz@apple.com <mitz@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Feb 2012 03:32:07 +0000 (03:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=78759

Reviewed by Simon Fraser.

* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::boxShadowCanBeAppliedToBackground): Added. Returns false if
paintFillLayer() would push a clip before painting the layer, thus preventing it from casting
its own shadow.
(WebCore::InlineFlowBox::paintBoxDecorations): Pass this as an additional parameter to
boxShadowShouldBeAppliedToBackground().
* rendering/InlineFlowBox.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended): Pass the InlineFlowBox along to
boxShadowShouldBeAppliedToBackground().
(WebCore::RenderBoxModelObject::boxShadowShouldBeAppliedToBackground): Added an InlineFlowBox
parameter. If non-0, check boxShadowCanBeAppliedToBackground(). Also check for shadow spread,
and for the case of border radius with a background image, in which paintFillLayerExtended uses
clipping. Finally, fixed a bug in the for() loop for finding the last background layer which
was noticed by Tony Chang.
* rendering/RenderBoxModelObject.h:
* rendering/RenderTableCell.cpp:
(WebCore::RenderTableCell::boxShadowShouldBeAppliedToBackground):
* rendering/RenderTableCell.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@107874 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/rendering/InlineFlowBox.cpp
Source/WebCore/rendering/InlineFlowBox.h
Source/WebCore/rendering/RenderBoxModelObject.cpp
Source/WebCore/rendering/RenderBoxModelObject.h
Source/WebCore/rendering/RenderTableCell.cpp
Source/WebCore/rendering/RenderTableCell.h

index 81b85cf..691a3db 100644 (file)
@@ -1,3 +1,30 @@
+2012-02-15  Dan Bernstein  <mitz@apple.com>
+
+        REGRESSION (r107836): fast/box-shadow/spread.html and fast/writing-mode/box-shadow-*.html tests failing
+        https://bugs.webkit.org/show_bug.cgi?id=78759
+
+        Reviewed by Simon Fraser.
+
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::boxShadowCanBeAppliedToBackground): Added. Returns false if
+        paintFillLayer() would push a clip before painting the layer, thus preventing it from casting
+        its own shadow.
+        (WebCore::InlineFlowBox::paintBoxDecorations): Pass this as an additional parameter to
+        boxShadowShouldBeAppliedToBackground().
+        * rendering/InlineFlowBox.h:
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::paintFillLayerExtended): Pass the InlineFlowBox along to
+        boxShadowShouldBeAppliedToBackground().
+        (WebCore::RenderBoxModelObject::boxShadowShouldBeAppliedToBackground): Added an InlineFlowBox
+        parameter. If non-0, check boxShadowCanBeAppliedToBackground(). Also check for shadow spread,
+        and for the case of border radius with a background image, in which paintFillLayerExtended uses
+        clipping. Finally, fixed a bug in the for() loop for finding the last background layer which
+        was noticed by Tony Chang.
+        * rendering/RenderBoxModelObject.h:
+        * rendering/RenderTableCell.cpp:
+        (WebCore::RenderTableCell::boxShadowShouldBeAppliedToBackground):
+        * rendering/RenderTableCell.h:
+
 2012-02-15  Erik Arvidsson  <arv@chromium.org>
 
         Expose Window constructor
index 0d8e861..bbe6219 100644 (file)
@@ -1079,6 +1079,15 @@ void InlineFlowBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c,
     paintFillLayer(paintInfo, c, fillLayer, rect, op);
 }
 
+bool InlineFlowBox::boxShadowCanBeAppliedToBackground(const FillLayer& lastBackgroundLayer) const
+{
+    // The checks here match how paintFillLayer() decides whether to clip (if it does, the shadow
+    // would be clipped out, so it has to be drawn separately).
+    StyleImage* image = lastBackgroundLayer.image();
+    bool hasFillImage = image && image->canRender(renderer(), renderer()->style()->effectiveZoom());
+    return (!hasFillImage && !renderer()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent();
+}
+
 void InlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, const LayoutRect& rect, CompositeOperator op)
 {
     StyleImage* img = fillLayer->image();
@@ -1203,7 +1212,7 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&
     if ((!parent() && m_firstLine && styleToUse != renderer()->style()) || (parent() && renderer()->hasBoxDecorations())) {
         LayoutRect paintRect = LayoutRect(adjustedPaintoffset, frameRect.size());
         // Shadow comes first and is behind the background and border.
-        if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedNone))
+        if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedNone, this))
             paintBoxShadow(paintInfo, styleToUse, Normal, paintRect);
 
         Color c = styleToUse->visitedDependentColor(CSSPropertyBackgroundColor);
index 2ea5c47..500de7e 100644 (file)
@@ -114,6 +114,8 @@ public:
     virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom);
 
+    bool boxShadowCanBeAppliedToBackground(const FillLayer&) const;
+
     virtual RenderLineBoxList* rendererLineBoxes() const;
 
     // logicalLeft = left in a horizontal line and top in a vertical line.
index 63a7386..4e38bf3 100644 (file)
@@ -682,7 +682,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
         if (!colorVisible)
             return;
 
-        bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppliedToBackground(bleedAvoidance);
+        bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppliedToBackground(bleedAvoidance, box);
         GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAppliedToBackground);
         if (boxShadowShouldBeAppliedToBackground)
             applyBoxShadowForBackground(context, style());
@@ -796,7 +796,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
     // Paint the color first underneath all images.
     if (!bgLayer->next()) {
         IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect));
-        bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppliedToBackground(bleedAvoidance);
+        bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppliedToBackground(bleedAvoidance, box);
         if (!boxShadowShouldBeAppliedToBackground)
             backgroundRect.intersect(paintInfo.rect);
 
@@ -2581,7 +2581,7 @@ bool RenderBoxModelObject::borderObscuresBackground() const
     return true;
 }
 
-bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance bleedAvoidance) const
+bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* inlineFlowBox) const
 {
     if (bleedAvoidance != BackgroundBleedNone)
         return false;
@@ -2589,14 +2589,17 @@ bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(BackgroundBleedA
     if (style()->hasAppearance())
         return false;
 
-    const ShadowData* boxShadow = style()->boxShadow();
     bool hasOneNormalBoxShadow = false;
-    for (const ShadowData* currentShadow = boxShadow; currentShadow; currentShadow = currentShadow->next()) {
+    for (const ShadowData* currentShadow = style()->boxShadow(); currentShadow; currentShadow = currentShadow->next()) {
         if (currentShadow->style() != Normal)
             continue;
+
         if (hasOneNormalBoxShadow)
             return false;
         hasOneNormalBoxShadow = true;
+
+        if (currentShadow->spread())
+            return false;
     }
 
     if (!hasOneNormalBoxShadow)
@@ -2607,12 +2610,18 @@ bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(BackgroundBleedA
         return false;
 
     const FillLayer* lastBackgroundLayer = style()->backgroundLayers();
-    for (const FillLayer* next = lastBackgroundLayer->next(); next; )
+    for (const FillLayer* next = lastBackgroundLayer->next(); next; next = lastBackgroundLayer->next())
         lastBackgroundLayer = next;
 
     if (lastBackgroundLayer->clip() != BorderFillBox)
         return false;
 
+    if (lastBackgroundLayer->image() && style()->hasBorderRadius())
+        return false;
+
+    if (inlineFlowBox && !inlineFlowBox->boxShadowCanBeAppliedToBackground(*lastBackgroundLayer))
+        return false;
+
     if (hasOverflowClip() && lastBackgroundLayer->attachment() == LocalBackgroundAttachment)
         return false;
 
index c1d0497..12447a1 100644 (file)
@@ -127,7 +127,7 @@ public:
     void paintBoxShadow(const PaintInfo&, const LayoutRect&, const RenderStyle*, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
     void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox* = 0, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);
     
-    virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance) const;
+    virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox* = 0) const;
 
     // Overridden by subclasses to determine line height and baseline position.
     virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
index 0fef8ad..e9954d2 100644 (file)
@@ -1068,7 +1068,7 @@ void RenderTableCell::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOf
     paintMaskImages(paintInfo, LayoutRect(paintOffset, size()));
 }
 
-bool RenderTableCell::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance) const
+bool RenderTableCell::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox*) const
 {
     return false;
 }
index 6bfbf1e..5407e5d 100644 (file)
@@ -151,7 +151,7 @@ private:
     virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&);
     virtual void paintMask(PaintInfo&, const LayoutPoint&);
 
-    virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance) const OVERRIDE;
+    virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox*) const OVERRIDE;
 
     virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&) const;
     virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const;