Bug 197065. Do more complete invalidation on block size changes. r=jkeiser,sr=dbaron

This commit is contained in:
roc+%cs.cmu.edu 2003-04-05 21:27:45 +00:00
Родитель 9e2ee95ed4
Коммит 825677d0f1
8 изменённых файлов: 124 добавлений и 192 удалений

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

@ -1069,8 +1069,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
}
#endif
// Determine if we need to repaint our border
CheckInvalidateBorder(aPresContext, aMetrics, aReflowState);
// Determine if we need to repaint our border, background or outline
CheckInvalidateSizeChange(aPresContext, aMetrics, aReflowState);
// Let the absolutely positioned container reflow any absolutely positioned
// child frames that need to be reflowed, e.g., elements with a percentage

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

@ -574,8 +574,8 @@ nsHTMLFrameOuterFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.mMaxElementWidth = kidMetrics.mMaxElementWidth;
}
// Determine if we need to repaint our border
CheckInvalidateBorder(aPresContext, aDesiredSize, aReflowState);
// Determine if we need to repaint our border, background or outline
CheckInvalidateSizeChange(aPresContext, aDesiredSize, aReflowState);
{
// Invalidate the frame

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

@ -698,100 +698,64 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext,
}
void
nsHTMLContainerFrame::CheckInvalidateBorder(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState)
nsHTMLContainerFrame::CheckInvalidateSizeChange(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState)
{
// XXX This method ought to deal with padding as well
// If this is a style change reflow targeted at this frame, we must repaint
// everything (well, we really just have to repaint the borders but we're
// a bunch of lazybones).
if (aReflowState.reason == eReflowReason_Incremental) {
nsHTMLReflowCommand *command = aReflowState.path->mReflowCommand;
if (command) {
nsReflowType type;
command->GetType(type);
if (type == eReflowType_StyleChanged) {
if (aDesiredSize.width == mRect.width
&& aDesiredSize.height == mRect.height)
return;
#ifdef NOISY_BLOCK_INVALIDATE
printf("%p invalidate 1 (%d, %d, %d, %d)\n",
this, 0, 0, mRect.width, mRect.height);
#endif
// Below, we invalidate the old frame area (or, in the case of
// outline, combined area) if the outline, border or background
// settings indicate that something other than the difference
// between the old and new areas needs to be painted. We are
// assuming that the difference between the old and new areas will
// be invalidated by some other means. That also means invalidating
// the old frame area is the same as invalidating the new frame area
// (since in either case the UNION of old and new areas will be
// invalidated)
// Lots of things could have changed so damage our entire bounds
nsRect damageRect(0, 0, mRect.width, mRect.height);
if (!damageRect.IsEmpty()) {
Invalidate(aPresContext,damageRect);
}
// Invalidate the entire old frame+outline if the frame has an outline
return;
}
// This assumes 'outline' is painted outside the element, as CSS2 requires.
// Currently we actually paint 'outline' inside the element so this code
// isn't strictly necessary. But we're trying to get ready to switch to
// CSS2 compliance.
const nsStyleOutline* outline;
::GetStyleData(this, &outline);
PRUint8 outlineStyle = outline->GetOutlineStyle();
if (outlineStyle != NS_STYLE_BORDER_STYLE_NONE
&& outlineStyle != NS_STYLE_BORDER_STYLE_HIDDEN) {
nscoord width;
outline->GetOutlineWidth(width);
if (width > 0) {
nsRect r(0, 0, mRect.width, mRect.height);
r.Inflate(width, width);
Invalidate(aPresContext, r);
return;
}
}
// If we changed size, we must invalidate the parts of us that have changed
// to make the border show up.
if ((aReflowState.reason == eReflowReason_Incremental ||
aReflowState.reason == eReflowReason_Dirty)) {
nsMargin border = aReflowState.mComputedBorderPadding -
aReflowState.mComputedPadding;
// Invalidate the old frame if the frame has borders. Those borders
// may be moving.
const nsStyleBorder* border;
::GetStyleData(this, &border);
if (border->IsBorderSideVisible(NS_SIDE_LEFT)
|| border->IsBorderSideVisible(NS_SIDE_RIGHT)
|| border->IsBorderSideVisible(NS_SIDE_TOP)
|| border->IsBorderSideVisible(NS_SIDE_BOTTOM)) {
Invalidate(aPresContext, nsRect(0, 0, mRect.width, mRect.height));
return;
}
// See if our width changed
if ((aDesiredSize.width != mRect.width) && (border.right > 0)) {
nsRect damageRect;
if (aDesiredSize.width < mRect.width) {
// Our new width is smaller, so we need to make sure that
// we paint our border in its new position
damageRect.x = aDesiredSize.width - border.right;
damageRect.width = border.right;
damageRect.y = 0;
damageRect.height = aDesiredSize.height;
} else {
// Our new width is larger, so we need to erase our border in its
// old position
damageRect.x = mRect.width - border.right;
damageRect.width = border.right;
damageRect.y = 0;
damageRect.height = mRect.height;
}
#ifdef NOISY_BLOCK_INVALIDATE
printf("%p invalidate 2 (%d, %d, %d, %d)\n",
this, damageRect.x, damageRect.y, damageRect.width, damageRect.height);
#endif
if (!damageRect.IsEmpty()) {
Invalidate(aPresContext, damageRect);
}
}
// See if our height changed
if ((aDesiredSize.height != mRect.height) && (border.bottom > 0)) {
nsRect damageRect;
if (aDesiredSize.height < mRect.height) {
// Our new height is smaller, so we need to make sure that
// we paint our border in its new position
damageRect.x = 0;
damageRect.width = aDesiredSize.width;
damageRect.y = aDesiredSize.height - border.bottom;
damageRect.height = border.bottom;
} else {
// Our new height is larger, so we need to erase our border in its
// old position
damageRect.x = 0;
damageRect.width = mRect.width;
damageRect.y = mRect.height - border.bottom;
damageRect.height = border.bottom;
}
#ifdef NOISY_BLOCK_INVALIDATE
printf("%p invalidate 3 (%d, %d, %d, %d)\n",
this, damageRect.x, damageRect.y, damageRect.width, damageRect.height);
#endif
if (!damageRect.IsEmpty()) {
Invalidate(aPresContext, damageRect);
}
}
// Invalidate the old frame if the frame has a background
// whose position depends on the size of the frame
const nsStyleBackground* background;
::GetStyleData(this, &background);
if (background->mBackgroundFlags &
(NS_STYLE_BG_X_POSITION_PERCENT | NS_STYLE_BG_Y_POSITION_PERCENT)) {
Invalidate(aPresContext, nsRect(0, 0, mRect.width, mRect.height));
return;
}
}

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

@ -110,15 +110,17 @@ public:
/**
* Helper method to invalidate portions of a standard container frame if the
* reflow state indicates that they have changed (specifically border and
* padding).
* reflow state indicates that the size has changed (specifically border,
* background and outline).
* We assume that the difference between the old frame area and the new
* frame area is invalidated by some other means.
* @param aPresContext the presentation context
* @param aDesiredSize the new size of the frame
* @param aReflowState the reflow that was just done on this frame
*/
void CheckInvalidateBorder(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState);
void CheckInvalidateSizeChange(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState);
protected:
virtual PRIntn GetSkipSides() const = 0;

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

@ -1069,8 +1069,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
}
#endif
// Determine if we need to repaint our border
CheckInvalidateBorder(aPresContext, aMetrics, aReflowState);
// Determine if we need to repaint our border, background or outline
CheckInvalidateSizeChange(aPresContext, aMetrics, aReflowState);
// Let the absolutely positioned container reflow any absolutely positioned
// child frames that need to be reflowed, e.g., elements with a percentage

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

@ -698,100 +698,64 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext,
}
void
nsHTMLContainerFrame::CheckInvalidateBorder(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState)
nsHTMLContainerFrame::CheckInvalidateSizeChange(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState)
{
// XXX This method ought to deal with padding as well
// If this is a style change reflow targeted at this frame, we must repaint
// everything (well, we really just have to repaint the borders but we're
// a bunch of lazybones).
if (aReflowState.reason == eReflowReason_Incremental) {
nsHTMLReflowCommand *command = aReflowState.path->mReflowCommand;
if (command) {
nsReflowType type;
command->GetType(type);
if (type == eReflowType_StyleChanged) {
if (aDesiredSize.width == mRect.width
&& aDesiredSize.height == mRect.height)
return;
#ifdef NOISY_BLOCK_INVALIDATE
printf("%p invalidate 1 (%d, %d, %d, %d)\n",
this, 0, 0, mRect.width, mRect.height);
#endif
// Below, we invalidate the old frame area (or, in the case of
// outline, combined area) if the outline, border or background
// settings indicate that something other than the difference
// between the old and new areas needs to be painted. We are
// assuming that the difference between the old and new areas will
// be invalidated by some other means. That also means invalidating
// the old frame area is the same as invalidating the new frame area
// (since in either case the UNION of old and new areas will be
// invalidated)
// Lots of things could have changed so damage our entire bounds
nsRect damageRect(0, 0, mRect.width, mRect.height);
if (!damageRect.IsEmpty()) {
Invalidate(aPresContext,damageRect);
}
// Invalidate the entire old frame+outline if the frame has an outline
return;
}
// This assumes 'outline' is painted outside the element, as CSS2 requires.
// Currently we actually paint 'outline' inside the element so this code
// isn't strictly necessary. But we're trying to get ready to switch to
// CSS2 compliance.
const nsStyleOutline* outline;
::GetStyleData(this, &outline);
PRUint8 outlineStyle = outline->GetOutlineStyle();
if (outlineStyle != NS_STYLE_BORDER_STYLE_NONE
&& outlineStyle != NS_STYLE_BORDER_STYLE_HIDDEN) {
nscoord width;
outline->GetOutlineWidth(width);
if (width > 0) {
nsRect r(0, 0, mRect.width, mRect.height);
r.Inflate(width, width);
Invalidate(aPresContext, r);
return;
}
}
// If we changed size, we must invalidate the parts of us that have changed
// to make the border show up.
if ((aReflowState.reason == eReflowReason_Incremental ||
aReflowState.reason == eReflowReason_Dirty)) {
nsMargin border = aReflowState.mComputedBorderPadding -
aReflowState.mComputedPadding;
// Invalidate the old frame if the frame has borders. Those borders
// may be moving.
const nsStyleBorder* border;
::GetStyleData(this, &border);
if (border->IsBorderSideVisible(NS_SIDE_LEFT)
|| border->IsBorderSideVisible(NS_SIDE_RIGHT)
|| border->IsBorderSideVisible(NS_SIDE_TOP)
|| border->IsBorderSideVisible(NS_SIDE_BOTTOM)) {
Invalidate(aPresContext, nsRect(0, 0, mRect.width, mRect.height));
return;
}
// See if our width changed
if ((aDesiredSize.width != mRect.width) && (border.right > 0)) {
nsRect damageRect;
if (aDesiredSize.width < mRect.width) {
// Our new width is smaller, so we need to make sure that
// we paint our border in its new position
damageRect.x = aDesiredSize.width - border.right;
damageRect.width = border.right;
damageRect.y = 0;
damageRect.height = aDesiredSize.height;
} else {
// Our new width is larger, so we need to erase our border in its
// old position
damageRect.x = mRect.width - border.right;
damageRect.width = border.right;
damageRect.y = 0;
damageRect.height = mRect.height;
}
#ifdef NOISY_BLOCK_INVALIDATE
printf("%p invalidate 2 (%d, %d, %d, %d)\n",
this, damageRect.x, damageRect.y, damageRect.width, damageRect.height);
#endif
if (!damageRect.IsEmpty()) {
Invalidate(aPresContext, damageRect);
}
}
// See if our height changed
if ((aDesiredSize.height != mRect.height) && (border.bottom > 0)) {
nsRect damageRect;
if (aDesiredSize.height < mRect.height) {
// Our new height is smaller, so we need to make sure that
// we paint our border in its new position
damageRect.x = 0;
damageRect.width = aDesiredSize.width;
damageRect.y = aDesiredSize.height - border.bottom;
damageRect.height = border.bottom;
} else {
// Our new height is larger, so we need to erase our border in its
// old position
damageRect.x = 0;
damageRect.width = mRect.width;
damageRect.y = mRect.height - border.bottom;
damageRect.height = border.bottom;
}
#ifdef NOISY_BLOCK_INVALIDATE
printf("%p invalidate 3 (%d, %d, %d, %d)\n",
this, damageRect.x, damageRect.y, damageRect.width, damageRect.height);
#endif
if (!damageRect.IsEmpty()) {
Invalidate(aPresContext, damageRect);
}
}
// Invalidate the old frame if the frame has a background
// whose position depends on the size of the frame
const nsStyleBackground* background;
::GetStyleData(this, &background);
if (background->mBackgroundFlags &
(NS_STYLE_BG_X_POSITION_PERCENT | NS_STYLE_BG_Y_POSITION_PERCENT)) {
Invalidate(aPresContext, nsRect(0, 0, mRect.width, mRect.height));
return;
}
}

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

@ -110,15 +110,17 @@ public:
/**
* Helper method to invalidate portions of a standard container frame if the
* reflow state indicates that they have changed (specifically border and
* padding).
* reflow state indicates that the size has changed (specifically border,
* background and outline).
* We assume that the difference between the old frame area and the new
* frame area is invalidated by some other means.
* @param aPresContext the presentation context
* @param aDesiredSize the new size of the frame
* @param aReflowState the reflow that was just done on this frame
*/
void CheckInvalidateBorder(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState);
void CheckInvalidateSizeChange(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState);
protected:
virtual PRIntn GetSkipSides() const = 0;

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

@ -574,8 +574,8 @@ nsHTMLFrameOuterFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.mMaxElementWidth = kidMetrics.mMaxElementWidth;
}
// Determine if we need to repaint our border
CheckInvalidateBorder(aPresContext, aDesiredSize, aReflowState);
// Determine if we need to repaint our border, background or outline
CheckInvalidateSizeChange(aPresContext, aDesiredSize, aReflowState);
{
// Invalidate the frame