Focus ring for a child layer is incorrectly offset by ancestor composited layer's...
authorwangxianzhu@chromium.org <wangxianzhu@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Feb 2013 20:38:23 +0000 (20:38 +0000)
committerwangxianzhu@chromium.org <wangxianzhu@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Feb 2013 20:38:23 +0000 (20:38 +0000)
https://bugs.webkit.org/show_bug.cgi?id=110895

Reviewed by Simon Fraser.

Source/WebCore:

Test: compositing/sub-layer-focus-ring.html

The problem occurs in RenderBlock::addFocusRingRects() where the absolute position of a sub-layer is used to calculate the focus ring rect of the layer.
Should use the relative position to the current paintContainer instead.

To fix the issue:
- RenderLayer passes LayerPaintingInfo.rootLayer to PaintInfo.paintContainer
- Let RenderObject::paintFocusRing() and RenderObject::paintOutline() take PaintInfo instead of GraphicsContext* so that the paintContainer can be passed
- RenderBlock::addFocusRingRects() uses localToContainerPoint(FloatPoint(), paintContainer) instead of localToAbsolute() to calculate the focus ring rect of a sublayer.

* rendering/PaintInfo.h:
(WebCore):
(WebCore::PaintInfo::PaintInfo): Add a field paintContainer (the RenderLayerModelObject which originates the current painting)
(PaintInfo):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paintObject):
(WebCore::RenderBlock::paintContinuationOutlines):
(WebCore::RenderBlock::addFocusRingRects): Use the added paintContainer parameter to calculate the relative offset of the child layer.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintBackgroundForFragments): Pass LayerPaintingInfo.rootLayer to PaintInfo.paintContainer.
(WebCore::RenderLayer::paintForegroundForFragmentsWithPhase): Ditto.
(WebCore::RenderLayer::paintOutlineForFragments): Ditto.
(WebCore::RenderLayer::paintMaskForFragments): Ditto.
* rendering/RenderLayer.cpp:
* rendering/RenderObject.cpp:
(WebCore::RenderObject::paintFocusRing): Now takes PaintInfo instead of GraphicsContext*. Pass paintInfo.paintContainer to addFocusRingRects().
(WebCore::RenderObject::paintOutline): Now takes PaintInfo instead of GraphicsContext*.
(WebCore::RenderObject::absoluteFocusRingQuads):
* rendering/RenderObject.h:
(WebCore::RenderObject::addFocusRingRects): Add paintContainer parameter.

LayoutTests:

New ref test for the bug.

* compositing/sub-layer-focus-ring-expected.html: Added.
* compositing/sub-layer-focus-ring.html: Added.

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

30 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/sub-layer-focus-ring-expected.html [new file with mode: 0644]
LayoutTests/compositing/sub-layer-focus-ring.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/PaintInfo.h
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderInline.cpp
Source/WebCore/rendering/RenderInline.h
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLineBoxList.cpp
Source/WebCore/rendering/RenderListBox.cpp
Source/WebCore/rendering/RenderListBox.h
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
Source/WebCore/rendering/RenderReplaced.cpp
Source/WebCore/rendering/RenderTable.cpp
Source/WebCore/rendering/RenderTableRow.cpp
Source/WebCore/rendering/RenderTableSection.cpp
Source/WebCore/rendering/RenderTextControl.cpp
Source/WebCore/rendering/RenderTextControl.h
Source/WebCore/rendering/RenderWidget.cpp
Source/WebCore/rendering/svg/RenderSVGContainer.cpp
Source/WebCore/rendering/svg/RenderSVGContainer.h
Source/WebCore/rendering/svg/RenderSVGImage.cpp
Source/WebCore/rendering/svg/RenderSVGImage.h
Source/WebCore/rendering/svg/RenderSVGShape.cpp
Source/WebCore/rendering/svg/RenderSVGShape.h

index 13a5f89..334a7ea 100644 (file)
@@ -1,3 +1,15 @@
+2013-02-28  Xianzhu Wang  <wangxianzhu@chromium.org>
+
+        Focus ring for a child layer is incorrectly offset by ancestor composited layer's position
+        https://bugs.webkit.org/show_bug.cgi?id=110895
+
+        Reviewed by Simon Fraser.
+
+        New ref test for the bug.
+
+        * compositing/sub-layer-focus-ring-expected.html: Added.
+        * compositing/sub-layer-focus-ring.html: Added.
+
 2013-02-28  Justin Novosad  <junov@google.com>
 
         Re-baselining expected pixels for fast/borders/border-radius-percent.html on linux
diff --git a/LayoutTests/compositing/sub-layer-focus-ring-expected.html b/LayoutTests/compositing/sub-layer-focus-ring-expected.html
new file mode 100644 (file)
index 0000000..7f7df15
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.composited {
+  -webkit-transform: translateZ(0);
+}
+
+.outer {
+  position: absolute;
+  width: 500px;
+  height: 300px;
+  top: 60px;
+  left: 100px;
+  background-color: yellow;
+}
+
+.outlined {
+  outline: red auto thin;
+  width: 150px;
+  height: 50px;
+  background-color: lightgrey;
+}
+
+.inner {
+  width: 80px;
+  height: 100px;
+}
+</style>
+</head>
+<body>
+  <!-- Still let outer layer composited to avoid the minor edge pixel diffs. -->
+  <div class="composited outer">
+    <div class="outlined">
+      <div class="inner"></div>
+    </div>
+  </div>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/sub-layer-focus-ring.html b/LayoutTests/compositing/sub-layer-focus-ring.html
new file mode 100644 (file)
index 0000000..be41e90
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.composited {
+  -webkit-transform: translateZ(0);
+}
+
+.outer {
+  position: absolute;
+  width: 500px;
+  height: 300px;
+  top: 60px;
+  left: 100px;
+  background-color: yellow;
+}
+
+.outlined {
+  outline: red auto thin;
+  width: 150px;
+  height: 50px;
+  background-color: lightgrey;
+}
+
+.inner {
+  width: 80px;
+  height: 100px;
+}
+</style>
+</head>
+<body>
+  <!-- The focus ring parts for the sub-layers should be at correct position,
+       regardless whether the inner layer is composited. -->
+  <div class="composited outer">
+    <div class="outlined">
+      <div class="composited inner"></div>
+    </div>
+  </div>
+</body>
+</html>
+
index 3ae8464..8e44f8e 100644 (file)
@@ -1,3 +1,41 @@
+2013-02-28  Xianzhu Wang  <wangxianzhu@chromium.org>
+
+        Focus ring for a child layer is incorrectly offset by ancestor composited layer's position
+        https://bugs.webkit.org/show_bug.cgi?id=110895
+
+        Reviewed by Simon Fraser.
+
+        Test: compositing/sub-layer-focus-ring.html
+
+        The problem occurs in RenderBlock::addFocusRingRects() where the absolute position of a sub-layer is used to calculate the focus ring rect of the layer.
+        Should use the relative position to the current paintContainer instead.
+
+        To fix the issue:
+        - RenderLayer passes LayerPaintingInfo.rootLayer to PaintInfo.paintContainer
+        - Let RenderObject::paintFocusRing() and RenderObject::paintOutline() take PaintInfo instead of GraphicsContext* so that the paintContainer can be passed
+        - RenderBlock::addFocusRingRects() uses localToContainerPoint(FloatPoint(), paintContainer) instead of localToAbsolute() to calculate the focus ring rect of a sublayer.
+
+        * rendering/PaintInfo.h:
+        (WebCore):
+        (WebCore::PaintInfo::PaintInfo): Add a field paintContainer (the RenderLayerModelObject which originates the current painting)
+        (PaintInfo):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::paintObject):
+        (WebCore::RenderBlock::paintContinuationOutlines):
+        (WebCore::RenderBlock::addFocusRingRects): Use the added paintContainer parameter to calculate the relative offset of the child layer.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintBackgroundForFragments): Pass LayerPaintingInfo.rootLayer to PaintInfo.paintContainer.
+        (WebCore::RenderLayer::paintForegroundForFragmentsWithPhase): Ditto.
+        (WebCore::RenderLayer::paintOutlineForFragments): Ditto.
+        (WebCore::RenderLayer::paintMaskForFragments): Ditto.
+        * rendering/RenderLayer.cpp:
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::paintFocusRing): Now takes PaintInfo instead of GraphicsContext*. Pass paintInfo.paintContainer to addFocusRingRects().
+        (WebCore::RenderObject::paintOutline): Now takes PaintInfo instead of GraphicsContext*.
+        (WebCore::RenderObject::absoluteFocusRingQuads):
+        * rendering/RenderObject.h:
+        (WebCore::RenderObject::addFocusRingRects): Add paintContainer parameter.
+
 2013-02-28  David Hyatt  <hyatt@apple.com>
 
         Remove the quirk margin bits from RenderObject and put them back in RenderBlock.
index c51b7fe..8209eaa 100644 (file)
@@ -42,6 +42,7 @@ namespace WebCore {
 
 class OverlapTestRequestClient;
 class RenderInline;
+class RenderLayerModelObject;
 class RenderObject;
 class RenderRegion;
 
@@ -53,8 +54,8 @@ typedef HashMap<OverlapTestRequestClient*, IntRect> OverlapTestRequestMap;
  */
 struct PaintInfo {
     PaintInfo(GraphicsContext* newContext, const IntRect& newRect, PaintPhase newPhase, PaintBehavior newPaintBehavior,
-              RenderObject* newPaintingRoot = 0, RenderRegion* region = 0, ListHashSet<RenderInline*>* newOutlineObjects = 0,
-              OverlapTestRequestMap* overlapTestRequests = 0)
+        RenderObject* newPaintingRoot = 0, RenderRegion* region = 0, ListHashSet<RenderInline*>* newOutlineObjects = 0,
+        OverlapTestRequestMap* overlapTestRequests = 0, const RenderLayerModelObject* newPaintContainer = 0)
         : context(newContext)
         , rect(newRect)
         , phase(newPhase)
@@ -63,6 +64,7 @@ struct PaintInfo {
         , renderRegion(region)
         , outlineObjects(newOutlineObjects)
         , overlapTestRequests(overlapTestRequests)
+        , paintContainer(newPaintContainer)
     {
     }
 
@@ -114,6 +116,7 @@ struct PaintInfo {
     RenderRegion* renderRegion;
     ListHashSet<RenderInline*>* outlineObjects; // used to list outlines that should be painted by a block with inline children
     OverlapTestRequestMap* overlapTestRequests;
+    const RenderLayerModelObject* paintContainer; // the layer object that originates the current painting
 };
 
 } // namespace WebCore
index d221c4e..65f2604 100644 (file)
@@ -3161,7 +3161,7 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs
 
     // 5. paint outline.
     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
-        paintOutline(paintInfo.context, LayoutRect(paintOffset, size()));
+        paintOutline(paintInfo, LayoutRect(paintOffset, size()));
 
     // 6. paint continuation outlines.
     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines)) {
@@ -3184,7 +3184,7 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs
             if (!inlineEnclosedInSelfPaintingLayer && !hasLayer())
                 cb->addContinuationWithOutline(inlineRenderer);
             else if (!inlineRenderer->firstLineBox() || (!inlineEnclosedInSelfPaintingLayer && hasLayer()))
-                inlineRenderer->paintOutline(paintInfo.context, paintOffset - locationOffset() + inlineRenderer->containingBlock()->location());
+                inlineRenderer->paintOutline(paintInfo, paintOffset - locationOffset() + inlineRenderer->containingBlock()->location());
         }
         paintContinuationOutlines(paintInfo, paintOffset);
     }
@@ -3312,7 +3312,7 @@ void RenderBlock::paintContinuationOutlines(PaintInfo& info, const LayoutPoint&
         for ( ; block && block != this; block = block->containingBlock())
             accumulatedPaintOffset.moveBy(block->location());
         ASSERT(block);   
-        flow->paintOutline(info.context, accumulatedPaintOffset);
+        flow->paintOutline(info, accumulatedPaintOffset);
     }
 }
 
@@ -7117,7 +7117,7 @@ LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, La
     return caretRect;
 }
 
-void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset)
+void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
 {
     // For blocks inside inlines, we go ahead and include margins so that we run right up to the
     // inline boxes above and below us (thus getting merged with them to form a single irregular
@@ -7152,16 +7152,16 @@ void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& a
                 FloatPoint pos;
                 // FIXME: This doesn't work correctly with transforms.
                 if (box->layer()) 
-                    pos = curr->localToAbsolute();
+                    pos = curr->localToContainerPoint(FloatPoint(), paintContainer);
                 else
                     pos = FloatPoint(additionalOffset.x() + box->x(), additionalOffset.y() + box->y());
-                box->addFocusRingRects(rects, flooredLayoutPoint(pos));
+                box->addFocusRingRects(rects, flooredLayoutPoint(pos), paintContainer);
             }
         }
     }
 
     if (inlineElementContinuation())
-        inlineElementContinuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + inlineElementContinuation()->containingBlock()->location() - location()));
+        inlineElementContinuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + inlineElementContinuation()->containingBlock()->location() - location()), paintContainer);
 }
 
 RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const
index 367df35..f339baa 100644 (file)
@@ -544,7 +544,7 @@ protected:
     void addOverflowFromInlineChildren();
     void addVisualOverflowFromTheme();
 
-    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
+    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
 
 #if ENABLE(SVG)
     // Only used by RenderSVGText, which explicitely overrides RenderBlock::layoutBlock(), do NOT use for anything else.
index f685359..e7c95cb 100644 (file)
@@ -541,7 +541,7 @@ LayoutRect RenderBox::outlineBoundsForRepaint(const RenderLayerModelObject* repa
     return box;
 }
 
-void RenderBox::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset)
+void RenderBox::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*)
 {
     if (!size().isEmpty())
         rects.append(pixelSnappedIntRect(additionalOffset, size()));
index 8613678..725fdc7 100644 (file)
@@ -162,7 +162,7 @@ public:
 
     // Bounds of the outline box in absolute coords. Respects transforms
     virtual LayoutRect outlineBoundsForRepaint(const RenderLayerModelObject* /*repaintContainer*/, const RenderGeometryMap*) const OVERRIDE;
-    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
+    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
 
     // Use this with caution! No type checking is done!
     RenderBox* previousSiblingBox() const;
index eb130c8..88f819f 100644 (file)
@@ -1365,7 +1365,7 @@ void RenderInline::imageChanged(WrappedImagePtr, const IntRect*)
     repaint();
 }
 
-void RenderInline::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset)
+void RenderInline::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
 {
     AbsoluteRectsGeneratorContext context(rects, additionalOffset);
     generateLineBoxRects(context);
@@ -1375,22 +1375,22 @@ void RenderInline::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&
             FloatPoint pos(additionalOffset);
             // FIXME: This doesn't work correctly with transforms.
             if (curr->hasLayer()) 
-                pos = curr->localToAbsolute();
+                pos = curr->localToContainerPoint(FloatPoint(), paintContainer);
             else if (curr->isBox())
                 pos.move(toRenderBox(curr)->locationOffset());
-            curr->addFocusRingRects(rects, flooredIntPoint(pos));
+            curr->addFocusRingRects(rects, flooredIntPoint(pos), paintContainer);
         }
     }
 
     if (continuation()) {
         if (continuation()->isInline())
-            continuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + continuation()->containingBlock()->location() - containingBlock()->location()));
+            continuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + continuation()->containingBlock()->location() - containingBlock()->location()), paintContainer);
         else
-            continuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + toRenderBox(continuation())->location() - containingBlock()->location()));
+            continuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + toRenderBox(continuation())->location() - containingBlock()->location()), paintContainer);
     }
 }
 
-void RenderInline::paintOutline(GraphicsContext* graphicsContext, const LayoutPoint& paintOffset)
+void RenderInline::paintOutline(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
     if (!hasOutline())
         return;
@@ -1399,10 +1399,11 @@ void RenderInline::paintOutline(GraphicsContext* graphicsContext, const LayoutPo
     if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) {
         if (!theme()->supportsFocusRing(styleToUse)) {
             // Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
-            paintFocusRing(graphicsContext, paintOffset, styleToUse);
+            paintFocusRing(paintInfo, paintOffset, styleToUse);
         }
     }
 
+    GraphicsContext* graphicsContext = paintInfo.context;
     if (graphicsContext->paintingDisabled())
         return;
 
index 39620b6..b54aaa8 100644 (file)
@@ -81,8 +81,8 @@ public:
     
     LayoutSize offsetForInFlowPositionedInline(const RenderBox* child) const;
 
-    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
-    void paintOutline(GraphicsContext*, const LayoutPoint&);
+    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
+    void paintOutline(PaintInfo&, const LayoutPoint&);
 
     using RenderBoxModelObject::continuation;
     using RenderBoxModelObject::setContinuation;
index 43228db..36c855e 100644 (file)
@@ -4027,7 +4027,7 @@ void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen
         
         // Paint the background.
         // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
-        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, localPaintingInfo.region);
+        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
         renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
 
         if (localPaintingInfo.clipToDirtyRect)
@@ -4085,7 +4085,7 @@ void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const L
         if (shouldClip)
             clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
     
-        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, localPaintingInfo.region);
+        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
         if (phase == PaintPhaseForeground)
             paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests;
         renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
@@ -4104,7 +4104,7 @@ void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments,
             continue;
     
         // Paint our own outline
-        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, localPaintingInfo.region);
+        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
         clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.outlineRect, DoNotIncludeSelfForBorderRadius);
         renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
         restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect);
@@ -4124,7 +4124,7 @@ void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, Gr
         
         // Paint the mask.
         // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
-        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, localPaintingInfo.region);
+        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
         renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
         
         if (localPaintingInfo.clipToDirtyRect)
index eb56dfd..7b562b4 100644 (file)
@@ -267,7 +267,7 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn
         ListHashSet<RenderInline*>::iterator end = info.outlineObjects->end();
         for (ListHashSet<RenderInline*>::iterator it = info.outlineObjects->begin(); it != end; ++it) {
             RenderInline* flow = *it;
-            flow->paintOutline(info.context, paintOffset);
+            flow->paintOutline(info, paintOffset);
         }
         info.outlineObjects->clear();
     }
index 51f8e46..f45fda3 100644 (file)
@@ -327,10 +327,10 @@ void RenderListBox::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOf
     }
 }
 
-void RenderListBox::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset)
+void RenderListBox::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
 {
     if (!isSpatialNavigationEnabled(frame()))
-        return RenderBlock::addFocusRingRects(rects, additionalOffset);
+        return RenderBlock::addFocusRingRects(rects, additionalOffset, paintContainer);
 
     HTMLSelectElement* select = selectElement();
 
index 47a7a3d..6ea7c3b 100644 (file)
@@ -82,7 +82,7 @@ private:
 
     virtual void layout();
 
-    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
+    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
 
     virtual bool canBeProgramaticallyScrolled() const { return true; }
     virtual void autoscroll(const IntPoint&);
index 5309a22..aefdb46 100644 (file)
@@ -1090,14 +1090,14 @@ void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1,
     }
 }
 
-void RenderObject::paintFocusRing(GraphicsContext* context, const LayoutPoint& paintOffset, RenderStyle* style)
+void RenderObject::paintFocusRing(PaintInfo& paintInfo, const LayoutPoint& paintOffset, RenderStyle* style)
 {
     Vector<IntRect> focusRingRects;
-    addFocusRingRects(focusRingRects, paintOffset);
+    addFocusRingRects(focusRingRects, paintOffset, paintInfo.paintContainer);
     if (style->outlineStyleIsAuto())
-        context->drawFocusRing(focusRingRects, style->outlineWidth(), style->outlineOffset(), style->visitedDependentColor(CSSPropertyOutlineColor));
+        paintInfo.context->drawFocusRing(focusRingRects, style->outlineWidth(), style->outlineOffset(), style->visitedDependentColor(CSSPropertyOutlineColor));
     else
-        addPDFURLRect(context, unionRect(focusRingRects));
+        addPDFURLRect(paintInfo.context, unionRect(focusRingRects));
 }
 
 void RenderObject::addPDFURLRect(GraphicsContext* context, const LayoutRect& rect)
@@ -1113,23 +1113,20 @@ void RenderObject::addPDFURLRect(GraphicsContext* context, const LayoutRect& rec
     context->setURLForRect(n->document()->completeURL(href), pixelSnappedIntRect(rect));
 }
 
-void RenderObject::paintOutline(GraphicsContext* graphicsContext, const LayoutRect& paintRect)
+void RenderObject::paintOutline(PaintInfo& paintInfo, const LayoutRect& paintRect)
 {
     if (!hasOutline())
         return;
 
     RenderStyle* styleToUse = style();
     LayoutUnit outlineWidth = styleToUse->outlineWidth();
-    EBorderStyle outlineStyle = styleToUse->outlineStyle();
-
-    Color outlineColor = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
 
     int outlineOffset = styleToUse->outlineOffset();
 
     if (styleToUse->outlineStyleIsAuto() || hasOutlineAnnotation()) {
         if (!theme()->supportsFocusRing(styleToUse)) {
             // Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
-            paintFocusRing(graphicsContext, paintRect.location(), styleToUse);
+            paintFocusRing(paintInfo, paintRect.location(), styleToUse);
         }
     }
 
@@ -1146,6 +1143,10 @@ void RenderObject::paintOutline(GraphicsContext* graphicsContext, const LayoutRe
     if (outer.isEmpty())
         return;
 
+    EBorderStyle outlineStyle = styleToUse->outlineStyle();
+    Color outlineColor = styleToUse->visitedDependentColor(CSSPropertyOutlineColor);
+
+    GraphicsContext* graphicsContext = paintInfo.context;
     bool useTransparencyLayer = outlineColor.hasAlpha();
     if (useTransparencyLayer) {
         if (outlineStyle == SOLID) {
@@ -1218,7 +1219,7 @@ void RenderObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
     // descendants.
     FloatPoint absolutePoint = localToAbsolute();
     addFocusRingRects(rects, flooredLayoutPoint(absolutePoint));
-    size_t count = rects.size(); 
+    size_t count = rects.size();
     for (size_t i = 0; i < count; ++i) {
         IntRect rect = rects[i];
         rect.move(-absolutePoint.x(), -absolutePoint.y());
index 1513af9..7a59ff7 100644 (file)
@@ -958,7 +958,7 @@ public:
     // return true if this object requires a new stacking context
     bool createsGroup() const { return isTransparent() || hasMask() || hasFilter() || hasBlendMode(); } 
     
-    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&) { };
+    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& /* additionalOffset */, const RenderLayerModelObject* /* paintContainer */ = 0) { };
 
     LayoutRect absoluteOutlineBounds() const
     {
@@ -982,8 +982,8 @@ protected:
     void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide,
                             Color, EBorderStyle, int adjbw1, int adjbw2, bool antialias = false);
 
-    void paintFocusRing(GraphicsContext*, const LayoutPoint&, RenderStyle*);
-    void paintOutline(GraphicsContext*, const LayoutRect&);
+    void paintFocusRing(PaintInfo&, const LayoutPoint&, RenderStyle*);
+    void paintOutline(PaintInfo&, const LayoutRect&);
     void addPDFURLRect(GraphicsContext*, const LayoutRect&);
     
     virtual LayoutRect viewRect() const;
index 3be91bb..1199f0e 100644 (file)
@@ -123,7 +123,7 @@ void RenderReplaced::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 
     LayoutRect paintRect = LayoutRect(adjustedPaintOffset, size());
     if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
-        paintOutline(paintInfo.context, paintRect);
+        paintOutline(paintInfo, paintRect);
     
     if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection && !canHaveChildren())
         return;
index 128c0e2..21ccd93 100644 (file)
@@ -664,7 +664,7 @@ void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs
 
     // Paint outline.
     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
-        paintOutline(paintInfo.context, LayoutRect(paintOffset, size()));
+        paintOutline(paintInfo, LayoutRect(paintOffset, size()));
 }
 
 void RenderTable::subtractCaptionRect(LayoutRect& rect) const
index 25cc6dc..93c384c 100644 (file)
@@ -238,7 +238,7 @@ void RenderTableRow::paintOutlineForRowIfNeeded(PaintInfo& paintInfo, const Layo
     LayoutPoint adjustedPaintOffset = paintOffset + location();
     PaintPhase paintPhase = paintInfo.phase;
     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && style()->visibility() == VISIBLE)
-        paintOutline(paintInfo.context, LayoutRect(adjustedPaintOffset, size()));
+        paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size()));
 }
 
 void RenderTableRow::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
index 8b3d73b..46e7f57 100644 (file)
@@ -917,7 +917,7 @@ void RenderTableSection::paint(PaintInfo& paintInfo, const LayoutPoint& paintOff
         popContentsClip(paintInfo, phase, adjustedPaintOffset);
 
     if ((phase == PaintPhaseOutline || phase == PaintPhaseSelfOutline) && style()->visibility() == VISIBLE)
-        paintOutline(paintInfo.context, LayoutRect(adjustedPaintOffset, size()));
+        paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size()));
 }
 
 static inline bool compareCellPositions(RenderTableCell* elem1, RenderTableCell* elem2)
index c7c5768..fc0e7d4 100644 (file)
@@ -293,7 +293,7 @@ void RenderTextControl::computePreferredLogicalWidths()
     setPreferredLogicalWidthsDirty(false);
 }
 
-void RenderTextControl::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset)
+void RenderTextControl::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*)
 {
     if (!size().isEmpty())
         rects.append(pixelSnappedIntRect(additionalOffset, size()));
index f1f592e..7a893fa 100644 (file)
@@ -75,7 +75,7 @@ private:
     virtual bool canHaveGeneratedChildren() const OVERRIDE { return false; }
     virtual bool canBeReplacedWithInlineRunIn() const OVERRIDE;
     
-    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
+    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
 
     virtual bool canBeProgramaticallyScrolled() const { return true; }
 
index c8dc5da..c20fbbb 100644 (file)
@@ -287,7 +287,7 @@ void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
     }
 
     if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && hasOutline())
-        paintOutline(paintInfo.context, LayoutRect(adjustedPaintOffset, size()));
+        paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size()));
 
     if (!m_frameView || paintInfo.phase != PaintPhaseForeground)
         return;
index 5069f41..6f03910 100644 (file)
@@ -150,12 +150,12 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, const LayoutPoint&)
     // We should instead disable our clip during PaintPhaseOutline
     if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE) {
         IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRect));
-        paintOutline(paintInfo.context, paintRectInParent);
+        paintOutline(paintInfo, paintRectInParent);
     }
 }
 
 // addFocusRingRects is called from paintOutline and needs to be in the same coordinates as the paintOuline call
-void RenderSVGContainer::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&)
+void RenderSVGContainer::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
 {
     IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRectInLocalCoordinates()));
     if (!paintRectInParent.isEmpty())
index 4d21b79..70e1ec8 100644 (file)
@@ -59,7 +59,7 @@ protected:
 
     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
     virtual void removeChild(RenderObject*) OVERRIDE;
-    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
+    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
 
     virtual FloatRect objectBoundingBox() const { return m_objectBoundingBox; }
     virtual FloatRect strokeBoundingBox() const { return m_strokeBoundingBox; }
index 45db954..c964c18 100644 (file)
@@ -144,7 +144,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, const LayoutPoint&)
         }
 
         if (drawsOutline)
-            paintOutline(childPaintInfo.context, IntRect(boundingBox));
+            paintOutline(childPaintInfo, IntRect(boundingBox));
     }
 }
 
@@ -191,7 +191,7 @@ void RenderSVGImage::imageChanged(WrappedImagePtr, const IntRect*)
     repaint();
 }
 
-void RenderSVGImage::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&)
+void RenderSVGImage::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
 {
     // this is called from paint() after the localTransform has already been applied
     IntRect contentRect = enclosingIntRect(repaintRectInLocalCoordinates());
index 232ad83..9e05b0a 100644 (file)
@@ -60,7 +60,7 @@ private:
     virtual FloatRect repaintRectInLocalCoordinates() const { return m_repaintBoundingBox; }
     virtual FloatRect repaintRectInLocalCoordinatesExcludingSVGShadow() const OVERRIDE { return m_repaintBoundingBoxExcludingShadow; }
 
-    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
+    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
 
     virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
 
index dda972e..3425513 100644 (file)
@@ -297,13 +297,13 @@ void RenderSVGShape::paint(PaintInfo& paintInfo, const LayoutPoint&)
         }
 
         if (drawsOutline)
-            paintOutline(childPaintInfo.context, IntRect(boundingBox));
+            paintOutline(childPaintInfo, IntRect(boundingBox));
     }
 }
 
 // This method is called from inside paintOutline() since we call paintOutline()
 // while transformed to our coord system, return local coords
-void RenderSVGShape::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&)
+void RenderSVGShape::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
 {
     IntRect rect = enclosingIntRect(repaintRectInLocalCoordinates());
     if (!rect.isEmpty())
index 44a3b4a..479da66 100644 (file)
@@ -114,7 +114,7 @@ private:
 
     virtual void layout();
     virtual void paint(PaintInfo&, const LayoutPoint&);
-    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
+    virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
 
     virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);