Bug 840272 - Avoid asserting and crashing if SVG text frames are painted before they are reflowed. r=roc
authorCameron McCormack <cam@mcc.id.au>
Tue, 12 Feb 2013 15:21:58 +1100
changeset 121588 44af3765d3d30dca92e390a532c3a49b03f396f3
parent 121587 328742b12ef546892628fd33327eaa63c22ecc15
child 121589 9672b9989f3436fb3792a2bc4a688a907639a984
push id24296
push useremorley@mozilla.com
push dateTue, 12 Feb 2013 14:43:19 +0000
treeherderautoland@860d7a47b675 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs840272
milestone21.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 840272 - Avoid asserting and crashing if SVG text frames are painted before they are reflowed. r=roc
layout/svg/nsSVGTextFrame2.cpp
--- a/layout/svg/nsSVGTextFrame2.cpp
+++ b/layout/svg/nsSVGTextFrame2.cpp
@@ -2822,17 +2822,22 @@ nsSVGTextFrame2::Init(nsIContent* aConte
   return rv;
 }
 
 NS_IMETHODIMP
 nsSVGTextFrame2::BuildDisplayList(nsDisplayListBuilder* aBuilder,
                                   const nsRect& aDirtyRect,
                                   const nsDisplayListSet& aLists)
 {
-  NS_ASSERTION(!NS_SUBTREE_DIRTY(this), "reflow should have happened");
+  if (NS_SUBTREE_DIRTY(this)) {
+    // We can sometimes be asked to paint before reflow happens and we
+    // have updated mPositions, etc.  In this case, we just avoid
+    // painting.
+    return NS_OK;
+  }
   return aLists.Content()->AppendNewToTop(
            new (aBuilder) nsDisplaySVGText(aBuilder, this));
 }
 
 NS_IMETHODIMP
 nsSVGTextFrame2::AttributeChanged(int32_t aNameSpaceID,
                                   nsIAtom* aAttribute,
                                   int32_t aModType)
@@ -3095,18 +3100,21 @@ nsSVGTextFrame2::PaintSVG(nsRenderingCon
   gfxMatrix initialMatrix = gfx->CurrentMatrix();
 
   AutoCanvasTMForMarker autoCanvasTMFor(this, FOR_PAINTING);
 
   if (mState & NS_STATE_SVG_NONDISPLAY_CHILD) {
     // Text frames inside <clipPath>, <mask>, etc. will never have had
     // ReflowSVG called on them, so call UpdateGlyphPositioning to do this now.
     UpdateGlyphPositioning(true);
-  } else {
-    NS_ASSERTION(!NS_SUBTREE_DIRTY(this), "reflow should have happened");
+  } else if (NS_SUBTREE_DIRTY(this)) {
+    // If we are asked to paint before reflow has recomputed mPositions etc.
+    // directly via PaintSVG, rather than via a display list, then we need
+    // to bail out here too.
+    return NS_OK;
   }
 
   gfxMatrix canvasTM = GetCanvasTM(FOR_PAINTING);
   if (canvasTM.IsSingular()) {
     NS_WARNING("Can't render text element!");
     return NS_ERROR_FAILURE;
   }