void FixedTableLayout::calcPrefWidths(int& minWidth, int& maxWidth) { // FIXME: This entire calculation is incorrect for both minwidth and maxwidth. // we might want to wait until we have all of the first row before // layouting for the first time. // only need to calculate the minimum width as the sum of the // cols/cells with a fixed width. // // The maximum width is max(minWidth, tableWidth). int bs = m_table->bordersPaddingAndSpacing(); int tableWidth = m_table->style()->width().isFixed() ? m_table->style()->width().value() - bs : 0; int mw = calcWidthArray(tableWidth) + bs; minWidth = max(mw, tableWidth); maxWidth = minWidth; }
void FixedTableLayout::calcPrefWidths(int& minWidth, int& maxWidth) { // FIXME: This entire calculation is incorrect for both minwidth and maxwidth. // we might want to wait until we have all of the first row before // layouting for the first time. // only need to calculate the minimum width as the sum of the // cols/cells with a fixed width. // // The maximum width is max(minWidth, tableWidth). int bs = m_table->bordersPaddingAndSpacing(); int tableWidth = m_table->style()->width().isFixed() ? m_table->style()->width().value() - bs : 0; int mw = calcWidthArray(tableWidth) + bs; minWidth = max(mw, tableWidth); maxWidth = minWidth; // This quirk is very similar to one that exists in RenderBlock::calcBlockPrefWidths(). // Here's the example for this one: /* <table style="width:100%; background-color:red"><tr><td> <table style="background-color:blue"><tr><td> <table style="width:100%; background-color:green; table-layout:fixed"><tr><td> Content </td></tr></table> </td></tr></table> </td></tr></table> */ // In this example, the two inner tables should be as large as the outer table. // We can achieve this effect by making the maxwidth of fixed tables with percentage // widths be infinite. if (m_table->document()->inQuirksMode() && m_table->style()->width().isPercent() && maxWidth < TABLE_MAX_WIDTH) maxWidth = TABLE_MAX_WIDTH; }
void FixedTableLayout::layout() { int tableLogicalWidth = m_table->logicalWidth() - m_table->bordersPaddingAndSpacingInRowDirection(); unsigned nEffCols = m_table->numEffCols(); // FIXME: It is possible to be called without having properly updated our internal representation. // This means that our preferred logical widths were not recomputed as expected. if (nEffCols != m_width.size()) { calcWidthArray(); // FIXME: Table layout shouldn't modify our table structure (but does due to columns and column-groups). nEffCols = m_table->numEffCols(); } Vector<int> calcWidth(nEffCols, 0); unsigned numAuto = 0; unsigned autoSpan = 0; int totalFixedWidth = 0; int totalPercentWidth = 0; float totalPercent = 0; // Compute requirements and try to satisfy fixed and percent widths. // Percentages are of the table's width, so for example // for a table width of 100px with columns (40px, 10%), the 10% compute // to 10px here, and will scale up to 20px in the final (80px, 20px). for (unsigned i = 0; i < nEffCols; i++) { if (m_width[i].isFixed()) { calcWidth[i] = m_width[i].value(); totalFixedWidth += calcWidth[i]; } else if (m_width[i].isPercentNotCalculated()) { calcWidth[i] = valueForLength(m_width[i], tableLogicalWidth); totalPercentWidth += calcWidth[i]; totalPercent += m_width[i].percent(); } else if (m_width[i].isAuto()) { numAuto++; autoSpan += m_table->spanOfEffCol(i); } } int hspacing = m_table->hBorderSpacing(); int totalWidth = totalFixedWidth + totalPercentWidth; if (!numAuto || totalWidth > tableLogicalWidth) { // If there are no auto columns, or if the total is too wide, take // what we have and scale it to fit as necessary. if (totalWidth != tableLogicalWidth) { // Fixed widths only scale up if (totalFixedWidth && totalWidth < tableLogicalWidth) { totalFixedWidth = 0; for (unsigned i = 0; i < nEffCols; i++) { if (m_width[i].isFixed()) { calcWidth[i] = calcWidth[i] * tableLogicalWidth / totalWidth; totalFixedWidth += calcWidth[i]; } } } if (totalPercent) { totalPercentWidth = 0; for (unsigned i = 0; i < nEffCols; i++) { if (m_width[i].isPercentNotCalculated()) { calcWidth[i] = m_width[i].percent() * (tableLogicalWidth - totalFixedWidth) / totalPercent; totalPercentWidth += calcWidth[i]; } } } totalWidth = totalFixedWidth + totalPercentWidth; } } else { // Divide the remaining width among the auto columns. ASSERT(autoSpan >= numAuto); int remainingWidth = tableLogicalWidth - totalFixedWidth - totalPercentWidth - hspacing * (autoSpan - numAuto); int lastAuto = 0; for (unsigned i = 0; i < nEffCols; i++) { if (m_width[i].isAuto()) { unsigned span = m_table->spanOfEffCol(i); int w = remainingWidth * span / autoSpan; calcWidth[i] = w + hspacing * (span - 1); remainingWidth -= w; if (!remainingWidth) break; lastAuto = i; numAuto--; ASSERT(autoSpan >= span); autoSpan -= span; } } // Last one gets the remainder. if (remainingWidth) calcWidth[lastAuto] += remainingWidth; totalWidth = tableLogicalWidth; } if (totalWidth < tableLogicalWidth) { // Spread extra space over columns. int remainingWidth = tableLogicalWidth - totalWidth; int total = nEffCols; while (total) { int w = remainingWidth / total; remainingWidth -= w; calcWidth[--total] += w; } if (nEffCols > 0) calcWidth[nEffCols - 1] += remainingWidth; } int pos = 0; for (unsigned i = 0; i < nEffCols; i++) { m_table->setColumnPosition(i, pos); pos += calcWidth[i] + hspacing; } int colPositionsSize = m_table->columnPositions().size(); if (colPositionsSize > 0) m_table->setColumnPosition(colPositionsSize - 1, pos); }
void FixedTableLayout::computeIntrinsicLogicalWidths(LayoutUnit& minWidth, LayoutUnit& maxWidth) { minWidth = maxWidth = calcWidthArray(); }
void TableLayoutAlgorithmFixed::computeIntrinsicLogicalWidths(LayoutUnit& minWidth, LayoutUnit& maxWidth) { minWidth = maxWidth = LayoutUnit(calcWidthArray()); }