📄 rendertablesection.cpp
字号:
continue; const BorderValue& cb = current.cell->style()->borderBottom(); // FIXME: Don't repeat for the same col group RenderTableCol* colGroup = table()->colElement(c); if (colGroup) { const BorderValue& gb = colGroup->style()->borderBottom(); 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 + 1) / 2;}int RenderTableSection::calcOuterBorderLeft(bool rtl) const{ int totalCols = table()->numEffCols(); if (!m_gridRows || !totalCols) return 0; unsigned borderWidth = 0; const BorderValue& sb = style()->borderLeft(); if (sb.style() == BHIDDEN) return -1; if (sb.style() > BHIDDEN) borderWidth = sb.width; int leftmostColumn = rtl ? totalCols - 1 : 0; RenderTableCol* colGroup = table()->colElement(leftmostColumn); if (colGroup) { const BorderValue& gb = colGroup->style()->borderLeft(); if (gb.style() == BHIDDEN) return -1; if (gb.style() > BHIDDEN && gb.width > borderWidth) borderWidth = gb.width; } bool allHidden = true; for (int r = 0; r < m_gridRows; r++) { const CellStruct& current = cellAt(r, leftmostColumn); if (!current.cell) continue; // FIXME: Don't repeat for the same cell const BorderValue& cb = current.cell->style()->borderLeft(); const BorderValue& rb = current.cell->parent()->style()->borderLeft(); if (cb.style() == BHIDDEN || rb.style() == BHIDDEN) continue; else allHidden = false; if (cb.style() > BHIDDEN && cb.width > borderWidth) borderWidth = cb.width; if (rb.style() > BHIDDEN && rb.width > borderWidth) borderWidth = rb.width; } if (allHidden) return -1; return borderWidth / 2;}int RenderTableSection::calcOuterBorderRight(bool rtl) const{ int totalCols = table()->numEffCols(); if (!m_gridRows || !totalCols) return 0; unsigned borderWidth = 0; const BorderValue& sb = style()->borderRight(); if (sb.style() == BHIDDEN) return -1; if (sb.style() > BHIDDEN) borderWidth = sb.width; int rightmostColumn = rtl ? 0 : totalCols - 1; RenderTableCol* colGroup = table()->colElement(rightmostColumn); if (colGroup) { const BorderValue& gb = colGroup->style()->borderRight(); if (gb.style() == BHIDDEN) return -1; if (gb.style() > BHIDDEN && gb.width > borderWidth) borderWidth = gb.width; } bool allHidden = true; for (int r = 0; r < m_gridRows; r++) { const CellStruct& current = cellAt(r, rightmostColumn); if (!current.cell) continue; // FIXME: Don't repeat for the same cell const BorderValue& cb = current.cell->style()->borderRight(); const BorderValue& rb = current.cell->parent()->style()->borderRight(); if (cb.style() == BHIDDEN || rb.style() == BHIDDEN) continue; else allHidden = false; if (cb.style() > BHIDDEN && cb.width > borderWidth) borderWidth = cb.width; if (rb.style() > BHIDDEN && rb.width > borderWidth) borderWidth = rb.width; } if (allHidden) return -1; return (borderWidth + 1) / 2;}void RenderTableSection::recalcOuterBorder(){ bool rtl = table()->style()->direction() == RTL; m_outerBorderTop = calcOuterBorderTop(); m_outerBorderBottom = calcOuterBorderBottom(); m_outerBorderLeft = calcOuterBorderLeft(rtl); m_outerBorderRight = calcOuterBorderRight(rtl);}int RenderTableSection::firstLineBoxBaseline() const{ if (!m_gridRows) return -1; int firstLineBaseline = m_grid[0].baseline; if (firstLineBaseline) return firstLineBaseline + m_rowPos[0]; firstLineBaseline = -1; Row* firstRow = m_grid[0].row; for (size_t i = 0; i < firstRow->size(); ++i) { RenderTableCell* cell = firstRow->at(i).cell; if (cell) firstLineBaseline = max(firstLineBaseline, cell->y() + cell->paddingTop() + cell->borderTop() + cell->contentHeight()); } return firstLineBaseline;}void RenderTableSection::paint(PaintInfo& paintInfo, int tx, int ty){ // put this back in when all layout tests can handle it // ASSERT(!needsLayout()); // avoid crashing on bugs that cause us to paint with dirty layout if (needsLayout()) return; unsigned totalRows = m_gridRows; unsigned totalCols = table()->columns().size(); if (!totalRows || !totalCols) return; tx += x(); ty += y(); PaintPhase phase = paintInfo.phase; bool pushedClip = pushContentsClip(paintInfo, tx, ty); paintObject(paintInfo, tx, ty); if (pushedClip) popContentsClip(paintInfo, phase, tx, ty);}void RenderTableSection::paintObject(PaintInfo& paintInfo, int tx, int ty){ // Check which rows and cols are visible and only paint these. // FIXME: Could use a binary search here. unsigned totalRows = m_gridRows; unsigned totalCols = table()->columns().size(); PaintPhase paintPhase = paintInfo.phase; int x = paintInfo.rect.x(); int y = paintInfo.rect.y(); int w = paintInfo.rect.width(); int h = paintInfo.rect.height(); int os = 2 * maximalOutlineSize(paintPhase); unsigned startrow = 0; unsigned endrow = totalRows; // If some cell overflows, just paint all of them. if (!m_hasOverflowingCell) { for (; startrow < totalRows; startrow++) { if (ty + m_rowPos[startrow + 1] >= y - os) break; } if (startrow == totalRows && ty + m_rowPos[totalRows] + table()->outerBorderBottom() >= y - os) startrow--; for (; endrow > 0; endrow--) { if (ty + m_rowPos[endrow - 1] <= y + h + os) break; } if (!endrow && ty + m_rowPos[0] - table()->outerBorderTop() <= y + h + os) endrow++; } unsigned startcol = 0; unsigned endcol = totalCols; // FIXME: Implement RTL. if (!m_hasOverflowingCell && style()->direction() == LTR) { for (; startcol < totalCols; startcol++) { if (tx + table()->columnPositions()[startcol + 1] >= x - os) break; } if (startcol == totalCols && tx + table()->columnPositions()[totalCols] + table()->outerBorderRight() >= x - os) startcol--; for (; endcol > 0; endcol--) { if (tx + table()->columnPositions()[endcol - 1] <= x + w + os) break; } if (!endcol && tx + table()->columnPositions()[0] - table()->outerBorderLeft() <= y + w + os) endcol++; } if (startcol < endcol) { // draw the cells for (unsigned r = startrow; r < endrow; r++) { unsigned c = startcol; // since a cell can be -1 (indicating a colspan) we might have to search backwards to include it while (c && cellAt(r, c).inColSpan) c--; for (; c < endcol; c++) { CellStruct current = cellAt(r, c); RenderTableCell* cell = current.cell; // Cells must always paint in the order in which they appear taking into account // their upper left originating row/column. For cells with rowspans, avoid repainting // if we've already seen the cell. if (!cell || (r > startrow && (cellAt(r - 1, c).cell == cell))) continue; RenderTableRow* row = static_cast<RenderTableRow*>(cell->parent()); if (paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) { // We need to handle painting a stack of backgrounds. This stack (from bottom to top) consists of // the column group, column, row group, row, and then the cell. RenderObject* col = table()->colElement(c); RenderObject* colGroup = 0; if (col && col->parent()->style()->display() == TABLE_COLUMN_GROUP) colGroup = col->parent(); // Column groups and columns first. // FIXME: Columns and column groups do not currently support opacity, and they are being painted "too late" in // the stack, since we have already opened a transparency layer (potentially) for the table row group. // Note that we deliberately ignore whether or not the cell has a layer, since these backgrounds paint "behind" the // cell. cell->paintBackgroundsBehindCell(paintInfo, tx, ty, colGroup); cell->paintBackgroundsBehindCell(paintInfo, tx, ty, col); // Paint the row group next. cell->paintBackgroundsBehindCell(paintInfo, tx, ty, this); // Paint the row next, but only if it doesn't have a layer. If a row has a layer, it will be responsible for // painting the row background for the cell. if (!row->hasSelfPaintingLayer()) cell->paintBackgroundsBehindCell(paintInfo, tx, ty, row); } if ((!cell->hasSelfPaintingLayer() && !row->hasSelfPaintingLayer()) || paintInfo.phase == PaintPhaseCollapsedTableBorders) cell->paint(paintInfo, tx, ty); } } }}void RenderTableSection::imageChanged(WrappedImagePtr, const IntRect*){ // FIXME: Examine cells and repaint only the rect the image paints in. repaint();}void RenderTableSection::recalcCells(){ m_cCol = 0; m_cRow = -1; clearGrid(); m_gridRows = 0; for (RenderObject* row = firstChild(); row; row = row->nextSibling()) { if (row->isTableRow()) { m_cRow++; m_cCol = 0; if (!ensureRows(m_cRow + 1)) break; RenderTableRow* tableRow = static_cast<RenderTableRow*>(row); m_grid[m_cRow].rowRenderer = tableRow; for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) { if (cell->isTableCell()) addCell(static_cast<RenderTableCell*>(cell), tableRow); } } } m_needsCellRecalc = false; setNeedsLayout(true);}void RenderTableSection::clearGrid(){ int rows = m_gridRows; while (rows--) delete m_grid[rows].row;}int RenderTableSection::numColumns() const{ int result = 0; for (int r = 0; r < m_gridRows; ++r) { for (int c = result; c < table()->numEffCols(); ++c) { const CellStruct& cell = cellAt(r, c); if (cell.cell || cell.inColSpan) result = c; } } return result + 1;}void RenderTableSection::appendColumn(int pos){ for (int row = 0; row < m_gridRows; ++row) { m_grid[row].row->resize(pos + 1); CellStruct& c = cellAt(row, pos); c.cell = 0; c.inColSpan = false; }}void RenderTableSection::splitColumn(int pos, int newSize){ if (m_cCol > pos) m_cCol++; for (int row = 0; row < m_gridRows; ++row) { m_grid[row].row->resize(newSize); Row& r = *m_grid[row].row; memmove(r.data() + pos + 1, r.data() + pos, (newSize - 1 - pos) * sizeof(CellStruct)); r[pos + 1].cell = 0; r[pos + 1].inColSpan = r[pos].inColSpan || r[pos].cell; }}// Hit Testingbool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction action){ // Table sections cannot ever be hit tested. Effectively they do not exist. // Just forward to our children always. tx += x(); ty += y(); if (hasOverflowClip() && !overflowClipRect(tx, ty).contains(xPos, yPos)) return false; for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { // FIXME: We have to skip over inline flows, since they can show up inside table rows // at the moment (a demoted inline <form> for example). If we ever implement a // table-specific hit-test method (which we should do for performance reasons anyway), // then we can remove this check. if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) { updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty)); return true; } } return false;}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -