mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
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:
parent
dd5f4dec71
commit
0d540807d5
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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___ */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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___ */
|
||||
|
Loading…
Reference in New Issue
Block a user