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;