table header and footer rowgroups placed properly, replicated across continuing tables

some pagination fixes, including a hack to make negative available heights = 1.
This commit is contained in:
buster 1998-04-23 17:29:07 +00:00
parent ac6d7c116e
commit 9481637fae
17 changed files with 2213 additions and 385 deletions

View File

@ -145,6 +145,30 @@ PRInt32 nsTableCellFrame::GetRowSpan()
return result;
}
/** helper method to get the col span of this frame's content (which must be a cell) */
PRInt32 nsTableCellFrame::GetColSpan()
{
PRInt32 result = 0;
nsTableCell *cellContent = (nsTableCell *)mContent;
if (nsnull!=cellContent)
{
result = cellContent->GetColSpan();
}
return result;
}
/** helper method to get the col index of this frame's content (which must be a cell) */
PRInt32 nsTableCellFrame::GetColIndex()
{
PRInt32 result = 0;
nsTableCell *cellContent = (nsTableCell *)mContent;
if (nsnull!=cellContent)
{
result = cellContent->GetColIndex();
}
return result;
}
void nsTableCellFrame::CreatePsuedoFrame(nsIPresContext* aPresContext)
{
// Do we have a prev-in-flow?
@ -229,6 +253,8 @@ NS_METHOD nsTableCellFrame::ResizeReflow(nsIPresContext* aPresContext,
// Try to reflow the child into the available space. It might not
// fit or might need continuing.
if (availSize.height < 0)
availSize.height = 1;
nsSize maxKidElementSize;
if (gsDebug==PR_TRUE)
printf(" nsTableCellFrame::ResizeReflow calling ReflowChild with availSize=%d,%d\n",

View File

@ -63,8 +63,15 @@ public:
void VerticallyAlignChild(nsIPresContext* aPresContext);
/** return the mapped cell's row span. Always >= 1. */
virtual PRInt32 GetRowSpan();
/** return the mapped cell's col span. Always >= 1. */
virtual PRInt32 GetColSpan();
/** return the mapped cell's column index (starting at 0 for the first column) */
virtual PRInt32 GetColIndex();
virtual ~nsTableCellFrame();
protected:

View File

@ -90,6 +90,12 @@ struct InnerTableReflowState {
// Flag for whether we're dealing with the first interior row group
PRBool firstRowGroup;
// a list of the footers in this table frame, for quick access when inserting bodies
nsVoidArray *footerList;
// cache the total height of the footers for placing body rows
nscoord footerHeight;
InnerTableReflowState(nsIPresContext* aPresContext,
const nsSize& aMaxSize,
nsStyleMolecule* aMol)
@ -103,9 +109,13 @@ struct InnerTableReflowState {
unconstrainedWidth = PRBool(aMaxSize.width == NS_UNCONSTRAINEDSIZE);
unconstrainedHeight = PRBool(aMaxSize.height == NS_UNCONSTRAINEDSIZE);
firstRowGroup = PR_TRUE;
footerHeight = 0;
footerList = nsnull;
}
~InnerTableReflowState() {
if (nsnull!=footerList)
delete footerList;
}
};
@ -712,7 +722,7 @@ nsIFrame::ReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresCont
nsIFrame* prevKidFrame = nsnull;/* XXX incremental reflow! */
#ifdef NS_DEBUG
PreReflowCheck();
//PreReflowCheck();
#endif
// Initialize out parameter
@ -775,7 +785,7 @@ nsIFrame::ReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresCont
}
// Return our desired rect
NS_ASSERTION(0<state.y, "illegal height after reflow");
//NS_ASSERTION(0<state.y, "illegal height after reflow");
aDesiredSize.width = aMaxSize.width;
aDesiredSize.height = state.y;
@ -798,7 +808,7 @@ nsIFrame::ReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresCont
mPass = kPASS_UNDEFINED; // we're no longer in-process
#ifdef NS_DEBUG
PostReflowCheck(status);
//PostReflowCheck(status);
#endif
return status;
@ -850,6 +860,48 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
aState.availSize.height -= aKidRect.height;
}
// If this is a footer row group, add it to the list of footer row groups
nsIAtom * tFootTag = NS_NewAtom(nsTablePart::kRowGroupFootTagString); // tFootTag: REFCNT++
nsIAtom *kidType=nsnull;
((nsTableRowGroupFrame *)aKidFrame)->GetRowGroupType(kidType);
if (tFootTag==kidType)
{
if (nsnull==aState.footerList)
aState.footerList = new nsVoidArray();
aState.footerList->AppendElement((void *)aKidFrame);
aState.footerHeight += aKidRect.height;
}
// else if this is a body row group, push down all the footer row groups
else
{
// don't bother unless there are footers to push down
if (nsnull!=aState.footerList && 0!=aState.footerList->Count())
{
nsPoint origin;
aKidFrame->GetOrigin(origin);
origin.y -= aState.footerHeight;
aKidFrame->MoveTo(origin.x, origin.y);
nsIAtom * tBodyTag = NS_NewAtom(nsTablePart::kRowGroupBodyTagString); // tBodyTag: REFCNT++
if (tBodyTag==kidType)
{
PRInt32 numFooters = aState.footerList->Count();
for (PRInt32 footerIndex = 0; footerIndex < numFooters; footerIndex++)
{
nsTableRowGroupFrame * footer = (nsTableRowGroupFrame *)(aState.footerList->ElementAt(footerIndex));
NS_ASSERTION(nsnull!=footer, "bad footer list in table inner frame.");
if (nsnull!=footer)
{
footer->GetOrigin(origin);
origin.y += aKidRect.height;
footer->MoveTo(origin.x, origin.y);
}
}
}
NS_RELEASE(tBodyTag);
}
}
NS_RELEASE(tFootTag);
// Update the maximum element size
if (PR_TRUE==aState.firstRowGroup)
{
@ -1284,8 +1336,8 @@ PRBool nsTableFrame::PullUpChildren(nsIPresContext* aPresContext,
*/
nsIFrame::ReflowStatus
nsTableFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
InnerTableReflowState& aState,
nsSize* aMaxElementSize)
InnerTableReflowState& aState,
nsSize* aMaxElementSize)
{
#ifdef NS_DEBUG
VerifyLastIsComplete();
@ -2441,16 +2493,53 @@ NS_METHOD nsTableFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
cf->SetRect(nsRect(0, 0, mRect.width, 0));
// add headers and footers to cf
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
PRInt32 childCount;
firstInFlow->ChildCount(childCount);
PRInt32 childIndex = 0;
for (; childIndex < childCount; childIndex++)
nsIFrame * rg = nsnull;
firstInFlow->ChildAt(0, rg);
NS_ASSERTION (nsnull!=rg, "previous frame has no children");
nsIAtom * tHeadTag = NS_NewAtom(nsTablePart::kRowGroupHeadTagString); // tHeadTag: REFCNT++
nsIAtom * tFootTag = NS_NewAtom(nsTablePart::kRowGroupFootTagString); // tFootTag: REFCNT++
PRInt32 index = 0;
nsIFrame * bodyRowGroupFromOverflow = mOverflowList;
nsIFrame * lastSib = nsnull;
for ( ; nsnull!=rg; index++)
{
// TODO: place copies of the header and footer row groups here
// maybe need to do this in ResizeReflow at the beginning, when we determine we are a continuing frame
nsIContent *content = nsnull;
rg->GetContent(content); // content: REFCNT++
NS_ASSERTION(nsnull!=content, "bad frame, returned null content.");
nsIAtom * rgTag = content->GetTag();
// if we've found a header or a footer, replicate it
if (tHeadTag==rgTag || tFootTag==rgTag)
{
printf("found a head or foot in continuing frame\n");
// Resolve style for the child
nsIStyleContext* kidStyleContext =
aPresContext->ResolveStyleContextFor(content, cf); // kidStyleContext: REFCNT++
nsStyleMolecule* kidMol =
(nsStyleMolecule*)kidStyleContext->GetData(kStyleMoleculeSID);
nsIContentDelegate* kidDel = nsnull;
kidDel = content->GetDelegate(aPresContext); // kidDel: REFCNT++
nsIFrame * duplicateFrame = kidDel->CreateFrame(aPresContext, content, index, cf);
NS_RELEASE(kidDel); // kidDel: REFCNT--
duplicateFrame->SetStyleContext(kidStyleContext);
NS_RELEASE(kidStyleContext); // kidStyleContenxt: REFCNT--
if (nsnull==lastSib)
{
mOverflowList = duplicateFrame;
}
else
{
lastSib->SetNextSibling(duplicateFrame);
}
duplicateFrame->SetNextSibling(bodyRowGroupFromOverflow);
lastSib = duplicateFrame;
}
NS_RELEASE(content); // content: REFCNT--
// get the next row group
rg->GetNextSibling(rg);
}
NS_RELEASE(tFootTag); // tHeadTag: REFCNT --
NS_RELEASE(tHeadTag); // tFootTag: REFCNT --
aContinuingFrame = cf;
return NS_OK;
}

View File

@ -305,7 +305,13 @@ NS_METHOD nsTableOuterFrame::ResizeReflow(nsIPresContext* aPresContext,
//NS_ASSERTION(0<state.y, "illegal height after reflow");
//NS_ASSERTION(0<state.innerTableMaxSize.width, "illegal width after reflow");
aDesiredSize.width = state.innerTableMaxSize.width;
aDesiredSize.height = state.y;
/* if we're incomplete, take up all the remaining height so we don't waste time
* trying to lay out in a slot that we know isn't tall enough to fit our minimum.
* otherwise, we're as tall as our kids want us to be */
if (frNotComplete == aStatus)
aDesiredSize.height = aMaxSize.height;
else
aDesiredSize.height = state.y;
if (gsDebug==PR_TRUE)
{
@ -486,7 +492,7 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
// Did the child fit?
if ((kidSize.height > aState.availSize.height) && (kidFrame != mFirstChild)) {
// The child is too wide to fit in the available space, and it's
// The child is too tall to fit in the available space, and it's
// not our first child
// Since we are giving the next-in-flow our last child, we
@ -518,8 +524,6 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
// Update mLastContentIsComplete now that this kid fits
mLastContentIsComplete = PRBool(status == frComplete);
// Is the child complete?
mLastContentIsComplete = PRBool(status == frComplete);
if (frNotComplete == status) {
// No, the child isn't complete
nsIFrame* kidNextInFlow;
@ -555,6 +559,21 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
kidFrame->GetNextSibling(nextSibling);
if (nsnull != nextSibling) {
PushChildren(nextSibling, kidFrame, lastContentIsComplete);
/* debug */
/*
printf ("having just pushed children, here is the frame hierarchy.\n");
nsIFrame *p;
GetGeometricParent(p);
nsIFrame *root;
while (nsnull!=p)
{
root = p;
p->GetGeometricParent(p);
}
root->List();
fflush(stdout);
*/
/* end debug */
SetLastContentOffset(prevKidFrame);
}
result = PR_FALSE;

View File

@ -593,7 +593,7 @@ PRBool nsTablePart::AppendRowGroup (nsTableRowGroup *aContent)
// if aContent is a body and the current child is a footer, stop, we've found the spot
else if (tBodyTag==rowGroupTag && tFootTag==tableChildTag)
{
break;
continue;
}
// if aContent is a body and we've gotten this far, keep going
else if (tBodyTag==rowGroupTag)

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@
#include "nscore.h"
#include "nsContainerFrame.h"
struct RowReflowState;
/**
* nsTableRowFrame is the frame that maps table rows
@ -110,12 +112,60 @@ protected:
/** protected constructor.
* @see NewFrame
*/
nsTableRowFrame(nsIContent* aContent,
PRInt32 aIndexInParent,
nsIFrame* aParentFrame);
nsTableRowFrame(nsIContent* aContent,
PRInt32 aIndexInParent,
nsIFrame* aParentFrame);
/** destructor */
virtual ~nsTableRowFrame();
nscoord GetTopMarginFor(nsIPresContext* aCX,
RowReflowState& aState,
nsStyleMolecule* aKidMol);
void PlaceChild( nsIPresContext* aPresContext,
RowReflowState& aState,
nsIFrame* aKidFrame,
const nsRect& aKidRect,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
/**
* Reflow the frames we've already created
*
* @param aPresContext presentation context to use
* @param aState current inline state
* @return true if we successfully reflowed all the mapped children and false
* otherwise, e.g. we pushed children to the next in flow
*/
PRBool ReflowMappedChildren(nsIPresContext* aPresContext,
RowReflowState& aState,
nsSize* aMaxElementSize);
/**
* Try and pull-up frames from our next-in-flow
*
* @param aPresContext presentation context to use
* @param aState current inline state
* @return true if we successfully pulled-up all the children and false
* otherwise, e.g. child didn't fit
*/
PRBool PullUpChildren(nsIPresContext* aPresContext,
RowReflowState& aState,
nsSize* aMaxElementSize);
/**
* Create new frames for content we haven't yet mapped
*
* @param aPresContext presentation context to use
* @param aState current inline state
* @return frComplete if all content has been mapped and frNotComplete
* if we should be continued
*/
ReflowStatus ReflowUnmappedChildren(nsIPresContext* aPresContext,
RowReflowState& aState,
nsSize* aMaxElementSize);
/** destructor */
virtual ~nsTableRowFrame();
private:
PRInt32 mTallestCell; // not my height, but the height of my tallest child

View File

@ -95,14 +95,24 @@ struct RowGroupReflowState {
/* ----------- nsTableRowGroupFrame ---------- */
nsTableRowGroupFrame::nsTableRowGroupFrame(nsIContent* aContent,
PRInt32 aIndexInParent,
nsIFrame* aParentFrame)
PRInt32 aIndexInParent,
nsIFrame* aParentFrame)
: nsContainerFrame(aContent, aIndexInParent, aParentFrame)
{
mType = aContent->GetTag(); // mType: REFCNT++
}
nsTableRowGroupFrame::~nsTableRowGroupFrame()
{
if (nsnull!=mType)
NS_RELEASE(mType); // mType: REFCNT--
}
NS_METHOD nsTableRowGroupFrame::GetRowGroupType(nsIAtom *& aType)
{
NS_ADDREF(mType);
aType=mType;
return NS_OK;
}
@ -264,6 +274,8 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
nsSize kidAvailSize(aState.availSize);
if (0>=kidAvailSize.height)
kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet
nsReflowMetrics desiredSize;
nsIFrame::ReflowStatus status;
@ -290,7 +302,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
// Reflow the child into the available space
status = ReflowChild(kidFrame, aPresContext, desiredSize,
kidAvailSize, pKidMaxElementSize);
kidAvailSize, pKidMaxElementSize);
// Did the child fit?
if ((kidFrame != mFirstChild) &&
@ -381,6 +393,12 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
break;
}
// Add back in the left and right margins, because one row does not
// impact another row's width
if (PR_FALSE == aState.unconstrainedWidth) {
kidAvailSize.width += kidMol->margin.left + kidMol->margin.right;
}
// Get the next child
kidFrame->GetNextSibling(kidFrame);
@ -868,10 +886,10 @@ nsTableRowGroupFrame::ResizeReflow( nsIPresContext* aPresContext,
}
// Return our desired rect
NS_ASSERTION(0<state.firstRowHeight, "illegal firstRowHeight after reflow");
NS_ASSERTION(0<state.y, "illegal height after reflow");
//NS_ASSERTION(0<state.firstRowHeight, "illegal firstRowHeight after reflow");
//NS_ASSERTION(0<state.y, "illegal height after reflow");
aDesiredSize.width = aMaxSize.width;
aDesiredSize.height = state.y;
aDesiredSize.height = state.y;
#ifdef NS_DEBUG
PostReflowCheck(aStatus);

View File

@ -20,6 +20,7 @@
#include "nscore.h"
#include "nsContainerFrame.h"
#include "nsIAtom.h"
struct RowGroupReflowState;
struct nsStyleMolecule;
@ -90,6 +91,15 @@ public:
nsIFrame* aParent,
nsIFrame*& aContinuingFrame);
/** returns the type of the mapped row group content in aType.
* caller MUST call release on the returned object if it is not null.
*
* @param aType out param filled with the type of the mapped content, or null if none.
*
* @return NS_OK
*/
NS_IMETHOD GetRowGroupType(nsIAtom *& aType);
protected:
/** protected constructor.
@ -149,6 +159,9 @@ protected:
RowGroupReflowState& aState,
nsSize* aMaxElementSize);
private:
nsIAtom *mType;
};

View File

@ -145,6 +145,30 @@ PRInt32 nsTableCellFrame::GetRowSpan()
return result;
}
/** helper method to get the col span of this frame's content (which must be a cell) */
PRInt32 nsTableCellFrame::GetColSpan()
{
PRInt32 result = 0;
nsTableCell *cellContent = (nsTableCell *)mContent;
if (nsnull!=cellContent)
{
result = cellContent->GetColSpan();
}
return result;
}
/** helper method to get the col index of this frame's content (which must be a cell) */
PRInt32 nsTableCellFrame::GetColIndex()
{
PRInt32 result = 0;
nsTableCell *cellContent = (nsTableCell *)mContent;
if (nsnull!=cellContent)
{
result = cellContent->GetColIndex();
}
return result;
}
void nsTableCellFrame::CreatePsuedoFrame(nsIPresContext* aPresContext)
{
// Do we have a prev-in-flow?
@ -229,6 +253,8 @@ NS_METHOD nsTableCellFrame::ResizeReflow(nsIPresContext* aPresContext,
// Try to reflow the child into the available space. It might not
// fit or might need continuing.
if (availSize.height < 0)
availSize.height = 1;
nsSize maxKidElementSize;
if (gsDebug==PR_TRUE)
printf(" nsTableCellFrame::ResizeReflow calling ReflowChild with availSize=%d,%d\n",

View File

@ -63,8 +63,15 @@ public:
void VerticallyAlignChild(nsIPresContext* aPresContext);
/** return the mapped cell's row span. Always >= 1. */
virtual PRInt32 GetRowSpan();
/** return the mapped cell's col span. Always >= 1. */
virtual PRInt32 GetColSpan();
/** return the mapped cell's column index (starting at 0 for the first column) */
virtual PRInt32 GetColIndex();
virtual ~nsTableCellFrame();
protected:

View File

@ -90,6 +90,12 @@ struct InnerTableReflowState {
// Flag for whether we're dealing with the first interior row group
PRBool firstRowGroup;
// a list of the footers in this table frame, for quick access when inserting bodies
nsVoidArray *footerList;
// cache the total height of the footers for placing body rows
nscoord footerHeight;
InnerTableReflowState(nsIPresContext* aPresContext,
const nsSize& aMaxSize,
nsStyleMolecule* aMol)
@ -103,9 +109,13 @@ struct InnerTableReflowState {
unconstrainedWidth = PRBool(aMaxSize.width == NS_UNCONSTRAINEDSIZE);
unconstrainedHeight = PRBool(aMaxSize.height == NS_UNCONSTRAINEDSIZE);
firstRowGroup = PR_TRUE;
footerHeight = 0;
footerList = nsnull;
}
~InnerTableReflowState() {
if (nsnull!=footerList)
delete footerList;
}
};
@ -712,7 +722,7 @@ nsIFrame::ReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresCont
nsIFrame* prevKidFrame = nsnull;/* XXX incremental reflow! */
#ifdef NS_DEBUG
PreReflowCheck();
//PreReflowCheck();
#endif
// Initialize out parameter
@ -775,7 +785,7 @@ nsIFrame::ReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresCont
}
// Return our desired rect
NS_ASSERTION(0<state.y, "illegal height after reflow");
//NS_ASSERTION(0<state.y, "illegal height after reflow");
aDesiredSize.width = aMaxSize.width;
aDesiredSize.height = state.y;
@ -798,7 +808,7 @@ nsIFrame::ReflowStatus nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresCont
mPass = kPASS_UNDEFINED; // we're no longer in-process
#ifdef NS_DEBUG
PostReflowCheck(status);
//PostReflowCheck(status);
#endif
return status;
@ -850,6 +860,48 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
aState.availSize.height -= aKidRect.height;
}
// If this is a footer row group, add it to the list of footer row groups
nsIAtom * tFootTag = NS_NewAtom(nsTablePart::kRowGroupFootTagString); // tFootTag: REFCNT++
nsIAtom *kidType=nsnull;
((nsTableRowGroupFrame *)aKidFrame)->GetRowGroupType(kidType);
if (tFootTag==kidType)
{
if (nsnull==aState.footerList)
aState.footerList = new nsVoidArray();
aState.footerList->AppendElement((void *)aKidFrame);
aState.footerHeight += aKidRect.height;
}
// else if this is a body row group, push down all the footer row groups
else
{
// don't bother unless there are footers to push down
if (nsnull!=aState.footerList && 0!=aState.footerList->Count())
{
nsPoint origin;
aKidFrame->GetOrigin(origin);
origin.y -= aState.footerHeight;
aKidFrame->MoveTo(origin.x, origin.y);
nsIAtom * tBodyTag = NS_NewAtom(nsTablePart::kRowGroupBodyTagString); // tBodyTag: REFCNT++
if (tBodyTag==kidType)
{
PRInt32 numFooters = aState.footerList->Count();
for (PRInt32 footerIndex = 0; footerIndex < numFooters; footerIndex++)
{
nsTableRowGroupFrame * footer = (nsTableRowGroupFrame *)(aState.footerList->ElementAt(footerIndex));
NS_ASSERTION(nsnull!=footer, "bad footer list in table inner frame.");
if (nsnull!=footer)
{
footer->GetOrigin(origin);
origin.y += aKidRect.height;
footer->MoveTo(origin.x, origin.y);
}
}
}
NS_RELEASE(tBodyTag);
}
}
NS_RELEASE(tFootTag);
// Update the maximum element size
if (PR_TRUE==aState.firstRowGroup)
{
@ -1284,8 +1336,8 @@ PRBool nsTableFrame::PullUpChildren(nsIPresContext* aPresContext,
*/
nsIFrame::ReflowStatus
nsTableFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
InnerTableReflowState& aState,
nsSize* aMaxElementSize)
InnerTableReflowState& aState,
nsSize* aMaxElementSize)
{
#ifdef NS_DEBUG
VerifyLastIsComplete();
@ -2441,16 +2493,53 @@ NS_METHOD nsTableFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
cf->SetRect(nsRect(0, 0, mRect.width, 0));
// add headers and footers to cf
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
PRInt32 childCount;
firstInFlow->ChildCount(childCount);
PRInt32 childIndex = 0;
for (; childIndex < childCount; childIndex++)
nsIFrame * rg = nsnull;
firstInFlow->ChildAt(0, rg);
NS_ASSERTION (nsnull!=rg, "previous frame has no children");
nsIAtom * tHeadTag = NS_NewAtom(nsTablePart::kRowGroupHeadTagString); // tHeadTag: REFCNT++
nsIAtom * tFootTag = NS_NewAtom(nsTablePart::kRowGroupFootTagString); // tFootTag: REFCNT++
PRInt32 index = 0;
nsIFrame * bodyRowGroupFromOverflow = mOverflowList;
nsIFrame * lastSib = nsnull;
for ( ; nsnull!=rg; index++)
{
// TODO: place copies of the header and footer row groups here
// maybe need to do this in ResizeReflow at the beginning, when we determine we are a continuing frame
nsIContent *content = nsnull;
rg->GetContent(content); // content: REFCNT++
NS_ASSERTION(nsnull!=content, "bad frame, returned null content.");
nsIAtom * rgTag = content->GetTag();
// if we've found a header or a footer, replicate it
if (tHeadTag==rgTag || tFootTag==rgTag)
{
printf("found a head or foot in continuing frame\n");
// Resolve style for the child
nsIStyleContext* kidStyleContext =
aPresContext->ResolveStyleContextFor(content, cf); // kidStyleContext: REFCNT++
nsStyleMolecule* kidMol =
(nsStyleMolecule*)kidStyleContext->GetData(kStyleMoleculeSID);
nsIContentDelegate* kidDel = nsnull;
kidDel = content->GetDelegate(aPresContext); // kidDel: REFCNT++
nsIFrame * duplicateFrame = kidDel->CreateFrame(aPresContext, content, index, cf);
NS_RELEASE(kidDel); // kidDel: REFCNT--
duplicateFrame->SetStyleContext(kidStyleContext);
NS_RELEASE(kidStyleContext); // kidStyleContenxt: REFCNT--
if (nsnull==lastSib)
{
mOverflowList = duplicateFrame;
}
else
{
lastSib->SetNextSibling(duplicateFrame);
}
duplicateFrame->SetNextSibling(bodyRowGroupFromOverflow);
lastSib = duplicateFrame;
}
NS_RELEASE(content); // content: REFCNT--
// get the next row group
rg->GetNextSibling(rg);
}
NS_RELEASE(tFootTag); // tHeadTag: REFCNT --
NS_RELEASE(tHeadTag); // tFootTag: REFCNT --
aContinuingFrame = cf;
return NS_OK;
}

View File

@ -305,7 +305,13 @@ NS_METHOD nsTableOuterFrame::ResizeReflow(nsIPresContext* aPresContext,
//NS_ASSERTION(0<state.y, "illegal height after reflow");
//NS_ASSERTION(0<state.innerTableMaxSize.width, "illegal width after reflow");
aDesiredSize.width = state.innerTableMaxSize.width;
aDesiredSize.height = state.y;
/* if we're incomplete, take up all the remaining height so we don't waste time
* trying to lay out in a slot that we know isn't tall enough to fit our minimum.
* otherwise, we're as tall as our kids want us to be */
if (frNotComplete == aStatus)
aDesiredSize.height = aMaxSize.height;
else
aDesiredSize.height = state.y;
if (gsDebug==PR_TRUE)
{
@ -486,7 +492,7 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
// Did the child fit?
if ((kidSize.height > aState.availSize.height) && (kidFrame != mFirstChild)) {
// The child is too wide to fit in the available space, and it's
// The child is too tall to fit in the available space, and it's
// not our first child
// Since we are giving the next-in-flow our last child, we
@ -518,8 +524,6 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
// Update mLastContentIsComplete now that this kid fits
mLastContentIsComplete = PRBool(status == frComplete);
// Is the child complete?
mLastContentIsComplete = PRBool(status == frComplete);
if (frNotComplete == status) {
// No, the child isn't complete
nsIFrame* kidNextInFlow;
@ -555,6 +559,21 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
kidFrame->GetNextSibling(nextSibling);
if (nsnull != nextSibling) {
PushChildren(nextSibling, kidFrame, lastContentIsComplete);
/* debug */
/*
printf ("having just pushed children, here is the frame hierarchy.\n");
nsIFrame *p;
GetGeometricParent(p);
nsIFrame *root;
while (nsnull!=p)
{
root = p;
p->GetGeometricParent(p);
}
root->List();
fflush(stdout);
*/
/* end debug */
SetLastContentOffset(prevKidFrame);
}
result = PR_FALSE;

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@
#include "nscore.h"
#include "nsContainerFrame.h"
struct RowReflowState;
/**
* nsTableRowFrame is the frame that maps table rows
@ -110,12 +112,60 @@ protected:
/** protected constructor.
* @see NewFrame
*/
nsTableRowFrame(nsIContent* aContent,
PRInt32 aIndexInParent,
nsIFrame* aParentFrame);
nsTableRowFrame(nsIContent* aContent,
PRInt32 aIndexInParent,
nsIFrame* aParentFrame);
/** destructor */
virtual ~nsTableRowFrame();
nscoord GetTopMarginFor(nsIPresContext* aCX,
RowReflowState& aState,
nsStyleMolecule* aKidMol);
void PlaceChild( nsIPresContext* aPresContext,
RowReflowState& aState,
nsIFrame* aKidFrame,
const nsRect& aKidRect,
nsSize* aMaxElementSize,
nsSize& aKidMaxElementSize);
/**
* Reflow the frames we've already created
*
* @param aPresContext presentation context to use
* @param aState current inline state
* @return true if we successfully reflowed all the mapped children and false
* otherwise, e.g. we pushed children to the next in flow
*/
PRBool ReflowMappedChildren(nsIPresContext* aPresContext,
RowReflowState& aState,
nsSize* aMaxElementSize);
/**
* Try and pull-up frames from our next-in-flow
*
* @param aPresContext presentation context to use
* @param aState current inline state
* @return true if we successfully pulled-up all the children and false
* otherwise, e.g. child didn't fit
*/
PRBool PullUpChildren(nsIPresContext* aPresContext,
RowReflowState& aState,
nsSize* aMaxElementSize);
/**
* Create new frames for content we haven't yet mapped
*
* @param aPresContext presentation context to use
* @param aState current inline state
* @return frComplete if all content has been mapped and frNotComplete
* if we should be continued
*/
ReflowStatus ReflowUnmappedChildren(nsIPresContext* aPresContext,
RowReflowState& aState,
nsSize* aMaxElementSize);
/** destructor */
virtual ~nsTableRowFrame();
private:
PRInt32 mTallestCell; // not my height, but the height of my tallest child

View File

@ -95,14 +95,24 @@ struct RowGroupReflowState {
/* ----------- nsTableRowGroupFrame ---------- */
nsTableRowGroupFrame::nsTableRowGroupFrame(nsIContent* aContent,
PRInt32 aIndexInParent,
nsIFrame* aParentFrame)
PRInt32 aIndexInParent,
nsIFrame* aParentFrame)
: nsContainerFrame(aContent, aIndexInParent, aParentFrame)
{
mType = aContent->GetTag(); // mType: REFCNT++
}
nsTableRowGroupFrame::~nsTableRowGroupFrame()
{
if (nsnull!=mType)
NS_RELEASE(mType); // mType: REFCNT--
}
NS_METHOD nsTableRowGroupFrame::GetRowGroupType(nsIAtom *& aType)
{
NS_ADDREF(mType);
aType=mType;
return NS_OK;
}
@ -264,6 +274,8 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
nsSize kidAvailSize(aState.availSize);
if (0>=kidAvailSize.height)
kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet
nsReflowMetrics desiredSize;
nsIFrame::ReflowStatus status;
@ -290,7 +302,7 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
// Reflow the child into the available space
status = ReflowChild(kidFrame, aPresContext, desiredSize,
kidAvailSize, pKidMaxElementSize);
kidAvailSize, pKidMaxElementSize);
// Did the child fit?
if ((kidFrame != mFirstChild) &&
@ -381,6 +393,12 @@ PRBool nsTableRowGroupFrame::ReflowMappedChildren( nsIPresContext* aPresCon
break;
}
// Add back in the left and right margins, because one row does not
// impact another row's width
if (PR_FALSE == aState.unconstrainedWidth) {
kidAvailSize.width += kidMol->margin.left + kidMol->margin.right;
}
// Get the next child
kidFrame->GetNextSibling(kidFrame);
@ -868,10 +886,10 @@ nsTableRowGroupFrame::ResizeReflow( nsIPresContext* aPresContext,
}
// Return our desired rect
NS_ASSERTION(0<state.firstRowHeight, "illegal firstRowHeight after reflow");
NS_ASSERTION(0<state.y, "illegal height after reflow");
//NS_ASSERTION(0<state.firstRowHeight, "illegal firstRowHeight after reflow");
//NS_ASSERTION(0<state.y, "illegal height after reflow");
aDesiredSize.width = aMaxSize.width;
aDesiredSize.height = state.y;
aDesiredSize.height = state.y;
#ifdef NS_DEBUG
PostReflowCheck(aStatus);

View File

@ -20,6 +20,7 @@
#include "nscore.h"
#include "nsContainerFrame.h"
#include "nsIAtom.h"
struct RowGroupReflowState;
struct nsStyleMolecule;
@ -90,6 +91,15 @@ public:
nsIFrame* aParent,
nsIFrame*& aContinuingFrame);
/** returns the type of the mapped row group content in aType.
* caller MUST call release on the returned object if it is not null.
*
* @param aType out param filled with the type of the mapped content, or null if none.
*
* @return NS_OK
*/
NS_IMETHOD GetRowGroupType(nsIAtom *& aType);
protected:
/** protected constructor.
@ -149,6 +159,9 @@ protected:
RowGroupReflowState& aState,
nsSize* aMaxElementSize);
private:
nsIAtom *mType;
};