📄 rendertablesection.cpp
字号:
m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[r]); }#ifndef NDEBUG setNeedsLayoutIsForbidden(false);#endif ASSERT(!needsLayout()); statePusher.pop(); return m_rowPos[m_gridRows];}void RenderTableSection::layout(){ ASSERT(needsLayout()); LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y())); for (RenderObject* child = children()->firstChild(); child; child = child->nextSibling()) { if (child->isTableRow()) { child->layoutIfNeeded(); ASSERT(!child->needsLayout()); } } statePusher.pop(); setNeedsLayout(false);}int RenderTableSection::layoutRows(int toAdd){#ifndef NDEBUG setNeedsLayoutIsForbidden(true);#endif ASSERT(!needsLayout()); int rHeight; int rindx; int totalRows = m_gridRows; // Set the width of our section now. The rows will also be this width. setWidth(table()->contentWidth()); m_overflowLeft = 0; m_overflowWidth = width(); m_overflowTop = 0; m_overflowHeight = 0; m_hasOverflowingCell = false; if (toAdd && totalRows && (m_rowPos[totalRows] || !nextSibling())) { int totalHeight = m_rowPos[totalRows] + toAdd; int dh = toAdd; int totalPercent = 0; int numAuto = 0; for (int r = 0; r < totalRows; r++) { if (m_grid[r].height.isAuto()) numAuto++; else if (m_grid[r].height.isPercent()) totalPercent += m_grid[r].height.rawValue(); } if (totalPercent) { // try to satisfy percent int add = 0; totalPercent = min(totalPercent, 100 * percentScaleFactor); int rh = m_rowPos[1] - m_rowPos[0]; for (int r = 0; r < totalRows; r++) { if (totalPercent > 0 && m_grid[r].height.isPercent()) { int toAdd = min(dh, (totalHeight * m_grid[r].height.rawValue() / (100 * percentScaleFactor)) - rh); // If toAdd is negative, then we don't want to shrink the row (this bug // affected Outlook Web Access). toAdd = max(0, toAdd); add += toAdd; dh -= toAdd; totalPercent -= m_grid[r].height.rawValue(); } if (r < totalRows - 1) rh = m_rowPos[r + 2] - m_rowPos[r + 1]; m_rowPos[r + 1] += add; } } if (numAuto) { // distribute over variable cols int add = 0; for (int r = 0; r < totalRows; r++) { if (numAuto > 0 && m_grid[r].height.isAuto()) { int toAdd = dh / numAuto; add += toAdd; dh -= toAdd; numAuto--; } m_rowPos[r + 1] += add; } } if (dh > 0 && m_rowPos[totalRows]) { // if some left overs, distribute equally. int tot = m_rowPos[totalRows]; int add = 0; int prev = m_rowPos[0]; for (int r = 0; r < totalRows; r++) { //weight with the original height add += dh * (m_rowPos[r + 1] - prev) / tot; prev = m_rowPos[r + 1]; m_rowPos[r + 1] += add; } } } int hspacing = table()->hBorderSpacing(); int vspacing = table()->vBorderSpacing(); int nEffCols = table()->numEffCols(); LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y())); for (int r = 0; r < totalRows; r++) { // Set the row's x/y position and width/height. if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) { rowRenderer->setLocation(0, m_rowPos[r]); rowRenderer->setWidth(width()); rowRenderer->setHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing); } for (int c = 0; c < nEffCols; c++) { RenderTableCell* cell = cellAt(r, c).cell; if (!cell) continue; if (r < totalRows - 1 && cell == cellAt(r + 1, c).cell) continue; rindx = max(0, r - cell->rowSpan() + 1); rHeight = m_rowPos[r + 1] - m_rowPos[rindx] - vspacing; // Force percent height children to lay themselves out again. // This will cause these children to grow to fill the cell. // FIXME: There is still more work to do here to fully match WinIE (should // it become necessary to do so). In quirks mode, WinIE behaves like we // do, but it will clip the cells that spill out of the table section. In // strict mode, Mozilla and WinIE both regrow the table to accommodate the // new height of the cell (thus letting the percentages cause growth one // time only). We may also not be handling row-spanning cells correctly. // // Note also the oddity where replaced elements always flex, and yet blocks/tables do // not necessarily flex. WinIE is crazy and inconsistent, and we can't hope to // match the behavior perfectly, but we'll continue to refine it as we discover new // bugs. :) bool cellChildrenFlex = false; bool flexAllChildren = cell->style()->height().isFixed() || (!table()->style()->height().isAuto() && rHeight != cell->height()); for (RenderObject* o = cell->firstChild(); o; o = o->nextSibling()) { if (!o->isText() && o->style()->height().isPercent() && (o->isReplaced() || (o->isBox() && toRenderBox(o)->scrollsOverflow()) || flexAllChildren)) { // Tables with no sections do not flex. if (!o->isTable() || static_cast<RenderTable*>(o)->hasSections()) { o->setNeedsLayout(true, false); cell->setChildNeedsLayout(true, false); cellChildrenFlex = true; } } } if (cellChildrenFlex) { // Alignment within a cell is based off the calculated // height, which becomes irrelevant once the cell has // been resized based off its percentage. cell->setOverrideSize(max(0, rHeight - cell->borderTop() - cell->paddingTop() - cell->borderBottom() - cell->paddingBottom())); cell->layoutIfNeeded(); // If the baseline moved, we may have to update the data for our row. Find out the new baseline. EVerticalAlign va = cell->style()->verticalAlign(); if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP || va == SUPER || va == SUB) { int b = cell->baselinePosition(); if (b > cell->borderTop() + cell->paddingTop()) m_grid[r].baseline = max(m_grid[r].baseline, b); } } int oldTe = cell->intrinsicPaddingTop(); int oldBe = cell->intrinsicPaddingBottom(); int heightWithoutIntrinsicPadding = cell->height() - oldTe - oldBe; int te = 0; switch (cell->style()->verticalAlign()) { case SUB: case SUPER: case TEXT_TOP: case TEXT_BOTTOM: case BASELINE: { int b = cell->baselinePosition(); if (b > cell->borderTop() + cell->paddingTop()) te = getBaseline(r) - (b - oldTe); break; } case TOP: te = 0; break; case MIDDLE: te = (rHeight - heightWithoutIntrinsicPadding) / 2; break; case BOTTOM: te = rHeight - heightWithoutIntrinsicPadding; break; default: break; } int be = rHeight - heightWithoutIntrinsicPadding - te; cell->setIntrinsicPaddingTop(te); cell->setIntrinsicPaddingBottom(be); if (te != oldTe || be != oldBe) { cell->setNeedsLayout(true, false); cell->layoutIfNeeded(); } if ((te != oldTe || be > oldBe) && !table()->selfNeedsLayout() && cell->checkForRepaintDuringLayout()) cell->repaint(); IntRect oldCellRect(cell->x(), cell->y() , cell->width(), cell->height()); if (style()->direction() == RTL) { cell->setLocation(table()->columnPositions()[nEffCols] - table()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + hspacing, m_rowPos[rindx]); } else cell->setLocation(table()->columnPositions()[c] + hspacing, m_rowPos[rindx]); m_overflowLeft = min(m_overflowLeft, cell->x() + cell->overflowLeft(false)); m_overflowWidth = max(m_overflowWidth, cell->x() + cell->overflowWidth(false)); m_overflowTop = min(m_overflowTop, cell->y() + cell->overflowTop(false)); m_overflowHeight = max(m_overflowHeight, cell->y() + cell->overflowHeight(false)); m_hasOverflowingCell |= cell->overflowLeft(false) || cell->overflowWidth(false) > cell->width() || cell->overflowTop(false) || cell->overflowHeight(false) > cell->height(); // If the cell moved, we have to repaint it as well as any floating/positioned // descendants. An exception is if we need a layout. In this case, we know we're going to // repaint ourselves (and the cell) anyway. if (!table()->selfNeedsLayout() && cell->checkForRepaintDuringLayout()) cell->repaintDuringLayoutIfMoved(oldCellRect); } }#ifndef NDEBUG setNeedsLayoutIsForbidden(false);#endif ASSERT(!needsLayout()); statePusher.pop(); setHeight(m_rowPos[totalRows]); m_overflowHeight = max(m_overflowHeight, height()); return height();}int RenderTableSection::lowestPosition(bool includeOverflowInterior, bool includeSelf) const{ int bottom = RenderBox::lowestPosition(includeOverflowInterior, includeSelf); if (!includeOverflowInterior && hasOverflowClip()) return bottom; for (RenderObject* row = firstChild(); row; row = row->nextSibling()) { for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) { if (curr->isTableCell()) { RenderTableCell* cell = static_cast<RenderTableCell*>(curr); bottom = max(bottom, cell->y() + cell->lowestPosition(false)); } } } return bottom;}int RenderTableSection::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const{ int right = RenderBox::rightmostPosition(includeOverflowInterior, includeSelf); if (!includeOverflowInterior && hasOverflowClip()) return right; for (RenderObject* row = firstChild(); row; row = row->nextSibling()) { for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) { if (curr->isTableCell()) { RenderTableCell* cell = static_cast<RenderTableCell*>(curr); right = max(right, cell->x() + cell->rightmostPosition(false)); } } } return right;}int RenderTableSection::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const{ int left = RenderBox::leftmostPosition(includeOverflowInterior, includeSelf); if (!includeOverflowInterior && hasOverflowClip()) return left; for (RenderObject* row = firstChild(); row; row = row->nextSibling()) { for (RenderObject* curr = row->firstChild(); curr; curr = curr->nextSibling()) { if (curr->isTableCell()) { RenderTableCell* cell = static_cast<RenderTableCell*>(curr); left = min(left, cell->x() + cell->leftmostPosition(false)); } } } return left;}int RenderTableSection::calcOuterBorderTop() const{ int totalCols = table()->numEffCols(); if (!m_gridRows || !totalCols) return 0; unsigned borderWidth = 0; const BorderValue& sb = style()->borderTop(); if (sb.style() == BHIDDEN) return -1; if (sb.style() > BHIDDEN) borderWidth = sb.width; const BorderValue& rb = firstChild()->style()->borderTop(); if (rb.style() == BHIDDEN) return -1; if (rb.style() > BHIDDEN && rb.width > borderWidth) borderWidth = rb.width; bool allHidden = true; for (int c = 0; c < totalCols; c++) { const CellStruct& current = cellAt(0, c); if (current.inColSpan || !current.cell) continue; const BorderValue& cb = current.cell->style()->borderTop(); // FIXME: Don't repeat for the same col group RenderTableCol* colGroup = table()->colElement(c); if (colGroup) { const BorderValue& gb = colGroup->style()->borderTop(); if (gb.style() == BHIDDEN || cb.style() == BHIDDEN) continue; else allHidden = false; if (gb.style() > BHIDDEN && gb.width > borderWidth) borderWidth = gb.width; if (cb.style() > BHIDDEN && cb.width > borderWidth) borderWidth = cb.width; } else { if (cb.style() == BHIDDEN) continue; else allHidden = false; if (cb.style() > BHIDDEN && cb.width > borderWidth) borderWidth = cb.width; } } if (allHidden) return -1; return borderWidth / 2;}int RenderTableSection::calcOuterBorderBottom() const{ int totalCols = table()->numEffCols(); if (!m_gridRows || !totalCols) return 0; unsigned borderWidth = 0; const BorderValue& sb = style()->borderBottom(); if (sb.style() == BHIDDEN) return -1; if (sb.style() > BHIDDEN) borderWidth = sb.width; const BorderValue& rb = lastChild()->style()->borderBottom(); if (rb.style() == BHIDDEN) return -1; if (rb.style() > BHIDDEN && rb.width > borderWidth) borderWidth = rb.width; bool allHidden = true; for (int c = 0; c < totalCols; c++) { const CellStruct& current = cellAt(m_gridRows - 1, c); if (current.inColSpan || !current.cell)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -