r=troy; bugs: 13196; fixed floating table reflow issues found in 13196 by storing floater max-element-size for later retrieval

This commit is contained in:
kipp%netscape.com 1999-10-21 20:44:22 +00:00
parent dd5f4dec71
commit 0d540807d5
4 changed files with 282 additions and 22 deletions

View File

@ -16,10 +16,15 @@
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsCOMPtr.h"
#include "nsBlockBandData.h"
#include "nsIFrame.h"
#include "nsIFrameReflow.h"
#include "nsIStyleContext.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIFrameManager.h"
#include "nsLayoutAtoms.h"
#include "nsVoidArray.h"
nsBlockBandData::nsBlockBandData()
@ -280,34 +285,143 @@ nsBlockBandData::ClearFloaters(nscoord aY, PRUint8 aBreakType)
return aY;
}
//----------------------------------------------------------------------
static void
MaxElementSizePropertyDtor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIAtom* aPropertyName,
void* aPropertyValue)
{
nsSize* size = (nsSize*) aPropertyValue;
delete size;
}
void
nsBlockBandData::GetMaxElementSize(nscoord* aWidthResult,
nsBlockBandData::StoreMaxElementSize(nsIPresContext* aPresContext,
nsIFrame* aFrame,
const nsSize& aMaxElementSize)
{
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
if (shell) {
nsCOMPtr<nsIFrameManager> mgr;
shell->GetFrameManager(getter_AddRefs(mgr));
if (mgr) {
nsSize* size = new nsSize(aMaxElementSize);
if (size) {
mgr->SetFrameProperty(aFrame, nsLayoutAtoms::maxElementSizeProperty,
size, MaxElementSizePropertyDtor);
}
}
}
}
void
nsBlockBandData::RecoverMaxElementSize(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsSize* aResult)
{
if (!aResult) return;
nsSize answer(0, 0);
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
if (shell) {
nsCOMPtr<nsIFrameManager> mgr;
shell->GetFrameManager(getter_AddRefs(mgr));
if (mgr) {
nsSize* size = nsnull;
mgr->GetFrameProperty(aFrame, nsLayoutAtoms::maxElementSizeProperty,
0, (void**) &size);
if (size) {
answer = *size;
}
}
}
*aResult = answer;
}
void
nsBlockBandData::GetMaxElementSize(nsIPresContext* aPresContext,
nscoord* aWidthResult,
nscoord* aHeightResult) const
{
nsCOMPtr<nsIFrameManager> mgr;
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
if (shell) {
shell->GetFrameManager(getter_AddRefs(mgr));
}
nsRect r;
nscoord maxWidth = 0;
nscoord maxHeight = 0;
for (PRInt32 i = 0; i < mCount; i++) {
const nsBandTrapezoid* trap = &mTrapezoids[i];
if (trap->mState != nsBandTrapezoid::Available) {
// Get the width of the impacted area and update the maxWidth
trap->GetRect(r);
if (r.width > maxWidth) maxWidth = r.width;
// Get the total height of the frame to compute the maxHeight,
// Note: get the total height of the frame to compute the maxHeight,
// not just the height that is part of this band.
// XXX vertical margins!
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);
f->GetRect(r);
if (r.height > maxHeight) maxHeight = r.height;
if (mgr) {
nsSize* maxElementSize = nsnull;
mgr->GetFrameProperty(f, nsLayoutAtoms::maxElementSizeProperty,
0, (void**) &maxElementSize);
if (maxElementSize) {
useBackupValue = PR_FALSE;
if (maxElementSize->width > maxWidth) {
maxWidth = maxElementSize->width;
}
if (maxElementSize->height > maxHeight) {
maxHeight = maxElementSize->height;
}
}
}
if (useBackupValue) {
usedBackupValue = PR_TRUE;
f->GetRect(r);
if (r.height > maxHeight) maxHeight = r.height;
}
}
// Get the width of the impacted area and update the maxWidth
if (usedBackupValue) {
trap->GetRect(r);
if (r.width > maxWidth) maxWidth = r.width;
}
} else {
trap->mFrame->GetRect(r);
if (r.height > maxHeight) maxHeight = r.height;
PRBool useBackupValue = PR_TRUE;
if (mgr) {
nsSize* maxElementSize = nsnull;
mgr->GetFrameProperty(trap->mFrame,
nsLayoutAtoms::maxElementSizeProperty,
0, (void**) &maxElementSize);
if (maxElementSize) {
useBackupValue = PR_FALSE;
if (maxElementSize->width > maxWidth) {
maxWidth = maxElementSize->width;
}
if (maxElementSize->height > maxHeight) {
maxHeight = maxElementSize->height;
}
}
}
if (useBackupValue) {
trap->GetRect(r);
if (r.width > maxWidth) maxWidth = r.width;
trap->mFrame->GetRect(r);
if (r.height > maxHeight) maxHeight = r.height;
}
}
}
}

View File

@ -21,6 +21,8 @@
#include "nsISpaceManager.h"
class nsIPresContext;
// Number of builtin nsBandTrapezoid's
#define NS_BLOCK_BAND_DATA_TRAPS 6
@ -69,7 +71,20 @@ public:
// Return the impact on the max-element-size for this band by
// computing the maximum width and maximum height of all the
// floaters.
void GetMaxElementSize(nscoord* aWidthResult, nscoord* aHeightResult) const;
void GetMaxElementSize(nsIPresContext* aPresContext,
nscoord* aWidthResult, nscoord* aHeightResult) const;
// Utility method to save away the max-element-size associated with
// a floating frame.
static void StoreMaxElementSize(nsIPresContext* aPresContext,
nsIFrame* aFrame,
const nsSize& aMaxElementSize);
// Utility method to recover a stored max-element-size value
// associated with a floating frame.
static void RecoverMaxElementSize(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsSize* aResult);
protected:
// The spacemanager we are getting space from
@ -93,6 +108,7 @@ protected:
void ComputeAvailSpaceRect();
PRBool ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType);
};
#endif /* nsBlockBandData_h___ */

View File

@ -16,10 +16,15 @@
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsCOMPtr.h"
#include "nsBlockBandData.h"
#include "nsIFrame.h"
#include "nsIFrameReflow.h"
#include "nsIStyleContext.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIFrameManager.h"
#include "nsLayoutAtoms.h"
#include "nsVoidArray.h"
nsBlockBandData::nsBlockBandData()
@ -280,34 +285,143 @@ nsBlockBandData::ClearFloaters(nscoord aY, PRUint8 aBreakType)
return aY;
}
//----------------------------------------------------------------------
static void
MaxElementSizePropertyDtor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIAtom* aPropertyName,
void* aPropertyValue)
{
nsSize* size = (nsSize*) aPropertyValue;
delete size;
}
void
nsBlockBandData::GetMaxElementSize(nscoord* aWidthResult,
nsBlockBandData::StoreMaxElementSize(nsIPresContext* aPresContext,
nsIFrame* aFrame,
const nsSize& aMaxElementSize)
{
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
if (shell) {
nsCOMPtr<nsIFrameManager> mgr;
shell->GetFrameManager(getter_AddRefs(mgr));
if (mgr) {
nsSize* size = new nsSize(aMaxElementSize);
if (size) {
mgr->SetFrameProperty(aFrame, nsLayoutAtoms::maxElementSizeProperty,
size, MaxElementSizePropertyDtor);
}
}
}
}
void
nsBlockBandData::RecoverMaxElementSize(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsSize* aResult)
{
if (!aResult) return;
nsSize answer(0, 0);
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
if (shell) {
nsCOMPtr<nsIFrameManager> mgr;
shell->GetFrameManager(getter_AddRefs(mgr));
if (mgr) {
nsSize* size = nsnull;
mgr->GetFrameProperty(aFrame, nsLayoutAtoms::maxElementSizeProperty,
0, (void**) &size);
if (size) {
answer = *size;
}
}
}
*aResult = answer;
}
void
nsBlockBandData::GetMaxElementSize(nsIPresContext* aPresContext,
nscoord* aWidthResult,
nscoord* aHeightResult) const
{
nsCOMPtr<nsIFrameManager> mgr;
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
if (shell) {
shell->GetFrameManager(getter_AddRefs(mgr));
}
nsRect r;
nscoord maxWidth = 0;
nscoord maxHeight = 0;
for (PRInt32 i = 0; i < mCount; i++) {
const nsBandTrapezoid* trap = &mTrapezoids[i];
if (trap->mState != nsBandTrapezoid::Available) {
// Get the width of the impacted area and update the maxWidth
trap->GetRect(r);
if (r.width > maxWidth) maxWidth = r.width;
// Get the total height of the frame to compute the maxHeight,
// Note: get the total height of the frame to compute the maxHeight,
// not just the height that is part of this band.
// XXX vertical margins!
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);
f->GetRect(r);
if (r.height > maxHeight) maxHeight = r.height;
if (mgr) {
nsSize* maxElementSize = nsnull;
mgr->GetFrameProperty(f, nsLayoutAtoms::maxElementSizeProperty,
0, (void**) &maxElementSize);
if (maxElementSize) {
useBackupValue = PR_FALSE;
if (maxElementSize->width > maxWidth) {
maxWidth = maxElementSize->width;
}
if (maxElementSize->height > maxHeight) {
maxHeight = maxElementSize->height;
}
}
}
if (useBackupValue) {
usedBackupValue = PR_TRUE;
f->GetRect(r);
if (r.height > maxHeight) maxHeight = r.height;
}
}
// Get the width of the impacted area and update the maxWidth
if (usedBackupValue) {
trap->GetRect(r);
if (r.width > maxWidth) maxWidth = r.width;
}
} else {
trap->mFrame->GetRect(r);
if (r.height > maxHeight) maxHeight = r.height;
PRBool useBackupValue = PR_TRUE;
if (mgr) {
nsSize* maxElementSize = nsnull;
mgr->GetFrameProperty(trap->mFrame,
nsLayoutAtoms::maxElementSizeProperty,
0, (void**) &maxElementSize);
if (maxElementSize) {
useBackupValue = PR_FALSE;
if (maxElementSize->width > maxWidth) {
maxWidth = maxElementSize->width;
}
if (maxElementSize->height > maxHeight) {
maxHeight = maxElementSize->height;
}
}
}
if (useBackupValue) {
trap->GetRect(r);
if (r.width > maxWidth) maxWidth = r.width;
trap->mFrame->GetRect(r);
if (r.height > maxHeight) maxHeight = r.height;
}
}
}
}

View File

@ -21,6 +21,8 @@
#include "nsISpaceManager.h"
class nsIPresContext;
// Number of builtin nsBandTrapezoid's
#define NS_BLOCK_BAND_DATA_TRAPS 6
@ -69,7 +71,20 @@ public:
// Return the impact on the max-element-size for this band by
// computing the maximum width and maximum height of all the
// floaters.
void GetMaxElementSize(nscoord* aWidthResult, nscoord* aHeightResult) const;
void GetMaxElementSize(nsIPresContext* aPresContext,
nscoord* aWidthResult, nscoord* aHeightResult) const;
// Utility method to save away the max-element-size associated with
// a floating frame.
static void StoreMaxElementSize(nsIPresContext* aPresContext,
nsIFrame* aFrame,
const nsSize& aMaxElementSize);
// Utility method to recover a stored max-element-size value
// associated with a floating frame.
static void RecoverMaxElementSize(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsSize* aResult);
protected:
// The spacemanager we are getting space from
@ -93,6 +108,7 @@ protected:
void ComputeAvailSpaceRect();
PRBool ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType);
};
#endif /* nsBlockBandData_h___ */