Bug 488901. When an element's size changes and it has borders, we don't necessarily need to invalidate the entire border-box --- if there is no right or bottom border, and other conditions are met. r+sr=dbaron

--HG--
extra : rebase_source : 24306ec844dab873cc9b580f32a383f0ccb769a5
This commit is contained in:
Robert O'Callahan 2009-05-08 13:52:22 +12:00
Родитель 081257d0d7
Коммит 4962cbd940
4 изменённых файлов: 59 добавлений и 3 удалений

Просмотреть файл

@ -3060,6 +3060,44 @@ nsLayoutUtils::HasNonZeroCorner(const nsStyleCorners& aCorners)
return PR_FALSE;
}
// aCorner is a "full corner" value, i.e. NS_CORNER_TOP_LEFT etc
static PRBool IsCornerAdjacentToSide(PRUint8 aCorner, PRUint8 aSide)
{
PR_STATIC_ASSERT(NS_SIDE_TOP == NS_CORNER_TOP_LEFT);
PR_STATIC_ASSERT(NS_SIDE_RIGHT == NS_CORNER_TOP_RIGHT);
PR_STATIC_ASSERT(NS_SIDE_BOTTOM == NS_CORNER_BOTTOM_RIGHT);
PR_STATIC_ASSERT(NS_SIDE_LEFT == NS_CORNER_BOTTOM_LEFT);
PR_STATIC_ASSERT(NS_SIDE_TOP == ((NS_CORNER_TOP_RIGHT - 1)&3));
PR_STATIC_ASSERT(NS_SIDE_RIGHT == ((NS_CORNER_BOTTOM_RIGHT - 1)&3));
PR_STATIC_ASSERT(NS_SIDE_BOTTOM == ((NS_CORNER_BOTTOM_LEFT - 1)&3));
PR_STATIC_ASSERT(NS_SIDE_LEFT == ((NS_CORNER_TOP_LEFT - 1)&3));
return aSide == aCorner || aSide == ((aCorner - 1)&3);
}
/* static */ PRBool
nsLayoutUtils::HasNonZeroCornerOnSide(const nsStyleCorners& aCorners,
PRUint8 aSide)
{
PR_STATIC_ASSERT(NS_CORNER_TOP_LEFT_X/2 == NS_CORNER_TOP_LEFT);
PR_STATIC_ASSERT(NS_CORNER_TOP_LEFT_Y/2 == NS_CORNER_TOP_LEFT);
PR_STATIC_ASSERT(NS_CORNER_TOP_RIGHT_X/2 == NS_CORNER_TOP_RIGHT);
PR_STATIC_ASSERT(NS_CORNER_TOP_RIGHT_Y/2 == NS_CORNER_TOP_RIGHT);
PR_STATIC_ASSERT(NS_CORNER_BOTTOM_RIGHT_X/2 == NS_CORNER_BOTTOM_RIGHT);
PR_STATIC_ASSERT(NS_CORNER_BOTTOM_RIGHT_Y/2 == NS_CORNER_BOTTOM_RIGHT);
PR_STATIC_ASSERT(NS_CORNER_BOTTOM_LEFT_X/2 == NS_CORNER_BOTTOM_LEFT);
PR_STATIC_ASSERT(NS_CORNER_BOTTOM_LEFT_Y/2 == NS_CORNER_BOTTOM_LEFT);
NS_FOR_CSS_HALF_CORNERS(corner) {
// corner is a "half corner" value, so dividing by two gives us a
// "full corner" value.
if (NonZeroStyleCoord(aCorners.Get(corner)) &&
IsCornerAdjacentToSide(corner/2, aSide))
return PR_TRUE;
}
return PR_FALSE;
}
/* static */ nsTransparencyMode
nsLayoutUtils::GetFrameTransparency(nsIFrame* aFrame) {
if (aFrame->GetStyleContext()->GetStyleDisplay()->mOpacity < 1.0f)

Просмотреть файл

@ -943,6 +943,13 @@ public:
*/
static PRBool HasNonZeroCorner(const nsStyleCorners& aCorners);
/**
* Determine if there is any corner radius on corners adjacent to the
* given side.
*/
static PRBool HasNonZeroCornerOnSide(const nsStyleCorners& aCorners,
PRUint8 aSide);
/**
* Determine if a widget is likely to require transparency or translucency.
* @param aFrame the frame of a <window>, <popup> or <menupopup> element.

Просмотреть файл

@ -4051,11 +4051,22 @@ nsIFrame::CheckInvalidateSizeChange(const nsRect& aOldRect,
return;
}
// Invalidate the old frame borders if the frame has borders. Those borders
// may be moving.
// Invalidate the old frame border box if the frame has borders. Those
// borders may be moving.
const nsStyleBorder* border = GetStyleBorder();
NS_FOR_CSS_SIDES(side) {
if (border->GetActualBorderWidth(side) != 0) {
if ((side == NS_SIDE_LEFT || side == NS_SIDE_TOP) &&
!nsLayoutUtils::HasNonZeroCornerOnSide(border->mBorderRadius, side) &&
!border->GetBorderImage() &&
border->GetBorderStyle(side) == NS_STYLE_BORDER_STYLE_SOLID) {
// We also need to be sure that the bottom-left or top-right
// corner is simple. For example, if the bottom or right border
// has a different color, we would need to invalidate the corner
// area. But that's OK because if there is a right or bottom border,
// we'll invalidate the entire border-box here anyway.
continue;
}
Invalidate(nsRect(0, 0, aOldRect.width, aOldRect.height));
return;
}

Просмотреть файл

@ -578,7 +578,7 @@ struct nsStyleBorder {
return mComputedBorder;
}
// Get the actual border width for a particular side, in twips. Note that
// Get the actual border width for a particular side, in appunits. 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.