📄 rendertable.cpp
字号:
m_overflowWidth = max(m_overflowWidth, m_caption->x() + m_caption->overflowWidth(false)); } if (isPositioned()) calcHeight(); m_overflowHeight = max(m_overflowHeight, height()); // table can be containing block of positioned elements. // FIXME: Only pass true if width or height changed. layoutPositionedObjects(true); if (!hasOverflowClip()) { for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) { m_overflowLeft = min(m_overflowLeft, boxShadow->x - boxShadow->blur); m_overflowWidth = max(m_overflowWidth, width() + boxShadow->x + boxShadow->blur); m_overflowTop = min(m_overflowTop, boxShadow->y - boxShadow->blur); m_overflowHeight = max(m_overflowHeight, height() + boxShadow->y + boxShadow->blur); } if (hasReflection()) { IntRect reflection(reflectionBox()); m_overflowTop = min(m_overflowTop, reflection.y()); m_overflowHeight = max(m_overflowHeight, reflection.bottom()); m_overflowLeft = min(m_overflowLeft, reflection.x()); m_overflowHeight = max(m_overflowWidth, reflection.right()); } } statePusher.pop(); bool didFullRepaint = repainter.repaintAfterLayout(); // Repaint with our new bounds if they are different from our old bounds. if (!didFullRepaint && sectionMoved) repaintRectangle(IntRect(m_overflowLeft, movedSectionTop, m_overflowWidth - m_overflowLeft, m_overflowHeight - movedSectionTop)); setNeedsLayout(false);}void RenderTable::setCellWidths(){ for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) static_cast<RenderTableSection*>(child)->setCellWidths(); }}void RenderTable::paint(PaintInfo& paintInfo, int tx, int ty){ tx += x(); ty += y(); PaintPhase paintPhase = paintInfo.phase; int os = 2 * maximalOutlineSize(paintPhase); if (ty + overflowTop(false) >= paintInfo.rect.bottom() + os || ty + overflowHeight(false) <= paintInfo.rect.y() - os) return; if (tx + overflowLeft(false) >= paintInfo.rect.right() + os || tx + overflowWidth(false) <= paintInfo.rect.x() - os) return; bool pushedClip = pushContentsClip(paintInfo, tx, ty); paintObject(paintInfo, tx, ty); if (pushedClip) popContentsClip(paintInfo, paintPhase, tx, ty);}void RenderTable::paintObject(PaintInfo& paintInfo, int tx, int ty){ PaintPhase paintPhase = paintInfo.phase; if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && hasBoxDecorations() && style()->visibility() == VISIBLE) paintBoxDecorations(paintInfo, tx, ty); if (paintPhase == PaintPhaseMask) { paintMask(paintInfo, tx, ty); return; } // We're done. We don't bother painting any children. if (paintPhase == PaintPhaseBlockBackground) return; // We don't paint our own background, but we do let the kids paint their backgrounds. if (paintPhase == PaintPhaseChildBlockBackgrounds) paintPhase = PaintPhaseChildBlockBackground; PaintInfo info(paintInfo); info.phase = paintPhase; info.paintingRoot = paintingRootForChildren(paintInfo); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption)) child->paint(info, tx, ty); } if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) { // Collect all the unique border styles that we want to paint in a sorted list. Once we // have all the styles sorted, we then do individual passes, painting each style of border // from lowest precedence to highest precedence. info.phase = PaintPhaseCollapsedTableBorders; RenderTableCell::CollapsedBorderStyles borderStyles; RenderObject* stop = nextInPreOrderAfterChildren(); for (RenderObject* o = firstChild(); o && o != stop; o = o->nextInPreOrder()) if (o->isTableCell()) static_cast<RenderTableCell*>(o)->collectBorderStyles(borderStyles); RenderTableCell::sortBorderStyles(borderStyles); size_t count = borderStyles.size(); for (size_t i = 0; i < count; ++i) { m_currentBorder = &borderStyles[i]; for (RenderObject* child = firstChild(); child; child = child->nextSibling()) if (child->isTableSection()) child->paint(info, tx, ty); } m_currentBorder = 0; }}void RenderTable::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty){ int w = width(); int h = height(); // Account for the caption. if (m_caption) { int captionHeight = (m_caption->height() + m_caption->marginBottom() + m_caption->marginTop()); h -= captionHeight; if (m_caption->style()->captionSide() != CAPBOTTOM) ty += captionHeight; } int my = max(ty, paintInfo.rect.y()); int mh; if (ty < paintInfo.rect.y()) mh = max(0, h - (paintInfo.rect.y() - ty)); else mh = min(paintInfo.rect.height(), h); paintBoxShadow(paintInfo.context, tx, ty, w, h, style()); paintFillLayers(paintInfo, style()->backgroundColor(), style()->backgroundLayers(), my, mh, tx, ty, w, h); if (style()->hasBorder() && !collapseBorders()) paintBorder(paintInfo.context, tx, ty, w, h, style());}void RenderTable::paintMask(PaintInfo& paintInfo, int tx, int ty){ if (style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask) return; int w = width(); int h = height(); // Account for the caption. if (m_caption) { int captionHeight = (m_caption->height() + m_caption->marginBottom() + m_caption->marginTop()); h -= captionHeight; if (m_caption->style()->captionSide() != CAPBOTTOM) ty += captionHeight; } int my = max(ty, paintInfo.rect.y()); int mh; if (ty < paintInfo.rect.y()) mh = max(0, h - (paintInfo.rect.y() - ty)); else mh = min(paintInfo.rect.height(), h); paintMaskImages(paintInfo, my, mh, tx, ty, w, h);}void RenderTable::calcPrefWidths(){ ASSERT(prefWidthsDirty()); recalcSectionsIfNeeded(); recalcHorizontalBorders(); m_tableLayout->calcPrefWidths(m_minPrefWidth, m_maxPrefWidth); if (m_caption) m_minPrefWidth = max(m_minPrefWidth, m_caption->minPrefWidth()); setPrefWidthsDirty(false);}void RenderTable::splitColumn(int pos, int firstSpan){ // we need to add a new columnStruct int oldSize = m_columns.size(); m_columns.grow(oldSize + 1); int oldSpan = m_columns[pos].span; ASSERT(oldSpan > firstSpan); m_columns[pos].span = firstSpan; memmove(m_columns.data() + pos + 1, m_columns.data() + pos, (oldSize - pos) * sizeof(ColumnStruct)); m_columns[pos + 1].span = oldSpan - firstSpan; // change width of all rows. for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) static_cast<RenderTableSection*>(child)->splitColumn(pos, oldSize + 1); } m_columnPos.grow(numEffCols() + 1); setNeedsLayoutAndPrefWidthsRecalc();}void RenderTable::appendColumn(int span){ // easy case. int pos = m_columns.size(); int newSize = pos + 1; m_columns.grow(newSize); m_columns[pos].span = span; // change width of all rows. for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) static_cast<RenderTableSection*>(child)->appendColumn(pos); } m_columnPos.grow(numEffCols() + 1); setNeedsLayoutAndPrefWidthsRecalc();}RenderTableCol* RenderTable::colElement(int col, bool* startEdge, bool* endEdge) const{ if (!m_hasColElements) return 0; RenderObject* child = firstChild(); int cCol = 0; while (child) { if (child->isTableCol()) { RenderTableCol* colElem = static_cast<RenderTableCol*>(child); int span = colElem->span(); if (!colElem->firstChild()) { int startCol = cCol; int endCol = cCol + span - 1; cCol += span; if (cCol > col) { if (startEdge) *startEdge = startCol == col; if (endEdge) *endEdge = endCol == col; return colElem; } } RenderObject* next = child->firstChild(); if (!next) next = child->nextSibling(); if (!next && child->parent()->isTableCol()) next = child->parent()->nextSibling(); child = next; } else if (child == m_caption) child = child->nextSibling(); else break; } return 0;}void RenderTable::recalcSections() const{ m_caption = 0; m_head = 0; m_foot = 0; m_firstBody = 0; m_hasColElements = false; // We need to get valid pointers to caption, head, foot and first body again for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { switch (child->style()->display()) { case TABLE_CAPTION: if (!m_caption && child->isRenderBlock()) { m_caption = toRenderBlock(child); m_caption->setNeedsLayout(true); } break; case TABLE_COLUMN: case TABLE_COLUMN_GROUP: m_hasColElements = true; break; case TABLE_HEADER_GROUP: if (child->isTableSection()) { RenderTableSection* section = static_cast<RenderTableSection*>(child); if (!m_head) m_head = section; else if (!m_firstBody) m_firstBody = section; section->recalcCellsIfNeeded(); } break; case TABLE_FOOTER_GROUP: if (child->isTableSection()) { RenderTableSection* section = static_cast<RenderTableSection*>(child); if (!m_foot) m_foot = section; else if (!m_firstBody) m_firstBody = section; section->recalcCellsIfNeeded(); } break; case TABLE_ROW_GROUP: if (child->isTableSection()) { RenderTableSection* section = static_cast<RenderTableSection*>(child); if (!m_firstBody) m_firstBody = section; section->recalcCellsIfNeeded(); } break; default: break; } } // repair column count (addChild can grow it too much, because it always adds elements to the last row of a section) int maxCols = 0; for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) { RenderTableSection* section = static_cast<RenderTableSection*>(child); int sectionCols = section->numColumns(); if (sectionCols > maxCols) maxCols = sectionCols; } } m_columns.resize(maxCols); m_columnPos.resize(maxCols + 1); ASSERT(selfNeedsLayout()); m_needsSectionRecalc = false;}int RenderTable::calcBorderLeft() const{ if (collapseBorders()) { // Determined by the first cell of the first row. See the CSS 2.1 spec, section 17.6.2. if (!numEffCols()) return 0; unsigned borderWidth = 0; const BorderValue& tb = style()->borderLeft(); if (tb.style() == BHIDDEN) return 0; if (tb.style() > BHIDDEN) borderWidth = tb.width; int leftmostColumn = style()->direction() == RTL ? numEffCols() - 1 : 0; RenderTableCol* colGroup = colElement(leftmostColumn); if (colGroup) { const BorderValue& gb = style()->borderLeft(); if (gb.style() == BHIDDEN) return 0; if (gb.style() > BHIDDEN) borderWidth = max(borderWidth, static_cast<unsigned>(gb.width)); } RenderTableSection* firstNonEmptySection = m_head ? m_head : (m_firstBody ? m_firstBody : m_foot); if (firstNonEmptySection && !firstNonEmptySection->numRows()) firstNonEmptySection = sectionBelow(firstNonEmptySection, true); if (firstNonEmptySection) { const BorderValue& sb = firstNonEmptySection->style()->borderLeft(); if (sb.style() == BHIDDEN) return 0; if (sb.style() > BHIDDEN) borderWidth = max(borderWidth, static_cast<unsigned>(sb.width)); const RenderTableSection::CellStruct& cs = firstNonEmptySection->cellAt(0, leftmostColumn); if (cs.cell) { const BorderValue& cb = cs.cell->style()->borderLeft(); if (cb.style() == BHIDDEN) return 0; const BorderValue& rb = cs.cell->parent()->style()->borderLeft(); if (rb.style() == BHIDDEN) return 0; if (cb.style() > BHIDDEN) borderWidth = max(borderWidth, static_cast<unsigned>(cb.width)); if (rb.style() > BHIDDEN) borderWidth = max(borderWidth, static_cast<unsigned>(rb.width)); } } return borderWidth / 2; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -