diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp
index dc38326bc910..e14927974161 100644
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -761,13 +761,8 @@ nsGenericHTMLElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
// work more like IE if we don't do this, so lets try this and see
// if people agree.
const nsStyleBorder* border = frame->GetStyleBorder();
-
- if (eStyleUnit_Coord == border->mBorder.GetLeftUnit()) {
- origin.x += border->mBorder.GetLeft(coord).GetCoordValue();
- }
- if (eStyleUnit_Coord == border->mBorder.GetTopUnit()) {
- origin.y += border->mBorder.GetTop(coord).GetCoordValue();
- }
+ origin.x += border->GetBorderWidth(NS_SIDE_LEFT);
+ origin.y += border->GetBorderWidth(NS_SIDE_TOP);
#endif
// And subtract out the border for the parent
@@ -780,12 +775,8 @@ nsGenericHTMLElement::GetOffsetRect(nsRect& aRect, nsIContent** aOffsetParent)
if (includeBorder) {
const nsStyleBorder* border = parent->GetStyleBorder();
- if (eStyleUnit_Coord == border->mBorder.GetLeftUnit()) {
- origin.x -= border->mBorder.GetLeft(coord).GetCoordValue();
- }
- if (eStyleUnit_Coord == border->mBorder.GetTopUnit()) {
- origin.y -= border->mBorder.GetTop(coord).GetCoordValue();
- }
+ origin.x -= border->GetBorderWidth(NS_SIDE_LEFT);
+ origin.y -= border->GetBorderWidth(NS_SIDE_TOP);
}
}
diff --git a/gfx/public/gfxCore.h b/gfx/public/gfxCore.h
index 89a5345c655d..0e622e0fa7a7 100644
--- a/gfx/public/gfxCore.h
+++ b/gfx/public/gfxCore.h
@@ -40,6 +40,12 @@
#include "nscore.h"
+// Side constants for use in various places
+#define NS_SIDE_TOP 0
+#define NS_SIDE_RIGHT 1
+#define NS_SIDE_BOTTOM 2
+#define NS_SIDE_LEFT 3
+
#ifdef _IMPL_NS_GFX
#define NS_GFX NS_EXPORT
#define NS_GFX_(type) NS_EXPORT_(type)
diff --git a/gfx/public/nsMargin.h b/gfx/public/nsMargin.h
index d20466b3c130..11206bf208e8 100644
--- a/gfx/public/nsMargin.h
+++ b/gfx/public/nsMargin.h
@@ -39,9 +39,10 @@
#define NSMARGIN_H
#include "nsCoord.h"
+#include "gfxCore.h"
struct nsMargin {
- nscoord left, top, right, bottom;
+ nscoord top, right, bottom, left;
// Constructors
nsMargin() {}
@@ -57,6 +58,23 @@ struct nsMargin {
nscoord aRight, nscoord aBottom) {left += aLeft; top += aTop;
right += aRight; bottom += aBottom;}
+ nscoord& side(PRUint8 aSide) {
+ NS_PRECONDITION(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 &&
+ NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3,
+ "Unexpected side constants");
+ NS_PRECONDITION(aSide <= NS_SIDE_LEFT, "Out of range side");
+ return *(&top + aSide);
+ }
+
+#if (NS_SIDE_TOP == 0) && (NS_SIDE_RIGHT == 1) && (NS_SIDE_BOTTOM == 2) && (NS_SIDE_LEFT == 3)
+ nscoord side(PRUint8 aSide) const {
+ NS_PRECONDITION(aSide <= NS_SIDE_LEFT, "Out of range side");
+ return *(&top + aSide);
+ }
+#else
+#error "Somebody changed the side constants."
+#endif
+
// Overloaded operators. Note that '=' isn't defined so we'll get the
// compiler generated default assignment operator
PRBool operator==(const nsMargin& aMargin) const {
@@ -89,7 +107,7 @@ struct nsMargin {
#ifdef NS_COORD_IS_FLOAT
struct nsIntMargin {
- PRInt32 left, top, right, bottom;
+ PRInt32 top, right, bottom, left;
// Constructors
nsIntMargin() {}
diff --git a/gfx/src/shared/nsNativeTheme.cpp b/gfx/src/shared/nsNativeTheme.cpp
index e9829d96459b..98e629a87551 100644
--- a/gfx/src/shared/nsNativeTheme.cpp
+++ b/gfx/src/shared/nsNativeTheme.cpp
@@ -314,8 +314,7 @@ nsNativeTheme::IsWidgetStyled(nsPresContext* aPresContext, nsIFrame* aFrame,
}
// Check whether border size differs from default
- nsMargin borderSize;
- if (ourBorder->GetBorder(borderSize) && borderSize != defaultBorderSize)
+ if (ourBorder->GetBorder() != defaultBorderSize)
return PR_TRUE;
}
}
diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp
index 1712d5abc426..0c8f09063d78 100644
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2818,9 +2818,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
if (aColor.mBackgroundClip != NS_STYLE_BG_CLIP_BORDER) {
NS_ASSERTION(aColor.mBackgroundClip == NS_STYLE_BG_CLIP_PADDING,
"unknown background-clip value");
- nsMargin border;
- aBorder.GetBorder(border);
- bgClipArea.Deflate(border);
+ bgClipArea.Deflate(aBorder.GetBorder());
}
}
@@ -2895,12 +2893,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
// Background images are tiled over the 'background-clip' area
// but the origin of the tiling is based on the 'background-origin' area
if (aColor.mBackgroundOrigin != NS_STYLE_BG_ORIGIN_BORDER) {
- nsMargin border;
- if (!aBorder.GetBorder(border)) {
- NS_NOTYETIMPLEMENTED("percentage border");
- }
-
- bgOriginArea.Deflate(border);
+ bgOriginArea.Deflate(aBorder.GetBorder());
if (aColor.mBackgroundOrigin != NS_STYLE_BG_ORIGIN_PADDING) {
nsMargin padding;
// XXX CalcPaddingFor is deprecated, but we need it for percentage padding
@@ -3035,9 +3028,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
// Take the border out of the frame's rect
const nsStyleBorder* borderStyle = firstRootElementFrame->GetStyleBorder();
- nsMargin border;
- borderStyle->GetBorder(border);
- firstRootElementFrameArea.Deflate(border);
+ firstRootElementFrameArea.Deflate(borderStyle->GetBorder());
// Get the anchor point
ComputeBackgroundAnchorPoint(aColor, firstRootElementFrameArea, bgClipArea, tileWidth, tileHeight, anchor);
@@ -3271,9 +3262,7 @@ nsCSSRendering::PaintBackgroundColor(nsPresContext* aPresContext,
// to show the parent's background-color instead of its background-color.
// This seems wrong, but we handle that here by explictly clipping the
// background to the padding area.
- nsMargin border;
- aBorder.GetBorder(border);
- bgClipArea.Deflate(border);
+ bgClipArea.Deflate(aBorder.GetBorder());
}
nscolor color = aColor.mBackgroundColor;
@@ -3324,16 +3313,9 @@ nsCSSRendering::PaintRoundedBackground(nsPresContext* aPresContext,
// Get the radius to the outer edge of the padding.
// -moz-border-radius is the radius to the outer edge of the border.
- nsMargin border;
- aBorder.GetBorder(border);
- aTheRadius[NS_SIDE_TOP] -= border.top;
- aTheRadius[NS_SIDE_RIGHT] -= border.right;
- aTheRadius[NS_SIDE_BOTTOM] -= border.bottom;
- aTheRadius[NS_SIDE_LEFT] -= border.left;
- for (PRUint8 i = 0; i < 4; ++i) {
- if (aTheRadius[i] < 0) {
- aTheRadius[i] = 0;
- }
+ NS_FOR_CSS_SIDES(side) {
+ aTheRadius[side] -= aBorder.GetBorderWidth(side);
+ aTheRadius[side] = PR_MAX(aTheRadius[side], 0);
}
}
diff --git a/layout/base/nsStyleConsts.h b/layout/base/nsStyleConsts.h
index 980595e8ef49..cedadc02816e 100644
--- a/layout/base/nsStyleConsts.h
+++ b/layout/base/nsStyleConsts.h
@@ -230,7 +230,7 @@
#define NS_STYLE_BORDER_COLLAPSE 0
#define NS_STYLE_BORDER_SEPARATE 1
-// See nsStyleBorder mBorder enum values
+// Possible enumerated specified values of border-*-width, used by nsCSSMargin
#define NS_STYLE_BORDER_WIDTH_THIN 0
#define NS_STYLE_BORDER_WIDTH_MEDIUM 1
#define NS_STYLE_BORDER_WIDTH_THICK 2
diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp
index 0f3b6368b8c7..c550dbd2ae13 100644
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -194,17 +194,14 @@ nsFieldSetFrame::Paint(nsPresContext* aPresContext,
const nsStyleBorder* borderStyle = GetStyleBorder();
const nsStylePadding* paddingStyle = GetStylePadding();
- nsMargin border;
- if (!borderStyle->GetBorder(border)) {
- NS_NOTYETIMPLEMENTED("percentage border");
- }
+ nscoord topBorder = borderStyle->GetBorderWidth(NS_SIDE_TOP);
nscoord yoff = 0;
// if the border is smaller than the legend. Move the border down
// to be centered on the legend.
- if (border.top < mLegendRect.height)
- yoff = (mLegendRect.height - border.top)/2;
+ if (topBorder < mLegendRect.height)
+ yoff = (mLegendRect.height - topBorder)/2;
nsRect rect(0, yoff, mRect.width, mRect.height - yoff);
@@ -224,7 +221,7 @@ nsFieldSetFrame::Paint(nsPresContext* aPresContext,
// draw left side
nsRect clipRect(rect);
clipRect.width = legendRect.x - rect.x;
- clipRect.height = border.top;
+ clipRect.height = topBorder;
aRenderingContext.PushState();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);
@@ -238,7 +235,7 @@ nsFieldSetFrame::Paint(nsPresContext* aPresContext,
clipRect = rect;
clipRect.x = legendRect.x + legendRect.width;
clipRect.width -= (legendRect.x + legendRect.width);
- clipRect.height = border.top;
+ clipRect.height = topBorder;
aRenderingContext.PushState();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);
@@ -250,8 +247,8 @@ nsFieldSetFrame::Paint(nsPresContext* aPresContext,
// draw bottom
clipRect = rect;
- clipRect.y += border.top;
- clipRect.height = mRect.height - (yoff + border.top);
+ clipRect.y += topBorder;
+ clipRect.height = mRect.height - (yoff + topBorder);
aRenderingContext.PushState();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);
diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp
index d6bb5219ea62..e6626d282aa5 100644
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -257,10 +257,6 @@ nsAbsoluteContainingBlock::ReflowingAbsolutesOnly(nsIFrame* aDelegatingFrame,
return PR_TRUE;
}
-static PRBool IsFixedBorderSize(nsStyleUnit aUnit) {
- return aUnit == eStyleUnit_Coord || aUnit == eStyleUnit_Enumerated
- || aUnit == eStyleUnit_Null;
-}
static PRBool IsFixedPaddingSize(nsStyleUnit aUnit) {
return aUnit == eStyleUnit_Coord || aUnit == eStyleUnit_Null;
}
@@ -298,7 +294,6 @@ nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
// skip getting style data
return PR_FALSE;
}
- const nsStyleBorder* border = f->GetStyleBorder();
const nsStylePadding* padding = f->GetStylePadding();
const nsStyleMargin* margin = f->GetStyleMargin();
if (aCBWidthChanged) {
@@ -306,11 +301,10 @@ nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
// If border-left, border-right, padding-left, padding-right,
// width, min-width, and max-width are all lengths, 'none', or enumerated,
// then our frame width does not depend on the parent width.
+ // Note that borders never depend on the parent width
if (pos->mWidth.GetUnit() != eStyleUnit_Coord ||
pos->mMinWidth.GetUnit() != eStyleUnit_Coord ||
!IsFixedMaxSize(pos->mMaxWidth.GetUnit()) ||
- !IsFixedBorderSize(border->mBorder.GetLeftUnit()) ||
- !IsFixedBorderSize(border->mBorder.GetRightUnit()) ||
!IsFixedPaddingSize(padding->mPadding.GetLeftUnit()) ||
!IsFixedPaddingSize(padding->mPadding.GetRightUnit())) {
return PR_TRUE;
@@ -346,14 +340,13 @@ nsAbsoluteContainingBlock::FrameDependsOnContainer(nsIFrame* f,
// min-height, and max-height are all lengths or 'none',
// and height is a length or height and bottom are auto and top is not auto,
// then our frame height does not depend on the parent height.
+ // Note that borders never depend on the parent height
if (!(pos->mHeight.GetUnit() == eStyleUnit_Coord ||
(pos->mHeight.GetUnit() == eStyleUnit_Auto &&
pos->mOffset.GetBottomUnit() == eStyleUnit_Auto &&
pos->mOffset.GetTopUnit() != eStyleUnit_Auto)) ||
pos->mMinHeight.GetUnit() != eStyleUnit_Coord ||
!IsFixedMaxSize(pos->mMaxHeight.GetUnit()) ||
- !IsFixedBorderSize(border->mBorder.GetTopUnit()) ||
- !IsFixedBorderSize(border->mBorder.GetBottomUnit()) ||
!IsFixedPaddingSize(padding->mPadding.GetTopUnit()) ||
!IsFixedPaddingSize(padding->mPadding.GetBottomUnit())) {
return PR_TRUE;
@@ -494,11 +487,8 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
#endif // DEBUG
nsresult rv;
- nsMargin border;
// Get the border values
- if (!aReflowState.mStyleBorder->GetBorder(border)) {
- NS_NOTYETIMPLEMENTED("percentage border");
- }
+ const nsMargin& border = aReflowState.mStyleBorder->GetBorder();
nscoord availWidth = aReflowState.mComputedWidth;
enum { NOT_SHRINK_TO_FIT, SHRINK_TO_FIT_AVAILWIDTH, SHRINK_TO_FIT_MEW };
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index 43925d28cee1..fc8f3d3925b8 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -584,10 +584,7 @@ CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
nsSize cbSize(aFrameSize);
// Containing block is relative to the padding edge
- nsMargin border;
- if (!aReflowState.mStyleBorder->GetBorder(border)) {
- NS_NOTYETIMPLEMENTED("percentage border");
- }
+ const nsMargin& border = aReflowState.mStyleBorder->GetBorder();
cbSize.width -= border.left + border.right;
cbSize.height -= border.top + border.bottom;
@@ -1137,10 +1134,7 @@ IsPercentageAwareChild(const nsIFrame* aFrame)
return PR_TRUE;
}
- const nsStyleBorder* border = aFrame->GetStyleBorder();
- if (nsLineLayout::IsPercentageUnitSides(&border->mBorder)) {
- return PR_TRUE;
- }
+ // Note that borders can't be aware of percentages
const nsStylePosition* pos = aFrame->GetStylePosition();
@@ -3011,12 +3005,6 @@ nsBlockFrame::AttributeChanged(nsIContent* aChild,
return rv;
}
-inline PRBool
-IsBorderZero(nsStyleUnit aUnit, nsStyleCoord &aCoord)
-{
- return ((aUnit == eStyleUnit_Coord && aCoord.GetCoordValue() == 0));
-}
-
inline PRBool
IsPaddingZero(nsStyleUnit aUnit, nsStyleCoord &aCoord)
{
@@ -3070,12 +3058,8 @@ nsBlockFrame::IsSelfEmpty()
const nsStyleBorder* border = GetStyleBorder();
const nsStylePadding* padding = GetStylePadding();
nsStyleCoord coord;
- if ((border->IsBorderSideVisible(NS_SIDE_TOP) &&
- !IsBorderZero(border->mBorder.GetTopUnit(),
- border->mBorder.GetTop(coord))) ||
- (border->IsBorderSideVisible(NS_SIDE_BOTTOM) &&
- !IsBorderZero(border->mBorder.GetBottomUnit(),
- border->mBorder.GetBottom(coord))) ||
+ if (border->GetBorderWidth(NS_SIDE_TOP) != 0 ||
+ border->GetBorderWidth(NS_SIDE_BOTTOM) != 0 ||
!IsPaddingZero(padding->mPadding.GetTopUnit(),
padding->mPadding.GetTop(coord)) ||
!IsPaddingZero(padding->mPadding.GetBottomUnit(),
diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp
index 7d638c4fcb4b..54fc66188c89 100644
--- a/layout/generic/nsBlockReflowState.cpp
+++ b/layout/generic/nsBlockReflowState.cpp
@@ -258,9 +258,7 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
styleMargin->GetMargin(m); // XXX percentage margins
if (NS_STYLE_FLOAT_EDGE_PADDING == borderStyle->mFloatEdge) {
// Add in border too
- nsMargin b;
- borderStyle->GetBorder(b);
- m += b;
+ m += borderStyle->GetBorder();
}
// determine left edge
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
index 7ebfaf195fde..64331476a054 100644
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -610,14 +610,18 @@ SyncFrameViewGeometryDependentProperties(nsPresContext* aPresContext,
const nsStyleBorder* borderStyle = aStyleContext->GetStyleBorder();
const nsStylePadding* paddingStyle = aStyleContext->GetStylePadding();
- nsMargin border, padding;
+ nsMargin padding;
nsRect overflowClipRect(0, 0, frameSize.width, frameSize.height);
- borderStyle->GetBorder(border);
- overflowClipRect.Deflate(border);
+ overflowClipRect.Deflate(borderStyle->GetBorder());
// XXX We need to handle percentage padding
if (paddingStyle->GetPadding(padding)) {
overflowClipRect.Deflate(padding);
}
+#ifdef DEBUG
+ else {
+ NS_WARNING("Percentage padding and CLIP overflow don't mix");
+ }
+#endif
if (hasClip) {
// If both 'clip' and 'overflow-clip' apply then use the intersection
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index 5d6425a34eb7..1d2f2473848f 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -703,10 +703,7 @@ NS_IMETHODIMP nsFrame::CalcBorderPadding(nsMargin& aBorderPadding) const {
const nsStylePadding* paddingStyle = GetStylePadding();
paddingStyle->CalcPaddingFor(this, aBorderPadding);
const nsStyleBorder* borderStyle = GetStyleBorder();
- nsMargin border;
- if (borderStyle->GetBorder(border)) {
- aBorderPadding += border;
- }
+ aBorderPadding += borderStyle->GetBorder();
}
return NS_OK;
}
@@ -797,14 +794,18 @@ nsFrame::SetOverflowClipRect(nsIRenderingContext& aRenderingContext)
// XXX We don't support the 'overflow-clip' property yet, so just use the
// content area (which is the default value) as the clip shape
- nsMargin border, padding;
- borderStyle->GetBorder(border);
- clipRect.Deflate(border);
+ clipRect.Deflate(borderStyle->GetBorder());
// XXX We need to handle percentage padding
+ nsMargin padding;
if (paddingStyle->GetPadding(padding)) {
clipRect.Deflate(padding);
}
+#ifdef DEBUG
+ else {
+ NS_WARNING("Percentage padding and CLIP overflow don't mix yet");
+ }
+#endif
// Set updated clip-rect into the rendering context
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);
@@ -2617,12 +2618,11 @@ nsFrame::CheckInvalidateSizeChange(nsPresContext* aPresContext,
// Invalidate the old frame borders if the frame has borders. Those borders
// may be moving.
const nsStyleBorder* border = GetStyleBorder();
- if (border->IsBorderSideVisible(NS_SIDE_LEFT)
- || border->IsBorderSideVisible(NS_SIDE_RIGHT)
- || border->IsBorderSideVisible(NS_SIDE_TOP)
- || border->IsBorderSideVisible(NS_SIDE_BOTTOM)) {
- Invalidate(nsRect(0, 0, mRect.width, mRect.height));
- return;
+ NS_FOR_CSS_SIDES(side) {
+ if (border->GetBorderWidth(side) != 0) {
+ Invalidate(nsRect(0, 0, mRect.width, mRect.height));
+ return;
+ }
}
// Invalidate the old frame background if the frame has a background
diff --git a/layout/generic/nsHTMLContainerFrame.cpp b/layout/generic/nsHTMLContainerFrame.cpp
index 57b6e983cd6f..cdbc96c894c4 100644
--- a/layout/generic/nsHTMLContainerFrame.cpp
+++ b/layout/generic/nsHTMLContainerFrame.cpp
@@ -251,17 +251,6 @@ HasTextFrameDescendantOrInFlow(nsPresContext* aPresContext, nsIFrame* aFrame)
return PR_FALSE;
}
-#if (NS_SIDE_TOP == 0) && (NS_SIDE_RIGHT == 1) && (NS_SIDE_BOTTOM == 2) && (NS_SIDE_LEFT == 3)
-static nscoord nsMargin::* const nsMarginSides[4] = {
- &nsMargin::top,
- &nsMargin::right,
- &nsMargin::bottom,
- &nsMargin::left,
-};
-#else
-#error "Somebody changed the side constants."
-#endif
-
/*virtual*/ void
nsHTMLContainerFrame::PaintTextDecorationLines(
nsIRenderingContext& aRenderingContext,
@@ -275,7 +264,7 @@ nsHTMLContainerFrame::PaintTextDecorationLines(
PRIntn skip = GetSkipSides();
NS_FOR_CSS_SIDES(side) {
if (skip & (1 << side)) {
- bp.*(nsMarginSides[side]) = 0;
+ bp.side(side) = 0;
}
}
aRenderingContext.SetColor(aColor);
diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp
index 2c6f6b7ca812..fe51e129a739 100644
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -665,13 +665,8 @@ GetIntrinsicSizeFor(nsIFrame* aFrame, nsSize& aIntrinsicSize)
nscoord
nsHTMLReflowState::CalculateHorizBorderPaddingMargin(nscoord aContainingBlockWidth)
{
- nsMargin border, padding, margin;
-
- // Get the border
- if (!mStyleBorder->GetBorder(border)) {
- // CSS2 has no percentage borders
- border.SizeTo(0, 0, 0, 0);
- }
+ const nsMargin& border = mStyleBorder->GetBorder();
+ nsMargin padding, margin;
// See if the style system can provide us the padding directly
if (!mStylePadding->GetPadding(padding)) {
@@ -1720,16 +1715,10 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
}
}
if (aBorder) { // border is an input arg
- mComputedBorderPadding.top = aBorder->top;
- mComputedBorderPadding.right = aBorder->right;
- mComputedBorderPadding.bottom = aBorder->bottom;
- mComputedBorderPadding.left = aBorder->left;
+ mComputedBorderPadding = *aBorder;
}
else {
- if (!mStyleBorder->GetBorder(mComputedBorderPadding)) {
- // CSS2 has no percentage borders
- mComputedBorderPadding.SizeTo(0, 0, 0, 0);
- }
+ mComputedBorderPadding = mStyleBorder->GetBorder();
}
mComputedBorderPadding += mComputedPadding;
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
index ecebbf670113..02450a18cde7 100644
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1398,8 +1398,10 @@ NS_PTR_TO_INT32(frame->GetProperty(nsLayoutAtoms::embeddingLevel))
return NS_OK;
}
NS_HIDDEN_(nsresult) GetParentBox(nsIBox** aParent);
+ // Box methods. Note that these do NOT just get the CSS border, padding,
+ // etc. They also talk to nsITheme.
NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding);
- NS_IMETHOD GetBorder(nsMargin& aBorderAndPadding)=0;
+ NS_IMETHOD GetBorder(nsMargin& aBorder)=0;
NS_IMETHOD GetPadding(nsMargin& aBorderAndPadding)=0;
#ifdef DEBUG_LAYOUT
NS_IMETHOD GetInset(nsMargin& aInset)=0;
diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp
index 120611a7b5e9..6022ba4bc2cd 100644
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1168,24 +1168,11 @@ struct nsRecessedBorder : public nsStyleBorder {
nsRecessedBorder(nscoord aBorderWidth)
: nsStyleBorder()
{
- nsStyleCoord styleCoord(aBorderWidth);
-
- mBorder.SetLeft(styleCoord);
- mBorder.SetTop(styleCoord);
- mBorder.SetRight(styleCoord);
- mBorder.SetBottom(styleCoord);
-
- mBorderStyle[0] = NS_STYLE_BORDER_STYLE_INSET;
- mBorderStyle[1] = NS_STYLE_BORDER_STYLE_INSET;
- mBorderStyle[2] = NS_STYLE_BORDER_STYLE_INSET;
- mBorderStyle[3] = NS_STYLE_BORDER_STYLE_INSET;
-
- mBorderColor[0] = 0;
- mBorderColor[1] = 0;
- mBorderColor[2] = 0;
- mBorderColor[3] = 0;
-
- mHasCachedBorder = PR_FALSE;
+ // Note: use SetBorderStyle here because we want to affect mComputedBorder
+ NS_FOR_CSS_SIDES(side) {
+ mBorder.side(side) = aBorderWidth;
+ SetBorderStyle(side, NS_STYLE_BORDER_STYLE_INSET);
+ }
}
};
diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp
index e1f09e9d4d5b..ef806d8f03a7 100644
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -154,16 +154,12 @@ nsInlineFrame::IsSelfEmpty()
// XXX Top and bottom removed, since they shouldn't affect things, but this
// doesn't really match with nsLineLayout.cpp's setting of
// ZeroEffectiveSpanBox, anymore, so what should this really be?
- if ((border->IsBorderSideVisible(NS_SIDE_RIGHT) &&
- !IsBorderZero(border->mBorder.GetRightUnit(),
- border->mBorder.GetRight(coord))) ||
- (border->IsBorderSideVisible(NS_SIDE_LEFT) &&
- !IsBorderZero(border->mBorder.GetLeftUnit(),
- border->mBorder.GetLeft(coord))) ||
+ if (border->GetBorderWidth(NS_SIDE_RIGHT) != 0 ||
+ border->GetBorderWidth(NS_SIDE_LEFT) != 0 ||
!IsPaddingZero(padding->mPadding.GetRightUnit(),
- padding->mPadding.GetRight(coord)) ||
+ padding->mPadding.GetRight(coord)) ||
!IsPaddingZero(padding->mPadding.GetLeftUnit(),
- padding->mPadding.GetLeft(coord)) ||
+ padding->mPadding.GetLeft(coord)) ||
!IsMarginZero(margin->mMargin.GetRightUnit(),
margin->mMargin.GetRight(coord)) ||
!IsMarginZero(margin->mMargin.GetLeftUnit(),
diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp
index bd1bdc1b4508..242cf9f27679 100644
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -1577,10 +1577,7 @@ nsLineLayout::IsPercentageAwareReplacedElement(nsPresContext *aPresContext,
return PR_TRUE;
}
- const nsStyleBorder* border = aFrame->GetStyleBorder();
- if (IsPercentageUnitSides(&border->mBorder)) {
- return PR_TRUE;
- }
+ // Borders aren't percentage aware
const nsStylePosition* pos = aFrame->GetStylePosition();
if (eStyleUnit_Percent == pos->mWidth.GetUnit()
diff --git a/layout/generic/nsPageContentFrame.cpp b/layout/generic/nsPageContentFrame.cpp
index b33c5fef6649..41af17f2dcb4 100644
--- a/layout/generic/nsPageContentFrame.cpp
+++ b/layout/generic/nsPageContentFrame.cpp
@@ -96,13 +96,10 @@ NS_IMETHODIMP nsPageContentFrame::Reflow(nsPresContext* aPresContext,
// The document element's background should cover the entire canvas, so
// take into account the combined area and any space taken up by
// absolutely positioned elements
- nsMargin border(0,0,0,0);
- nsMargin padding(0,0,0,0);
+ nsMargin padding(0,0,0,0);
- // Ignore the return values for these
- // Typically they are zero and if they fail
- // we should keep going anyway, there impact is small
- kidReflowState.mStyleBorder->GetBorder(border);
+ // XXXbz this screws up percentage padding (sets padding to zero
+ // in the percentage padding case)
kidReflowState.mStylePadding->GetPadding(padding);
// First check the combined area
@@ -110,7 +107,10 @@ NS_IMETHODIMP nsPageContentFrame::Reflow(nsPresContext* aPresContext,
// The background covers the content area and padding area, so check
// for children sticking outside the child frame's padding edge
if (aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) {
- mPD->mPageContentXMost = aDesiredSize.mOverflowArea.XMost() + border.right + padding.right;
+ mPD->mPageContentXMost =
+ aDesiredSize.mOverflowArea.XMost() +
+ kidReflowState.mStyleBorder->GetBorderWidth(NS_SIDE_RIGHT) +
+ padding.right;
}
}
diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp
index 2b309fb291d9..1fa79a2ef0d2 100644
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -3498,34 +3498,9 @@ nsComputedDOMStyle::GetBorderWidthFor(PRUint8 aSide, nsIFrame *aFrame,
GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)border, aFrame);
if (border) {
- nsStyleCoord coord;
- PRUint8 borderStyle = border->GetBorderStyle(aSide);
- if (borderStyle == NS_STYLE_BORDER_STYLE_NONE) {
- coord.SetCoordValue(0);
- } else {
- border->mBorder.Get(aSide, coord);
- }
-
- switch (coord.GetUnit()) {
- case eStyleUnit_Coord:
- val->SetTwips(coord.GetCoordValue());
- break;
- case eStyleUnit_Enumerated:
- {
- const nsAFlatCString& width=
- nsCSSProps::ValueToKeyword(coord.GetIntValue(),
- nsCSSProps::kBorderWidthKTable);
- val->SetIdent(width);
- break;
- }
- case eStyleUnit_Chars:
- // XXX we need a frame and a rendering context to calculate this, bug 281972, bug 282126.
- val->SetTwips(0);
- break;
- default:
- NS_ERROR("Unexpected border width unit");
- break;
- }
+ nscoord width;
+ border->CalcBorderFor(aFrame, aSide, width);
+ val->SetTwips(width);
}
return CallQueryInterface(val, aValue);
diff --git a/layout/style/nsHTMLStyleSheet.cpp b/layout/style/nsHTMLStyleSheet.cpp
index dbf3024b75f4..894ba44bd781 100644
--- a/layout/style/nsHTMLStyleSheet.cpp
+++ b/layout/style/nsHTMLStyleSheet.cpp
@@ -192,21 +192,7 @@ ProcessTableRulesAttribute(nsStyleStruct* aStyleStruct,
// set the border width to be 1 pixel
nscoord onePixel =
NSToCoordRound(aRuleData->mPresContext->ScaledPixelsToTwips());
- nsStyleCoord coord(onePixel);
- switch(aSide) {
- case NS_SIDE_TOP:
- borderData->mBorder.SetTop(coord);
- break;
- case NS_SIDE_RIGHT:
- borderData->mBorder.SetRight(coord);
- break;
- case NS_SIDE_BOTTOM:
- borderData->mBorder.SetBottom(coord);
- break;
- default: // NS_SIDE_LEFT
- borderData->mBorder.SetLeft(coord);
- break;
- }
+ borderData->SetBorderWidth(aSide, onePixel);
}
}
}
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index 11e4f1c8f219..5800dba423fc 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -3382,12 +3382,41 @@ nsRuleNode::ComputeBorderData(nsStyleStruct* aStartStruct,
{ // scope for compilers with broken |for| loop scoping
NS_FOR_CSS_SIDES(side) {
const nsCSSValue &value = marginData.mBorderWidth.*(nsCSSRect::sides[side]);
- if (SetCoord(value, coord, parentCoord, SETCOORD_LE, aContext,
- mPresContext, inherited))
- border->mBorder.Set(side, coord);
+ NS_ASSERTION(eCSSUnit_Percent != value.GetUnit(),
+ "Percentage borders not implemented yet "
+ "If implementing, make sure to fix all consumers of "
+ "nsStyleBorder, the IsPercentageAwareChild method, "
+ "the nsAbsoluteContainingBlock::FrameDependsOnContainer "
+ "method, the "
+ "nsLineLayout::IsPercentageAwareReplacedElement method "
+ "and probably some other places");
+ if (eCSSUnit_Enumerated == value.GetUnit()) {
+ NS_ASSERTION(value.GetIntValue() == NS_STYLE_BORDER_WIDTH_THIN ||
+ value.GetIntValue() == NS_STYLE_BORDER_WIDTH_MEDIUM ||
+ value.GetIntValue() == NS_STYLE_BORDER_WIDTH_THICK,
+ "Unexpected enum value");
+ border->SetBorderWidth(side,
+ (mPresContext->GetBorderWidthTable())[value.GetIntValue()]);
+ }
+ else if (SetCoord(value, coord, parentCoord, SETCOORD_LENGTH, aContext,
+ mPresContext, inherited)) {
+ if (coord.GetUnit() == eStyleUnit_Coord) {
+ border->SetBorderWidth(side, coord.GetCoordValue());
+ }
+#ifdef DEBUG
+ else {
+ NS_ASSERTION(coord.GetUnit() == eStyleUnit_Chars, "unexpected unit");
+ NS_WARNING("Border set in chars; we don't handle that");
+ }
+#endif
+ }
else if (eCSSUnit_Inherit == value.GetUnit()) {
inherited = PR_TRUE;
- border->mBorder.Set(side, parentBorder->mBorder.Get(side, coord));
+ border->SetBorderWidth(side, parentBorder->GetBorderWidth(side));
+ }
+ else if (eCSSUnit_Initial == value.GetUnit()) {
+ border->SetBorderWidth(side,
+ (mPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM]);
}
}
}
@@ -3401,7 +3430,7 @@ nsRuleNode::ComputeBorderData(nsStyleStruct* aStartStruct,
if (eCSSUnit_Enumerated == unit) {
border->SetBorderStyle(side, value.GetIntValue());
}
- else if (eCSSUnit_None == unit) {
+ else if (eCSSUnit_None == unit || eCSSUnit_Initial == unit) {
border->SetBorderStyle(side, NS_STYLE_BORDER_STYLE_NONE);
}
else if (eCSSUnit_Inherit == unit) {
@@ -3518,7 +3547,6 @@ nsRuleNode::ComputeBorderData(nsStyleStruct* aStartStruct,
PropagateDependentBit(NS_STYLE_INHERIT_BIT(Border), aHighestNode);
}
- border->RecalcData(mPresContext);
return border;
}
diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp
index 019e7050da44..36f67c571420 100644
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -54,6 +54,8 @@
#include "nsStyleContext.h"
#include "imgIRequest.h"
+#include "nsPrintfCString.h"
+
#ifdef DEBUG
// #define NOISY_DEBUG
#endif
@@ -260,12 +262,10 @@ inline const nsStyleStruct* nsStyleContext::PeekStyleData(nsStyleStructID aSID)
void
nsStyleContext::GetBorderPaddingFor(nsStyleBorderPadding& aBorderPadding)
{
- nsMargin border, padding;
- if (GetStyleBorder()->GetBorder(border)) {
- if (GetStylePadding()->GetPadding(padding)) {
- border += padding;
- aBorderPadding.SetBorderPadding(border);
- }
+ nsMargin padding;
+ if (GetStylePadding()->GetPadding(padding)) {
+ padding += GetStyleBorder()->GetBorder();
+ aBorderPadding.SetBorderPadding(padding);
}
}
@@ -660,8 +660,17 @@ void nsStyleContext::DumpRegressionData(nsPresContext* aPresContext, FILE* out,
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
const nsStyleBorder* border = GetStyleBorder();
- border->mBorder.ToString(str);
- fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
+#ifdef NS_COORD_IS_FLOAT
+ const char format [] = "top: %ftw right: %ftw bottom: %ftw left: %ftw";
+#else
+ const char format [] = "top: %dtw right: %dtw bottom: %dtw left: %dtw";
+#endif
+ nsPrintfCString output(format,
+ border->GetBorderWidth(NS_SIDE_TOP),
+ border->GetBorderWidth(NS_SIDE_RIGHT),
+ border->GetBorderWidth(NS_SIDE_BOTTOM),
+ border->GetBorderWidth(NS_SIDE_LEFT));
+ fprintf(out, "%s ", output.get());
border->mBorderRadius.ToString(str);
fprintf(out, "%s ", NS_ConvertUCS2toUTF8(str).get());
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
index 477e37c495fb..4793ff1e0acf 100644
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -273,10 +273,6 @@ nsChangeHint nsStyleFont::CalcFontDifference(const nsFont& aFont1, const nsFont&
return NS_STYLE_HINT_REFLOW;
}
-static nscoord nsMargin::* const gMarginSides[4] = {
- &nsMargin::top, &nsMargin::right, &nsMargin::bottom, &nsMargin::left
-};
-
static PRBool IsFixedData(const nsStyleSides& aSides, PRBool aEnumOK)
{
NS_FOR_CSS_SIDES(side) {
@@ -344,7 +340,7 @@ void nsStyleMargin::RecalcData()
if (IsFixedData(mMargin, PR_FALSE)) {
nsStyleCoord coord;
NS_FOR_CSS_SIDES(side) {
- mCachedMargin.*(gMarginSides[side]) =
+ mCachedMargin.side(side) =
CalcCoord(mMargin.Get(side, coord), nsnull, 0);
}
mHasCachedMargin = PR_TRUE;
@@ -408,7 +404,7 @@ void nsStylePadding::RecalcData()
if (IsFixedData(mPadding, PR_FALSE)) {
nsStyleCoord coord;
NS_FOR_CSS_SIDES(side) {
- mCachedPadding.*(gMarginSides[side]) =
+ mCachedPadding.side(side) =
CalcCoord(mPadding.Get(side, coord), nsnull, 0);
}
mHasCachedPadding = PR_TRUE;
@@ -444,31 +440,21 @@ nsStylePadding::CalcPaddingFor(const nsIFrame* aFrame, nsMargin& aPadding) const
}
nsStyleBorder::nsStyleBorder(nsPresContext* aPresContext)
+ : mComputedBorder(0, 0, 0, 0)
{
- // spacing values not inherited
- const nsStyleCoord medium(NS_STYLE_BORDER_WIDTH_MEDIUM, eStyleUnit_Enumerated);
- mBorder.SetLeft(medium);
- mBorder.SetTop(medium);
- mBorder.SetRight(medium);
- mBorder.SetBottom(medium);
-
- mBorderStyle[0] = NS_STYLE_BORDER_STYLE_NONE | BORDER_COLOR_FOREGROUND;
- mBorderStyle[1] = NS_STYLE_BORDER_STYLE_NONE | BORDER_COLOR_FOREGROUND;
- mBorderStyle[2] = NS_STYLE_BORDER_STYLE_NONE | BORDER_COLOR_FOREGROUND;
- mBorderStyle[3] = NS_STYLE_BORDER_STYLE_NONE | BORDER_COLOR_FOREGROUND;
-
- mBorderColor[0] = NS_RGB(0, 0, 0);
- mBorderColor[1] = NS_RGB(0, 0, 0);
- mBorderColor[2] = NS_RGB(0, 0, 0);
- mBorderColor[3] = NS_RGB(0, 0, 0);
+ nscoord medium =
+ (aPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM];
+ NS_FOR_CSS_SIDES(side) {
+ mBorder.side(side) = medium;
+ mBorderStyle[side] = NS_STYLE_BORDER_STYLE_NONE | BORDER_COLOR_FOREGROUND;
+ mBorderColor[side] = NS_RGB(0, 0, 0);
+ }
mBorderColors = nsnull;
mBorderRadius.Reset();
mFloatEdge = NS_STYLE_FLOAT_EDGE_CONTENT;
-
- mHasCachedBorder = PR_FALSE;
}
nsStyleBorder::nsStyleBorder(const nsStyleBorder& aSrc)
@@ -483,7 +469,6 @@ nsStyleBorder::nsStyleBorder(const nsStyleBorder& aSrc)
else
mBorderColors[i] = nsnull;
}
- mHasCachedBorder = PR_FALSE;
}
void*
@@ -501,63 +486,25 @@ nsStyleBorder::Destroy(nsPresContext* aContext) {
}
-PRBool nsStyleBorder::IsBorderSideVisible(PRUint8 aSide) const
-{
- PRUint8 borderStyle = GetBorderStyle(aSide);
- return ((borderStyle != NS_STYLE_BORDER_STYLE_NONE)
- && (borderStyle != NS_STYLE_BORDER_STYLE_HIDDEN));
-}
-
-void nsStyleBorder::RecalcData(nsPresContext* aContext)
-{
- PRBool allFixed = PR_TRUE;
- {NS_FOR_CSS_SIDES(side) {
- if (IsBorderSideVisible(side) &&
- !IsFixedUnit(mBorder.GetUnit(side), PR_TRUE)) {
- allFixed = PR_FALSE;
- break;
- }
- }}
- if (allFixed) {
- nsStyleCoord coord;
- const nscoord* borderWidths = aContext->GetBorderWidthTable();
- NS_FOR_CSS_SIDES(side) {
- mCachedBorder.*(gMarginSides[side]) = IsBorderSideVisible(side)
- ? CalcCoord(mBorder.Get(side, coord), borderWidths, 3)
- : 0;
- }
- mHasCachedBorder = PR_TRUE;
- }
- else {
- mHasCachedBorder = PR_FALSE;
- }
-}
-
nsChangeHint nsStyleBorder::CalcDifference(const nsStyleBorder& aOther) const
{
- if ((mBorder == aOther.mBorder) &&
- (mFloatEdge == aOther.mFloatEdge)) {
+ // Note that differences in mBorder don't affect rendering (which should only
+ // use mComputedBorder), so don't need to be tested for here.
+ if (mComputedBorder == aOther.mComputedBorder &&
+ mFloatEdge == aOther.mFloatEdge) {
// Note that mBorderStyle stores not only the border style but also
- // color-related flags. So while it's OK to compare entries in
- // mBorderStyle directly for purposes of finding out whether something at
- // all changed, any time we want to work with actual border styles we
- // should use GetBorderStyle().
- PRBool hasVisualChange = PR_FALSE;
+ // color-related flags. Given that we've already done an mComputedBorder
+ // comparison, border-style differences can only lead to a VISUAL hint. So
+ // it's OK to just compare the values directly -- if either the actual
+ // style or the color flags differ we want to repaint.
NS_FOR_CSS_SIDES(ix) {
- if ((mBorderStyle[ix] != aOther.mBorderStyle[ix]) ||
- (mBorderColor[ix] != aOther.mBorderColor[ix])) {
- if (GetBorderStyle(ix) != aOther.GetBorderStyle(ix) &&
- (NS_STYLE_BORDER_STYLE_NONE == GetBorderStyle(ix) ||
- NS_STYLE_BORDER_STYLE_NONE == aOther.GetBorderStyle(ix) ||
- NS_STYLE_BORDER_STYLE_HIDDEN == GetBorderStyle(ix) || // bug 45754
- NS_STYLE_BORDER_STYLE_HIDDEN == aOther.GetBorderStyle(ix))) {
- return NS_STYLE_HINT_REFLOW; // border on or off
- }
- hasVisualChange = PR_TRUE;
+ if (mBorderStyle[ix] != aOther.mBorderStyle[ix] ||
+ mBorderColor[ix] != aOther.mBorderColor[ix]) {
+ return NS_STYLE_HINT_VISUAL;
}
}
- if (hasVisualChange ||
- mBorderRadius != aOther.mBorderRadius ||
+
+ if (mBorderRadius != aOther.mBorderRadius ||
!mBorderColors != !aOther.mBorderColors) {
return NS_STYLE_HINT_VISUAL;
}
@@ -566,8 +513,7 @@ nsChangeHint nsStyleBorder::CalcDifference(const nsStyleBorder& aOther) const
// aOther.mBorderColors
if (mBorderColors) {
NS_FOR_CSS_SIDES(ix) {
- if (mBorderColors[ix] && !aOther.mBorderColors[ix] ||
- !mBorderColors[ix] && aOther.mBorderColors[ix]) {
+ if (!mBorderColors[ix] != !aOther.mBorderColors[ix]) {
return NS_STYLE_HINT_VISUAL;
} else if (mBorderColors[ix] && aOther.mBorderColors[ix]) {
if (!mBorderColors[ix]->Equals(aOther.mBorderColors[ix]))
@@ -590,40 +536,6 @@ nsChangeHint nsStyleBorder::MaxDifference()
}
#endif
-void
-nsStyleBorder::CalcBorderFor(const nsIFrame* aFrame, nsMargin& aBorder) const
-{
- if (mHasCachedBorder) {
- aBorder = mCachedBorder;
- } else {
- CalcSidesFor(aFrame, mBorder, NS_SPACING_BORDER,
- aFrame->GetPresContext()->GetBorderWidthTable(), 3, aBorder);
- }
-}
-
-void
-nsStyleBorder::CalcBorderFor(const nsIFrame* aFrame, PRUint8 aSide, nscoord& aWidth) const
-{
- aWidth = 0;
- // using mCachedBorder as above, doesn't work properly
- nsStyleCoord coord;
- switch(aSide) {
- case NS_SIDE_TOP:
- coord = mBorder.GetTop(coord);
- break;
- case NS_SIDE_RIGHT:
- coord = mBorder.GetRight(coord);
- break;
- case NS_SIDE_BOTTOM:
- coord = mBorder.GetBottom(coord);
- break;
- default: // NS_SIDE_LEFT
- coord = mBorder.GetLeft(coord);
- }
- aWidth = CalcSideFor(aFrame, coord, NS_SPACING_BORDER, aSide,
- aFrame->GetPresContext()->GetBorderWidthTable(), 3);
-}
-
nsStyleOutline::nsStyleOutline(nsPresContext* aPresContext)
{
// spacing values not inherited
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index accce7fc1dab..aa1c0602d6e4 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -342,14 +342,11 @@ struct nsStyleBorder: public nsStyleStruct {
void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW;
void Destroy(nsPresContext* aContext);
- PRBool IsBorderSideVisible(PRUint8 aSide) const;
- void RecalcData(nsPresContext* aContext);
nsChangeHint CalcDifference(const nsStyleBorder& aOther) const;
#ifdef DEBUG
static nsChangeHint MaxDifference();
#endif
- nsStyleSides mBorder; // [reset] length, enum (see nsStyleConsts.h)
nsStyleSides mBorderRadius; // [reset] length, percent, inherit
PRUint8 mFloatEdge; // [reset] see nsStyleConsts.h
nsBorderColors** mBorderColors; // [reset] multiple levels of color for a border.
@@ -370,13 +367,36 @@ struct nsStyleBorder: public nsStyleStruct {
}
}
- PRBool GetBorder(nsMargin& aBorder) const
+ // Return whether aStyle is a visible style. Invisible styles cause
+ // the relevant computed border width to be 0.
+ static PRBool IsVisibleStyle(PRUint8 aStyle) {
+ return aStyle != NS_STYLE_BORDER_STYLE_NONE &&
+ aStyle != NS_STYLE_BORDER_STYLE_HIDDEN;
+ }
+
+ // aBorderWidth is in twips
+ void SetBorderWidth(PRUint8 aSide, nscoord aBorderWidth)
{
- if (mHasCachedBorder) {
- aBorder = mCachedBorder;
- return PR_TRUE;
+ NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
+ mBorder.side(aSide) = aBorderWidth;
+ if (IsVisibleStyle(GetBorderStyle(aSide))) {
+ mComputedBorder.side(aSide) = aBorderWidth;
}
- return PR_FALSE;
+ }
+
+ // Get the computed border, in twips.
+ const nsMargin& GetBorder() const
+ {
+ return mComputedBorder;
+ }
+
+ // Get the computed border width for a particular side, in twips. Note that
+ // this is zero if and only if there is no border to be painted for this
+ // side. That is, this value takes into account the border style.
+ nscoord GetBorderWidth(PRUint8 aSide) const
+ {
+ NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
+ return mComputedBorder.side(aSide);
}
PRUint8 GetBorderStyle(PRUint8 aSide) const
@@ -390,7 +410,11 @@ struct nsStyleBorder: public nsStyleStruct {
NS_ASSERTION(aSide <= NS_SIDE_LEFT, "bad side");
mBorderStyle[aSide] &= ~BORDER_STYLE_MASK;
mBorderStyle[aSide] |= (aStyle & BORDER_STYLE_MASK);
-
+ if (IsVisibleStyle(aStyle)) {
+ mComputedBorder.side(aSide) = mBorder.side(aSide);
+ } else {
+ mComputedBorder.side(aSide) = 0;
+ }
}
void GetBorderColor(PRUint8 aSide, nscolor& aColor,
@@ -451,12 +475,31 @@ struct nsStyleBorder: public nsStyleStruct {
}
// XXX these are deprecated methods
- void CalcBorderFor(const nsIFrame* aFrame, nsMargin& aBorder) const;
- void CalcBorderFor(const nsIFrame* aFrame, PRUint8 aSide, nscoord& aWidth) const;
+ void CalcBorderFor(const nsIFrame* aFrame, nsMargin& aBorder) const
+ {
+ aBorder = GetBorder();
+ }
+ void CalcBorderFor(const nsIFrame* aFrame, PRUint8 aSide,
+ nscoord& aWidth) const {
+ aWidth = GetBorderWidth(aSide);
+ }
protected:
- PRPackedBool mHasCachedBorder;
- nsMargin mCachedBorder;
+ // mComputedBorder holds the CSS2.1 computed border-width values. In
+ // particular, these widths take into account the border-style for the
+ // relevant side.
+ nsMargin mComputedBorder;
+
+ // mBorder holds the nscoord values for the border widths as they would be if
+ // all the border-style values were visible (not hidden or none). This
+ // member exists solely so that when we create structs using the copy
+ // constructor during style resolution the new structs will know what the
+ // specified values of the border were in case they have more specific rules
+ // setting the border style. Note that this isn't quite the CSS specified
+ // value, since this has had the enumerated border widths converted to
+ // lengths, and all lengths converted to twips. But it's not quite the
+ // computed value either; mComputedBorder is that.
+ nsMargin mBorder;
PRUint8 mBorderStyle[4]; // [reset] See nsStyleConsts.h
nscolor mBorderColor[4]; // [reset] the colors to use for a simple border. not used
diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp
index 0cd19226155d..ca0876d959c3 100644
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -1161,10 +1161,7 @@ nsMargin*
nsTableCellFrame::GetBorderWidth(float aPixelsToTwips,
nsMargin& aBorder) const
{
- aBorder.left = aBorder.right = aBorder.top = aBorder.bottom = 0;
-
- const nsStyleBorder* borderData = GetStyleBorder();
- borderData->GetBorder(aBorder);
+ aBorder = GetStyleBorder()->GetBorder();
return &aBorder;
}
@@ -1320,17 +1317,11 @@ nsBCTableCellFrame::PaintUnderlay(nsPresContext& aPresContext,
nsMargin borderWidth;
GetBorderWidth(p2t, borderWidth);
- nsStyleBorder myBorder = aStyleBorder;
+ nsStyleBorder myBorder(aStyleBorder);
- nsStyleCoord coord(borderWidth.top);
- myBorder.mBorder.SetTop(coord);
- coord.SetCoordValue(borderWidth.right);
- myBorder.mBorder.SetRight(coord);
- coord.SetCoordValue(borderWidth.bottom);
- myBorder.mBorder.SetBottom(coord);
- coord.SetCoordValue(borderWidth.left);
- myBorder.mBorder.SetLeft(coord);
- myBorder.RecalcData(&aPresContext);
+ NS_FOR_CSS_SIDES(side) {
+ myBorder.SetBorderWidth(side, borderWidth.side(side));
+ }
nsRect rect(0, 0, mRect.width, mRect.height);
nsCSSRendering::PaintBackground(&aPresContext, aRenderingContext, this,
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
index 2479a88c45a9..bf4e05de9bac 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -2776,8 +2776,11 @@ void GetSeparateModelBorderPadding(const nsHTMLReflowState* aReflowState,
nsStyleContext& aStyleContext,
nsMargin& aBorderPadding)
{
+ // XXXbz Either we _do_ have a reflow state and then we can use its
+ // mComputedBorderPadding or we don't and then we get the padding
+ // wrong!
const nsStyleBorder* border = aStyleContext.GetStyleBorder();
- border->GetBorder(aBorderPadding);
+ aBorderPadding = border->GetBorder();
if (aReflowState) {
aBorderPadding += aReflowState->mComputedPadding;
}
diff --git a/layout/tables/nsTablePainter.cpp b/layout/tables/nsTablePainter.cpp
index 5145d92ecafe..33124704db63 100644
--- a/layout/tables/nsTablePainter.cpp
+++ b/layout/tables/nsTablePainter.cpp
@@ -212,16 +212,10 @@ TableBackgroundPainter::TableBackgroundData::SetBCBorder(nsMargin& aBorder,
if (!mSynthBorder) return NS_ERROR_OUT_OF_MEMORY;
}
- nsStyleCoord coord(aBorder.top);
- mSynthBorder->mBorder.SetTop(coord);
- coord.SetCoordValue(aBorder.right);
- mSynthBorder->mBorder.SetRight(coord);
- coord.SetCoordValue(aBorder.bottom);
- mSynthBorder->mBorder.SetBottom(coord);
- coord.SetCoordValue(aBorder.left);
- mSynthBorder->mBorder.SetLeft(coord);
- mSynthBorder->RecalcData(aPainter->mPresContext);
-
+ NS_FOR_CSS_SIDES(side) {
+ mSynthBorder->SetBorderWidth(side, aBorder.side(side));
+ }
+
mBorder = mSynthBorder;
return NS_OK;
}
@@ -240,16 +234,10 @@ TableBackgroundPainter::TableBackgroundPainter(nsTableFrame* aTableFrame,
{
MOZ_COUNT_CTOR(TableBackgroundPainter);
- mZeroBorder.SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_SOLID);
- mZeroBorder.SetBorderStyle(NS_SIDE_RIGHT, NS_STYLE_BORDER_STYLE_SOLID);
- mZeroBorder.SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_SOLID);
- mZeroBorder.SetBorderStyle(NS_SIDE_LEFT, NS_STYLE_BORDER_STYLE_SOLID);
- nsStyleCoord coord(0);
- mZeroBorder.mBorder.SetTop(coord);
- mZeroBorder.mBorder.SetRight(coord);
- mZeroBorder.mBorder.SetBottom(coord);
- mZeroBorder.mBorder.SetLeft(coord);
- mZeroBorder.RecalcData(aPresContext);
+ NS_FOR_CSS_SIDES(side) {
+ mZeroBorder.SetBorderStyle(side, NS_STYLE_BORDER_STYLE_SOLID);
+ mZeroBorder.SetBorderWidth(side, 0);
+ }
mZeroPadding.RecalcData();
diff --git a/layout/xul/base/src/nsBox.cpp b/layout/xul/base/src/nsBox.cpp
index aa5e009a54b7..f3284a68dd74 100644
--- a/layout/xul/base/src/nsBox.cpp
+++ b/layout/xul/base/src/nsBox.cpp
@@ -571,7 +571,7 @@ nsBox::GetBorder(nsMargin& aMargin)
}
}
- GetStyleBorder()->GetBorder(aMargin);
+ aMargin = GetStyleBorder()->GetBorder();
return NS_OK;
}
diff --git a/layout/xul/base/src/nsBoxObject.cpp b/layout/xul/base/src/nsBoxObject.cpp
index b157ada8210e..9c8fc5795a56 100644
--- a/layout/xul/base/src/nsBoxObject.cpp
+++ b/layout/xul/base/src/nsBoxObject.cpp
@@ -225,24 +225,15 @@ nsBoxObject::GetOffsetRect(nsRect& aRect)
}
// For the origin, add in the border for the frame
- nsStyleCoord coord;
const nsStyleBorder* border = frame->GetStyleBorder();
- if (eStyleUnit_Coord == border->mBorder.GetLeftUnit()) {
- origin.x += border->mBorder.GetLeft(coord).GetCoordValue();
- }
- if (eStyleUnit_Coord == border->mBorder.GetTopUnit()) {
- origin.y += border->mBorder.GetTop(coord).GetCoordValue();
- }
+ origin.x += border->GetBorderWidth(NS_SIDE_LEFT);
+ origin.y += border->GetBorderWidth(NS_SIDE_TOP);
// And subtract out the border for the parent
if (parent) {
const nsStyleBorder* parentBorder = parent->GetStyleBorder();
- if (eStyleUnit_Coord == parentBorder->mBorder.GetLeftUnit()) {
- origin.x -= parentBorder->mBorder.GetLeft(coord).GetCoordValue();
- }
- if (eStyleUnit_Coord == parentBorder->mBorder.GetTopUnit()) {
- origin.y -= parentBorder->mBorder.GetTop(coord).GetCoordValue();
- }
+ origin.x -= parentBorder->GetBorderWidth(NS_SIDE_LEFT);
+ origin.y -= parentBorder->GetBorderWidth(NS_SIDE_TOP);
}
// Get the Presentation Context from the Shell
diff --git a/layout/xul/base/src/nsGroupBoxFrame.cpp b/layout/xul/base/src/nsGroupBoxFrame.cpp
index 452d9295ab8f..83370cab1acd 100644
--- a/layout/xul/base/src/nsGroupBoxFrame.cpp
+++ b/layout/xul/base/src/nsGroupBoxFrame.cpp
@@ -128,10 +128,7 @@ nsGroupBoxFrame::Paint(nsPresContext* aPresContext,
const nsStyleBorder* borderStyleData = GetStyleBorder();
const nsStylePadding* paddingStyleData = GetStylePadding();
- nsMargin border;
- if (!borderStyleData->GetBorder(border)) {
- NS_NOTYETIMPLEMENTED("percentage border");
- }
+ const nsMargin& border = borderStyleData->GetBorder();
nscoord yoff = 0;