Make nsBoundingMetrics::operator+= handle empty bounds. b=410132, r+sr+a=roc
authorkarlt+@karlt.net
Wed, 02 Jan 2008 20:32:12 -0800
changeset 9770 c468cca91ecae80d9e3b4fa9e373bfe81c5e79ef
parent 9769 bc2dc801c0dc65a266d410efa78330282fb4a030
child 9771 b49923f85daa6d6126eb6f738fee4b364f7ec1eb
push idunknown
push userunknown
push dateunknown
bugs410132
milestone1.9b3pre
Make nsBoundingMetrics::operator+= handle empty bounds. b=410132, r+sr+a=roc
gfx/public/nsIRenderingContext.h
layout/mathml/base/src/nsMathMLTokenFrame.cpp
layout/mathml/base/src/nsMathMLmfencedFrame.cpp
--- a/gfx/public/nsIRenderingContext.h
+++ b/gfx/public/nsIRenderingContext.h
@@ -885,23 +885,28 @@ struct nsBoundingMetrics {
   /* Set all member data to zero */
   void 
   Clear() {
     leftBearing = rightBearing = 0;
     ascent = descent = width = 0;
   }
 
   /* Append another bounding metrics */
-  /* Notice that leftBearing is not set. The user must set leftBearing on 
-     initialization and (repeatedly) use this operator to append 
-     other bounding metrics on the right.
-   */
   void 
   operator += (const nsBoundingMetrics& bm) {
-    if (ascent < bm.ascent) ascent = bm.ascent;
-    if (descent < bm.descent) descent = bm.descent;   
-    rightBearing = PR_MAX(rightBearing, width + bm.rightBearing);
+    if (ascent + descent == 0 && rightBearing - leftBearing == 0) {
+      ascent = bm.ascent;
+      descent = bm.descent;
+      leftBearing = width + bm.leftBearing;
+      rightBearing = width + bm.rightBearing;
+    }
+    else {
+      if (ascent < bm.ascent) ascent = bm.ascent;
+      if (descent < bm.descent) descent = bm.descent;   
+      leftBearing = PR_MIN(leftBearing, width + bm.leftBearing);
+      rightBearing = PR_MAX(rightBearing, width + bm.rightBearing);
+    }
     width += bm.width;
   }
 };
 #endif // MOZ_MATHML
 
 #endif /* nsIRenderingContext_h___ */
--- a/layout/mathml/base/src/nsMathMLTokenFrame.cpp
+++ b/layout/mathml/base/src/nsMathMLTokenFrame.cpp
@@ -124,43 +124,38 @@ nsMathMLTokenFrame::Reflow(nsPresContext
   nsresult rv = NS_OK;
 
   // initializations needed for empty markup like <mtag></mtag>
   aDesiredSize.width = aDesiredSize.height = 0;
   aDesiredSize.ascent = 0;
   aDesiredSize.mBoundingMetrics.Clear();
 
   nsSize availSize(aReflowState.ComputedWidth(), aReflowState.ComputedHeight());
-  PRInt32 count = 0;
   nsIFrame* childFrame = GetFirstChild(nsnull);
   while (childFrame) {
     // ask our children to compute their bounding metrics
     nsHTMLReflowMetrics childDesiredSize(aDesiredSize.mFlags
                                          | NS_REFLOW_CALC_BOUNDING_METRICS);
     nsHTMLReflowState childReflowState(aPresContext, aReflowState,
                                        childFrame, availSize);
     rv = ReflowChild(childFrame, aPresContext, childDesiredSize,
                      childReflowState, aStatus);
     //NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
     if (NS_FAILED(rv)) {
       // Call DidReflow() for the child frames we successfully did reflow.
       DidReflowChildren(GetFirstChild(nsnull), childFrame);
       return rv;
     }
 
-    // origins are used as placeholders to store the child's ascent and descent.
+    // origins are used as placeholders to store the child's ascent.
     childFrame->SetRect(nsRect(0, childDesiredSize.ascent,
                                childDesiredSize.width, childDesiredSize.height));
     // compute and cache the bounding metrics
-    if (0 == count)
-      aDesiredSize.mBoundingMetrics  = childDesiredSize.mBoundingMetrics;
-    else
-      aDesiredSize.mBoundingMetrics += childDesiredSize.mBoundingMetrics;
+    aDesiredSize.mBoundingMetrics += childDesiredSize.mBoundingMetrics;
 
-    count++;
     childFrame = childFrame->GetNextSibling();
   }
 
   // cache the frame's mBoundingMetrics
   mBoundingMetrics = aDesiredSize.mBoundingMetrics;
 
   // place and size children
   FinalizeReflow(*aReflowState.rendContext, aDesiredSize);
--- a/layout/mathml/base/src/nsMathMLmfencedFrame.cpp
+++ b/layout/mathml/base/src/nsMathMLmfencedFrame.cpp
@@ -282,17 +282,16 @@ nsMathMLmfencedFrame::doReflow(nsPresCon
   // Note that we don't use the base method nsMathMLContainerFrame::Reflow()
   // because we want to stretch our fences, separators and stretchy frames using
   // the *same* initial aDesiredSize.mBoundingMetrics. If we were to use the base
   // method here, our stretchy frames will be stretched and placed, and we may
   // end up stretching our fences/separators with a different aDesiredSize.
   // XXX The above decision was revisited in bug 121748 and this code can be
   // refactored to use nsMathMLContainerFrame::Reflow() at some stage.
 
-  PRInt32 count = 0;
   nsReflowStatus childStatus;
   nsSize availSize(aReflowState.ComputedWidth(), aReflowState.ComputedHeight());
   nsIFrame* firstChild = aForFrame->GetFirstChild(nsnull);
   nsIFrame* childFrame = firstChild;
   nscoord ascent = 0, descent = 0;
   if (firstChild || aOpenChar || aCloseChar || aSeparatorsCount > 0) {
     // We use the ASCII metrics to get our minimum height. This way, if we have
     // borders or a background, they will fit better with other elements on the line
@@ -320,20 +319,17 @@ nsMathMLmfencedFrame::doReflow(nsPresCon
                                childDesiredSize.width, childDesiredSize.height));
 
     // compute the bounding metrics right now for mfrac
     nscoord childDescent = childDesiredSize.height - childDesiredSize.ascent;
     if (descent < childDescent)
       descent = childDescent;
     if (ascent < childDesiredSize.ascent)
       ascent = childDesiredSize.ascent;
-    if (0 == count++)
-      aDesiredSize.mBoundingMetrics  = childDesiredSize.mBoundingMetrics;
-    else
-      aDesiredSize.mBoundingMetrics += childDesiredSize.mBoundingMetrics;
+    aDesiredSize.mBoundingMetrics += childDesiredSize.mBoundingMetrics;
 
     childFrame = childFrame->GetNextSibling();
   }
 
   /////////////
   // Ask stretchy children to stretch themselves
 
   nsBoundingMetrics containerSize;