Add border-radius-related helper functions to nsIFrame. (Bug 459144, patch 6) r=roc a2.0=blocking:beta6+
authorL. David Baron <dbaron@dbaron.org>
Tue, 07 Sep 2010 15:20:35 -0700
changeset 52131 c15d3e99d3dead5331d44ea57f48707fc225ffbd
parent 52130 be6a7ccc34fe3a68df899036dfbb2478945a9587
child 52132 a118b42abad133da59efb56a5b61b9b6237b2e44
push id15552
push userdbaron@mozilla.com
push dateTue, 07 Sep 2010 22:22:17 +0000
treeherdermozilla-central@ebabfab36a6f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs459144
milestone2.0b6pre
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
Add border-radius-related helper functions to nsIFrame. (Bug 459144, patch 6) r=roc a2.0=blocking:beta6+
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableCellFrame.h
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -814,16 +814,76 @@ nsIFrame::ComputeBorderRadii(const nsSty
     NS_FOR_CSS_HALF_CORNERS(corner) {
       aRadii[corner] *= ratio;
     }
   }
 
   return haveRadius;
 }
 
+/* static */ void
+nsIFrame::InsetBorderRadii(nscoord aRadii[8], const nsMargin &aOffsets)
+{
+  NS_FOR_CSS_SIDES(side) {
+    nscoord offset = aOffsets.side(side);
+    PRUint32 hc1 = NS_SIDE_TO_HALF_CORNER(side, PR_FALSE, PR_FALSE);
+    PRUint32 hc2 = NS_SIDE_TO_HALF_CORNER(side, PR_TRUE, PR_FALSE);
+    aRadii[hc1] = NS_MAX(0, aRadii[hc1] - offset);
+    aRadii[hc2] = NS_MAX(0, aRadii[hc2] - offset);
+  }
+}
+
+/* static */ void
+nsIFrame::OutsetBorderRadii(nscoord aRadii[8], const nsMargin &aOffsets)
+{
+  NS_FOR_CSS_SIDES(side) {
+    nscoord offset = aOffsets.side(side);
+    PRUint32 hc1 = NS_SIDE_TO_HALF_CORNER(side, PR_FALSE, PR_FALSE);
+    PRUint32 hc2 = NS_SIDE_TO_HALF_CORNER(side, PR_TRUE, PR_FALSE);
+    if (aRadii[hc1] > 0)
+      aRadii[hc1] += offset;
+    if (aRadii[hc2] > 0)
+      aRadii[hc2] += offset;
+  }
+}
+
+/* virtual */ PRBool
+nsIFrame::GetBorderRadii(nscoord aRadii[8]) const
+{
+  nsSize size = GetSize();
+  return ComputeBorderRadii(GetStyleBorder()->mBorderRadius, size, size,
+                            GetSkipSides(), aRadii);
+}
+
+PRBool
+nsIFrame::GetPaddingBoxBorderRadii(nscoord aRadii[8]) const
+{
+  if (!GetBorderRadii(aRadii))
+    return PR_FALSE;
+  InsetBorderRadii(aRadii, GetUsedBorder());
+  NS_FOR_CSS_HALF_CORNERS(corner) {
+    if (aRadii[corner])
+      return PR_TRUE;
+  }
+  return PR_FALSE;
+}
+
+PRBool
+nsIFrame::GetContentBoxBorderRadii(nscoord aRadii[8]) const
+{
+  if (!GetBorderRadii(aRadii))
+    return PR_FALSE;
+  InsetBorderRadii(aRadii, GetUsedBorderAndPadding());
+  NS_FOR_CSS_HALF_CORNERS(corner) {
+    if (aRadii[corner])
+      return PR_TRUE;
+  }
+  return PR_FALSE;
+}
+
 nsStyleContext*
 nsFrame::GetAdditionalStyleContext(PRInt32 aIndex) const
 {
   NS_PRECONDITION(aIndex >= 0, "invalid index number");
   return nsnull;
 }
 
 void
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -928,23 +928,52 @@ public:
    * space than aBorderArea, according to the algorithm in css3-background.
    *
    * aFrameSize is used as the basis for percentage widths and heights.
    * aBorderArea is used for the adjustment of radii that might be too
    * large.
    * FIXME: In the long run, we can probably get away with only one of
    * these, especially if we change the way we handle outline-radius (by
    * removing it and inflating the border radius)
+   *
+   * Return whether any radii are nonzero.
    */
   static PRBool ComputeBorderRadii(const nsStyleCorners& aBorderRadius,
                                    const nsSize& aFrameSize,
                                    const nsSize& aBorderArea,
                                    PRIntn aSkipSides,
                                    nscoord aRadii[8]);
 
+  /*
+   * Given a set of border radii for one box (e.g., border box), convert
+   * it to the equivalent set of radii for another box (e.g., in to
+   * padding box, out to outline box) by reducing radii or increasing
+   * nonzero radii as appropriate.
+   *
+   * Indices into aRadii are the NS_CORNER_* constants in nsStyleConsts.h
+   *
+   * Note that InsetBorderRadii is lossy, since it can turn nonzero
+   * radii into zero, and OutsetBorderRadii does not inflate zero radii.
+   * Therefore, callers should always inset or outset directly from the
+   * original value coming from style.
+   */
+  static void InsetBorderRadii(nscoord aRadii[8], const nsMargin &aOffsets);
+  static void OutsetBorderRadii(nscoord aRadii[8], const nsMargin &aOffsets);
+
+  /**
+   * Fill in border radii for this frame.  Return whether any are
+   * nonzero.
+   *
+   * Indices into aRadii are the NS_CORNER_* constants in nsStyleConsts.h
+   */
+  virtual PRBool GetBorderRadii(nscoord aRadii[8]) const;
+
+  PRBool GetPaddingBoxBorderRadii(nscoord aRadii[8]) const;
+  PRBool GetContentBoxBorderRadii(nscoord aRadii[8]) const;
+
   /**
    * Get the position of the frame's baseline, relative to the top of
    * the frame (its top border edge).  Only valid when Reflow is not
    * needed and when the frame returned nsHTMLReflowMetrics::
    * ASK_FOR_BASELINE as ascent in its reflow metrics.
    */
   virtual nscoord GetBaseline() const = 0;
 
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -1076,16 +1076,25 @@ nsBCTableCellFrame::GetType() const
 /* virtual */ nsMargin
 nsBCTableCellFrame::GetUsedBorder() const
 {
   nsMargin result;
   GetBorderWidth(result);
   return result;
 }
 
+/* virtual */ PRBool
+nsBCTableCellFrame::GetBorderRadii(nscoord aRadii[8]) const
+{
+  NS_FOR_CSS_HALF_CORNERS(corner) {
+    aRadii[corner] = 0;
+  }
+  return PR_FALSE;
+}
+
 #ifdef DEBUG
 NS_IMETHODIMP
 nsBCTableCellFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("BCTableCell"), aResult);
 }
 #endif
 
--- a/layout/tables/nsTableCellFrame.h
+++ b/layout/tables/nsTableCellFrame.h
@@ -317,16 +317,17 @@ public:
 
   nsBCTableCellFrame(nsStyleContext* aContext);
 
   ~nsBCTableCellFrame();
 
   virtual nsIAtom* GetType() const;
 
   virtual nsMargin GetUsedBorder() const;
+  virtual PRBool GetBorderRadii(nscoord aRadii[8]) const;
 
   // Get the *inner half of the border only*, in twips.
   virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const;
 
   // Get the *inner half of the border only*, in pixels.
   BCPixelSize GetBorderWidth(mozilla::css::Side aSide) const;
 
   // Set the full (both halves) width of the border