Work-in-progress for having maximum width (needed by tables) be updated

incrementally
This commit is contained in:
troy%netscape.com 1999-12-30 04:15:45 +00:00
Родитель 466850c23b
Коммит 4ddb903853
20 изменённых файлов: 346 добавлений и 34 удалений

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

@ -200,6 +200,9 @@ enum nsSpread {
//----------------------------------------------------------------------
// Option flags
#define NS_REFLOW_CALC_MAX_WIDTH 0x0001
/**
* Reflow metrics used to return the frame's desired size and alignment
* information.
@ -211,7 +214,11 @@ struct nsHTMLReflowMetrics {
nscoord ascent, descent; // [OUT] ascent and descent information
// Set this to null if you don't need to compute the max element size
nsSize* maxElementSize; // [IN OUT]
nsSize* maxElementSize; // [OUT]
// Used for incremental reflow. If the NS_REFLOW_CALC_MAX_WIDTH flag is set,
// then the caller is requesting that you update and return your maximum width
nscoord mMaximumWidth; // [OUT]
// Carried out bottom margin values. This is the collapsed
// (generational) bottom margin value.
@ -226,9 +233,13 @@ struct nsHTMLReflowMetrics {
// then the overflow area is identical to the desired size and should be
// {0, 0, mWidth, mHeight}.
nsRect mOverflowArea;
PRUint32 mFlags;
nsHTMLReflowMetrics(nsSize* aMaxElementSize) {
nsHTMLReflowMetrics(nsSize* aMaxElementSize, PRUint32 aFlags = 0) {
maxElementSize = aMaxElementSize;
mMaximumWidth = 0;
mFlags = aFlags;
mCarriedOutBottomMargin = 0;
mOverflowArea.x = 0;
mOverflowArea.y = 0;

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

@ -382,6 +382,12 @@ public:
#endif
}
void UpdateMaximumWidth(nscoord aMaximumWidth) {
if (aMaximumWidth > mMaximumWidth) {
mMaximumWidth = aMaximumWidth;
}
}
void RecoverVerticalMargins(nsLineBox* aLine,
PRBool aApplyTopMargin,
nscoord* aTopMarginResult,
@ -531,8 +537,10 @@ public:
nsFloaterCacheFreeList mBelowCurrentLineFloaters;
PRBool mComputeMaxElementSize;
PRBool mComputeMaximumWidth;
nsSize mMaxElementSize;
nscoord mMaximumWidth;
nscoord mMinLineHeight;
@ -643,6 +651,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mComputeMaxElementSize = nsnull != aMetrics.maxElementSize;
mMaxElementSize.SizeTo(0, 0);
mComputeMaximumWidth = NS_REFLOW_CALC_MAX_WIDTH == (aMetrics.mFlags & NS_REFLOW_CALC_MAX_WIDTH);
mMaximumWidth = 0;
if (0 != borderPadding.top) {
mIsTopMarginRoot = PR_TRUE;
@ -921,7 +931,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
// in this line.
mPrevChild = aLine->LastChild();
// Recover mKidXMost and max element width
// Recover mKidXMost and mMaxElementSize
nscoord xmost = aLine->mBounds.XMost();
if (xmost > mKidXMost) {
#ifdef DEBUG
@ -936,6 +946,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
UpdateMaxElementSize(nsSize(aLine->mMaxElementWidth, aLine->mBounds.height));
}
// If computing the maximum width, then update mMaximumWidth
if (mComputeMaximumWidth) {
UpdateMaximumWidth(aLine->mMaximumWidth);
}
// The line may have clear before semantics.
if (aLine->IsBlock() && aLine->HasBreak()) {
// Clear past floaters before the block if the clear style is not none
@ -1919,6 +1934,12 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
#endif
}
// If we're requested to update our maximum width, then compute it
if (aState.mComputeMaximumWidth) {
// We need to add in for the right border/padding
aMetrics.mMaximumWidth = aState.mMaximumWidth + borderPadding.right;
}
// Compute the combined area of our children
// XXX_perf: This can be done incrementally
nscoord xa = 0, ya = 0, xb = aMetrics.width, yb = aMetrics.height;
@ -3159,7 +3180,8 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
frame->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&) display);
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// See if we should apply the top margin. If the block frame being
@ -3366,6 +3388,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
ComputeLineMaxElementSize(aState, aLine, &maxElementSize);
}
}
// If we asked the block to update its maximum width, then record the
// updated value in the line, and update the current maximum width
if (aState.mComputeMaximumWidth) {
aLine->mMaximumWidth = brc.GetMaximumWidth();
aState.UpdateMaximumWidth(aLine->mMaximumWidth);
}
PostPlaceLine(aState, aLine, maxElementSize);
// Place the "marker" (bullet) frame.
@ -4195,6 +4224,13 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
aLine->mMaxElementWidth = aMaxElementSize.width;
}
// If this is an unconstrained reflow, then cache the line width in the
// line. We'll need this during incremental reflow if we're asked to
// calculate the maximum width
if (aState.mUnconstrainedWidth) {
aLine->mMaximumWidth = aLine->mBounds.XMost();
}
// Update xmost
nscoord xmost = aLine->mBounds.XMost();
#ifdef DEBUG
@ -4847,7 +4883,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
// Setup block reflow state to reflow the floater
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// Reflow the floater

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

@ -45,11 +45,13 @@
nsBlockReflowContext::nsBlockReflowContext(nsIPresContext* aPresContext,
const nsHTMLReflowState& aParentRS,
PRBool aComputeMaxElementSize)
PRBool aComputeMaxElementSize,
PRBool aComputeMaximumWidth)
: mPresContext(aPresContext),
mOuterReflowState(aParentRS),
mMetrics(aComputeMaxElementSize ? &mMaxElementSize : nsnull),
mMaxElementSize(0, 0)
mMaxElementSize(0, 0),
mComputeMaximumWidth(aComputeMaximumWidth)
{
mStyleSpacing = nsnull;
}
@ -144,6 +146,11 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
reason = eReflowReason_Incremental;
// Make sure we only incrementally reflow once
mNextRCFrame = nsnull;
// If we should compute the maximum width, then let the block know
if (mComputeMaximumWidth) {
mMetrics.mFlags |= NS_REFLOW_CALC_MAX_WIDTH;
}
}
else if (mOuterReflowState.reason == eReflowReason_StyleChange) {
reason = eReflowReason_StyleChange;

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

@ -38,7 +38,8 @@ class nsBlockReflowContext {
public:
nsBlockReflowContext(nsIPresContext* aPresContext,
const nsHTMLReflowState& aParentRS,
PRBool aComputeMaxElementSize);
PRBool aComputeMaxElementSize,
PRBool aComputeMaximumWidth);
~nsBlockReflowContext() { }
void SetNextRCFrame(nsIFrame* aNextRCFrame) {
@ -82,6 +83,10 @@ public:
const nsSize& GetMaxElementSize() const {
return mMaxElementSize;
}
nscoord GetMaximumWidth() const {
return mMetrics.mMaximumWidth;
}
// Compute the largest of two adjacent vertical margins, as per the
// CSS2 spec section 8.3.1
@ -126,6 +131,7 @@ protected:
nscoord mTopMargin;
nsSize mMaxElementSize;
PRBool mIsTable;
PRPackedBool mComputeMaximumWidth;
};
#endif /* nsBlockReflowContext_h___ */

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

@ -382,6 +382,12 @@ public:
#endif
}
void UpdateMaximumWidth(nscoord aMaximumWidth) {
if (aMaximumWidth > mMaximumWidth) {
mMaximumWidth = aMaximumWidth;
}
}
void RecoverVerticalMargins(nsLineBox* aLine,
PRBool aApplyTopMargin,
nscoord* aTopMarginResult,
@ -531,8 +537,10 @@ public:
nsFloaterCacheFreeList mBelowCurrentLineFloaters;
PRBool mComputeMaxElementSize;
PRBool mComputeMaximumWidth;
nsSize mMaxElementSize;
nscoord mMaximumWidth;
nscoord mMinLineHeight;
@ -643,6 +651,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mComputeMaxElementSize = nsnull != aMetrics.maxElementSize;
mMaxElementSize.SizeTo(0, 0);
mComputeMaximumWidth = NS_REFLOW_CALC_MAX_WIDTH == (aMetrics.mFlags & NS_REFLOW_CALC_MAX_WIDTH);
mMaximumWidth = 0;
if (0 != borderPadding.top) {
mIsTopMarginRoot = PR_TRUE;
@ -921,7 +931,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
// in this line.
mPrevChild = aLine->LastChild();
// Recover mKidXMost and max element width
// Recover mKidXMost and mMaxElementSize
nscoord xmost = aLine->mBounds.XMost();
if (xmost > mKidXMost) {
#ifdef DEBUG
@ -936,6 +946,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
UpdateMaxElementSize(nsSize(aLine->mMaxElementWidth, aLine->mBounds.height));
}
// If computing the maximum width, then update mMaximumWidth
if (mComputeMaximumWidth) {
UpdateMaximumWidth(aLine->mMaximumWidth);
}
// The line may have clear before semantics.
if (aLine->IsBlock() && aLine->HasBreak()) {
// Clear past floaters before the block if the clear style is not none
@ -1919,6 +1934,12 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
#endif
}
// If we're requested to update our maximum width, then compute it
if (aState.mComputeMaximumWidth) {
// We need to add in for the right border/padding
aMetrics.mMaximumWidth = aState.mMaximumWidth + borderPadding.right;
}
// Compute the combined area of our children
// XXX_perf: This can be done incrementally
nscoord xa = 0, ya = 0, xb = aMetrics.width, yb = aMetrics.height;
@ -3159,7 +3180,8 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
frame->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&) display);
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// See if we should apply the top margin. If the block frame being
@ -3366,6 +3388,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
ComputeLineMaxElementSize(aState, aLine, &maxElementSize);
}
}
// If we asked the block to update its maximum width, then record the
// updated value in the line, and update the current maximum width
if (aState.mComputeMaximumWidth) {
aLine->mMaximumWidth = brc.GetMaximumWidth();
aState.UpdateMaximumWidth(aLine->mMaximumWidth);
}
PostPlaceLine(aState, aLine, maxElementSize);
// Place the "marker" (bullet) frame.
@ -4195,6 +4224,13 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
aLine->mMaxElementWidth = aMaxElementSize.width;
}
// If this is an unconstrained reflow, then cache the line width in the
// line. We'll need this during incremental reflow if we're asked to
// calculate the maximum width
if (aState.mUnconstrainedWidth) {
aLine->mMaximumWidth = aLine->mBounds.XMost();
}
// Update xmost
nscoord xmost = aLine->mBounds.XMost();
#ifdef DEBUG
@ -4847,7 +4883,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
// Setup block reflow state to reflow the floater
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// Reflow the floater

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

@ -382,6 +382,12 @@ public:
#endif
}
void UpdateMaximumWidth(nscoord aMaximumWidth) {
if (aMaximumWidth > mMaximumWidth) {
mMaximumWidth = aMaximumWidth;
}
}
void RecoverVerticalMargins(nsLineBox* aLine,
PRBool aApplyTopMargin,
nscoord* aTopMarginResult,
@ -531,8 +537,10 @@ public:
nsFloaterCacheFreeList mBelowCurrentLineFloaters;
PRBool mComputeMaxElementSize;
PRBool mComputeMaximumWidth;
nsSize mMaxElementSize;
nscoord mMaximumWidth;
nscoord mMinLineHeight;
@ -643,6 +651,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mComputeMaxElementSize = nsnull != aMetrics.maxElementSize;
mMaxElementSize.SizeTo(0, 0);
mComputeMaximumWidth = NS_REFLOW_CALC_MAX_WIDTH == (aMetrics.mFlags & NS_REFLOW_CALC_MAX_WIDTH);
mMaximumWidth = 0;
if (0 != borderPadding.top) {
mIsTopMarginRoot = PR_TRUE;
@ -921,7 +931,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
// in this line.
mPrevChild = aLine->LastChild();
// Recover mKidXMost and max element width
// Recover mKidXMost and mMaxElementSize
nscoord xmost = aLine->mBounds.XMost();
if (xmost > mKidXMost) {
#ifdef DEBUG
@ -936,6 +946,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
UpdateMaxElementSize(nsSize(aLine->mMaxElementWidth, aLine->mBounds.height));
}
// If computing the maximum width, then update mMaximumWidth
if (mComputeMaximumWidth) {
UpdateMaximumWidth(aLine->mMaximumWidth);
}
// The line may have clear before semantics.
if (aLine->IsBlock() && aLine->HasBreak()) {
// Clear past floaters before the block if the clear style is not none
@ -1919,6 +1934,12 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
#endif
}
// If we're requested to update our maximum width, then compute it
if (aState.mComputeMaximumWidth) {
// We need to add in for the right border/padding
aMetrics.mMaximumWidth = aState.mMaximumWidth + borderPadding.right;
}
// Compute the combined area of our children
// XXX_perf: This can be done incrementally
nscoord xa = 0, ya = 0, xb = aMetrics.width, yb = aMetrics.height;
@ -3159,7 +3180,8 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
frame->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&) display);
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// See if we should apply the top margin. If the block frame being
@ -3366,6 +3388,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
ComputeLineMaxElementSize(aState, aLine, &maxElementSize);
}
}
// If we asked the block to update its maximum width, then record the
// updated value in the line, and update the current maximum width
if (aState.mComputeMaximumWidth) {
aLine->mMaximumWidth = brc.GetMaximumWidth();
aState.UpdateMaximumWidth(aLine->mMaximumWidth);
}
PostPlaceLine(aState, aLine, maxElementSize);
// Place the "marker" (bullet) frame.
@ -4195,6 +4224,13 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
aLine->mMaxElementWidth = aMaxElementSize.width;
}
// If this is an unconstrained reflow, then cache the line width in the
// line. We'll need this during incremental reflow if we're asked to
// calculate the maximum width
if (aState.mUnconstrainedWidth) {
aLine->mMaximumWidth = aLine->mBounds.XMost();
}
// Update xmost
nscoord xmost = aLine->mBounds.XMost();
#ifdef DEBUG
@ -4847,7 +4883,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
// Setup block reflow state to reflow the floater
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// Reflow the floater

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

@ -200,6 +200,9 @@ enum nsSpread {
//----------------------------------------------------------------------
// Option flags
#define NS_REFLOW_CALC_MAX_WIDTH 0x0001
/**
* Reflow metrics used to return the frame's desired size and alignment
* information.
@ -211,7 +214,11 @@ struct nsHTMLReflowMetrics {
nscoord ascent, descent; // [OUT] ascent and descent information
// Set this to null if you don't need to compute the max element size
nsSize* maxElementSize; // [IN OUT]
nsSize* maxElementSize; // [OUT]
// Used for incremental reflow. If the NS_REFLOW_CALC_MAX_WIDTH flag is set,
// then the caller is requesting that you update and return your maximum width
nscoord mMaximumWidth; // [OUT]
// Carried out bottom margin values. This is the collapsed
// (generational) bottom margin value.
@ -226,9 +233,13 @@ struct nsHTMLReflowMetrics {
// then the overflow area is identical to the desired size and should be
// {0, 0, mWidth, mHeight}.
nsRect mOverflowArea;
PRUint32 mFlags;
nsHTMLReflowMetrics(nsSize* aMaxElementSize) {
nsHTMLReflowMetrics(nsSize* aMaxElementSize, PRUint32 aFlags = 0) {
maxElementSize = aMaxElementSize;
mMaximumWidth = 0;
mFlags = aFlags;
mCarriedOutBottomMargin = 0;
mOverflowArea.x = 0;
mOverflowArea.y = 0;

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

@ -42,7 +42,8 @@ nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock)
mNext(nsnull),
mBounds(0, 0, 0, 0),
mMaxElementWidth(0),
mData(nsnull)
mData(nsnull),
mMaximumWidth(-1)
{
MOZ_COUNT_CTOR(nsLineBox);
#ifdef DEBUG

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

@ -291,6 +291,7 @@ public:
nsRect mBounds;
nscoord mMaxElementWidth; // width part of max-element-size
nscoord mMaximumWidth; // maximum width (needed for incremental reflow of tables)
struct FlagBits {
PRUint32 mDirty : 1;

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

@ -382,6 +382,12 @@ public:
#endif
}
void UpdateMaximumWidth(nscoord aMaximumWidth) {
if (aMaximumWidth > mMaximumWidth) {
mMaximumWidth = aMaximumWidth;
}
}
void RecoverVerticalMargins(nsLineBox* aLine,
PRBool aApplyTopMargin,
nscoord* aTopMarginResult,
@ -531,8 +537,10 @@ public:
nsFloaterCacheFreeList mBelowCurrentLineFloaters;
PRBool mComputeMaxElementSize;
PRBool mComputeMaximumWidth;
nsSize mMaxElementSize;
nscoord mMaximumWidth;
nscoord mMinLineHeight;
@ -643,6 +651,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mComputeMaxElementSize = nsnull != aMetrics.maxElementSize;
mMaxElementSize.SizeTo(0, 0);
mComputeMaximumWidth = NS_REFLOW_CALC_MAX_WIDTH == (aMetrics.mFlags & NS_REFLOW_CALC_MAX_WIDTH);
mMaximumWidth = 0;
if (0 != borderPadding.top) {
mIsTopMarginRoot = PR_TRUE;
@ -921,7 +931,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
// in this line.
mPrevChild = aLine->LastChild();
// Recover mKidXMost and max element width
// Recover mKidXMost and mMaxElementSize
nscoord xmost = aLine->mBounds.XMost();
if (xmost > mKidXMost) {
#ifdef DEBUG
@ -936,6 +946,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
UpdateMaxElementSize(nsSize(aLine->mMaxElementWidth, aLine->mBounds.height));
}
// If computing the maximum width, then update mMaximumWidth
if (mComputeMaximumWidth) {
UpdateMaximumWidth(aLine->mMaximumWidth);
}
// The line may have clear before semantics.
if (aLine->IsBlock() && aLine->HasBreak()) {
// Clear past floaters before the block if the clear style is not none
@ -1919,6 +1934,12 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
#endif
}
// If we're requested to update our maximum width, then compute it
if (aState.mComputeMaximumWidth) {
// We need to add in for the right border/padding
aMetrics.mMaximumWidth = aState.mMaximumWidth + borderPadding.right;
}
// Compute the combined area of our children
// XXX_perf: This can be done incrementally
nscoord xa = 0, ya = 0, xb = aMetrics.width, yb = aMetrics.height;
@ -3159,7 +3180,8 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
frame->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&) display);
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// See if we should apply the top margin. If the block frame being
@ -3366,6 +3388,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
ComputeLineMaxElementSize(aState, aLine, &maxElementSize);
}
}
// If we asked the block to update its maximum width, then record the
// updated value in the line, and update the current maximum width
if (aState.mComputeMaximumWidth) {
aLine->mMaximumWidth = brc.GetMaximumWidth();
aState.UpdateMaximumWidth(aLine->mMaximumWidth);
}
PostPlaceLine(aState, aLine, maxElementSize);
// Place the "marker" (bullet) frame.
@ -4195,6 +4224,13 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
aLine->mMaxElementWidth = aMaxElementSize.width;
}
// If this is an unconstrained reflow, then cache the line width in the
// line. We'll need this during incremental reflow if we're asked to
// calculate the maximum width
if (aState.mUnconstrainedWidth) {
aLine->mMaximumWidth = aLine->mBounds.XMost();
}
// Update xmost
nscoord xmost = aLine->mBounds.XMost();
#ifdef DEBUG
@ -4847,7 +4883,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
// Setup block reflow state to reflow the floater
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// Reflow the floater

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

@ -45,11 +45,13 @@
nsBlockReflowContext::nsBlockReflowContext(nsIPresContext* aPresContext,
const nsHTMLReflowState& aParentRS,
PRBool aComputeMaxElementSize)
PRBool aComputeMaxElementSize,
PRBool aComputeMaximumWidth)
: mPresContext(aPresContext),
mOuterReflowState(aParentRS),
mMetrics(aComputeMaxElementSize ? &mMaxElementSize : nsnull),
mMaxElementSize(0, 0)
mMaxElementSize(0, 0),
mComputeMaximumWidth(aComputeMaximumWidth)
{
mStyleSpacing = nsnull;
}
@ -144,6 +146,11 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
reason = eReflowReason_Incremental;
// Make sure we only incrementally reflow once
mNextRCFrame = nsnull;
// If we should compute the maximum width, then let the block know
if (mComputeMaximumWidth) {
mMetrics.mFlags |= NS_REFLOW_CALC_MAX_WIDTH;
}
}
else if (mOuterReflowState.reason == eReflowReason_StyleChange) {
reason = eReflowReason_StyleChange;

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

@ -38,7 +38,8 @@ class nsBlockReflowContext {
public:
nsBlockReflowContext(nsIPresContext* aPresContext,
const nsHTMLReflowState& aParentRS,
PRBool aComputeMaxElementSize);
PRBool aComputeMaxElementSize,
PRBool aComputeMaximumWidth);
~nsBlockReflowContext() { }
void SetNextRCFrame(nsIFrame* aNextRCFrame) {
@ -82,6 +83,10 @@ public:
const nsSize& GetMaxElementSize() const {
return mMaxElementSize;
}
nscoord GetMaximumWidth() const {
return mMetrics.mMaximumWidth;
}
// Compute the largest of two adjacent vertical margins, as per the
// CSS2 spec section 8.3.1
@ -126,6 +131,7 @@ protected:
nscoord mTopMargin;
nsSize mMaxElementSize;
PRBool mIsTable;
PRPackedBool mComputeMaximumWidth;
};
#endif /* nsBlockReflowContext_h___ */

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

@ -382,6 +382,12 @@ public:
#endif
}
void UpdateMaximumWidth(nscoord aMaximumWidth) {
if (aMaximumWidth > mMaximumWidth) {
mMaximumWidth = aMaximumWidth;
}
}
void RecoverVerticalMargins(nsLineBox* aLine,
PRBool aApplyTopMargin,
nscoord* aTopMarginResult,
@ -531,8 +537,10 @@ public:
nsFloaterCacheFreeList mBelowCurrentLineFloaters;
PRBool mComputeMaxElementSize;
PRBool mComputeMaximumWidth;
nsSize mMaxElementSize;
nscoord mMaximumWidth;
nscoord mMinLineHeight;
@ -643,6 +651,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mComputeMaxElementSize = nsnull != aMetrics.maxElementSize;
mMaxElementSize.SizeTo(0, 0);
mComputeMaximumWidth = NS_REFLOW_CALC_MAX_WIDTH == (aMetrics.mFlags & NS_REFLOW_CALC_MAX_WIDTH);
mMaximumWidth = 0;
if (0 != borderPadding.top) {
mIsTopMarginRoot = PR_TRUE;
@ -921,7 +931,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
// in this line.
mPrevChild = aLine->LastChild();
// Recover mKidXMost and max element width
// Recover mKidXMost and mMaxElementSize
nscoord xmost = aLine->mBounds.XMost();
if (xmost > mKidXMost) {
#ifdef DEBUG
@ -936,6 +946,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
UpdateMaxElementSize(nsSize(aLine->mMaxElementWidth, aLine->mBounds.height));
}
// If computing the maximum width, then update mMaximumWidth
if (mComputeMaximumWidth) {
UpdateMaximumWidth(aLine->mMaximumWidth);
}
// The line may have clear before semantics.
if (aLine->IsBlock() && aLine->HasBreak()) {
// Clear past floaters before the block if the clear style is not none
@ -1919,6 +1934,12 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
#endif
}
// If we're requested to update our maximum width, then compute it
if (aState.mComputeMaximumWidth) {
// We need to add in for the right border/padding
aMetrics.mMaximumWidth = aState.mMaximumWidth + borderPadding.right;
}
// Compute the combined area of our children
// XXX_perf: This can be done incrementally
nscoord xa = 0, ya = 0, xb = aMetrics.width, yb = aMetrics.height;
@ -3159,7 +3180,8 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
frame->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&) display);
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// See if we should apply the top margin. If the block frame being
@ -3366,6 +3388,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
ComputeLineMaxElementSize(aState, aLine, &maxElementSize);
}
}
// If we asked the block to update its maximum width, then record the
// updated value in the line, and update the current maximum width
if (aState.mComputeMaximumWidth) {
aLine->mMaximumWidth = brc.GetMaximumWidth();
aState.UpdateMaximumWidth(aLine->mMaximumWidth);
}
PostPlaceLine(aState, aLine, maxElementSize);
// Place the "marker" (bullet) frame.
@ -4195,6 +4224,13 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
aLine->mMaxElementWidth = aMaxElementSize.width;
}
// If this is an unconstrained reflow, then cache the line width in the
// line. We'll need this during incremental reflow if we're asked to
// calculate the maximum width
if (aState.mUnconstrainedWidth) {
aLine->mMaximumWidth = aLine->mBounds.XMost();
}
// Update xmost
nscoord xmost = aLine->mBounds.XMost();
#ifdef DEBUG
@ -4847,7 +4883,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
// Setup block reflow state to reflow the floater
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// Reflow the floater

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

@ -382,6 +382,12 @@ public:
#endif
}
void UpdateMaximumWidth(nscoord aMaximumWidth) {
if (aMaximumWidth > mMaximumWidth) {
mMaximumWidth = aMaximumWidth;
}
}
void RecoverVerticalMargins(nsLineBox* aLine,
PRBool aApplyTopMargin,
nscoord* aTopMarginResult,
@ -531,8 +537,10 @@ public:
nsFloaterCacheFreeList mBelowCurrentLineFloaters;
PRBool mComputeMaxElementSize;
PRBool mComputeMaximumWidth;
nsSize mMaxElementSize;
nscoord mMaximumWidth;
nscoord mMinLineHeight;
@ -643,6 +651,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mComputeMaxElementSize = nsnull != aMetrics.maxElementSize;
mMaxElementSize.SizeTo(0, 0);
mComputeMaximumWidth = NS_REFLOW_CALC_MAX_WIDTH == (aMetrics.mFlags & NS_REFLOW_CALC_MAX_WIDTH);
mMaximumWidth = 0;
if (0 != borderPadding.top) {
mIsTopMarginRoot = PR_TRUE;
@ -921,7 +931,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
// in this line.
mPrevChild = aLine->LastChild();
// Recover mKidXMost and max element width
// Recover mKidXMost and mMaxElementSize
nscoord xmost = aLine->mBounds.XMost();
if (xmost > mKidXMost) {
#ifdef DEBUG
@ -936,6 +946,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
UpdateMaxElementSize(nsSize(aLine->mMaxElementWidth, aLine->mBounds.height));
}
// If computing the maximum width, then update mMaximumWidth
if (mComputeMaximumWidth) {
UpdateMaximumWidth(aLine->mMaximumWidth);
}
// The line may have clear before semantics.
if (aLine->IsBlock() && aLine->HasBreak()) {
// Clear past floaters before the block if the clear style is not none
@ -1919,6 +1934,12 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
#endif
}
// If we're requested to update our maximum width, then compute it
if (aState.mComputeMaximumWidth) {
// We need to add in for the right border/padding
aMetrics.mMaximumWidth = aState.mMaximumWidth + borderPadding.right;
}
// Compute the combined area of our children
// XXX_perf: This can be done incrementally
nscoord xa = 0, ya = 0, xb = aMetrics.width, yb = aMetrics.height;
@ -3159,7 +3180,8 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
frame->GetStyleData(eStyleStruct_Display,
(const nsStyleStruct*&) display);
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// See if we should apply the top margin. If the block frame being
@ -3366,6 +3388,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
ComputeLineMaxElementSize(aState, aLine, &maxElementSize);
}
}
// If we asked the block to update its maximum width, then record the
// updated value in the line, and update the current maximum width
if (aState.mComputeMaximumWidth) {
aLine->mMaximumWidth = brc.GetMaximumWidth();
aState.UpdateMaximumWidth(aLine->mMaximumWidth);
}
PostPlaceLine(aState, aLine, maxElementSize);
// Place the "marker" (bullet) frame.
@ -4195,6 +4224,13 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
aLine->mMaxElementWidth = aMaxElementSize.width;
}
// If this is an unconstrained reflow, then cache the line width in the
// line. We'll need this during incremental reflow if we're asked to
// calculate the maximum width
if (aState.mUnconstrainedWidth) {
aLine->mMaximumWidth = aLine->mBounds.XMost();
}
// Update xmost
nscoord xmost = aLine->mBounds.XMost();
#ifdef DEBUG
@ -4847,7 +4883,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
// Setup block reflow state to reflow the floater
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
aState.mComputeMaxElementSize);
aState.mComputeMaxElementSize,
aState.mComputeMaximumWidth);
brc.SetNextRCFrame(aState.mNextRCFrame);
// Reflow the floater

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

@ -42,7 +42,8 @@ nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock)
mNext(nsnull),
mBounds(0, 0, 0, 0),
mMaxElementWidth(0),
mData(nsnull)
mData(nsnull),
mMaximumWidth(-1)
{
MOZ_COUNT_CTOR(nsLineBox);
#ifdef DEBUG

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

@ -291,6 +291,7 @@ public:
nsRect mBounds;
nscoord mMaxElementWidth; // width part of max-element-size
nscoord mMaximumWidth; // maximum width (needed for incremental reflow of tables)
struct FlagBits {
PRUint32 mDirty : 1;

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

@ -635,7 +635,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
if (availSize.height < 0)
availSize.height = 1;
nsHTMLReflowMetrics kidSize(pMaxElementSize);
nsHTMLReflowMetrics kidSize(pMaxElementSize, aDesiredSize.mFlags);
kidSize.width=kidSize.height=kidSize.ascent=kidSize.descent=0;
SetPriorAvailWidth(aReflowState.availableWidth);
nsIFrame* firstKid = mFrames.FirstChild();
@ -761,6 +761,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.height = cellHeight;
aDesiredSize.ascent = topInset;
aDesiredSize.descent = bottomInset;
if (aDesiredSize.mFlags & NS_REFLOW_CALC_MAX_WIDTH) {
aDesiredSize.mMaximumWidth = kidSize.mMaximumWidth + leftInset + rightInset;
}
if (nsnull!=aDesiredSize.maxElementSize) {
*aDesiredSize.maxElementSize = *pMaxElementSize;
if (0!=pMaxElementSize->height) {

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

@ -1236,7 +1236,7 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
// Pass along the reflow command
nsSize kidMaxElementSize;
nsHTMLReflowMetrics desiredSize(&kidMaxElementSize);
nsHTMLReflowMetrics desiredSize(&kidMaxElementSize, NS_REFLOW_CALC_MAX_WIDTH);
nsHTMLReflowState kidReflowState(aPresContext,
aReflowState.reflowState,
aNextFrame, kidAvailSize);
@ -1262,7 +1262,12 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
// Update the cell layout data.
((nsTableCellFrame *)aNextFrame)->SetPass1MaxElementSize(kidMaxElementSize);
// XXX TROY Not ready to be turned on yet...
#if 0
((nsTableCellFrame *)aNextFrame)->SetMaximumWidth(desiredSize.mMaximumWidth);
#endif
#if 1
// Now see if we need to do the regular pass 1 reflow and gather the preferred
// width. If the new minimum width is different from the old minimum width,
// then we should consider the max element size
@ -1323,6 +1328,17 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
aReflowState.tableFrame->InvalidateColumnWidths();
}
}
#else
// Now that we know the minimum and preferred widths see if the column
// widths need to be rebalanced
if (!aReflowState.tableFrame->ColumnsAreValidFor(*(nsTableCellFrame*)aNextFrame,
oldMinSize.width,
oldMaximumWidth)) {
// The column widths need to be rebalanced. Tell the table to rebalance
// the column widths
aReflowState.tableFrame->InvalidateColumnWidths();
}
#endif
// Calculate the cell's actual size given its pass2 size. This function
// takes into account the specified height (in the style), and any special

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

@ -635,7 +635,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
if (availSize.height < 0)
availSize.height = 1;
nsHTMLReflowMetrics kidSize(pMaxElementSize);
nsHTMLReflowMetrics kidSize(pMaxElementSize, aDesiredSize.mFlags);
kidSize.width=kidSize.height=kidSize.ascent=kidSize.descent=0;
SetPriorAvailWidth(aReflowState.availableWidth);
nsIFrame* firstKid = mFrames.FirstChild();
@ -761,6 +761,9 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.height = cellHeight;
aDesiredSize.ascent = topInset;
aDesiredSize.descent = bottomInset;
if (aDesiredSize.mFlags & NS_REFLOW_CALC_MAX_WIDTH) {
aDesiredSize.mMaximumWidth = kidSize.mMaximumWidth + leftInset + rightInset;
}
if (nsnull!=aDesiredSize.maxElementSize) {
*aDesiredSize.maxElementSize = *pMaxElementSize;
if (0!=pMaxElementSize->height) {

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

@ -1236,7 +1236,7 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
// Pass along the reflow command
nsSize kidMaxElementSize;
nsHTMLReflowMetrics desiredSize(&kidMaxElementSize);
nsHTMLReflowMetrics desiredSize(&kidMaxElementSize, NS_REFLOW_CALC_MAX_WIDTH);
nsHTMLReflowState kidReflowState(aPresContext,
aReflowState.reflowState,
aNextFrame, kidAvailSize);
@ -1262,7 +1262,12 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
// Update the cell layout data.
((nsTableCellFrame *)aNextFrame)->SetPass1MaxElementSize(kidMaxElementSize);
// XXX TROY Not ready to be turned on yet...
#if 0
((nsTableCellFrame *)aNextFrame)->SetMaximumWidth(desiredSize.mMaximumWidth);
#endif
#if 1
// Now see if we need to do the regular pass 1 reflow and gather the preferred
// width. If the new minimum width is different from the old minimum width,
// then we should consider the max element size
@ -1323,6 +1328,17 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
aReflowState.tableFrame->InvalidateColumnWidths();
}
}
#else
// Now that we know the minimum and preferred widths see if the column
// widths need to be rebalanced
if (!aReflowState.tableFrame->ColumnsAreValidFor(*(nsTableCellFrame*)aNextFrame,
oldMinSize.width,
oldMaximumWidth)) {
// The column widths need to be rebalanced. Tell the table to rebalance
// the column widths
aReflowState.tableFrame->InvalidateColumnWidths();
}
#endif
// Calculate the cell's actual size given its pass2 size. This function
// takes into account the specified height (in the style), and any special