Incremental reflow changes

This commit is contained in:
troy 1998-07-14 15:29:50 +00:00
parent e450a78d6b
commit 8fb033f617
4 changed files with 146 additions and 212 deletions

View File

@ -72,9 +72,6 @@ struct RowReflowState {
tableFrame = aTableFrame;
x=0;
}
~RowReflowState() {
}
};
@ -616,12 +613,16 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
// The things in the RowReflowState object we need to restore are:
// - maxCellHeight
// - maxVertCellSpace
// - x
nsresult nsTableRowFrame::RecoverState(RowReflowState& aState,
nsIFrame* aKidFrame)
{
// Walk the list of children looking for aKidFrame
// Walk the list of children looking for aKidFrame. While we're at
// it get the maxCellHeight and maxVertCellSpace for all the
// frames except aKidFrame
nsIFrame* prevKidFrame = nsnull;
for (nsIFrame* frame = mFirstChild; frame != aKidFrame;) {
for (nsIFrame* frame = mFirstChild; nsnull != frame;) {
if (frame != aKidFrame) {
PRInt32 rowSpan = ((nsTableCellFrame*)frame)->GetRowSpan();
if (mMinRowSpan == rowSpan) {
// XXX This isn't quite right. We also need to check whether the cell
@ -650,25 +651,30 @@ nsresult nsTableRowFrame::RecoverState(RowReflowState& aState,
//
// We should be using GetReflowMetrics() to get information from the
// table cell, and that will include the max element size...
}
// Remember the frame that precedes aKidFrame
prevKidFrame = frame;
frame->GetNextSibling(frame);
}
// Update the running x-offset based on the frame's current x-origin
nsPoint origin;
aKidFrame->GetOrigin(origin);
aState.x = origin.x;
return NS_OK;
}
nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
RowReflowState& aState,
const nsReflowState& aReflowState,
nsSize* aMaxElementSize)
nsReflowMetrics& aDesiredSize)
{
nsresult status;
// XXX Deal with the case where the reflow command is targeted at us
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
aState.reflowState.reflowCommand->GetTarget(target);
if (this == target) {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
return NS_ERROR_NOT_IMPLEMENTED;
@ -676,7 +682,7 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
// Get the next frame in the reflow chain
nsIFrame* kidFrame;
aReflowState.reflowCommand->GetNext(kidFrame);
aState.reflowState.reflowCommand->GetNext(kidFrame);
// Recover our reflow state
RecoverState(aState, kidFrame);
@ -685,35 +691,33 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
nsMargin kidMargin;
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, kidMargin);
// Figure out the amount of available space for the child
// XXX Shakey...
nsSize kidAvailSize(aState.availSize); // XXX: top and bottom margins?
// Compute the x-origin for the child, taking into account straddlers (cells
// from prior rows with rowspans > 1)
nscoord x = kidMargin.left;
// At this point, we know the column widths. Get the available width
// from the known column widths
PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
for (PRInt32 colIndex=0; colIndex<cellColIndex; colIndex++)
{
x += aState.tableFrame->GetColumnWidth(colIndex);
}
// at this point, we know the column widths.
// so we get the avail width from the known column widths
PRInt32 cellStartingCol = ((nsTableCellFrame *)kidFrame)->GetColIndex();
PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
nscoord availWidth = 0;
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
availWidth += aState.tableFrame->GetColumnWidth(cellStartingCol+numColSpan);
kidAvailSize.width = availWidth;
{
availWidth += aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
if (0<numColSpan)
{
availWidth += kidMargin.right;
if (0!=cellColIndex)
availWidth += kidMargin.left;
}
}
// Pass along the reflow command. Reflow the child with an unconstrained
// width and get its maxElementSize
// Always let the cell be as high as it wants. We ignore the height that's
// passed in and always place the entire row. Let the row group decide
// whether we fit or wehther the entire row is pushed
nsSize kidAvailSize(availWidth, NS_UNCONSTRAINEDSIZE);
// Pass along the reflow command
nsSize kidMaxElementSize;
nsReflowMetrics desiredSize(&kidMaxElementSize);
nsReflowState kidReflowState(kidFrame, aReflowState, kidAvailSize);
nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize);
kidFrame->WillReflow(*aPresContext);
kidFrame->MoveTo(x, kidMargin.top);
kidFrame->MoveTo(aState.x, kidMargin.top);
// XXX Unfortunately we need to reflow the child several times.
// The first time is for the incremental reflow command. We can't pass in
@ -769,56 +773,21 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
// end special Nav4 compatibility code
// Now place the child
nsRect kidRect (x, kidMargin.top, cellWidth, cellHeight);
nsRect kidRect (aState.x, kidMargin.top, cellWidth, cellHeight);
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize,
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
&kidMaxElementSize);
// Now iterate over the remaining cells, and update our max cell
// height and our running x-offset
//
// We don't have to re-position the x-origin of any of the child frames
// that follow, because the column width hasn't changed...
// XXX This needs to be computed somehow...
nscoord maxCellTopMargin = 0;
nscoord maxCellBottomMargin = 0;
kidFrame->GetNextSibling((nsIFrame*&)kidFrame);
while (nsnull != kidFrame) {
PRInt32 rowSpan = ((nsTableCellFrame*)kidFrame)->GetRowSpan();
nsRect rect;
kidFrame->GetRect(rect);
if (mMinRowSpan == rowSpan) {
nsSize desiredSize = ((nsTableCellFrame *)kidFrame)->GetDesiredSize();
// Update maxCellHeight
if (desiredSize.height > aState.maxCellHeight) {
aState.maxCellHeight = desiredSize.height;
}
// Update maxCellVertHeight
nsMargin margin;
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK)
{
nscoord height = desiredSize.height + margin.top + margin.bottom;
if (height > aState.maxCellVertSpace) {
aState.maxCellVertSpace = height;
}
// XXX Currently we assume cells have margins, but that isn't correct...
if (margin.top > maxCellTopMargin) {
maxCellTopMargin = margin.top;
}
if (margin.bottom > maxCellBottomMargin) {
maxCellBottomMargin = margin.bottom;
}
}
}
// Get the next cell frame
kidFrame->GetNextSibling((nsIFrame*&)kidFrame);
}
SetMaxChildHeight(aState.maxCellHeight, maxCellTopMargin, maxCellBottomMargin);
// Return our desired size. Note that our desired width is just whatever width
// we were given by the row group frame
aDesiredSize.width = aState.availSize.width;
aDesiredSize.height = aState.maxCellVertSpace;
return status;
}
@ -869,8 +838,7 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext,
break;
case eReflowReason_Incremental:
result = IncrementalReflow(aPresContext, state, aReflowState,
aDesiredSize.maxElementSize);
result = IncrementalReflow(aPresContext, state, aDesiredSize);
break;
}

View File

@ -163,8 +163,7 @@ protected:
*/
nsresult IncrementalReflow(nsIPresContext* aPresContext,
RowReflowState& aState,
const nsReflowState& aReflowState,
nsSize* aMaxElementSize);
nsReflowMetrics& aDesiredSize);
private:
PRInt32 mRowIndex;

View File

@ -72,9 +72,6 @@ struct RowReflowState {
tableFrame = aTableFrame;
x=0;
}
~RowReflowState() {
}
};
@ -616,12 +613,16 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
// The things in the RowReflowState object we need to restore are:
// - maxCellHeight
// - maxVertCellSpace
// - x
nsresult nsTableRowFrame::RecoverState(RowReflowState& aState,
nsIFrame* aKidFrame)
{
// Walk the list of children looking for aKidFrame
// Walk the list of children looking for aKidFrame. While we're at
// it get the maxCellHeight and maxVertCellSpace for all the
// frames except aKidFrame
nsIFrame* prevKidFrame = nsnull;
for (nsIFrame* frame = mFirstChild; frame != aKidFrame;) {
for (nsIFrame* frame = mFirstChild; nsnull != frame;) {
if (frame != aKidFrame) {
PRInt32 rowSpan = ((nsTableCellFrame*)frame)->GetRowSpan();
if (mMinRowSpan == rowSpan) {
// XXX This isn't quite right. We also need to check whether the cell
@ -650,25 +651,30 @@ nsresult nsTableRowFrame::RecoverState(RowReflowState& aState,
//
// We should be using GetReflowMetrics() to get information from the
// table cell, and that will include the max element size...
}
// Remember the frame that precedes aKidFrame
prevKidFrame = frame;
frame->GetNextSibling(frame);
}
// Update the running x-offset based on the frame's current x-origin
nsPoint origin;
aKidFrame->GetOrigin(origin);
aState.x = origin.x;
return NS_OK;
}
nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
RowReflowState& aState,
const nsReflowState& aReflowState,
nsSize* aMaxElementSize)
nsReflowMetrics& aDesiredSize)
{
nsresult status;
// XXX Deal with the case where the reflow command is targeted at us
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
aState.reflowState.reflowCommand->GetTarget(target);
if (this == target) {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
return NS_ERROR_NOT_IMPLEMENTED;
@ -676,7 +682,7 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
// Get the next frame in the reflow chain
nsIFrame* kidFrame;
aReflowState.reflowCommand->GetNext(kidFrame);
aState.reflowState.reflowCommand->GetNext(kidFrame);
// Recover our reflow state
RecoverState(aState, kidFrame);
@ -685,35 +691,33 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
nsMargin kidMargin;
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, kidMargin);
// Figure out the amount of available space for the child
// XXX Shakey...
nsSize kidAvailSize(aState.availSize); // XXX: top and bottom margins?
// Compute the x-origin for the child, taking into account straddlers (cells
// from prior rows with rowspans > 1)
nscoord x = kidMargin.left;
// At this point, we know the column widths. Get the available width
// from the known column widths
PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
for (PRInt32 colIndex=0; colIndex<cellColIndex; colIndex++)
{
x += aState.tableFrame->GetColumnWidth(colIndex);
}
// at this point, we know the column widths.
// so we get the avail width from the known column widths
PRInt32 cellStartingCol = ((nsTableCellFrame *)kidFrame)->GetColIndex();
PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
nscoord availWidth = 0;
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
availWidth += aState.tableFrame->GetColumnWidth(cellStartingCol+numColSpan);
kidAvailSize.width = availWidth;
{
availWidth += aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
if (0<numColSpan)
{
availWidth += kidMargin.right;
if (0!=cellColIndex)
availWidth += kidMargin.left;
}
}
// Pass along the reflow command. Reflow the child with an unconstrained
// width and get its maxElementSize
// Always let the cell be as high as it wants. We ignore the height that's
// passed in and always place the entire row. Let the row group decide
// whether we fit or wehther the entire row is pushed
nsSize kidAvailSize(availWidth, NS_UNCONSTRAINEDSIZE);
// Pass along the reflow command
nsSize kidMaxElementSize;
nsReflowMetrics desiredSize(&kidMaxElementSize);
nsReflowState kidReflowState(kidFrame, aReflowState, kidAvailSize);
nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize);
kidFrame->WillReflow(*aPresContext);
kidFrame->MoveTo(x, kidMargin.top);
kidFrame->MoveTo(aState.x, kidMargin.top);
// XXX Unfortunately we need to reflow the child several times.
// The first time is for the incremental reflow command. We can't pass in
@ -769,56 +773,21 @@ nsresult nsTableRowFrame::IncrementalReflow(nsIPresContext* aPresContext,
// end special Nav4 compatibility code
// Now place the child
nsRect kidRect (x, kidMargin.top, cellWidth, cellHeight);
nsRect kidRect (aState.x, kidMargin.top, cellWidth, cellHeight);
PlaceChild(aPresContext, aState, kidFrame, kidRect, aMaxElementSize,
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
&kidMaxElementSize);
// Now iterate over the remaining cells, and update our max cell
// height and our running x-offset
//
// We don't have to re-position the x-origin of any of the child frames
// that follow, because the column width hasn't changed...
// XXX This needs to be computed somehow...
nscoord maxCellTopMargin = 0;
nscoord maxCellBottomMargin = 0;
kidFrame->GetNextSibling((nsIFrame*&)kidFrame);
while (nsnull != kidFrame) {
PRInt32 rowSpan = ((nsTableCellFrame*)kidFrame)->GetRowSpan();
nsRect rect;
kidFrame->GetRect(rect);
if (mMinRowSpan == rowSpan) {
nsSize desiredSize = ((nsTableCellFrame *)kidFrame)->GetDesiredSize();
// Update maxCellHeight
if (desiredSize.height > aState.maxCellHeight) {
aState.maxCellHeight = desiredSize.height;
}
// Update maxCellVertHeight
nsMargin margin;
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK)
{
nscoord height = desiredSize.height + margin.top + margin.bottom;
if (height > aState.maxCellVertSpace) {
aState.maxCellVertSpace = height;
}
// XXX Currently we assume cells have margins, but that isn't correct...
if (margin.top > maxCellTopMargin) {
maxCellTopMargin = margin.top;
}
if (margin.bottom > maxCellBottomMargin) {
maxCellBottomMargin = margin.bottom;
}
}
}
// Get the next cell frame
kidFrame->GetNextSibling((nsIFrame*&)kidFrame);
}
SetMaxChildHeight(aState.maxCellHeight, maxCellTopMargin, maxCellBottomMargin);
// Return our desired size. Note that our desired width is just whatever width
// we were given by the row group frame
aDesiredSize.width = aState.availSize.width;
aDesiredSize.height = aState.maxCellVertSpace;
return status;
}
@ -869,8 +838,7 @@ nsTableRowFrame::Reflow(nsIPresContext* aPresContext,
break;
case eReflowReason_Incremental:
result = IncrementalReflow(aPresContext, state, aReflowState,
aDesiredSize.maxElementSize);
result = IncrementalReflow(aPresContext, state, aDesiredSize);
break;
}

View File

@ -163,8 +163,7 @@ protected:
*/
nsresult IncrementalReflow(nsIPresContext* aPresContext,
RowReflowState& aState,
const nsReflowState& aReflowState,
nsSize* aMaxElementSize);
nsReflowMetrics& aDesiredSize);
private:
PRInt32 mRowIndex;