mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-07 15:12:28 +00:00
Change the way we calculate max-element-width for blocks with floaters: stop trying (and sometimes failing) to ensure that there can always be text next to the floater. b=186593 r+sr=roc+moz
This commit is contained in:
parent
4b4f8625f1
commit
0ec06d045f
@ -351,137 +351,6 @@ nsBlockBandData::ClearFloaters(nscoord aY, PRUint8 aBreakType)
|
||||
return aY;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static void
|
||||
MaxElementWidthPropertyDtor(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue)
|
||||
{
|
||||
nscoord* size = (nscoord*) aPropertyValue;
|
||||
delete size;
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockBandData::StoreMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord aMaxElementWidth)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIFrameManager> mgr;
|
||||
shell->GetFrameManager(getter_AddRefs(mgr));
|
||||
if (mgr) {
|
||||
nscoord* size = new nscoord(aMaxElementWidth);
|
||||
if (size) {
|
||||
mgr->SetFrameProperty(aFrame, nsLayoutAtoms::maxElementWidthProperty,
|
||||
size, MaxElementWidthPropertyDtor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockBandData::RecoverMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord* aResult)
|
||||
{
|
||||
if (!aResult) return;
|
||||
|
||||
nscoord answer = 0;
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIFrameManager> mgr;
|
||||
shell->GetFrameManager(getter_AddRefs(mgr));
|
||||
if (mgr) {
|
||||
nscoord* width = nsnull;
|
||||
mgr->GetFrameProperty(aFrame, nsLayoutAtoms::maxElementWidthProperty,
|
||||
0, (void**) &width);
|
||||
if (width) {
|
||||
answer = *width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aResult = answer;
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockBandData::GetMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nscoord* aResult) const
|
||||
{
|
||||
nsCOMPtr<nsIFrameManager> mgr;
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
shell->GetFrameManager(getter_AddRefs(mgr));
|
||||
}
|
||||
|
||||
nsRect r;
|
||||
nscoord maxWidth = 0;
|
||||
for (PRInt32 i = 0; i < mCount; i++) {
|
||||
const nsBandTrapezoid* trap = &mTrapezoids[i];
|
||||
if (trap->mState != nsBandTrapezoid::Available) {
|
||||
|
||||
// Note: get the total height of the frame to compute the maxHeight,
|
||||
// not just the height that is part of this band.
|
||||
|
||||
if (nsBandTrapezoid::OccupiedMultiple == trap->mState) {
|
||||
PRBool usedBackupValue = PR_FALSE;
|
||||
PRInt32 j, numFrames = trap->mFrames->Count();
|
||||
NS_ASSERTION(numFrames > 0, "bad trapezoid frame list");
|
||||
for (j = 0; j < numFrames; j++) {
|
||||
PRBool useBackupValue = PR_TRUE;
|
||||
|
||||
nsIFrame* f = (nsIFrame*) trap->mFrames->ElementAt(j);
|
||||
if (mgr) {
|
||||
nscoord* maxElementWidth = nsnull;
|
||||
mgr->GetFrameProperty(f, nsLayoutAtoms::maxElementWidthProperty,
|
||||
0, (void**) &maxElementWidth);
|
||||
if (maxElementWidth) {
|
||||
useBackupValue = PR_FALSE;
|
||||
if (*maxElementWidth > maxWidth) {
|
||||
maxWidth = *maxElementWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (useBackupValue) {
|
||||
usedBackupValue = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the width of the impacted area and update the maxWidth
|
||||
if (usedBackupValue) {
|
||||
trap->GetRect(r);
|
||||
if (r.width > maxWidth) maxWidth = r.width;
|
||||
}
|
||||
} else {
|
||||
PRBool useBackupValue = PR_TRUE;
|
||||
if (mgr) {
|
||||
nscoord* maxElementWidth = nsnull;
|
||||
mgr->GetFrameProperty(trap->mFrame,
|
||||
nsLayoutAtoms::maxElementWidthProperty,
|
||||
0, (void**) &maxElementWidth);
|
||||
if (maxElementWidth) {
|
||||
useBackupValue = PR_FALSE;
|
||||
if (*maxElementWidth > maxWidth) {
|
||||
maxWidth = *maxElementWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (useBackupValue) {
|
||||
trap->GetRect(r);
|
||||
if (r.width > maxWidth) maxWidth = r.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*aResult = maxWidth;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void nsBlockBandData::List()
|
||||
{
|
||||
|
@ -86,24 +86,6 @@ public:
|
||||
return mRightFloaters;
|
||||
}
|
||||
|
||||
// Return the impact on the max-element-width for this band by
|
||||
// computing the maximum width and maximum height of all the
|
||||
// floaters.
|
||||
void GetMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nscoord* aResult) const;
|
||||
|
||||
// Utility method to save away the max-element-width associated with
|
||||
// a floating frame.
|
||||
static void StoreMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord aMaxElementWidth);
|
||||
|
||||
// Utility method to recover a stored max-element-width value
|
||||
// associated with a floating frame.
|
||||
static void RecoverMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord* aResult);
|
||||
|
||||
#ifdef DEBUG
|
||||
void List();
|
||||
#endif
|
||||
|
@ -1323,7 +1323,6 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
|
||||
computedWidth += borderPadding.right;
|
||||
}
|
||||
|
||||
// See if we should compute our max element size
|
||||
if (aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH)) {
|
||||
// Add in border and padding dimensions to already computed
|
||||
// max-element-width values.
|
||||
@ -3446,13 +3445,6 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
nscoord maxElementWidth = 0;
|
||||
if (aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH)) {
|
||||
maxElementWidth = brc.GetMaxElementWidth();
|
||||
if (aState.IsImpactedByFloater() &&
|
||||
(NS_FRAME_SPLITTABLE_NON_RECTANGULAR != splitType)) {
|
||||
// Add in floater impacts to the lines max-element-width, but
|
||||
// only if the block element isn't one of us (otherwise the
|
||||
// floater impacts will be counted twice).
|
||||
ComputeLineMaxElementWidth(aState, aLine, &maxElementWidth);
|
||||
}
|
||||
}
|
||||
// If we asked the block to update its maximum width, then record the
|
||||
// updated value in the line, and update the current maximum width
|
||||
@ -4355,24 +4347,6 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
||||
}
|
||||
|
||||
aState.mY = newY;
|
||||
if (aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH)) {
|
||||
#ifdef DEBUG
|
||||
if (gNoisyMaxElementWidth) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
if (NS_UNCONSTRAINEDSIZE == aState.mReflowState.availableWidth) {
|
||||
printf("PASS1 ");
|
||||
}
|
||||
ListTag(stdout);
|
||||
printf(": band.floaterCount=%d\n",
|
||||
//aLine->mFloaters.NotEmpty() ? "yes" : "no",
|
||||
aState.mBand.GetFloaterCount());
|
||||
}
|
||||
#endif
|
||||
if (0 != aState.mBand.GetFloaterCount()) {
|
||||
// Add in floater impacts to the lines max-element-width
|
||||
ComputeLineMaxElementWidth(aState, aLine, &maxElementWidth);
|
||||
}
|
||||
}
|
||||
|
||||
// If we're reflowing the line just to incrementally update the
|
||||
// maximum width, then don't post-place the line. It's doing work we
|
||||
@ -4458,40 +4432,6 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Compute the line's max-element-width by adding into the raw value
|
||||
// computed by reflowing the contents of the line (aMaxElementWidth)
|
||||
// the impact of floaters on this line or the preceeding lines.
|
||||
void
|
||||
nsBlockFrame::ComputeLineMaxElementWidth(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nscoord* aMaxElementWidth)
|
||||
{
|
||||
nscoord maxWidth;
|
||||
aState.mBand.GetMaxElementWidth(aState.mPresContext, &maxWidth);
|
||||
#ifdef DEBUG
|
||||
if (gNoisyMaxElementWidth) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
if (NS_UNCONSTRAINEDSIZE == aState.mReflowState.availableWidth) {
|
||||
printf("PASS1 ");
|
||||
}
|
||||
ListTag(stdout);
|
||||
printf(": maxFloaterWidth=%d\n", maxWidth);
|
||||
}
|
||||
#endif
|
||||
|
||||
// To ensure that we always place some content next to a floater,
|
||||
// _add_ the max floater width to our line's max element size.
|
||||
*aMaxElementWidth += maxWidth;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gNoisyMaxElementWidth) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
printf ("nsBlockFrame::ComputeLineMaxElementWidth: %p returning MEW %d\n",
|
||||
this, *aMaxElementWidth);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
@ -5276,9 +5216,7 @@ nsBlockFrame::DeleteNextInFlowChild(nsIPresContext* aPresContext,
|
||||
nsresult
|
||||
nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
nsPlaceholderFrame* aPlaceholder,
|
||||
nsRect& aCombinedRectResult,
|
||||
nsMargin& aMarginResult,
|
||||
nsMargin& aComputedOffsetsResult,
|
||||
nsFloaterCache* aFloaterCache,
|
||||
nsReflowStatus& aReflowStatus)
|
||||
{
|
||||
// Delete the placeholder's next in flows, if any
|
||||
@ -5379,7 +5317,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
|
||||
nsCollapsingMargin margin;
|
||||
nsresult rv = brc.ReflowBlock(availSpace, PR_TRUE, margin, isAdjacentWithTop,
|
||||
aComputedOffsetsResult, floaterRS, aReflowStatus);
|
||||
aFloaterCache->mOffsets, floaterRS,
|
||||
aReflowStatus);
|
||||
// An incomplete reflow status means we should split the floater
|
||||
// if the height is constrained (bug 145305).
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) && (NS_UNCONSTRAINEDSIZE == availHeight))
|
||||
@ -5399,7 +5338,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
nsSize(availSpace.width, availSpace.height),
|
||||
aState.mReflowState.reason, PR_FALSE);
|
||||
rv = brc.ReflowBlock(availSpace, PR_TRUE, marginMEW, isAdjacentWithTop,
|
||||
aComputedOffsetsResult, redoFloaterRS, aReflowStatus);
|
||||
aFloaterCache->mOffsets, redoFloaterRS,
|
||||
aReflowStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5417,14 +5357,14 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
|
||||
// Capture the margin information for the caller
|
||||
const nsMargin& m = brc.GetMargin();
|
||||
aMarginResult.top = brc.GetTopMargin();
|
||||
aMarginResult.right = m.right;
|
||||
aFloaterCache->mMargins.top = brc.GetTopMargin();
|
||||
aFloaterCache->mMargins.right = m.right;
|
||||
brc.GetCarriedOutBottomMargin().Include(m.bottom);
|
||||
aMarginResult.bottom = brc.GetCarriedOutBottomMargin().get();
|
||||
aMarginResult.left = m.left;
|
||||
aFloaterCache->mMargins.bottom = brc.GetCarriedOutBottomMargin().get();
|
||||
aFloaterCache->mMargins.left = m.left;
|
||||
|
||||
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
|
||||
aCombinedRectResult = metrics.mOverflowArea;
|
||||
aFloaterCache->mCombinedArea = metrics.mOverflowArea;
|
||||
|
||||
// Set the rect, make sure the view is properly sized and positioned,
|
||||
// and tell the frame we're done reflowing it
|
||||
@ -5444,11 +5384,17 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
floater->DidReflow(aState.mPresContext, &floaterRS, NS_FRAME_REFLOW_FINISHED);
|
||||
|
||||
// If we computed it, then stash away the max-element-width for later
|
||||
if (computeMaxElementWidth) {
|
||||
nscoord mew = brc.GetMaxElementWidth();
|
||||
mew += aMarginResult.left + aMarginResult.right;
|
||||
aState.StoreMaxElementWidth(floater, mew);
|
||||
if (aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH)) {
|
||||
nscoord mew = brc.GetMaxElementWidth() +
|
||||
aFloaterCache->mMargins.left + aFloaterCache->mMargins.right;
|
||||
|
||||
// This is all we need to do to include the floater
|
||||
// max-element-width since we don't require that we end up with
|
||||
// content next to floaters.
|
||||
aState.UpdateMaxElementWidth(mew); // fix for bug 13553
|
||||
|
||||
// Allow the floater width to be restored in state recovery.
|
||||
aFloaterCache->mMaxElementWidth = mew;
|
||||
}
|
||||
#ifdef NOISY_FLOATER
|
||||
printf("end ReflowFloater %p, sized to %d,%d\n", floater, metrics.width, metrics.height);
|
||||
|
@ -368,10 +368,6 @@ protected:
|
||||
nsLineBox* aLine,
|
||||
nscoord aMaxElementWidth);
|
||||
|
||||
void ComputeLineMaxElementWidth(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nscoord* aMaxElementWidth);
|
||||
|
||||
// XXX where to go
|
||||
PRBool ShouldJustifyLine(nsBlockReflowState& aState,
|
||||
line_iterator aLine);
|
||||
@ -428,9 +424,7 @@ protected:
|
||||
// but only if the available height is constrained.
|
||||
nsresult ReflowFloater(nsBlockReflowState& aState,
|
||||
nsPlaceholderFrame* aPlaceholder,
|
||||
nsRect& aCombinedRectResult,
|
||||
nsMargin& aMarginResult,
|
||||
nsMargin& aComputedOffsetsResult,
|
||||
nsFloaterCache* aFloaterCache,
|
||||
nsReflowStatus& aReflowStatus);
|
||||
|
||||
//----------------------------------------
|
||||
|
@ -591,6 +591,14 @@ nsBlockReflowState::RecoverStateFrom(nsLineList::iterator aLine,
|
||||
}
|
||||
#endif
|
||||
UpdateMaxElementWidth(aLine->mMaxElementWidth);
|
||||
|
||||
// Recover the floater MEWs for floaters in this line (but not in
|
||||
// blocks within it, since their MEWs are already part of the block's
|
||||
// MEW).
|
||||
if (aLine->HasFloaters()) {
|
||||
for (nsFloaterCache* fc = aLine->GetFirstFloater(); fc; fc = fc->Next())
|
||||
UpdateMaxElementWidth(fc->mMaxElementWidth);
|
||||
}
|
||||
}
|
||||
|
||||
// If computing the maximum width, then update mMaximumWidth
|
||||
@ -669,6 +677,7 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout,
|
||||
nsFloaterCache* fc = mFloaterCacheFreeList.Alloc();
|
||||
fc->mPlaceholder = aPlaceholder;
|
||||
fc->mIsCurrentLineFloater = aLineLayout.CanPlaceFloaterNow();
|
||||
fc->mMaxElementWidth = 0;
|
||||
|
||||
// Now place the floater immediately if possible. Otherwise stash it
|
||||
// away in mPendingFloaters and place it later.
|
||||
@ -884,8 +893,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
}
|
||||
|
||||
// Reflow the floater
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus);
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache, aReflowStatus);
|
||||
|
||||
// Get the floaters bounding box and margin information
|
||||
floater->GetRect(region);
|
||||
@ -968,8 +976,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
mY += mAvailSpaceRect.height;
|
||||
GetAvailableSpace();
|
||||
// reflow the floater again now since we have more space
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus);
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache, aReflowStatus);
|
||||
// Get the floaters bounding box and margin information
|
||||
floater->GetRect(region);
|
||||
// Adjust the floater size by its margin. That's the area that will
|
||||
|
@ -129,10 +129,6 @@ public:
|
||||
|
||||
void FreeLineBox(nsLineBox* aLine);
|
||||
|
||||
void StoreMaxElementWidth(nsIFrame* aFloater, nscoord aWidth) {
|
||||
mBand.StoreMaxElementWidth(mPresContext, aFloater, aWidth);
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// This state is the "global" state computed once for the reflow of
|
||||
|
@ -83,6 +83,9 @@ public:
|
||||
// the containing block frame.
|
||||
nsRect mCombinedArea;
|
||||
|
||||
// The floater's max-element-width.
|
||||
nscoord mMaxElementWidth;
|
||||
|
||||
protected:
|
||||
nsFloaterCache* mNext;
|
||||
|
||||
|
@ -351,137 +351,6 @@ nsBlockBandData::ClearFloaters(nscoord aY, PRUint8 aBreakType)
|
||||
return aY;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static void
|
||||
MaxElementWidthPropertyDtor(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue)
|
||||
{
|
||||
nscoord* size = (nscoord*) aPropertyValue;
|
||||
delete size;
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockBandData::StoreMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord aMaxElementWidth)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIFrameManager> mgr;
|
||||
shell->GetFrameManager(getter_AddRefs(mgr));
|
||||
if (mgr) {
|
||||
nscoord* size = new nscoord(aMaxElementWidth);
|
||||
if (size) {
|
||||
mgr->SetFrameProperty(aFrame, nsLayoutAtoms::maxElementWidthProperty,
|
||||
size, MaxElementWidthPropertyDtor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockBandData::RecoverMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord* aResult)
|
||||
{
|
||||
if (!aResult) return;
|
||||
|
||||
nscoord answer = 0;
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIFrameManager> mgr;
|
||||
shell->GetFrameManager(getter_AddRefs(mgr));
|
||||
if (mgr) {
|
||||
nscoord* width = nsnull;
|
||||
mgr->GetFrameProperty(aFrame, nsLayoutAtoms::maxElementWidthProperty,
|
||||
0, (void**) &width);
|
||||
if (width) {
|
||||
answer = *width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aResult = answer;
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockBandData::GetMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nscoord* aResult) const
|
||||
{
|
||||
nsCOMPtr<nsIFrameManager> mgr;
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
shell->GetFrameManager(getter_AddRefs(mgr));
|
||||
}
|
||||
|
||||
nsRect r;
|
||||
nscoord maxWidth = 0;
|
||||
for (PRInt32 i = 0; i < mCount; i++) {
|
||||
const nsBandTrapezoid* trap = &mTrapezoids[i];
|
||||
if (trap->mState != nsBandTrapezoid::Available) {
|
||||
|
||||
// Note: get the total height of the frame to compute the maxHeight,
|
||||
// not just the height that is part of this band.
|
||||
|
||||
if (nsBandTrapezoid::OccupiedMultiple == trap->mState) {
|
||||
PRBool usedBackupValue = PR_FALSE;
|
||||
PRInt32 j, numFrames = trap->mFrames->Count();
|
||||
NS_ASSERTION(numFrames > 0, "bad trapezoid frame list");
|
||||
for (j = 0; j < numFrames; j++) {
|
||||
PRBool useBackupValue = PR_TRUE;
|
||||
|
||||
nsIFrame* f = (nsIFrame*) trap->mFrames->ElementAt(j);
|
||||
if (mgr) {
|
||||
nscoord* maxElementWidth = nsnull;
|
||||
mgr->GetFrameProperty(f, nsLayoutAtoms::maxElementWidthProperty,
|
||||
0, (void**) &maxElementWidth);
|
||||
if (maxElementWidth) {
|
||||
useBackupValue = PR_FALSE;
|
||||
if (*maxElementWidth > maxWidth) {
|
||||
maxWidth = *maxElementWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (useBackupValue) {
|
||||
usedBackupValue = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the width of the impacted area and update the maxWidth
|
||||
if (usedBackupValue) {
|
||||
trap->GetRect(r);
|
||||
if (r.width > maxWidth) maxWidth = r.width;
|
||||
}
|
||||
} else {
|
||||
PRBool useBackupValue = PR_TRUE;
|
||||
if (mgr) {
|
||||
nscoord* maxElementWidth = nsnull;
|
||||
mgr->GetFrameProperty(trap->mFrame,
|
||||
nsLayoutAtoms::maxElementWidthProperty,
|
||||
0, (void**) &maxElementWidth);
|
||||
if (maxElementWidth) {
|
||||
useBackupValue = PR_FALSE;
|
||||
if (*maxElementWidth > maxWidth) {
|
||||
maxWidth = *maxElementWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (useBackupValue) {
|
||||
trap->GetRect(r);
|
||||
if (r.width > maxWidth) maxWidth = r.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*aResult = maxWidth;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void nsBlockBandData::List()
|
||||
{
|
||||
|
@ -86,24 +86,6 @@ public:
|
||||
return mRightFloaters;
|
||||
}
|
||||
|
||||
// Return the impact on the max-element-width for this band by
|
||||
// computing the maximum width and maximum height of all the
|
||||
// floaters.
|
||||
void GetMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nscoord* aResult) const;
|
||||
|
||||
// Utility method to save away the max-element-width associated with
|
||||
// a floating frame.
|
||||
static void StoreMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord aMaxElementWidth);
|
||||
|
||||
// Utility method to recover a stored max-element-width value
|
||||
// associated with a floating frame.
|
||||
static void RecoverMaxElementWidth(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord* aResult);
|
||||
|
||||
#ifdef DEBUG
|
||||
void List();
|
||||
#endif
|
||||
|
@ -1323,7 +1323,6 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
|
||||
computedWidth += borderPadding.right;
|
||||
}
|
||||
|
||||
// See if we should compute our max element size
|
||||
if (aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH)) {
|
||||
// Add in border and padding dimensions to already computed
|
||||
// max-element-width values.
|
||||
@ -3446,13 +3445,6 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
nscoord maxElementWidth = 0;
|
||||
if (aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH)) {
|
||||
maxElementWidth = brc.GetMaxElementWidth();
|
||||
if (aState.IsImpactedByFloater() &&
|
||||
(NS_FRAME_SPLITTABLE_NON_RECTANGULAR != splitType)) {
|
||||
// Add in floater impacts to the lines max-element-width, but
|
||||
// only if the block element isn't one of us (otherwise the
|
||||
// floater impacts will be counted twice).
|
||||
ComputeLineMaxElementWidth(aState, aLine, &maxElementWidth);
|
||||
}
|
||||
}
|
||||
// If we asked the block to update its maximum width, then record the
|
||||
// updated value in the line, and update the current maximum width
|
||||
@ -4355,24 +4347,6 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
||||
}
|
||||
|
||||
aState.mY = newY;
|
||||
if (aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH)) {
|
||||
#ifdef DEBUG
|
||||
if (gNoisyMaxElementWidth) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
if (NS_UNCONSTRAINEDSIZE == aState.mReflowState.availableWidth) {
|
||||
printf("PASS1 ");
|
||||
}
|
||||
ListTag(stdout);
|
||||
printf(": band.floaterCount=%d\n",
|
||||
//aLine->mFloaters.NotEmpty() ? "yes" : "no",
|
||||
aState.mBand.GetFloaterCount());
|
||||
}
|
||||
#endif
|
||||
if (0 != aState.mBand.GetFloaterCount()) {
|
||||
// Add in floater impacts to the lines max-element-width
|
||||
ComputeLineMaxElementWidth(aState, aLine, &maxElementWidth);
|
||||
}
|
||||
}
|
||||
|
||||
// If we're reflowing the line just to incrementally update the
|
||||
// maximum width, then don't post-place the line. It's doing work we
|
||||
@ -4458,40 +4432,6 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Compute the line's max-element-width by adding into the raw value
|
||||
// computed by reflowing the contents of the line (aMaxElementWidth)
|
||||
// the impact of floaters on this line or the preceeding lines.
|
||||
void
|
||||
nsBlockFrame::ComputeLineMaxElementWidth(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nscoord* aMaxElementWidth)
|
||||
{
|
||||
nscoord maxWidth;
|
||||
aState.mBand.GetMaxElementWidth(aState.mPresContext, &maxWidth);
|
||||
#ifdef DEBUG
|
||||
if (gNoisyMaxElementWidth) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
if (NS_UNCONSTRAINEDSIZE == aState.mReflowState.availableWidth) {
|
||||
printf("PASS1 ");
|
||||
}
|
||||
ListTag(stdout);
|
||||
printf(": maxFloaterWidth=%d\n", maxWidth);
|
||||
}
|
||||
#endif
|
||||
|
||||
// To ensure that we always place some content next to a floater,
|
||||
// _add_ the max floater width to our line's max element size.
|
||||
*aMaxElementWidth += maxWidth;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gNoisyMaxElementWidth) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
printf ("nsBlockFrame::ComputeLineMaxElementWidth: %p returning MEW %d\n",
|
||||
this, *aMaxElementWidth);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
@ -5276,9 +5216,7 @@ nsBlockFrame::DeleteNextInFlowChild(nsIPresContext* aPresContext,
|
||||
nsresult
|
||||
nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
nsPlaceholderFrame* aPlaceholder,
|
||||
nsRect& aCombinedRectResult,
|
||||
nsMargin& aMarginResult,
|
||||
nsMargin& aComputedOffsetsResult,
|
||||
nsFloaterCache* aFloaterCache,
|
||||
nsReflowStatus& aReflowStatus)
|
||||
{
|
||||
// Delete the placeholder's next in flows, if any
|
||||
@ -5379,7 +5317,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
|
||||
nsCollapsingMargin margin;
|
||||
nsresult rv = brc.ReflowBlock(availSpace, PR_TRUE, margin, isAdjacentWithTop,
|
||||
aComputedOffsetsResult, floaterRS, aReflowStatus);
|
||||
aFloaterCache->mOffsets, floaterRS,
|
||||
aReflowStatus);
|
||||
// An incomplete reflow status means we should split the floater
|
||||
// if the height is constrained (bug 145305).
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) && (NS_UNCONSTRAINEDSIZE == availHeight))
|
||||
@ -5399,7 +5338,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
nsSize(availSpace.width, availSpace.height),
|
||||
aState.mReflowState.reason, PR_FALSE);
|
||||
rv = brc.ReflowBlock(availSpace, PR_TRUE, marginMEW, isAdjacentWithTop,
|
||||
aComputedOffsetsResult, redoFloaterRS, aReflowStatus);
|
||||
aFloaterCache->mOffsets, redoFloaterRS,
|
||||
aReflowStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5417,14 +5357,14 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
|
||||
// Capture the margin information for the caller
|
||||
const nsMargin& m = brc.GetMargin();
|
||||
aMarginResult.top = brc.GetTopMargin();
|
||||
aMarginResult.right = m.right;
|
||||
aFloaterCache->mMargins.top = brc.GetTopMargin();
|
||||
aFloaterCache->mMargins.right = m.right;
|
||||
brc.GetCarriedOutBottomMargin().Include(m.bottom);
|
||||
aMarginResult.bottom = brc.GetCarriedOutBottomMargin().get();
|
||||
aMarginResult.left = m.left;
|
||||
aFloaterCache->mMargins.bottom = brc.GetCarriedOutBottomMargin().get();
|
||||
aFloaterCache->mMargins.left = m.left;
|
||||
|
||||
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
|
||||
aCombinedRectResult = metrics.mOverflowArea;
|
||||
aFloaterCache->mCombinedArea = metrics.mOverflowArea;
|
||||
|
||||
// Set the rect, make sure the view is properly sized and positioned,
|
||||
// and tell the frame we're done reflowing it
|
||||
@ -5444,11 +5384,17 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
floater->DidReflow(aState.mPresContext, &floaterRS, NS_FRAME_REFLOW_FINISHED);
|
||||
|
||||
// If we computed it, then stash away the max-element-width for later
|
||||
if (computeMaxElementWidth) {
|
||||
nscoord mew = brc.GetMaxElementWidth();
|
||||
mew += aMarginResult.left + aMarginResult.right;
|
||||
aState.StoreMaxElementWidth(floater, mew);
|
||||
if (aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH)) {
|
||||
nscoord mew = brc.GetMaxElementWidth() +
|
||||
aFloaterCache->mMargins.left + aFloaterCache->mMargins.right;
|
||||
|
||||
// This is all we need to do to include the floater
|
||||
// max-element-width since we don't require that we end up with
|
||||
// content next to floaters.
|
||||
aState.UpdateMaxElementWidth(mew); // fix for bug 13553
|
||||
|
||||
// Allow the floater width to be restored in state recovery.
|
||||
aFloaterCache->mMaxElementWidth = mew;
|
||||
}
|
||||
#ifdef NOISY_FLOATER
|
||||
printf("end ReflowFloater %p, sized to %d,%d\n", floater, metrics.width, metrics.height);
|
||||
|
@ -368,10 +368,6 @@ protected:
|
||||
nsLineBox* aLine,
|
||||
nscoord aMaxElementWidth);
|
||||
|
||||
void ComputeLineMaxElementWidth(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nscoord* aMaxElementWidth);
|
||||
|
||||
// XXX where to go
|
||||
PRBool ShouldJustifyLine(nsBlockReflowState& aState,
|
||||
line_iterator aLine);
|
||||
@ -428,9 +424,7 @@ protected:
|
||||
// but only if the available height is constrained.
|
||||
nsresult ReflowFloater(nsBlockReflowState& aState,
|
||||
nsPlaceholderFrame* aPlaceholder,
|
||||
nsRect& aCombinedRectResult,
|
||||
nsMargin& aMarginResult,
|
||||
nsMargin& aComputedOffsetsResult,
|
||||
nsFloaterCache* aFloaterCache,
|
||||
nsReflowStatus& aReflowStatus);
|
||||
|
||||
//----------------------------------------
|
||||
|
@ -591,6 +591,14 @@ nsBlockReflowState::RecoverStateFrom(nsLineList::iterator aLine,
|
||||
}
|
||||
#endif
|
||||
UpdateMaxElementWidth(aLine->mMaxElementWidth);
|
||||
|
||||
// Recover the floater MEWs for floaters in this line (but not in
|
||||
// blocks within it, since their MEWs are already part of the block's
|
||||
// MEW).
|
||||
if (aLine->HasFloaters()) {
|
||||
for (nsFloaterCache* fc = aLine->GetFirstFloater(); fc; fc = fc->Next())
|
||||
UpdateMaxElementWidth(fc->mMaxElementWidth);
|
||||
}
|
||||
}
|
||||
|
||||
// If computing the maximum width, then update mMaximumWidth
|
||||
@ -669,6 +677,7 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout,
|
||||
nsFloaterCache* fc = mFloaterCacheFreeList.Alloc();
|
||||
fc->mPlaceholder = aPlaceholder;
|
||||
fc->mIsCurrentLineFloater = aLineLayout.CanPlaceFloaterNow();
|
||||
fc->mMaxElementWidth = 0;
|
||||
|
||||
// Now place the floater immediately if possible. Otherwise stash it
|
||||
// away in mPendingFloaters and place it later.
|
||||
@ -884,8 +893,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
}
|
||||
|
||||
// Reflow the floater
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus);
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache, aReflowStatus);
|
||||
|
||||
// Get the floaters bounding box and margin information
|
||||
floater->GetRect(region);
|
||||
@ -968,8 +976,7 @@ nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
mY += mAvailSpaceRect.height;
|
||||
GetAvailableSpace();
|
||||
// reflow the floater again now since we have more space
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets, aReflowStatus);
|
||||
mBlock->ReflowFloater(*this, placeholder, aFloaterCache, aReflowStatus);
|
||||
// Get the floaters bounding box and margin information
|
||||
floater->GetRect(region);
|
||||
// Adjust the floater size by its margin. That's the area that will
|
||||
|
@ -129,10 +129,6 @@ public:
|
||||
|
||||
void FreeLineBox(nsLineBox* aLine);
|
||||
|
||||
void StoreMaxElementWidth(nsIFrame* aFloater, nscoord aWidth) {
|
||||
mBand.StoreMaxElementWidth(mPresContext, aFloater, aWidth);
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// This state is the "global" state computed once for the reflow of
|
||||
|
@ -83,6 +83,9 @@ public:
|
||||
// the containing block frame.
|
||||
nsRect mCombinedArea;
|
||||
|
||||
// The floater's max-element-width.
|
||||
nscoord mMaxElementWidth;
|
||||
|
||||
protected:
|
||||
nsFloaterCache* mNext;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user