Moved floater reflow out of PlaceFloater and into AddFloater so that floaters are only reflowed during reflow, not during placement; Added code to support css 10.3.5; reflow floaters more often so that % width values are recomputed properly

This commit is contained in:
kipp%netscape.com 1998-12-15 04:20:54 +00:00
Родитель daf32efa74
Коммит 081d6a2815
6 изменённых файлов: 222 добавлений и 324 удалений

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

@ -184,7 +184,8 @@ public:
void InitFloater(nsPlaceholderFrame* aPlaceholderFrame); void InitFloater(nsPlaceholderFrame* aPlaceholderFrame);
void AddFloater(nsPlaceholderFrame* aPlaceholderFrame); void AddFloater(nsPlaceholderFrame* aPlaceholderFrame,
PRBool aInitialReflow);
void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater); void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater);
@ -253,7 +254,7 @@ nsLineLayout::InitFloater(nsPlaceholderFrame* aFrame)
void void
nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame) nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame)
{ {
mBlockReflowState->AddFloater(aFrame); mBlockReflowState->AddFloater(aFrame, PR_FALSE);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1176,13 +1177,7 @@ nsresult
nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState)
{ {
// XXX temporary // XXX temporary
// Mark everything dirty return PrepareResizeReflow(aState);
nsLineBox* line = mLines;
while (nsnull != line) {
line->MarkDirty();
line = line->mNext;
}
return NS_OK;
} }
nsresult nsresult
@ -1610,11 +1605,6 @@ nsBaseIBFrame::ReflowLine(nsBlockReflowState& aState,
// If the line already has floaters on it from last time, remove // If the line already has floaters on it from last time, remove
// them from the spacemanager now. // them from the spacemanager now.
if (nsnull != aLine->mFloaters) { if (nsnull != aLine->mFloaters) {
#if 0
if (eReflowReason_Resize != aState.reason) {
aLine->UnplaceFloaters(aState.mSpaceManager);
}
#endif
aLine->mFloaters->Clear(); aLine->mFloaters->Clear();
} }
@ -3357,25 +3347,19 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right; kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right;
} }
else { else {
// If we are floating something and we don't know the width then // CSS2 section 10.3.5: Floating non-replaced elements with an
// find a maximum width for it to reflow into. Walk upwards until // auto width have the computed value of zero. Therefore, don't
// we find something with an unconstrained width. // bother reflowing them.
const nsHTMLReflowState* rsp = &aState; if (NS_FRAME_IS_NOT_REPLACED(aFloaterReflowState.frameType)) {
kidAvailSize.width = 0; // XXX Tables are weird and special, so check for them here...
while (nsnull != rsp) { const nsStyleDisplay* floaterDisplay;
if (eHTMLFrameConstraint_FixedContent == rsp->widthConstraint) { aFloaterFrame->GetStyleData(eStyleStruct_Display,
kidAvailSize.width = rsp->minWidth; (const nsStyleStruct*&)floaterDisplay);
break; if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay) {
} return;
else if (NS_UNCONSTRAINEDSIZE != rsp->widthConstraint) {
kidAvailSize.width = rsp->maxSize.width;
if (kidAvailSize.width > 0) {
break;
} }
} }
// XXX This cast is unfortunate! kidAvailSize.width = NS_UNCONSTRAINEDSIZE;
rsp = (const nsHTMLReflowState*) rsp->parentReflowState;
}
} }
// Compute the available height for the floater // Compute the available height for the floater
@ -3402,17 +3386,13 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
void void
nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
{ {
// Set the geometric parent of the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
floater->SetGeometricParent(mBlock); floater->SetGeometricParent(mBlock);
// XXX the choice of constructors is confusing and non-obvious // Then add the floater to the current line and place it when
nsSize kidAvailSize(0, 0); // appropriate
nsHTMLReflowState reflowState(mPresContext, floater, *this, AddFloater(aPlaceholder, PR_TRUE);
kidAvailSize, eReflowReason_Initial);
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
AddFloater(aPlaceholder);
} }
// This is called by the line layout's AddFloater method when a // This is called by the line layout's AddFloater method when a
@ -3421,7 +3401,8 @@ nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
// then the floater is place immediately, otherwise the floater // then the floater is place immediately, otherwise the floater
// placement is deferred until the line has been reflowed. // placement is deferred until the line has been reflowed.
void void
nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder,
PRBool aInitialReflow)
{ {
// Update the current line's floater array // Update the current line's floater array
NS_ASSERTION(nsnull != mCurrentLine, "null ptr"); NS_ASSERTION(nsnull != mCurrentLine, "null ptr");
@ -3430,6 +3411,21 @@ nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder)
} }
mCurrentLine->mFloaters->AppendElement(aPlaceholder); mCurrentLine->mFloaters->AppendElement(aPlaceholder);
// Reflow the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem();
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
reflowState.lineLayout = nsnull;
if ((nsnull == reflowCommand) || (floater != mNextRCFrame)) {
// Stub out reflowCommand and repair reasin in the reflowState
// when incremental reflow doesn't apply to the floater.
reflowState.reflowCommand = nsnull;
reflowState.reason = ((reason == eReflowReason_Initial) || aInitialReflow)
? eReflowReason_Initial
: eReflowReason_Resize;
}
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
// Now place the floater immediately if possible. Otherwise stash it // Now place the floater immediately if possible. Otherwise stash it
// away in mPendingFloaters and place it later. // away in mPendingFloaters and place it later.
if (0 == mLineLayout->GetPlacedFrames()) { if (0 == mLineLayout->GetPlacedFrames()) {
@ -3534,21 +3530,8 @@ nsBlockReflowState::PlaceFloater(nsPlaceholderFrame* aPlaceholder,
// placement are for the floater only, not for any non-floating // placement are for the floater only, not for any non-floating
// content. // content.
nscoord saveY = mY; nscoord saveY = mY;
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
// XXX the choice of constructors is confusing and non-obvious
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
// Reflow the floater if it's targetted for a reflow
if (nsnull != reflowCommand) {
if (floater == mNextRCFrame) {
reflowState.lineLayout = nsnull;
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
}
}
// Get the type of floater // Get the type of floater
const nsStyleDisplay* floaterDisplay; const nsStyleDisplay* floaterDisplay;
const nsStyleSpacing* floaterSpacing; const nsStyleSpacing* floaterSpacing;

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

@ -184,7 +184,8 @@ public:
void InitFloater(nsPlaceholderFrame* aPlaceholderFrame); void InitFloater(nsPlaceholderFrame* aPlaceholderFrame);
void AddFloater(nsPlaceholderFrame* aPlaceholderFrame); void AddFloater(nsPlaceholderFrame* aPlaceholderFrame,
PRBool aInitialReflow);
void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater); void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater);
@ -253,7 +254,7 @@ nsLineLayout::InitFloater(nsPlaceholderFrame* aFrame)
void void
nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame) nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame)
{ {
mBlockReflowState->AddFloater(aFrame); mBlockReflowState->AddFloater(aFrame, PR_FALSE);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1176,13 +1177,7 @@ nsresult
nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState)
{ {
// XXX temporary // XXX temporary
// Mark everything dirty return PrepareResizeReflow(aState);
nsLineBox* line = mLines;
while (nsnull != line) {
line->MarkDirty();
line = line->mNext;
}
return NS_OK;
} }
nsresult nsresult
@ -1610,11 +1605,6 @@ nsBaseIBFrame::ReflowLine(nsBlockReflowState& aState,
// If the line already has floaters on it from last time, remove // If the line already has floaters on it from last time, remove
// them from the spacemanager now. // them from the spacemanager now.
if (nsnull != aLine->mFloaters) { if (nsnull != aLine->mFloaters) {
#if 0
if (eReflowReason_Resize != aState.reason) {
aLine->UnplaceFloaters(aState.mSpaceManager);
}
#endif
aLine->mFloaters->Clear(); aLine->mFloaters->Clear();
} }
@ -3357,25 +3347,19 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right; kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right;
} }
else { else {
// If we are floating something and we don't know the width then // CSS2 section 10.3.5: Floating non-replaced elements with an
// find a maximum width for it to reflow into. Walk upwards until // auto width have the computed value of zero. Therefore, don't
// we find something with an unconstrained width. // bother reflowing them.
const nsHTMLReflowState* rsp = &aState; if (NS_FRAME_IS_NOT_REPLACED(aFloaterReflowState.frameType)) {
kidAvailSize.width = 0; // XXX Tables are weird and special, so check for them here...
while (nsnull != rsp) { const nsStyleDisplay* floaterDisplay;
if (eHTMLFrameConstraint_FixedContent == rsp->widthConstraint) { aFloaterFrame->GetStyleData(eStyleStruct_Display,
kidAvailSize.width = rsp->minWidth; (const nsStyleStruct*&)floaterDisplay);
break; if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay) {
} return;
else if (NS_UNCONSTRAINEDSIZE != rsp->widthConstraint) {
kidAvailSize.width = rsp->maxSize.width;
if (kidAvailSize.width > 0) {
break;
} }
} }
// XXX This cast is unfortunate! kidAvailSize.width = NS_UNCONSTRAINEDSIZE;
rsp = (const nsHTMLReflowState*) rsp->parentReflowState;
}
} }
// Compute the available height for the floater // Compute the available height for the floater
@ -3402,17 +3386,13 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
void void
nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
{ {
// Set the geometric parent of the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
floater->SetGeometricParent(mBlock); floater->SetGeometricParent(mBlock);
// XXX the choice of constructors is confusing and non-obvious // Then add the floater to the current line and place it when
nsSize kidAvailSize(0, 0); // appropriate
nsHTMLReflowState reflowState(mPresContext, floater, *this, AddFloater(aPlaceholder, PR_TRUE);
kidAvailSize, eReflowReason_Initial);
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
AddFloater(aPlaceholder);
} }
// This is called by the line layout's AddFloater method when a // This is called by the line layout's AddFloater method when a
@ -3421,7 +3401,8 @@ nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
// then the floater is place immediately, otherwise the floater // then the floater is place immediately, otherwise the floater
// placement is deferred until the line has been reflowed. // placement is deferred until the line has been reflowed.
void void
nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder,
PRBool aInitialReflow)
{ {
// Update the current line's floater array // Update the current line's floater array
NS_ASSERTION(nsnull != mCurrentLine, "null ptr"); NS_ASSERTION(nsnull != mCurrentLine, "null ptr");
@ -3430,6 +3411,21 @@ nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder)
} }
mCurrentLine->mFloaters->AppendElement(aPlaceholder); mCurrentLine->mFloaters->AppendElement(aPlaceholder);
// Reflow the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem();
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
reflowState.lineLayout = nsnull;
if ((nsnull == reflowCommand) || (floater != mNextRCFrame)) {
// Stub out reflowCommand and repair reasin in the reflowState
// when incremental reflow doesn't apply to the floater.
reflowState.reflowCommand = nsnull;
reflowState.reason = ((reason == eReflowReason_Initial) || aInitialReflow)
? eReflowReason_Initial
: eReflowReason_Resize;
}
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
// Now place the floater immediately if possible. Otherwise stash it // Now place the floater immediately if possible. Otherwise stash it
// away in mPendingFloaters and place it later. // away in mPendingFloaters and place it later.
if (0 == mLineLayout->GetPlacedFrames()) { if (0 == mLineLayout->GetPlacedFrames()) {
@ -3534,21 +3530,8 @@ nsBlockReflowState::PlaceFloater(nsPlaceholderFrame* aPlaceholder,
// placement are for the floater only, not for any non-floating // placement are for the floater only, not for any non-floating
// content. // content.
nscoord saveY = mY; nscoord saveY = mY;
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
// XXX the choice of constructors is confusing and non-obvious
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
// Reflow the floater if it's targetted for a reflow
if (nsnull != reflowCommand) {
if (floater == mNextRCFrame) {
reflowState.lineLayout = nsnull;
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
}
}
// Get the type of floater // Get the type of floater
const nsStyleDisplay* floaterDisplay; const nsStyleDisplay* floaterDisplay;
const nsStyleSpacing* floaterSpacing; const nsStyleSpacing* floaterSpacing;

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

@ -184,7 +184,8 @@ public:
void InitFloater(nsPlaceholderFrame* aPlaceholderFrame); void InitFloater(nsPlaceholderFrame* aPlaceholderFrame);
void AddFloater(nsPlaceholderFrame* aPlaceholderFrame); void AddFloater(nsPlaceholderFrame* aPlaceholderFrame,
PRBool aInitialReflow);
void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater); void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater);
@ -253,7 +254,7 @@ nsLineLayout::InitFloater(nsPlaceholderFrame* aFrame)
void void
nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame) nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame)
{ {
mBlockReflowState->AddFloater(aFrame); mBlockReflowState->AddFloater(aFrame, PR_FALSE);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1176,13 +1177,7 @@ nsresult
nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState)
{ {
// XXX temporary // XXX temporary
// Mark everything dirty return PrepareResizeReflow(aState);
nsLineBox* line = mLines;
while (nsnull != line) {
line->MarkDirty();
line = line->mNext;
}
return NS_OK;
} }
nsresult nsresult
@ -1610,11 +1605,6 @@ nsBaseIBFrame::ReflowLine(nsBlockReflowState& aState,
// If the line already has floaters on it from last time, remove // If the line already has floaters on it from last time, remove
// them from the spacemanager now. // them from the spacemanager now.
if (nsnull != aLine->mFloaters) { if (nsnull != aLine->mFloaters) {
#if 0
if (eReflowReason_Resize != aState.reason) {
aLine->UnplaceFloaters(aState.mSpaceManager);
}
#endif
aLine->mFloaters->Clear(); aLine->mFloaters->Clear();
} }
@ -3357,25 +3347,19 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right; kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right;
} }
else { else {
// If we are floating something and we don't know the width then // CSS2 section 10.3.5: Floating non-replaced elements with an
// find a maximum width for it to reflow into. Walk upwards until // auto width have the computed value of zero. Therefore, don't
// we find something with an unconstrained width. // bother reflowing them.
const nsHTMLReflowState* rsp = &aState; if (NS_FRAME_IS_NOT_REPLACED(aFloaterReflowState.frameType)) {
kidAvailSize.width = 0; // XXX Tables are weird and special, so check for them here...
while (nsnull != rsp) { const nsStyleDisplay* floaterDisplay;
if (eHTMLFrameConstraint_FixedContent == rsp->widthConstraint) { aFloaterFrame->GetStyleData(eStyleStruct_Display,
kidAvailSize.width = rsp->minWidth; (const nsStyleStruct*&)floaterDisplay);
break; if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay) {
} return;
else if (NS_UNCONSTRAINEDSIZE != rsp->widthConstraint) {
kidAvailSize.width = rsp->maxSize.width;
if (kidAvailSize.width > 0) {
break;
} }
} }
// XXX This cast is unfortunate! kidAvailSize.width = NS_UNCONSTRAINEDSIZE;
rsp = (const nsHTMLReflowState*) rsp->parentReflowState;
}
} }
// Compute the available height for the floater // Compute the available height for the floater
@ -3402,17 +3386,13 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
void void
nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
{ {
// Set the geometric parent of the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
floater->SetGeometricParent(mBlock); floater->SetGeometricParent(mBlock);
// XXX the choice of constructors is confusing and non-obvious // Then add the floater to the current line and place it when
nsSize kidAvailSize(0, 0); // appropriate
nsHTMLReflowState reflowState(mPresContext, floater, *this, AddFloater(aPlaceholder, PR_TRUE);
kidAvailSize, eReflowReason_Initial);
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
AddFloater(aPlaceholder);
} }
// This is called by the line layout's AddFloater method when a // This is called by the line layout's AddFloater method when a
@ -3421,7 +3401,8 @@ nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
// then the floater is place immediately, otherwise the floater // then the floater is place immediately, otherwise the floater
// placement is deferred until the line has been reflowed. // placement is deferred until the line has been reflowed.
void void
nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder,
PRBool aInitialReflow)
{ {
// Update the current line's floater array // Update the current line's floater array
NS_ASSERTION(nsnull != mCurrentLine, "null ptr"); NS_ASSERTION(nsnull != mCurrentLine, "null ptr");
@ -3430,6 +3411,21 @@ nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder)
} }
mCurrentLine->mFloaters->AppendElement(aPlaceholder); mCurrentLine->mFloaters->AppendElement(aPlaceholder);
// Reflow the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem();
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
reflowState.lineLayout = nsnull;
if ((nsnull == reflowCommand) || (floater != mNextRCFrame)) {
// Stub out reflowCommand and repair reasin in the reflowState
// when incremental reflow doesn't apply to the floater.
reflowState.reflowCommand = nsnull;
reflowState.reason = ((reason == eReflowReason_Initial) || aInitialReflow)
? eReflowReason_Initial
: eReflowReason_Resize;
}
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
// Now place the floater immediately if possible. Otherwise stash it // Now place the floater immediately if possible. Otherwise stash it
// away in mPendingFloaters and place it later. // away in mPendingFloaters and place it later.
if (0 == mLineLayout->GetPlacedFrames()) { if (0 == mLineLayout->GetPlacedFrames()) {
@ -3534,21 +3530,8 @@ nsBlockReflowState::PlaceFloater(nsPlaceholderFrame* aPlaceholder,
// placement are for the floater only, not for any non-floating // placement are for the floater only, not for any non-floating
// content. // content.
nscoord saveY = mY; nscoord saveY = mY;
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
// XXX the choice of constructors is confusing and non-obvious
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
// Reflow the floater if it's targetted for a reflow
if (nsnull != reflowCommand) {
if (floater == mNextRCFrame) {
reflowState.lineLayout = nsnull;
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
}
}
// Get the type of floater // Get the type of floater
const nsStyleDisplay* floaterDisplay; const nsStyleDisplay* floaterDisplay;
const nsStyleSpacing* floaterSpacing; const nsStyleSpacing* floaterSpacing;

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

@ -184,7 +184,8 @@ public:
void InitFloater(nsPlaceholderFrame* aPlaceholderFrame); void InitFloater(nsPlaceholderFrame* aPlaceholderFrame);
void AddFloater(nsPlaceholderFrame* aPlaceholderFrame); void AddFloater(nsPlaceholderFrame* aPlaceholderFrame,
PRBool aInitialReflow);
void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater); void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater);
@ -253,7 +254,7 @@ nsLineLayout::InitFloater(nsPlaceholderFrame* aFrame)
void void
nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame) nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame)
{ {
mBlockReflowState->AddFloater(aFrame); mBlockReflowState->AddFloater(aFrame, PR_FALSE);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1176,13 +1177,7 @@ nsresult
nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState)
{ {
// XXX temporary // XXX temporary
// Mark everything dirty return PrepareResizeReflow(aState);
nsLineBox* line = mLines;
while (nsnull != line) {
line->MarkDirty();
line = line->mNext;
}
return NS_OK;
} }
nsresult nsresult
@ -1610,11 +1605,6 @@ nsBaseIBFrame::ReflowLine(nsBlockReflowState& aState,
// If the line already has floaters on it from last time, remove // If the line already has floaters on it from last time, remove
// them from the spacemanager now. // them from the spacemanager now.
if (nsnull != aLine->mFloaters) { if (nsnull != aLine->mFloaters) {
#if 0
if (eReflowReason_Resize != aState.reason) {
aLine->UnplaceFloaters(aState.mSpaceManager);
}
#endif
aLine->mFloaters->Clear(); aLine->mFloaters->Clear();
} }
@ -3357,25 +3347,19 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right; kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right;
} }
else { else {
// If we are floating something and we don't know the width then // CSS2 section 10.3.5: Floating non-replaced elements with an
// find a maximum width for it to reflow into. Walk upwards until // auto width have the computed value of zero. Therefore, don't
// we find something with an unconstrained width. // bother reflowing them.
const nsHTMLReflowState* rsp = &aState; if (NS_FRAME_IS_NOT_REPLACED(aFloaterReflowState.frameType)) {
kidAvailSize.width = 0; // XXX Tables are weird and special, so check for them here...
while (nsnull != rsp) { const nsStyleDisplay* floaterDisplay;
if (eHTMLFrameConstraint_FixedContent == rsp->widthConstraint) { aFloaterFrame->GetStyleData(eStyleStruct_Display,
kidAvailSize.width = rsp->minWidth; (const nsStyleStruct*&)floaterDisplay);
break; if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay) {
} return;
else if (NS_UNCONSTRAINEDSIZE != rsp->widthConstraint) {
kidAvailSize.width = rsp->maxSize.width;
if (kidAvailSize.width > 0) {
break;
} }
} }
// XXX This cast is unfortunate! kidAvailSize.width = NS_UNCONSTRAINEDSIZE;
rsp = (const nsHTMLReflowState*) rsp->parentReflowState;
}
} }
// Compute the available height for the floater // Compute the available height for the floater
@ -3402,17 +3386,13 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
void void
nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
{ {
// Set the geometric parent of the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
floater->SetGeometricParent(mBlock); floater->SetGeometricParent(mBlock);
// XXX the choice of constructors is confusing and non-obvious // Then add the floater to the current line and place it when
nsSize kidAvailSize(0, 0); // appropriate
nsHTMLReflowState reflowState(mPresContext, floater, *this, AddFloater(aPlaceholder, PR_TRUE);
kidAvailSize, eReflowReason_Initial);
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
AddFloater(aPlaceholder);
} }
// This is called by the line layout's AddFloater method when a // This is called by the line layout's AddFloater method when a
@ -3421,7 +3401,8 @@ nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
// then the floater is place immediately, otherwise the floater // then the floater is place immediately, otherwise the floater
// placement is deferred until the line has been reflowed. // placement is deferred until the line has been reflowed.
void void
nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder,
PRBool aInitialReflow)
{ {
// Update the current line's floater array // Update the current line's floater array
NS_ASSERTION(nsnull != mCurrentLine, "null ptr"); NS_ASSERTION(nsnull != mCurrentLine, "null ptr");
@ -3430,6 +3411,21 @@ nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder)
} }
mCurrentLine->mFloaters->AppendElement(aPlaceholder); mCurrentLine->mFloaters->AppendElement(aPlaceholder);
// Reflow the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem();
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
reflowState.lineLayout = nsnull;
if ((nsnull == reflowCommand) || (floater != mNextRCFrame)) {
// Stub out reflowCommand and repair reasin in the reflowState
// when incremental reflow doesn't apply to the floater.
reflowState.reflowCommand = nsnull;
reflowState.reason = ((reason == eReflowReason_Initial) || aInitialReflow)
? eReflowReason_Initial
: eReflowReason_Resize;
}
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
// Now place the floater immediately if possible. Otherwise stash it // Now place the floater immediately if possible. Otherwise stash it
// away in mPendingFloaters and place it later. // away in mPendingFloaters and place it later.
if (0 == mLineLayout->GetPlacedFrames()) { if (0 == mLineLayout->GetPlacedFrames()) {
@ -3534,21 +3530,8 @@ nsBlockReflowState::PlaceFloater(nsPlaceholderFrame* aPlaceholder,
// placement are for the floater only, not for any non-floating // placement are for the floater only, not for any non-floating
// content. // content.
nscoord saveY = mY; nscoord saveY = mY;
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
// XXX the choice of constructors is confusing and non-obvious
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
// Reflow the floater if it's targetted for a reflow
if (nsnull != reflowCommand) {
if (floater == mNextRCFrame) {
reflowState.lineLayout = nsnull;
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
}
}
// Get the type of floater // Get the type of floater
const nsStyleDisplay* floaterDisplay; const nsStyleDisplay* floaterDisplay;
const nsStyleSpacing* floaterSpacing; const nsStyleSpacing* floaterSpacing;

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

@ -184,7 +184,8 @@ public:
void InitFloater(nsPlaceholderFrame* aPlaceholderFrame); void InitFloater(nsPlaceholderFrame* aPlaceholderFrame);
void AddFloater(nsPlaceholderFrame* aPlaceholderFrame); void AddFloater(nsPlaceholderFrame* aPlaceholderFrame,
PRBool aInitialReflow);
void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater); void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater);
@ -253,7 +254,7 @@ nsLineLayout::InitFloater(nsPlaceholderFrame* aFrame)
void void
nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame) nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame)
{ {
mBlockReflowState->AddFloater(aFrame); mBlockReflowState->AddFloater(aFrame, PR_FALSE);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1176,13 +1177,7 @@ nsresult
nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState)
{ {
// XXX temporary // XXX temporary
// Mark everything dirty return PrepareResizeReflow(aState);
nsLineBox* line = mLines;
while (nsnull != line) {
line->MarkDirty();
line = line->mNext;
}
return NS_OK;
} }
nsresult nsresult
@ -1610,11 +1605,6 @@ nsBaseIBFrame::ReflowLine(nsBlockReflowState& aState,
// If the line already has floaters on it from last time, remove // If the line already has floaters on it from last time, remove
// them from the spacemanager now. // them from the spacemanager now.
if (nsnull != aLine->mFloaters) { if (nsnull != aLine->mFloaters) {
#if 0
if (eReflowReason_Resize != aState.reason) {
aLine->UnplaceFloaters(aState.mSpaceManager);
}
#endif
aLine->mFloaters->Clear(); aLine->mFloaters->Clear();
} }
@ -3357,25 +3347,19 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right; kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right;
} }
else { else {
// If we are floating something and we don't know the width then // CSS2 section 10.3.5: Floating non-replaced elements with an
// find a maximum width for it to reflow into. Walk upwards until // auto width have the computed value of zero. Therefore, don't
// we find something with an unconstrained width. // bother reflowing them.
const nsHTMLReflowState* rsp = &aState; if (NS_FRAME_IS_NOT_REPLACED(aFloaterReflowState.frameType)) {
kidAvailSize.width = 0; // XXX Tables are weird and special, so check for them here...
while (nsnull != rsp) { const nsStyleDisplay* floaterDisplay;
if (eHTMLFrameConstraint_FixedContent == rsp->widthConstraint) { aFloaterFrame->GetStyleData(eStyleStruct_Display,
kidAvailSize.width = rsp->minWidth; (const nsStyleStruct*&)floaterDisplay);
break; if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay) {
} return;
else if (NS_UNCONSTRAINEDSIZE != rsp->widthConstraint) {
kidAvailSize.width = rsp->maxSize.width;
if (kidAvailSize.width > 0) {
break;
} }
} }
// XXX This cast is unfortunate! kidAvailSize.width = NS_UNCONSTRAINEDSIZE;
rsp = (const nsHTMLReflowState*) rsp->parentReflowState;
}
} }
// Compute the available height for the floater // Compute the available height for the floater
@ -3402,17 +3386,13 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
void void
nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
{ {
// Set the geometric parent of the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
floater->SetGeometricParent(mBlock); floater->SetGeometricParent(mBlock);
// XXX the choice of constructors is confusing and non-obvious // Then add the floater to the current line and place it when
nsSize kidAvailSize(0, 0); // appropriate
nsHTMLReflowState reflowState(mPresContext, floater, *this, AddFloater(aPlaceholder, PR_TRUE);
kidAvailSize, eReflowReason_Initial);
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
AddFloater(aPlaceholder);
} }
// This is called by the line layout's AddFloater method when a // This is called by the line layout's AddFloater method when a
@ -3421,7 +3401,8 @@ nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
// then the floater is place immediately, otherwise the floater // then the floater is place immediately, otherwise the floater
// placement is deferred until the line has been reflowed. // placement is deferred until the line has been reflowed.
void void
nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder,
PRBool aInitialReflow)
{ {
// Update the current line's floater array // Update the current line's floater array
NS_ASSERTION(nsnull != mCurrentLine, "null ptr"); NS_ASSERTION(nsnull != mCurrentLine, "null ptr");
@ -3430,6 +3411,21 @@ nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder)
} }
mCurrentLine->mFloaters->AppendElement(aPlaceholder); mCurrentLine->mFloaters->AppendElement(aPlaceholder);
// Reflow the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem();
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
reflowState.lineLayout = nsnull;
if ((nsnull == reflowCommand) || (floater != mNextRCFrame)) {
// Stub out reflowCommand and repair reasin in the reflowState
// when incremental reflow doesn't apply to the floater.
reflowState.reflowCommand = nsnull;
reflowState.reason = ((reason == eReflowReason_Initial) || aInitialReflow)
? eReflowReason_Initial
: eReflowReason_Resize;
}
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
// Now place the floater immediately if possible. Otherwise stash it // Now place the floater immediately if possible. Otherwise stash it
// away in mPendingFloaters and place it later. // away in mPendingFloaters and place it later.
if (0 == mLineLayout->GetPlacedFrames()) { if (0 == mLineLayout->GetPlacedFrames()) {
@ -3534,21 +3530,8 @@ nsBlockReflowState::PlaceFloater(nsPlaceholderFrame* aPlaceholder,
// placement are for the floater only, not for any non-floating // placement are for the floater only, not for any non-floating
// content. // content.
nscoord saveY = mY; nscoord saveY = mY;
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
// XXX the choice of constructors is confusing and non-obvious
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
// Reflow the floater if it's targetted for a reflow
if (nsnull != reflowCommand) {
if (floater == mNextRCFrame) {
reflowState.lineLayout = nsnull;
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
}
}
// Get the type of floater // Get the type of floater
const nsStyleDisplay* floaterDisplay; const nsStyleDisplay* floaterDisplay;
const nsStyleSpacing* floaterSpacing; const nsStyleSpacing* floaterSpacing;

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

@ -184,7 +184,8 @@ public:
void InitFloater(nsPlaceholderFrame* aPlaceholderFrame); void InitFloater(nsPlaceholderFrame* aPlaceholderFrame);
void AddFloater(nsPlaceholderFrame* aPlaceholderFrame); void AddFloater(nsPlaceholderFrame* aPlaceholderFrame,
PRBool aInitialReflow);
void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater); void PlaceFloater(nsPlaceholderFrame* aFloater, PRBool& aIsLeftFloater);
@ -253,7 +254,7 @@ nsLineLayout::InitFloater(nsPlaceholderFrame* aFrame)
void void
nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame) nsLineLayout::AddFloater(nsPlaceholderFrame* aFrame)
{ {
mBlockReflowState->AddFloater(aFrame); mBlockReflowState->AddFloater(aFrame, PR_FALSE);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1176,13 +1177,7 @@ nsresult
nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) nsBaseIBFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState)
{ {
// XXX temporary // XXX temporary
// Mark everything dirty return PrepareResizeReflow(aState);
nsLineBox* line = mLines;
while (nsnull != line) {
line->MarkDirty();
line = line->mNext;
}
return NS_OK;
} }
nsresult nsresult
@ -1610,11 +1605,6 @@ nsBaseIBFrame::ReflowLine(nsBlockReflowState& aState,
// If the line already has floaters on it from last time, remove // If the line already has floaters on it from last time, remove
// them from the spacemanager now. // them from the spacemanager now.
if (nsnull != aLine->mFloaters) { if (nsnull != aLine->mFloaters) {
#if 0
if (eReflowReason_Resize != aState.reason) {
aLine->UnplaceFloaters(aState.mSpaceManager);
}
#endif
aLine->mFloaters->Clear(); aLine->mFloaters->Clear();
} }
@ -3357,25 +3347,19 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right; kidAvailSize.width = aFloaterReflowState.minWidth + bp.left + bp.right;
} }
else { else {
// If we are floating something and we don't know the width then // CSS2 section 10.3.5: Floating non-replaced elements with an
// find a maximum width for it to reflow into. Walk upwards until // auto width have the computed value of zero. Therefore, don't
// we find something with an unconstrained width. // bother reflowing them.
const nsHTMLReflowState* rsp = &aState; if (NS_FRAME_IS_NOT_REPLACED(aFloaterReflowState.frameType)) {
kidAvailSize.width = 0; // XXX Tables are weird and special, so check for them here...
while (nsnull != rsp) { const nsStyleDisplay* floaterDisplay;
if (eHTMLFrameConstraint_FixedContent == rsp->widthConstraint) { aFloaterFrame->GetStyleData(eStyleStruct_Display,
kidAvailSize.width = rsp->minWidth; (const nsStyleStruct*&)floaterDisplay);
break; if (NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay) {
} return;
else if (NS_UNCONSTRAINEDSIZE != rsp->widthConstraint) {
kidAvailSize.width = rsp->maxSize.width;
if (kidAvailSize.width > 0) {
break;
} }
} }
// XXX This cast is unfortunate! kidAvailSize.width = NS_UNCONSTRAINEDSIZE;
rsp = (const nsHTMLReflowState*) rsp->parentReflowState;
}
} }
// Compute the available height for the floater // Compute the available height for the floater
@ -3402,17 +3386,13 @@ nsBaseIBFrame::ReflowFloater(nsIPresContext& aPresContext,
void void
nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
{ {
// Set the geometric parent of the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
floater->SetGeometricParent(mBlock); floater->SetGeometricParent(mBlock);
// XXX the choice of constructors is confusing and non-obvious // Then add the floater to the current line and place it when
nsSize kidAvailSize(0, 0); // appropriate
nsHTMLReflowState reflowState(mPresContext, floater, *this, AddFloater(aPlaceholder, PR_TRUE);
kidAvailSize, eReflowReason_Initial);
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
AddFloater(aPlaceholder);
} }
// This is called by the line layout's AddFloater method when a // This is called by the line layout's AddFloater method when a
@ -3421,7 +3401,8 @@ nsBlockReflowState::InitFloater(nsPlaceholderFrame* aPlaceholder)
// then the floater is place immediately, otherwise the floater // then the floater is place immediately, otherwise the floater
// placement is deferred until the line has been reflowed. // placement is deferred until the line has been reflowed.
void void
nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder) nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder,
PRBool aInitialReflow)
{ {
// Update the current line's floater array // Update the current line's floater array
NS_ASSERTION(nsnull != mCurrentLine, "null ptr"); NS_ASSERTION(nsnull != mCurrentLine, "null ptr");
@ -3430,6 +3411,21 @@ nsBlockReflowState::AddFloater(nsPlaceholderFrame* aPlaceholder)
} }
mCurrentLine->mFloaters->AppendElement(aPlaceholder); mCurrentLine->mFloaters->AppendElement(aPlaceholder);
// Reflow the floater
nsIFrame* floater = aPlaceholder->GetAnchoredItem();
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
reflowState.lineLayout = nsnull;
if ((nsnull == reflowCommand) || (floater != mNextRCFrame)) {
// Stub out reflowCommand and repair reasin in the reflowState
// when incremental reflow doesn't apply to the floater.
reflowState.reflowCommand = nsnull;
reflowState.reason = ((reason == eReflowReason_Initial) || aInitialReflow)
? eReflowReason_Initial
: eReflowReason_Resize;
}
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
// Now place the floater immediately if possible. Otherwise stash it // Now place the floater immediately if possible. Otherwise stash it
// away in mPendingFloaters and place it later. // away in mPendingFloaters and place it later.
if (0 == mLineLayout->GetPlacedFrames()) { if (0 == mLineLayout->GetPlacedFrames()) {
@ -3534,21 +3530,8 @@ nsBlockReflowState::PlaceFloater(nsPlaceholderFrame* aPlaceholder,
// placement are for the floater only, not for any non-floating // placement are for the floater only, not for any non-floating
// content. // content.
nscoord saveY = mY; nscoord saveY = mY;
nsIFrame* floater = aPlaceholder->GetAnchoredItem(); nsIFrame* floater = aPlaceholder->GetAnchoredItem();
// XXX the choice of constructors is confusing and non-obvious
nsSize kidAvailSize(0, 0);
nsHTMLReflowState reflowState(mPresContext, floater, *this, kidAvailSize);
// Reflow the floater if it's targetted for a reflow
if (nsnull != reflowCommand) {
if (floater == mNextRCFrame) {
reflowState.lineLayout = nsnull;
mBlock->ReflowFloater(mPresContext, *this, floater, reflowState);
}
}
// Get the type of floater // Get the type of floater
const nsStyleDisplay* floaterDisplay; const nsStyleDisplay* floaterDisplay;
const nsStyleSpacing* floaterSpacing; const nsStyleSpacing* floaterSpacing;