зеркало из https://github.com/mozilla/pjs.git
bug 7741 - handling of overlapping rowspans, r=troy.
This commit is contained in:
Родитель
a6a285f877
Коммит
c43f4c1b2e
|
@ -239,8 +239,8 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
|
|||
const nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
// Resize and re-align the cell frames based on our row height
|
||||
nscoord cellMaxTopMargin = GetChildMaxTopMargin();
|
||||
nscoord cellMaxBottomMargin = GetChildMaxBottomMargin();
|
||||
nscoord cellMaxTopMargin = GetTopMargin();
|
||||
nscoord cellMaxBottomMargin = GetBottomMargin();
|
||||
nscoord rowCellHeight = mRect.height - cellMaxTopMargin - cellMaxBottomMargin;
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
@ -455,7 +455,7 @@ nscoord nsTableRowFrame::GetTallestChild() const
|
|||
return mTallestCell;
|
||||
}
|
||||
|
||||
nscoord nsTableRowFrame::GetChildMaxTopMargin() const
|
||||
nscoord nsTableRowFrame::GetTopMargin() const
|
||||
{
|
||||
nsTableFrame *tableFrame;
|
||||
nsTableFrame::GetTableFrame((nsIFrame*)this, tableFrame);
|
||||
|
@ -464,7 +464,7 @@ nscoord nsTableRowFrame::GetChildMaxTopMargin() const
|
|||
return (GetRowIndex() == 0) ? tableFrame->GetCellSpacingY() : 0;
|
||||
}
|
||||
|
||||
nscoord nsTableRowFrame::GetChildMaxBottomMargin() const
|
||||
nscoord nsTableRowFrame::GetBottomMargin() const
|
||||
{
|
||||
nsTableFrame *tableFrame;
|
||||
nsTableFrame::GetTableFrame((nsIFrame*)this, tableFrame);
|
||||
|
@ -594,11 +594,10 @@ void nsTableRowFrame::PlaceChild(nsIPresContext* aPresContext,
|
|||
// needed for backwards compatibility.
|
||||
// Modifies the desired width and height that are passed in.
|
||||
nsresult
|
||||
nsTableRowFrame::CalculateCellActualSize(RowReflowState& aReflowState,
|
||||
nsIFrame* aCellFrame,
|
||||
nscoord& aDesiredWidth,
|
||||
nscoord& aDesiredHeight,
|
||||
nscoord aAvailWidth)
|
||||
nsTableRowFrame::CalculateCellActualSize(nsIFrame* aCellFrame,
|
||||
nscoord& aDesiredWidth,
|
||||
nscoord& aDesiredHeight,
|
||||
nscoord aAvailWidth)
|
||||
{
|
||||
nscoord specifiedHeight = 0;
|
||||
const nsStylePosition* position;
|
||||
|
@ -820,7 +819,7 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
reason);
|
||||
nsReflowStatus status;
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
|
||||
aReflowState.x, GetChildMaxTopMargin(), 0, status);
|
||||
aReflowState.x, GetTopMargin(), 0, status);
|
||||
#ifdef NS_DEBUG
|
||||
if (desiredSize.width > availWidth)
|
||||
{
|
||||
|
@ -865,12 +864,12 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
// Calculate the cell's actual size given its pass2 size. This function
|
||||
// takes into account the specified height (in the style), and any special
|
||||
// logic needed for backwards compatibility
|
||||
CalculateCellActualSize(aReflowState, kidFrame, desiredSize.width,
|
||||
CalculateCellActualSize(kidFrame, desiredSize.width,
|
||||
desiredSize.height, availWidth);
|
||||
|
||||
// Place the child
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
|
||||
aReflowState.x, GetChildMaxTopMargin(),
|
||||
aReflowState.x, GetTopMargin(),
|
||||
aDesiredSize.maxElementSize, kidMaxElementSize);
|
||||
|
||||
}
|
||||
|
@ -1066,8 +1065,7 @@ NS_METHOD nsTableRowFrame::RecoverState(nsIPresContext* aPresContext,
|
|||
// See if it has a specified height that overrides the desired size.
|
||||
// Note: we don't care about the width so don't compute the column
|
||||
// width and just pass in the desired width for the available width
|
||||
CalculateCellActualSize(aReflowState, frame, desiredSize.width, desiredSize.height,
|
||||
desiredSize.width);
|
||||
CalculateCellActualSize(frame, desiredSize.width, desiredSize.height, desiredSize.width);
|
||||
|
||||
// Update maxCellHeight
|
||||
if (desiredSize.height > aReflowState.maxCellHeight) {
|
||||
|
@ -1239,7 +1237,7 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
|||
// in a max width of NS_UNCONSTRAINEDSIZE, because the max width must match
|
||||
// the width of the previous reflow...
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
|
||||
aReflowState.x, GetChildMaxTopMargin(), 0, aStatus);
|
||||
aReflowState.x, GetTopMargin(), 0, aStatus);
|
||||
|
||||
// Update the cell layout data.. If the cell's maximum width changed,
|
||||
// then inform the table that its maximum width needs to be recomputed
|
||||
|
@ -1276,12 +1274,11 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
|||
// Calculate the cell's actual size given its pass2 size. This function
|
||||
// takes into account the specified height (in the style), and any special
|
||||
// logic needed for backwards compatibility
|
||||
CalculateCellActualSize(aReflowState, aNextFrame, desiredSize.width, desiredSize.height,
|
||||
cellAvailWidth);
|
||||
CalculateCellActualSize(aNextFrame, desiredSize.width, desiredSize.height, cellAvailWidth);
|
||||
|
||||
// Now place the child
|
||||
PlaceChild(aPresContext, aReflowState, aNextFrame, desiredSize, aReflowState.x,
|
||||
GetChildMaxTopMargin(), aDesiredSize.maxElementSize, &kidMaxElementSize);
|
||||
GetTopMargin(), aDesiredSize.maxElementSize, &kidMaxElementSize);
|
||||
|
||||
SetMaxChildHeight(aReflowState.maxCellHeight);
|
||||
|
||||
|
|
|
@ -163,8 +163,8 @@ public:
|
|||
|
||||
/** returns the tallest child in this row (ignoring any cell with rowspans) */
|
||||
nscoord GetTallestChild() const;
|
||||
nscoord GetChildMaxTopMargin() const;
|
||||
nscoord GetChildMaxBottomMargin() const;
|
||||
nscoord GetTopMargin() const;
|
||||
nscoord GetBottomMargin() const;
|
||||
|
||||
/** returns the ordinal position of this row in its table */
|
||||
virtual PRInt32 GetRowIndex() const;
|
||||
|
@ -184,6 +184,11 @@ public:
|
|||
nsReflowStatus& aStatus);
|
||||
void InsertCellFrame(nsTableCellFrame* aFrame, nsTableCellFrame* aPrevSibling);
|
||||
|
||||
nsresult CalculateCellActualSize(nsIFrame* aRowFrame,
|
||||
nscoord& aDesiredWidth,
|
||||
nscoord& aDesiredHeight,
|
||||
nscoord aAvailWidth);
|
||||
|
||||
protected:
|
||||
|
||||
/** protected constructor.
|
||||
|
@ -273,12 +278,6 @@ protected:
|
|||
nsTableCellFrame * aStartFrame,
|
||||
PRBool aDoSiblings);
|
||||
|
||||
nsresult CalculateCellActualSize(RowReflowState& aReflowState,
|
||||
nsIFrame* aRowFrame,
|
||||
nscoord& aDesiredWidth,
|
||||
nscoord& aDesiredHeight,
|
||||
nscoord aAvailWidth);
|
||||
|
||||
nscoord CalculateCellAvailableWidth(nsTableFrame* aTableFrame,
|
||||
nsIFrame* aCellFrame,
|
||||
PRInt32 aCellColIndex,
|
||||
|
|
|
@ -551,6 +551,37 @@ void nsTableRowGroupFrame::GetNextRowSibling(nsIFrame** aRowFrame)
|
|||
}
|
||||
}
|
||||
|
||||
// allocate the height of rows which have no cells originating in them
|
||||
// except with cells with rowspan > 1. Store the height as negative
|
||||
// to distinguish them from regular rows.
|
||||
void
|
||||
AllocateSpecialHeight(nsIPresContext* aPresContext,
|
||||
nsTableFrame* aTableFrame,
|
||||
nsIFrame* aRowFrame,
|
||||
nscoord& aHeight)
|
||||
{
|
||||
nsIFrame* cellFrame;
|
||||
aRowFrame->FirstChild(aPresContext, nsnull, &cellFrame);
|
||||
while (cellFrame) {
|
||||
nsCOMPtr<nsIAtom> cellType;
|
||||
cellFrame->GetFrameType(getter_AddRefs(cellType));
|
||||
if (nsLayoutAtoms::tableCellFrame == cellType) {
|
||||
PRInt32 rowSpan = aTableFrame->GetEffectiveRowSpan((nsTableCellFrame&)*cellFrame);
|
||||
if (rowSpan > 1) {
|
||||
// use a simple average to allocate the special row. This is not exact,
|
||||
// but much better than nothing.
|
||||
nsSize cellDesSize;
|
||||
((nsTableRowFrame*)aRowFrame)->CalculateCellActualSize(cellFrame, cellDesSize.width,
|
||||
cellDesSize.height, cellDesSize.width);
|
||||
PRInt32 propHeight = NSToCoordRound((float)cellDesSize.height / (float)rowSpan);
|
||||
// special rows store the largest negative value
|
||||
aHeight = PR_MIN(aHeight, -propHeight);
|
||||
}
|
||||
}
|
||||
cellFrame->GetNextSibling(&cellFrame);
|
||||
}
|
||||
}
|
||||
|
||||
/* CalculateRowHeights provides default heights for all rows in the rowgroup.
|
||||
* Actual row heights are ultimately determined by the table, when the table
|
||||
* height attribute is factored in.
|
||||
|
@ -559,18 +590,20 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return;
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame) return;
|
||||
|
||||
// all table cells have the same top and bottom margins, namely cellSpacingY
|
||||
nscoord cellSpacingY = tableFrame->GetCellSpacingY();
|
||||
|
||||
// iterate children and for each row get the height of the tallest cell. Keep
|
||||
// track of whether any of the rows have a cell that spans into the row
|
||||
PRBool hasRowSpanningCell = PR_FALSE;
|
||||
PRInt32 numRows;
|
||||
GetRowCount(numRows, PR_FALSE);
|
||||
// collect the current height of each row. rows which have 0 height because
|
||||
// they have no cells originating in them without rowspans > 1, are referred to as
|
||||
// special rows. The current height of a special row will be a negative number until
|
||||
// it comes time to actually resize frames.
|
||||
nscoord* rowHeights = nsnull;
|
||||
if (numRows > 0) {
|
||||
rowHeights = new nscoord[numRows];
|
||||
|
@ -578,91 +611,81 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
nsCRT::memset (rowHeights, 0, numRows*sizeof(nscoord));
|
||||
} // else - tree row groups need not have rows directly beneath them
|
||||
|
||||
/* Step 1: get the height of the tallest cell in the row and save it for
|
||||
* pass 2. This height is for table cells that originate in this
|
||||
* row and that don't span into the rows that follow
|
||||
*/
|
||||
// Step 1: get the height of the tallest cell in the row and save it for
|
||||
// pass 2. This height is for table cells that originate in this
|
||||
// row and that don't span into the rows that follow
|
||||
nsIFrame* rowFrame = GetFirstFrame();
|
||||
PRInt32 rowIndex = 0;
|
||||
|
||||
// For row groups that are split across pages, the first row frame won't
|
||||
// necessarily be index 0
|
||||
PRInt32 startRowIndex = -1;
|
||||
const nsStyleDisplay *childDisplay;
|
||||
while (nsnull != rowFrame)
|
||||
{
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
while (rowFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
rowFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableRowFrame == frameType) {
|
||||
if (startRowIndex == -1) {
|
||||
startRowIndex = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
|
||||
}
|
||||
|
||||
// get the height of the tallest cell in the row (excluding cells that span rows)
|
||||
// XXX GetChildMaxTopMargin and GetChildMaxBottomMargin should be removed/simplified because
|
||||
// according to CSS, all table cells must have the same top/bottom and left/right margins.
|
||||
nscoord maxCellHeight = ((nsTableRowFrame*)rowFrame)->GetTallestChild();
|
||||
nscoord maxCellTopMargin = ((nsTableRowFrame*)rowFrame)->GetChildMaxTopMargin();
|
||||
nscoord maxCellBottomMargin = ((nsTableRowFrame*)rowFrame)->GetChildMaxBottomMargin();
|
||||
nscoord maxRowHeight = maxCellHeight + maxCellTopMargin + maxCellBottomMargin;
|
||||
// only the top row has a top margin. Other rows start at the bottom of the prev row's bottom margin.
|
||||
// save the row height for pass 2 below
|
||||
rowHeights[rowIndex] = maxRowHeight;
|
||||
|
||||
nscoord maxCellHeight = ((nsTableRowFrame*)rowFrame)->GetTallestChild();
|
||||
nscoord topMargin = ((nsTableRowFrame*)rowFrame)->GetTopMargin();
|
||||
nscoord bottomMargin = ((nsTableRowFrame*)rowFrame)->GetBottomMargin();
|
||||
nscoord maxRowHeight = maxCellHeight + topMargin + bottomMargin;
|
||||
rowHeights[rowIndex] = maxRowHeight;
|
||||
// See if a cell spans into the row. If so we'll have to do step 2
|
||||
if (!hasRowSpanningCell) {
|
||||
if (tableFrame->RowIsSpannedInto(rowIndex + startRowIndex)) {
|
||||
hasRowSpanningCell = PR_TRUE;
|
||||
}
|
||||
}
|
||||
// special rows need to have some values, so they will get allocations
|
||||
// later. If left at 0, they would get nothing.
|
||||
if (0 == rowHeights[rowIndex]) {
|
||||
AllocateSpecialHeight(aPresContext, tableFrame, rowFrame, rowHeights[rowIndex]);
|
||||
}
|
||||
rowIndex++;
|
||||
}
|
||||
// Get the next row
|
||||
GetNextFrame(rowFrame, &rowFrame);
|
||||
GetNextFrame(rowFrame, &rowFrame); // Get the next row
|
||||
}
|
||||
|
||||
/* Step 2: Now account for cells that span rows. We only do this if there are cells
|
||||
* that span rows.
|
||||
* A spanning cell's height is the sum of the heights of the rows it spans,
|
||||
* or it's own desired height, whichever is greater.
|
||||
* If the cell's desired height is the larger value, resize the rows and contained
|
||||
* cells by an equal percentage of the additional space.
|
||||
* We go through this loop twice. The first time, we are adjusting cell heights
|
||||
* on the fly.
|
||||
* The second time through the loop, we're ensuring that subsequent row-spanning cells
|
||||
* didn't change prior calculations.
|
||||
* Since we are guaranteed to have found the max height spanners the first time through,
|
||||
* we know we only need two passes, not an arbitrary number.
|
||||
*/
|
||||
// Step 2: Now account for cells that span rows. We only do this if there are cells
|
||||
// that span rows. A spanning cell's height is the sum of the heights of the
|
||||
// rows it spans, or it's own desired height, whichever is greater.
|
||||
// If the cell's desired height is the larger value, resize the rows and contained
|
||||
// cells by an equal percentage of the additional space.
|
||||
// We go through this loop twice. The first time, we are adjusting cell heights
|
||||
// on the fly. The second time through the loop, we're ensuring that subsequent
|
||||
// row-spanning cells didn't change prior calculations. Since we are guaranteed
|
||||
// to have found the max height spanners the first time through, we know we only
|
||||
// need two passes, not an arbitrary number.
|
||||
if (hasRowSpanningCell) {
|
||||
nscoord deltaY = 0;
|
||||
for (PRInt32 counter=0; counter<2; counter++)
|
||||
{
|
||||
for (PRInt32 counter = 0; counter < 2; counter++) {
|
||||
rowFrame = GetFirstFrame();
|
||||
rowIndex = 0;
|
||||
while (nsnull != rowFrame)
|
||||
{
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
while (rowFrame) {
|
||||
nsCOMPtr<nsIAtom> rowType;
|
||||
rowFrame->GetFrameType(getter_AddRefs(rowType));
|
||||
if (nsLayoutAtoms::tableRowFrame == rowType) {
|
||||
// check this row for a cell with rowspans
|
||||
nsIFrame *cellFrame;
|
||||
nsIFrame* cellFrame;
|
||||
rowFrame->FirstChild(aPresContext, nsnull, &cellFrame);
|
||||
while (nsnull != cellFrame)
|
||||
{
|
||||
const nsStyleDisplay *cellChildDisplay;
|
||||
cellFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)cellChildDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == cellChildDisplay->mDisplay)
|
||||
{
|
||||
while (cellFrame) {
|
||||
nsCOMPtr<nsIAtom> cellType;
|
||||
cellFrame->GetFrameType(getter_AddRefs(cellType));
|
||||
if (nsLayoutAtoms::tableCellFrame == cellType) {
|
||||
PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan(rowIndex + startRowIndex,
|
||||
(nsTableCellFrame&)*cellFrame);
|
||||
if (rowSpan > 1)
|
||||
{ // found a cell with rowspan > 1, determine the height of the rows it
|
||||
// spans
|
||||
if (rowSpan > 1) { // found a cell with rowspan > 1, determine the height
|
||||
// of the rows it spans
|
||||
nscoord heightOfRowsSpanned = 0;
|
||||
PRInt32 i;
|
||||
for (i = 0; i < rowSpan; i++) {
|
||||
heightOfRowsSpanned += rowHeights[rowIndex + i];
|
||||
PRInt32 spanX;
|
||||
for (spanX = 0; spanX < rowSpan; spanX++) {
|
||||
if (rowHeights[rowIndex + spanX] > 0) {
|
||||
// don't consider negative values of special rows
|
||||
heightOfRowsSpanned += rowHeights[rowIndex + spanX];
|
||||
}
|
||||
}
|
||||
// reduce the height by top and bottom margins
|
||||
nscoord availHeightOfRowsSpanned = heightOfRowsSpanned - cellSpacingY - cellSpacingY;
|
||||
|
@ -673,44 +696,60 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
nsSize cellFrameSize;
|
||||
cellFrame->GetSize(cellFrameSize);
|
||||
if (0 == counter) {
|
||||
nsSize cellDesiredSize = ((nsTableCellFrame*)cellFrame)->GetDesiredSize();
|
||||
cellFrameSize.height = cellDesiredSize.height;
|
||||
nsSize cellDesSize = ((nsTableCellFrame*)cellFrame)->GetDesiredSize();
|
||||
((nsTableRowFrame*)rowFrame)->CalculateCellActualSize(cellFrame, cellDesSize.width,
|
||||
cellDesSize.height, cellDesSize.width);
|
||||
cellFrameSize.height = cellDesSize.height;
|
||||
}
|
||||
|
||||
if (availHeightOfRowsSpanned >= cellFrameSize.height)
|
||||
{
|
||||
if (availHeightOfRowsSpanned >= cellFrameSize.height) {
|
||||
// yes the cell's height fits with the available space of the rows it
|
||||
// spans. Set the cell frame's height
|
||||
cellFrame->SizeTo(aPresContext, cellFrameSize.width, availHeightOfRowsSpanned);
|
||||
// Realign cell content based on new height
|
||||
((nsTableCellFrame*)cellFrame)->VerticallyAlignChild(aPresContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// the cell's height is larger than the available space of the rows it
|
||||
// spans so distribute the excess height to the rows affected
|
||||
PRInt32 excessHeight = cellFrameSize.height - availHeightOfRowsSpanned;
|
||||
|
||||
// for every row starting at the row with the spanning cell and down
|
||||
// to the last row spanned by the cell
|
||||
nsTableRowFrame *rowFrameToBeResized = (nsTableRowFrame *)rowFrame;
|
||||
nsTableRowFrame* rowFrameToBeResized = (nsTableRowFrame *)rowFrame;
|
||||
nscoord excessAllocated = 0;
|
||||
for (i = rowIndex; i < (rowIndex + rowSpan); i++) {
|
||||
// The amount of additional space each row gets is based on the
|
||||
// percentage of space it occupies, i.e. they don't all get the
|
||||
// same amount of available space
|
||||
float percent = ((float)rowHeights[i]) / ((float)heightOfRowsSpanned);
|
||||
// iterate every row starting at last row spanned and up to the row with
|
||||
// the spanning cell. do this bottom up so that special rows can get a full
|
||||
// allocation before other rows.
|
||||
for (PRInt32 rowX = (rowIndex + rowSpan) - 1; rowX >= rowIndex; rowX--) {
|
||||
nscoord excessForRow;
|
||||
// special rows get as much they can
|
||||
if (rowHeights[rowX] < 0) {
|
||||
nscoord excessAvail = excessHeight - excessAllocated;
|
||||
if (excessAvail > 0) {
|
||||
// don't let the allocation excced what it needs
|
||||
excessForRow = (excessAvail > -rowHeights[rowX]) ? -rowHeights[rowX] : excessAvail;
|
||||
rowHeights[rowX] = excessForRow;
|
||||
}
|
||||
else {
|
||||
// nothing available so assign a zero allocation
|
||||
excessForRow = rowHeights[rowX] = 0;
|
||||
}
|
||||
}
|
||||
else { // normal rows
|
||||
// The amount of additional space each normal row gets is based on the
|
||||
// percentage of space it occupies, i.e. they don't all get the
|
||||
// same amount of available space
|
||||
float percent = ((float)rowHeights[rowX]) / ((float)heightOfRowsSpanned);
|
||||
|
||||
// give rows their percentage, except for the last row which gets
|
||||
// the remainder
|
||||
nscoord excessForRow = ((i + 1) == (rowIndex + rowSpan)) ?
|
||||
excessHeight - excessAllocated :
|
||||
NSToCoordRound(((float)(excessHeight)) * percent);
|
||||
// give rows their percentage, except for the first row which gets
|
||||
// the remainder
|
||||
excessForRow = (rowX == rowIndex)
|
||||
? excessHeight - excessAllocated
|
||||
: NSToCoordRound(((float)(excessHeight)) * percent);
|
||||
// update the row height
|
||||
rowHeights[rowX] += excessForRow;
|
||||
}
|
||||
excessAllocated += excessForRow;
|
||||
|
||||
// update the row height
|
||||
rowHeights[i] += excessForRow;
|
||||
|
||||
|
||||
// Get the next row frame
|
||||
GetNextRowSibling((nsIFrame**)&rowFrameToBeResized);
|
||||
}
|
||||
|
@ -718,8 +757,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
}
|
||||
// Get the next row child (cell frame)
|
||||
cellFrame->GetNextSibling(&cellFrame);
|
||||
cellFrame->GetNextSibling(&cellFrame); // Get the next row child (cell frame)
|
||||
}
|
||||
|
||||
// If this is pass 2 then resize the row to its final size and move the
|
||||
|
@ -741,7 +779,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
|
||||
if (movedFrame) {
|
||||
// Make sure any views are positioned properly
|
||||
nsIView* view;
|
||||
nsIView* view;
|
||||
rowFrame->GetView(aPresContext, &view);
|
||||
if (view) {
|
||||
nsContainerFrame::PositionFrameView(aPresContext, rowFrame, view);
|
||||
|
@ -753,9 +791,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
// Get the next rowgroup child (row frame)
|
||||
GetNextFrame(rowFrame, &rowFrame);
|
||||
GetNextFrame(rowFrame, &rowFrame); // Get the next rowgroup child (row frame)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -764,31 +800,26 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
nscoord rowGroupHeight = 0;
|
||||
rowFrame = GetFirstFrame();
|
||||
rowIndex = 0;
|
||||
while (nsnull != rowFrame)
|
||||
{
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
while (rowFrame) {
|
||||
nsCOMPtr<nsIAtom> rowType;
|
||||
rowFrame->GetFrameType(getter_AddRefs(rowType));
|
||||
if (nsLayoutAtoms::tableRowFrame == rowType) {
|
||||
// Notify the row of the new size
|
||||
((nsTableRowFrame *)rowFrame)->DidResize(aPresContext, aReflowState);
|
||||
}
|
||||
|
||||
// Update the running row group height. The height includes frames that
|
||||
// aren't rows as well
|
||||
nsSize rowSize;
|
||||
nsSize rowSize;
|
||||
rowFrame->GetSize(rowSize);
|
||||
rowGroupHeight += rowSize.height;
|
||||
|
||||
// Get the next row
|
||||
GetNextFrame(rowFrame, &rowFrame);
|
||||
GetNextFrame(rowFrame, &rowFrame); // Get the next row
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
// Adjust our desired size
|
||||
aDesiredSize.height = rowGroupHeight;
|
||||
|
||||
// cleanup
|
||||
delete []rowHeights;
|
||||
aDesiredSize.height = rowGroupHeight; // Adjust our desired size
|
||||
delete [] rowHeights; // cleanup
|
||||
}
|
||||
|
||||
// Called by IR_TargetIsChild() to adjust the sibling frames that follow
|
||||
|
|
|
@ -239,8 +239,8 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
|
|||
const nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
// Resize and re-align the cell frames based on our row height
|
||||
nscoord cellMaxTopMargin = GetChildMaxTopMargin();
|
||||
nscoord cellMaxBottomMargin = GetChildMaxBottomMargin();
|
||||
nscoord cellMaxTopMargin = GetTopMargin();
|
||||
nscoord cellMaxBottomMargin = GetBottomMargin();
|
||||
nscoord rowCellHeight = mRect.height - cellMaxTopMargin - cellMaxBottomMargin;
|
||||
nsTableFrame* tableFrame;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
@ -455,7 +455,7 @@ nscoord nsTableRowFrame::GetTallestChild() const
|
|||
return mTallestCell;
|
||||
}
|
||||
|
||||
nscoord nsTableRowFrame::GetChildMaxTopMargin() const
|
||||
nscoord nsTableRowFrame::GetTopMargin() const
|
||||
{
|
||||
nsTableFrame *tableFrame;
|
||||
nsTableFrame::GetTableFrame((nsIFrame*)this, tableFrame);
|
||||
|
@ -464,7 +464,7 @@ nscoord nsTableRowFrame::GetChildMaxTopMargin() const
|
|||
return (GetRowIndex() == 0) ? tableFrame->GetCellSpacingY() : 0;
|
||||
}
|
||||
|
||||
nscoord nsTableRowFrame::GetChildMaxBottomMargin() const
|
||||
nscoord nsTableRowFrame::GetBottomMargin() const
|
||||
{
|
||||
nsTableFrame *tableFrame;
|
||||
nsTableFrame::GetTableFrame((nsIFrame*)this, tableFrame);
|
||||
|
@ -594,11 +594,10 @@ void nsTableRowFrame::PlaceChild(nsIPresContext* aPresContext,
|
|||
// needed for backwards compatibility.
|
||||
// Modifies the desired width and height that are passed in.
|
||||
nsresult
|
||||
nsTableRowFrame::CalculateCellActualSize(RowReflowState& aReflowState,
|
||||
nsIFrame* aCellFrame,
|
||||
nscoord& aDesiredWidth,
|
||||
nscoord& aDesiredHeight,
|
||||
nscoord aAvailWidth)
|
||||
nsTableRowFrame::CalculateCellActualSize(nsIFrame* aCellFrame,
|
||||
nscoord& aDesiredWidth,
|
||||
nscoord& aDesiredHeight,
|
||||
nscoord aAvailWidth)
|
||||
{
|
||||
nscoord specifiedHeight = 0;
|
||||
const nsStylePosition* position;
|
||||
|
@ -820,7 +819,7 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
reason);
|
||||
nsReflowStatus status;
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
|
||||
aReflowState.x, GetChildMaxTopMargin(), 0, status);
|
||||
aReflowState.x, GetTopMargin(), 0, status);
|
||||
#ifdef NS_DEBUG
|
||||
if (desiredSize.width > availWidth)
|
||||
{
|
||||
|
@ -865,12 +864,12 @@ NS_METHOD nsTableRowFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
// Calculate the cell's actual size given its pass2 size. This function
|
||||
// takes into account the specified height (in the style), and any special
|
||||
// logic needed for backwards compatibility
|
||||
CalculateCellActualSize(aReflowState, kidFrame, desiredSize.width,
|
||||
CalculateCellActualSize(kidFrame, desiredSize.width,
|
||||
desiredSize.height, availWidth);
|
||||
|
||||
// Place the child
|
||||
PlaceChild(aPresContext, aReflowState, kidFrame, desiredSize,
|
||||
aReflowState.x, GetChildMaxTopMargin(),
|
||||
aReflowState.x, GetTopMargin(),
|
||||
aDesiredSize.maxElementSize, kidMaxElementSize);
|
||||
|
||||
}
|
||||
|
@ -1066,8 +1065,7 @@ NS_METHOD nsTableRowFrame::RecoverState(nsIPresContext* aPresContext,
|
|||
// See if it has a specified height that overrides the desired size.
|
||||
// Note: we don't care about the width so don't compute the column
|
||||
// width and just pass in the desired width for the available width
|
||||
CalculateCellActualSize(aReflowState, frame, desiredSize.width, desiredSize.height,
|
||||
desiredSize.width);
|
||||
CalculateCellActualSize(frame, desiredSize.width, desiredSize.height, desiredSize.width);
|
||||
|
||||
// Update maxCellHeight
|
||||
if (desiredSize.height > aReflowState.maxCellHeight) {
|
||||
|
@ -1239,7 +1237,7 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
|||
// in a max width of NS_UNCONSTRAINEDSIZE, because the max width must match
|
||||
// the width of the previous reflow...
|
||||
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
|
||||
aReflowState.x, GetChildMaxTopMargin(), 0, aStatus);
|
||||
aReflowState.x, GetTopMargin(), 0, aStatus);
|
||||
|
||||
// Update the cell layout data.. If the cell's maximum width changed,
|
||||
// then inform the table that its maximum width needs to be recomputed
|
||||
|
@ -1276,12 +1274,11 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
|||
// Calculate the cell's actual size given its pass2 size. This function
|
||||
// takes into account the specified height (in the style), and any special
|
||||
// logic needed for backwards compatibility
|
||||
CalculateCellActualSize(aReflowState, aNextFrame, desiredSize.width, desiredSize.height,
|
||||
cellAvailWidth);
|
||||
CalculateCellActualSize(aNextFrame, desiredSize.width, desiredSize.height, cellAvailWidth);
|
||||
|
||||
// Now place the child
|
||||
PlaceChild(aPresContext, aReflowState, aNextFrame, desiredSize, aReflowState.x,
|
||||
GetChildMaxTopMargin(), aDesiredSize.maxElementSize, &kidMaxElementSize);
|
||||
GetTopMargin(), aDesiredSize.maxElementSize, &kidMaxElementSize);
|
||||
|
||||
SetMaxChildHeight(aReflowState.maxCellHeight);
|
||||
|
||||
|
|
|
@ -163,8 +163,8 @@ public:
|
|||
|
||||
/** returns the tallest child in this row (ignoring any cell with rowspans) */
|
||||
nscoord GetTallestChild() const;
|
||||
nscoord GetChildMaxTopMargin() const;
|
||||
nscoord GetChildMaxBottomMargin() const;
|
||||
nscoord GetTopMargin() const;
|
||||
nscoord GetBottomMargin() const;
|
||||
|
||||
/** returns the ordinal position of this row in its table */
|
||||
virtual PRInt32 GetRowIndex() const;
|
||||
|
@ -184,6 +184,11 @@ public:
|
|||
nsReflowStatus& aStatus);
|
||||
void InsertCellFrame(nsTableCellFrame* aFrame, nsTableCellFrame* aPrevSibling);
|
||||
|
||||
nsresult CalculateCellActualSize(nsIFrame* aRowFrame,
|
||||
nscoord& aDesiredWidth,
|
||||
nscoord& aDesiredHeight,
|
||||
nscoord aAvailWidth);
|
||||
|
||||
protected:
|
||||
|
||||
/** protected constructor.
|
||||
|
@ -273,12 +278,6 @@ protected:
|
|||
nsTableCellFrame * aStartFrame,
|
||||
PRBool aDoSiblings);
|
||||
|
||||
nsresult CalculateCellActualSize(RowReflowState& aReflowState,
|
||||
nsIFrame* aRowFrame,
|
||||
nscoord& aDesiredWidth,
|
||||
nscoord& aDesiredHeight,
|
||||
nscoord aAvailWidth);
|
||||
|
||||
nscoord CalculateCellAvailableWidth(nsTableFrame* aTableFrame,
|
||||
nsIFrame* aCellFrame,
|
||||
PRInt32 aCellColIndex,
|
||||
|
|
|
@ -551,6 +551,37 @@ void nsTableRowGroupFrame::GetNextRowSibling(nsIFrame** aRowFrame)
|
|||
}
|
||||
}
|
||||
|
||||
// allocate the height of rows which have no cells originating in them
|
||||
// except with cells with rowspan > 1. Store the height as negative
|
||||
// to distinguish them from regular rows.
|
||||
void
|
||||
AllocateSpecialHeight(nsIPresContext* aPresContext,
|
||||
nsTableFrame* aTableFrame,
|
||||
nsIFrame* aRowFrame,
|
||||
nscoord& aHeight)
|
||||
{
|
||||
nsIFrame* cellFrame;
|
||||
aRowFrame->FirstChild(aPresContext, nsnull, &cellFrame);
|
||||
while (cellFrame) {
|
||||
nsCOMPtr<nsIAtom> cellType;
|
||||
cellFrame->GetFrameType(getter_AddRefs(cellType));
|
||||
if (nsLayoutAtoms::tableCellFrame == cellType) {
|
||||
PRInt32 rowSpan = aTableFrame->GetEffectiveRowSpan((nsTableCellFrame&)*cellFrame);
|
||||
if (rowSpan > 1) {
|
||||
// use a simple average to allocate the special row. This is not exact,
|
||||
// but much better than nothing.
|
||||
nsSize cellDesSize;
|
||||
((nsTableRowFrame*)aRowFrame)->CalculateCellActualSize(cellFrame, cellDesSize.width,
|
||||
cellDesSize.height, cellDesSize.width);
|
||||
PRInt32 propHeight = NSToCoordRound((float)cellDesSize.height / (float)rowSpan);
|
||||
// special rows store the largest negative value
|
||||
aHeight = PR_MIN(aHeight, -propHeight);
|
||||
}
|
||||
}
|
||||
cellFrame->GetNextSibling(&cellFrame);
|
||||
}
|
||||
}
|
||||
|
||||
/* CalculateRowHeights provides default heights for all rows in the rowgroup.
|
||||
* Actual row heights are ultimately determined by the table, when the table
|
||||
* height attribute is factored in.
|
||||
|
@ -559,18 +590,20 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
nsTableFrame *tableFrame=nsnull;
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame)
|
||||
return;
|
||||
if (NS_FAILED(rv) || nsnull==tableFrame) return;
|
||||
|
||||
// all table cells have the same top and bottom margins, namely cellSpacingY
|
||||
nscoord cellSpacingY = tableFrame->GetCellSpacingY();
|
||||
|
||||
// iterate children and for each row get the height of the tallest cell. Keep
|
||||
// track of whether any of the rows have a cell that spans into the row
|
||||
PRBool hasRowSpanningCell = PR_FALSE;
|
||||
PRInt32 numRows;
|
||||
GetRowCount(numRows, PR_FALSE);
|
||||
// collect the current height of each row. rows which have 0 height because
|
||||
// they have no cells originating in them without rowspans > 1, are referred to as
|
||||
// special rows. The current height of a special row will be a negative number until
|
||||
// it comes time to actually resize frames.
|
||||
nscoord* rowHeights = nsnull;
|
||||
if (numRows > 0) {
|
||||
rowHeights = new nscoord[numRows];
|
||||
|
@ -578,91 +611,81 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
nsCRT::memset (rowHeights, 0, numRows*sizeof(nscoord));
|
||||
} // else - tree row groups need not have rows directly beneath them
|
||||
|
||||
/* Step 1: get the height of the tallest cell in the row and save it for
|
||||
* pass 2. This height is for table cells that originate in this
|
||||
* row and that don't span into the rows that follow
|
||||
*/
|
||||
// Step 1: get the height of the tallest cell in the row and save it for
|
||||
// pass 2. This height is for table cells that originate in this
|
||||
// row and that don't span into the rows that follow
|
||||
nsIFrame* rowFrame = GetFirstFrame();
|
||||
PRInt32 rowIndex = 0;
|
||||
|
||||
// For row groups that are split across pages, the first row frame won't
|
||||
// necessarily be index 0
|
||||
PRInt32 startRowIndex = -1;
|
||||
const nsStyleDisplay *childDisplay;
|
||||
while (nsnull != rowFrame)
|
||||
{
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
while (rowFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
rowFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableRowFrame == frameType) {
|
||||
if (startRowIndex == -1) {
|
||||
startRowIndex = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
|
||||
}
|
||||
|
||||
// get the height of the tallest cell in the row (excluding cells that span rows)
|
||||
// XXX GetChildMaxTopMargin and GetChildMaxBottomMargin should be removed/simplified because
|
||||
// according to CSS, all table cells must have the same top/bottom and left/right margins.
|
||||
nscoord maxCellHeight = ((nsTableRowFrame*)rowFrame)->GetTallestChild();
|
||||
nscoord maxCellTopMargin = ((nsTableRowFrame*)rowFrame)->GetChildMaxTopMargin();
|
||||
nscoord maxCellBottomMargin = ((nsTableRowFrame*)rowFrame)->GetChildMaxBottomMargin();
|
||||
nscoord maxRowHeight = maxCellHeight + maxCellTopMargin + maxCellBottomMargin;
|
||||
// only the top row has a top margin. Other rows start at the bottom of the prev row's bottom margin.
|
||||
// save the row height for pass 2 below
|
||||
rowHeights[rowIndex] = maxRowHeight;
|
||||
|
||||
nscoord maxCellHeight = ((nsTableRowFrame*)rowFrame)->GetTallestChild();
|
||||
nscoord topMargin = ((nsTableRowFrame*)rowFrame)->GetTopMargin();
|
||||
nscoord bottomMargin = ((nsTableRowFrame*)rowFrame)->GetBottomMargin();
|
||||
nscoord maxRowHeight = maxCellHeight + topMargin + bottomMargin;
|
||||
rowHeights[rowIndex] = maxRowHeight;
|
||||
// See if a cell spans into the row. If so we'll have to do step 2
|
||||
if (!hasRowSpanningCell) {
|
||||
if (tableFrame->RowIsSpannedInto(rowIndex + startRowIndex)) {
|
||||
hasRowSpanningCell = PR_TRUE;
|
||||
}
|
||||
}
|
||||
// special rows need to have some values, so they will get allocations
|
||||
// later. If left at 0, they would get nothing.
|
||||
if (0 == rowHeights[rowIndex]) {
|
||||
AllocateSpecialHeight(aPresContext, tableFrame, rowFrame, rowHeights[rowIndex]);
|
||||
}
|
||||
rowIndex++;
|
||||
}
|
||||
// Get the next row
|
||||
GetNextFrame(rowFrame, &rowFrame);
|
||||
GetNextFrame(rowFrame, &rowFrame); // Get the next row
|
||||
}
|
||||
|
||||
/* Step 2: Now account for cells that span rows. We only do this if there are cells
|
||||
* that span rows.
|
||||
* A spanning cell's height is the sum of the heights of the rows it spans,
|
||||
* or it's own desired height, whichever is greater.
|
||||
* If the cell's desired height is the larger value, resize the rows and contained
|
||||
* cells by an equal percentage of the additional space.
|
||||
* We go through this loop twice. The first time, we are adjusting cell heights
|
||||
* on the fly.
|
||||
* The second time through the loop, we're ensuring that subsequent row-spanning cells
|
||||
* didn't change prior calculations.
|
||||
* Since we are guaranteed to have found the max height spanners the first time through,
|
||||
* we know we only need two passes, not an arbitrary number.
|
||||
*/
|
||||
// Step 2: Now account for cells that span rows. We only do this if there are cells
|
||||
// that span rows. A spanning cell's height is the sum of the heights of the
|
||||
// rows it spans, or it's own desired height, whichever is greater.
|
||||
// If the cell's desired height is the larger value, resize the rows and contained
|
||||
// cells by an equal percentage of the additional space.
|
||||
// We go through this loop twice. The first time, we are adjusting cell heights
|
||||
// on the fly. The second time through the loop, we're ensuring that subsequent
|
||||
// row-spanning cells didn't change prior calculations. Since we are guaranteed
|
||||
// to have found the max height spanners the first time through, we know we only
|
||||
// need two passes, not an arbitrary number.
|
||||
if (hasRowSpanningCell) {
|
||||
nscoord deltaY = 0;
|
||||
for (PRInt32 counter=0; counter<2; counter++)
|
||||
{
|
||||
for (PRInt32 counter = 0; counter < 2; counter++) {
|
||||
rowFrame = GetFirstFrame();
|
||||
rowIndex = 0;
|
||||
while (nsnull != rowFrame)
|
||||
{
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
while (rowFrame) {
|
||||
nsCOMPtr<nsIAtom> rowType;
|
||||
rowFrame->GetFrameType(getter_AddRefs(rowType));
|
||||
if (nsLayoutAtoms::tableRowFrame == rowType) {
|
||||
// check this row for a cell with rowspans
|
||||
nsIFrame *cellFrame;
|
||||
nsIFrame* cellFrame;
|
||||
rowFrame->FirstChild(aPresContext, nsnull, &cellFrame);
|
||||
while (nsnull != cellFrame)
|
||||
{
|
||||
const nsStyleDisplay *cellChildDisplay;
|
||||
cellFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)cellChildDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_CELL == cellChildDisplay->mDisplay)
|
||||
{
|
||||
while (cellFrame) {
|
||||
nsCOMPtr<nsIAtom> cellType;
|
||||
cellFrame->GetFrameType(getter_AddRefs(cellType));
|
||||
if (nsLayoutAtoms::tableCellFrame == cellType) {
|
||||
PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan(rowIndex + startRowIndex,
|
||||
(nsTableCellFrame&)*cellFrame);
|
||||
if (rowSpan > 1)
|
||||
{ // found a cell with rowspan > 1, determine the height of the rows it
|
||||
// spans
|
||||
if (rowSpan > 1) { // found a cell with rowspan > 1, determine the height
|
||||
// of the rows it spans
|
||||
nscoord heightOfRowsSpanned = 0;
|
||||
PRInt32 i;
|
||||
for (i = 0; i < rowSpan; i++) {
|
||||
heightOfRowsSpanned += rowHeights[rowIndex + i];
|
||||
PRInt32 spanX;
|
||||
for (spanX = 0; spanX < rowSpan; spanX++) {
|
||||
if (rowHeights[rowIndex + spanX] > 0) {
|
||||
// don't consider negative values of special rows
|
||||
heightOfRowsSpanned += rowHeights[rowIndex + spanX];
|
||||
}
|
||||
}
|
||||
// reduce the height by top and bottom margins
|
||||
nscoord availHeightOfRowsSpanned = heightOfRowsSpanned - cellSpacingY - cellSpacingY;
|
||||
|
@ -673,44 +696,60 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
nsSize cellFrameSize;
|
||||
cellFrame->GetSize(cellFrameSize);
|
||||
if (0 == counter) {
|
||||
nsSize cellDesiredSize = ((nsTableCellFrame*)cellFrame)->GetDesiredSize();
|
||||
cellFrameSize.height = cellDesiredSize.height;
|
||||
nsSize cellDesSize = ((nsTableCellFrame*)cellFrame)->GetDesiredSize();
|
||||
((nsTableRowFrame*)rowFrame)->CalculateCellActualSize(cellFrame, cellDesSize.width,
|
||||
cellDesSize.height, cellDesSize.width);
|
||||
cellFrameSize.height = cellDesSize.height;
|
||||
}
|
||||
|
||||
if (availHeightOfRowsSpanned >= cellFrameSize.height)
|
||||
{
|
||||
if (availHeightOfRowsSpanned >= cellFrameSize.height) {
|
||||
// yes the cell's height fits with the available space of the rows it
|
||||
// spans. Set the cell frame's height
|
||||
cellFrame->SizeTo(aPresContext, cellFrameSize.width, availHeightOfRowsSpanned);
|
||||
// Realign cell content based on new height
|
||||
((nsTableCellFrame*)cellFrame)->VerticallyAlignChild(aPresContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// the cell's height is larger than the available space of the rows it
|
||||
// spans so distribute the excess height to the rows affected
|
||||
PRInt32 excessHeight = cellFrameSize.height - availHeightOfRowsSpanned;
|
||||
|
||||
// for every row starting at the row with the spanning cell and down
|
||||
// to the last row spanned by the cell
|
||||
nsTableRowFrame *rowFrameToBeResized = (nsTableRowFrame *)rowFrame;
|
||||
nsTableRowFrame* rowFrameToBeResized = (nsTableRowFrame *)rowFrame;
|
||||
nscoord excessAllocated = 0;
|
||||
for (i = rowIndex; i < (rowIndex + rowSpan); i++) {
|
||||
// The amount of additional space each row gets is based on the
|
||||
// percentage of space it occupies, i.e. they don't all get the
|
||||
// same amount of available space
|
||||
float percent = ((float)rowHeights[i]) / ((float)heightOfRowsSpanned);
|
||||
// iterate every row starting at last row spanned and up to the row with
|
||||
// the spanning cell. do this bottom up so that special rows can get a full
|
||||
// allocation before other rows.
|
||||
for (PRInt32 rowX = (rowIndex + rowSpan) - 1; rowX >= rowIndex; rowX--) {
|
||||
nscoord excessForRow;
|
||||
// special rows get as much they can
|
||||
if (rowHeights[rowX] < 0) {
|
||||
nscoord excessAvail = excessHeight - excessAllocated;
|
||||
if (excessAvail > 0) {
|
||||
// don't let the allocation excced what it needs
|
||||
excessForRow = (excessAvail > -rowHeights[rowX]) ? -rowHeights[rowX] : excessAvail;
|
||||
rowHeights[rowX] = excessForRow;
|
||||
}
|
||||
else {
|
||||
// nothing available so assign a zero allocation
|
||||
excessForRow = rowHeights[rowX] = 0;
|
||||
}
|
||||
}
|
||||
else { // normal rows
|
||||
// The amount of additional space each normal row gets is based on the
|
||||
// percentage of space it occupies, i.e. they don't all get the
|
||||
// same amount of available space
|
||||
float percent = ((float)rowHeights[rowX]) / ((float)heightOfRowsSpanned);
|
||||
|
||||
// give rows their percentage, except for the last row which gets
|
||||
// the remainder
|
||||
nscoord excessForRow = ((i + 1) == (rowIndex + rowSpan)) ?
|
||||
excessHeight - excessAllocated :
|
||||
NSToCoordRound(((float)(excessHeight)) * percent);
|
||||
// give rows their percentage, except for the first row which gets
|
||||
// the remainder
|
||||
excessForRow = (rowX == rowIndex)
|
||||
? excessHeight - excessAllocated
|
||||
: NSToCoordRound(((float)(excessHeight)) * percent);
|
||||
// update the row height
|
||||
rowHeights[rowX] += excessForRow;
|
||||
}
|
||||
excessAllocated += excessForRow;
|
||||
|
||||
// update the row height
|
||||
rowHeights[i] += excessForRow;
|
||||
|
||||
|
||||
// Get the next row frame
|
||||
GetNextRowSibling((nsIFrame**)&rowFrameToBeResized);
|
||||
}
|
||||
|
@ -718,8 +757,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
}
|
||||
// Get the next row child (cell frame)
|
||||
cellFrame->GetNextSibling(&cellFrame);
|
||||
cellFrame->GetNextSibling(&cellFrame); // Get the next row child (cell frame)
|
||||
}
|
||||
|
||||
// If this is pass 2 then resize the row to its final size and move the
|
||||
|
@ -741,7 +779,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
|
||||
if (movedFrame) {
|
||||
// Make sure any views are positioned properly
|
||||
nsIView* view;
|
||||
nsIView* view;
|
||||
rowFrame->GetView(aPresContext, &view);
|
||||
if (view) {
|
||||
nsContainerFrame::PositionFrameView(aPresContext, rowFrame, view);
|
||||
|
@ -753,9 +791,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
// Get the next rowgroup child (row frame)
|
||||
GetNextFrame(rowFrame, &rowFrame);
|
||||
GetNextFrame(rowFrame, &rowFrame); // Get the next rowgroup child (row frame)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -764,31 +800,26 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
|||
nscoord rowGroupHeight = 0;
|
||||
rowFrame = GetFirstFrame();
|
||||
rowIndex = 0;
|
||||
while (nsnull != rowFrame)
|
||||
{
|
||||
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
|
||||
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
|
||||
{
|
||||
while (rowFrame) {
|
||||
nsCOMPtr<nsIAtom> rowType;
|
||||
rowFrame->GetFrameType(getter_AddRefs(rowType));
|
||||
if (nsLayoutAtoms::tableRowFrame == rowType) {
|
||||
// Notify the row of the new size
|
||||
((nsTableRowFrame *)rowFrame)->DidResize(aPresContext, aReflowState);
|
||||
}
|
||||
|
||||
// Update the running row group height. The height includes frames that
|
||||
// aren't rows as well
|
||||
nsSize rowSize;
|
||||
nsSize rowSize;
|
||||
rowFrame->GetSize(rowSize);
|
||||
rowGroupHeight += rowSize.height;
|
||||
|
||||
// Get the next row
|
||||
GetNextFrame(rowFrame, &rowFrame);
|
||||
GetNextFrame(rowFrame, &rowFrame); // Get the next row
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
// Adjust our desired size
|
||||
aDesiredSize.height = rowGroupHeight;
|
||||
|
||||
// cleanup
|
||||
delete []rowHeights;
|
||||
aDesiredSize.height = rowGroupHeight; // Adjust our desired size
|
||||
delete [] rowHeights; // cleanup
|
||||
}
|
||||
|
||||
// Called by IR_TargetIsChild() to adjust the sibling frames that follow
|
||||
|
|
Загрузка…
Ссылка в новой задаче