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
This commit is contained in:
masayuki%d-toybox.com 2006-12-27 14:21:43 +00:00
parent 627a20a258
commit fa284ddafc
6 changed files with 62 additions and 32 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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) ||

View File

@ -21,6 +21,7 @@
*
* Contributor(s):
* Mats Palmgren <mats.palmgren@bredband.net>
* Masayuki Nakano <masayuki@d-toybox.com>
*
* 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;
};

View File

@ -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) {)