From fa284ddafcd10c30bcf6845828cda57d02b656b5 Mon Sep 17 00:00:00 2001 From: "masayuki%d-toybox.com" Date: Wed, 27 Dec 2006 14:21:43 +0000 Subject: [PATCH] Bug 287624 ? round CSS border widths to nearest pixel r+sr=dbaron git-svn-id: svn://10.0.0.236/trunk@217460 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/nsCSSRendering.cpp | 13 ++--- mozilla/layout/generic/nsImageFrame.cpp | 6 +-- mozilla/layout/style/nsComputedDOMStyle.cpp | 2 +- mozilla/layout/style/nsStyleStruct.cpp | 16 ++++-- mozilla/layout/style/nsStyleStruct.h | 55 +++++++++++++++------ mozilla/layout/style/nsStyleStructList.h | 2 +- 6 files changed, 62 insertions(+), 32 deletions(-) diff --git a/mozilla/layout/base/nsCSSRendering.cpp b/mozilla/layout/base/nsCSSRendering.cpp index 117eed5f9e6..8c20ced7a52 100644 --- a/mozilla/layout/base/nsCSSRendering.cpp +++ b/mozilla/layout/base/nsCSSRendering.cpp @@ -1825,7 +1825,7 @@ void nsCSSRendering::PaintBorder(nsPresContext* aPresContext, } } /* Get our conversion values */ - nscoord twipsPerPixel = aPresContext->IntScaledPixelsToTwips(1); + nscoord twipsPerPixel = NSIntPixelsToTwips(1, aPresContext->PixelsToTwips()); static PRUint8 sideOrder[] = { NS_SIDE_BOTTOM, NS_SIDE_LEFT, NS_SIDE_TOP, NS_SIDE_RIGHT }; nscolor sideColor; @@ -2188,11 +2188,7 @@ nscoord width, offset; // Draw all the other sides - /* XXX something is misnamed here!!!! */ - nscoord twipsPerPixel;/* XXX */ - float p2t;/* XXX */ - p2t = aPresContext->PixelsToTwips();/* XXX */ - twipsPerPixel = (nscoord) p2t;/* XXX */ + nscoord twipsPerPixel = NSIntPixelsToTwips(1, aPresContext->PixelsToTwips()); // default to current color in case it is invert color // and the platform does not support that @@ -2234,7 +2230,7 @@ nscoord width, offset; outlineColor, bgColor->mBackgroundColor,outside, inside,aSkipSides, twipsPerPixel, aGap); - + if(modeChanged ) { aRenderingContext.SetPenMode(nsPenMode_kNone); } @@ -3544,8 +3540,7 @@ nsCSSRendering::PaintRoundedBorder(nsPresContext* aPresContext, } // needed for our border thickness - p2t = aPresContext->PixelsToTwips(); - twipsPerPixel = NSToCoordRound(p2t); + twipsPerPixel = NSIntPixelsToTwips(1, aPresContext->PixelsToTwips()); // Base our thickness check on the segment being less than a pixel and 1/2 qtwips = twipsPerPixel >> 2; diff --git a/mozilla/layout/generic/nsImageFrame.cpp b/mozilla/layout/generic/nsImageFrame.cpp index 6452d020c3d..e26ef6f2fec 100644 --- a/mozilla/layout/generic/nsImageFrame.cpp +++ b/mozilla/layout/generic/nsImageFrame.cpp @@ -1035,8 +1035,8 @@ nsImageFrame::DisplayAltText(nsPresContext* aPresContext, } struct nsRecessedBorder : public nsStyleBorder { - nsRecessedBorder(nscoord aBorderWidth) - : nsStyleBorder() + nsRecessedBorder(nscoord aBorderWidth, nsPresContext* aPresContext) + : nsStyleBorder(aPresContext) { NS_FOR_CSS_SIDES(side) { // Note: use SetBorderColor here because we want to make sure @@ -1076,7 +1076,7 @@ nsImageFrame::DisplayAltFeedback(nsIRenderingContext& aRenderingContext, } // Paint the border - nsRecessedBorder recessedBorder(borderEdgeWidth); + nsRecessedBorder recessedBorder(borderEdgeWidth, GetPresContext()); nsCSSRendering::PaintBorder(GetPresContext(), aRenderingContext, this, inner, inner, recessedBorder, mStyleContext, 0); diff --git a/mozilla/layout/style/nsComputedDOMStyle.cpp b/mozilla/layout/style/nsComputedDOMStyle.cpp index 4517c2b83c6..99f870adcdf 100644 --- a/mozilla/layout/style/nsComputedDOMStyle.cpp +++ b/mozilla/layout/style/nsComputedDOMStyle.cpp @@ -3230,7 +3230,7 @@ nsComputedDOMStyle::GetBorderWidthFor(PRUint8 aSide, nsIDOMCSSValue** aValue) const nsStyleBorder* border = GetStyleBorder(); if (border) { - val->SetTwips(border->GetBorderWidth(aSide)); + val->SetTwips(border->GetComputedBorderWidth(aSide)); } return CallQueryInterface(val, aValue); diff --git a/mozilla/layout/style/nsStyleStruct.cpp b/mozilla/layout/style/nsStyleStruct.cpp index d5a5729f59b..0bd0d8806fa 100644 --- a/mozilla/layout/style/nsStyleStruct.cpp +++ b/mozilla/layout/style/nsStyleStruct.cpp @@ -332,7 +332,7 @@ nsChangeHint nsStylePadding::MaxDifference() #endif nsStyleBorder::nsStyleBorder(nsPresContext* aPresContext) - : mComputedBorder(0, 0, 0, 0) + : mActualBorder(0, 0, 0, 0) { nscoord medium = (aPresContext->GetBorderWidthTable())[NS_STYLE_BORDER_WIDTH_MEDIUM]; @@ -346,6 +346,8 @@ nsStyleBorder::nsStyleBorder(nsPresContext* aPresContext) mBorderColors = nsnull; mFloatEdge = NS_STYLE_FLOAT_EDGE_CONTENT; + + mTwipsPerPixel = NSIntPixelsToTwips(1, aPresContext->PixelsToTwips()); } nsStyleBorder::nsStyleBorder(const nsStyleBorder& aSrc) @@ -381,7 +383,8 @@ nsChangeHint nsStyleBorder::CalcDifference(const nsStyleBorder& aOther) const { // 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 && + if (mTwipsPerPixel == aOther.mTwipsPerPixel && + mActualBorder == aOther.mActualBorder && mFloatEdge == aOther.mFloatEdge) { // Note that mBorderStyle stores not only the border style but also // color-related flags. Given that we've already done an mComputedBorder @@ -442,6 +445,7 @@ nsStyleOutline::nsStyleOutline(nsPresContext* aPresContext) mOutlineColor = NS_RGB(0, 0, 0); mHasCachedOutline = PR_FALSE; + mTwipsPerPixel = NSIntPixelsToTwips(1, aPresContext->PixelsToTwips()); } nsStyleOutline::nsStyleOutline(const nsStyleOutline& aSrc) { @@ -455,7 +459,10 @@ nsStyleOutline::RecalcData(nsPresContext* aContext) mCachedOutlineWidth = 0; mHasCachedOutline = PR_TRUE; } else if (IsFixedUnit(mOutlineWidth.GetUnit(), PR_TRUE)) { - mCachedOutlineWidth = CalcCoord(mOutlineWidth, aContext->GetBorderWidthTable(), 3); + mCachedOutlineWidth = + CalcCoord(mOutlineWidth, aContext->GetBorderWidthTable(), 3); + mCachedOutlineWidth = + NS_ROUND_BORDER_TO_PIXELS(mCachedOutlineWidth, mTwipsPerPixel); mHasCachedOutline = PR_TRUE; } else @@ -470,7 +477,8 @@ nsChangeHint nsStyleOutline::CalcDifference(const nsStyleOutline& aOther) const aOther.mCachedOutlineWidth > 0 && aOther.mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE; if (outlineWasVisible != outlineIsVisible || (outlineIsVisible && (mOutlineOffset != aOther.mOutlineOffset || - mOutlineWidth != aOther.mOutlineWidth))) { + mOutlineWidth != aOther.mOutlineWidth || + mTwipsPerPixel != aOther.mTwipsPerPixel))) { return NS_CombineHint(nsChangeHint_ReflowFrame, nsChangeHint_RepaintFrame); } if ((mOutlineStyle != aOther.mOutlineStyle) || diff --git a/mozilla/layout/style/nsStyleStruct.h b/mozilla/layout/style/nsStyleStruct.h index ad54ad6b88d..b9e7b3f7915 100644 --- a/mozilla/layout/style/nsStyleStruct.h +++ b/mozilla/layout/style/nsStyleStruct.h @@ -21,6 +21,7 @@ * * Contributor(s): * Mats Palmgren + * Masayuki Nakano * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -310,8 +311,12 @@ struct nsBorderColors { } }; +// Border widths are rounded to the nearest integer number of pixels, but values +// between zero and one device pixels are always rounded up to one device pixel. +#define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \ + ((l) == 0) ? 0 : PR_MAX((tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) + struct nsStyleBorder: public nsStyleStruct { - nsStyleBorder() :mBorderColors(nsnull) {}; nsStyleBorder(nsPresContext* aContext); nsStyleBorder(const nsStyleBorder& aBorder); ~nsStyleBorder(void) { @@ -362,22 +367,33 @@ struct nsStyleBorder: public nsStyleStruct { { mBorder.side(aSide) = aBorderWidth; if (IsVisibleStyle(GetBorderStyle(aSide))) { - mComputedBorder.side(aSide) = aBorderWidth; + mActualBorder.side(aSide) = + NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, mTwipsPerPixel); } } - // Get the computed border, in twips. + // Get the actual border, in twips. const nsMargin& GetBorder() const { - return mComputedBorder; + return mActualBorder; + } + + // Get the actual 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 and the + // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS. + nscoord GetBorderWidth(PRUint8 aSide) const + { + return mActualBorder.side(aSide); } // 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 + // side. That is, this value takes into account the border style and the + // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS. + nscoord GetComputedBorderWidth(PRUint8 aSide) const { - return mComputedBorder.side(aSide); + return mActualBorder.side(aSide) ? mBorder.side(aSide) : 0; } PRUint8 GetBorderStyle(PRUint8 aSide) const @@ -392,9 +408,10 @@ struct nsStyleBorder: public nsStyleStruct { mBorderStyle[aSide] &= ~BORDER_STYLE_MASK; mBorderStyle[aSide] |= (aStyle & BORDER_STYLE_MASK); if (IsVisibleStyle(aStyle)) { - mComputedBorder.side(aSide) = mBorder.side(aSide); + mActualBorder.side(aSide) = + NS_ROUND_BORDER_TO_PIXELS(mBorder.side(aSide), mTwipsPerPixel); } else { - mComputedBorder.side(aSide) = 0; + mActualBorder.side(aSide) = 0; } } @@ -456,10 +473,10 @@ struct nsStyleBorder: public nsStyleStruct { } protected: - // mComputedBorder holds the CSS2.1 computed border-width values. In + // mActualBorder holds the CSS2.1 actual border-width values. In // particular, these widths take into account the border-style for the - // relevant side. - nsMargin mComputedBorder; + // relevant side and the values are rounded to the nearest device pixel. + nsMargin mActualBorder; // 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 @@ -469,12 +486,14 @@ protected: // 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. + // computed value either. nsMargin mBorder; PRUint8 mBorderStyle[4]; // [reset] See nsStyleConsts.h nscolor mBorderColor[4]; // [reset] the colors to use for a simple border. not used // if -moz-border-colors is specified + + nscoord mTwipsPerPixel; }; @@ -500,13 +519,17 @@ struct nsStyleOutline: public nsStyleStruct { nsStyleSides mOutlineRadius; // [reset] length, percent // (top=topLeft, right=topRight, bottom=bottomRight, left=bottomLeft) + // Note that these are specified values. You can get the actual values with + // GetOutlineWidth and GetOutlineOffset. You cannot get the computed values + // directly. nsStyleCoord mOutlineOffset; // [reset] length nsStyleCoord mOutlineWidth; // [reset] length, enum (see nsStyleConsts.h) PRBool GetOutlineOffset(nscoord& aOffset) const { if (mOutlineOffset.GetUnit() == eStyleUnit_Coord) { - aOffset = mOutlineOffset.GetCoordValue(); + nscoord offset = mOutlineOffset.GetCoordValue(); + aOffset = NS_ROUND_BORDER_TO_PIXELS(offset, mTwipsPerPixel); return PR_TRUE; } else { NS_NOTYETIMPLEMENTED("GetOutlineOffset: eStyleUnit_Chars"); @@ -562,12 +585,16 @@ struct nsStyleOutline: public nsStyleStruct { } protected: + // This value is the actual value, so it's rounded to the nearest device + // pixel. nscoord mCachedOutlineWidth; nscolor mOutlineColor; // [reset] PRPackedBool mHasCachedOutline; PRUint8 mOutlineStyle; // [reset] See nsStyleConsts.h + + nscoord mTwipsPerPixel; }; diff --git a/mozilla/layout/style/nsStyleStructList.h b/mozilla/layout/style/nsStyleStructList.h index a8d2dbfcda5..20ed3f610c1 100644 --- a/mozilla/layout/style/nsStyleStructList.h +++ b/mozilla/layout/style/nsStyleStructList.h @@ -131,7 +131,7 @@ STYLE_STRUCT_RESET(Margin, nsnull, ()) STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 16) {) STYLE_STRUCT_RESET(Padding, nsnull, ()) STYLE_STRUCT_TEST_CODE( } else {) -STYLE_STRUCT_RESET(Border, nsnull, ()) +STYLE_STRUCT_RESET(Border, nsnull, (SSARG_PRESCONTEXT)) STYLE_STRUCT_TEST_CODE( }) STYLE_STRUCT_TEST_CODE( } else {) STYLE_STRUCT_TEST_CODE( if (STYLE_STRUCT_TEST == 18) {)