Bug 769922 - Implement nsDisplayAltFeedback, since it can draw outside of the frame's overflow rect. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 29 Aug 2012 17:48:44 +1200
changeset 108563 9bf0072dcd72219dc4d8fdbbdc524516c24a25c0
parent 108562 967b1ef7afdc527e91a3263e6387d8501073c694
child 108564 32c4a08f8e6ec61221fa4816e89d803c2adc4c64
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersroc
bugs769922
milestone18.0a1
Bug 769922 - Implement nsDisplayAltFeedback, since it can draw outside of the frame's overflow rect. r=roc
layout/generic/nsImageFrame.cpp
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1032,16 +1032,43 @@ struct nsRecessedBorder : public nsStyle
       mBorder.Side(side) = aBorderWidth;
       // Note: use SetBorderStyle here because we want to affect
       // mComputedBorder
       SetBorderStyle(side, NS_STYLE_BORDER_STYLE_INSET);
     }
   }
 };
 
+class nsDisplayAltFeedback : public nsDisplayItem {
+public:
+  nsDisplayAltFeedback(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
+    : nsDisplayItem(aBuilder, aFrame) {}
+
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
+  {
+    *aSnap = false;
+    return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
+  }
+
+  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx)
+  {
+    nsImageFrame* f = static_cast<nsImageFrame*>(mFrame);
+    nsEventStates state = f->GetContent()->AsElement()->State();
+    f->DisplayAltFeedback(*aCtx,
+                          mVisibleRect,
+                          IMAGE_OK(state, true)
+                             ? nsImageFrame::gIconLoad->mLoadingImage
+                             : nsImageFrame::gIconLoad->mBrokenImage,
+                          ToReferenceFrame());
+
+  }
+
+  NS_DISPLAY_DECL_NAME("AltFeedback", TYPE_ALT_FEEDBACK)
+};
+
 void
 nsImageFrame::DisplayAltFeedback(nsRenderingContext& aRenderingContext,
                                  const nsRect&        aDirtyRect,
                                  imgIRequest*         aRequest,
                                  nsPoint              aPt)
 {
   // We should definitely have a gIconLoad here.
   NS_ABORT_IF_FALSE(gIconLoad, "How did we succeed in Init then?");
@@ -1146,29 +1173,16 @@ nsImageFrame::DisplayAltFeedback(nsRende
                                                  altText);
       DisplayAltText(PresContext(), aRenderingContext, altText, inner);
     }
   }
 
   aRenderingContext.PopState();
 }
 
-static void PaintAltFeedback(nsIFrame* aFrame, nsRenderingContext* aCtx,
-     const nsRect& aDirtyRect, nsPoint aPt)
-{
-  nsImageFrame* f = static_cast<nsImageFrame*>(aFrame);
-  nsEventStates state = f->GetContent()->AsElement()->State();
-  f->DisplayAltFeedback(*aCtx,
-                        aDirtyRect,
-                        IMAGE_OK(state, true)
-                           ? nsImageFrame::gIconLoad->mLoadingImage
-                           : nsImageFrame::gIconLoad->mBrokenImage,
-                        aPt);
-}
-
 #ifdef DEBUG
 static void PaintDebugImageMap(nsIFrame* aFrame, nsRenderingContext* aCtx,
      const nsRect& aDirtyRect, nsPoint aPt) {
   nsImageFrame* f = static_cast<nsImageFrame*>(aFrame);
   nsRect inner = f->GetInnerArea() + aPt;
 
   aCtx->SetColor(NS_RGB(0, 0, 0));
   aCtx->PushState();
@@ -1360,18 +1374,17 @@ nsImageFrame::BuildDisplayList(nsDisplay
 
     // We should never have the size and not have an image container
     NS_ABORT_IF_FALSE(!haveSize || imgCon, "Have size but not container?");
 
     if (!imageOK || !haveSize) {
       // No image yet, or image load failed. Draw the alt-text and an icon
       // indicating the status
       rv = replacedContent.AppendNewToTop(new (aBuilder)
-          nsDisplayGeneric(aBuilder, this, PaintAltFeedback, "AltFeedback",
-                           nsDisplayItem::TYPE_ALT_FEEDBACK));
+          nsDisplayAltFeedback(aBuilder, this));
       NS_ENSURE_SUCCESS(rv, rv);
     }
     else {
       rv = replacedContent.AppendNewToTop(new (aBuilder)
           nsDisplayImage(aBuilder, this, imgCon));
       NS_ENSURE_SUCCESS(rv, rv);
 
       // If we were previously displaying an icon, we're not anymore