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 108454 9bf0072dcd72219dc4d8fdbbdc524516c24a25c0
parent 108453 967b1ef7afdc527e91a3263e6387d8501073c694
child 108455 32c4a08f8e6ec61221fa4816e89d803c2adc4c64
push id23564
push useremorley@mozilla.com
push dateFri, 28 Sep 2012 23:09:34 +0000
treeherdermozilla-central@b62b229a4d41 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs769922
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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