⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rendertablecell.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1997 Martin Jones (mjones@kde.org) *           (C) 1997 Torben Weis (weis@kde.org) *           (C) 1998 Waldo Bastian (bastian@kde.org) *           (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "config.h"#include "RenderTableCell.h"#include "FloatQuad.h"#include "GraphicsContext.h"#include "HTMLNames.h"#include "HTMLTableCellElement.h"#include "RenderTableCol.h"#include "RenderView.h"#include "TransformState.h"using namespace std;namespace WebCore {using namespace HTMLNames;RenderTableCell::RenderTableCell(Node* node)    : RenderBlock(node)    , m_row(-1)    , m_column(-1)    , m_rowSpan(1)    , m_columnSpan(1)    , m_intrinsicPaddingTop(0)    , m_intrinsicPaddingBottom(0)    , m_percentageHeight(0){    updateFromElement();}void RenderTableCell::destroy(){    RenderTableSection* recalcSection = parent() ? section() : 0;    RenderBlock::destroy();    if (recalcSection)        recalcSection->setNeedsCellRecalc();}void RenderTableCell::updateFromElement(){    Node* n = node();    if (n && (n->hasTagName(tdTag) || n->hasTagName(thTag))) {        HTMLTableCellElement* tc = static_cast<HTMLTableCellElement*>(n);        int oldRSpan = m_rowSpan;        int oldCSpan = m_columnSpan;        m_columnSpan = tc->colSpan();        m_rowSpan = tc->rowSpan();        if ((oldRSpan != m_rowSpan || oldCSpan != m_columnSpan) && style() && parent()) {            setNeedsLayoutAndPrefWidthsRecalc();            if (section())                section()->setNeedsCellRecalc();        }    }}Length RenderTableCell::styleOrColWidth() const{    Length w = style()->width();    if (colSpan() > 1 || !w.isAuto())        return w;    RenderTableCol* tableCol = table()->colElement(col());    if (tableCol) {        w = tableCol->style()->width();                // Column widths specified on <col> apply to the border box of the cell.        // Percentages don't need to be handled since they're always treated this way (even when specified on the cells).        // See Bugzilla bug 8126 for details.        if (w.isFixed() && w.value() > 0)            w = Length(max(0, w.value() - borderLeft() - borderRight() - paddingLeft() - paddingRight()), Fixed);    }    return w;}void RenderTableCell::calcPrefWidths(){    // The child cells rely on the grids up in the sections to do their calcPrefWidths work.  Normally the sections are set up early, as table    // cells are added, but relayout can cause the cells to be freed, leaving stale pointers in the sections'    // grids.  We must refresh those grids before the child cells try to use them.    table()->recalcSectionsIfNeeded();    RenderBlock::calcPrefWidths();    if (node() && style()->autoWrap()) {        // See if nowrap was set.        Length w = styleOrColWidth();        String nowrap = static_cast<Element*>(node())->getAttribute(nowrapAttr);        if (!nowrap.isNull() && w.isFixed())            // Nowrap is set, but we didn't actually use it because of the            // fixed width set on the cell.  Even so, it is a WinIE/Moz trait            // to make the minwidth of the cell into the fixed width.  They do this            // even in strict mode, so do not make this a quirk.  Affected the top            // of hiptop.com.            m_minPrefWidth = max(w.value(), m_minPrefWidth);    }}void RenderTableCell::calcWidth(){}void RenderTableCell::updateWidth(int w){    if (w != width()) {        setWidth(w);        setCellWidthChanged(true);    }}void RenderTableCell::layout(){    layoutBlock(cellWidthChanged());    setCellWidthChanged(false);}int RenderTableCell::paddingTop(bool includeIntrinsicPadding) const{    return RenderBlock::paddingTop() + (includeIntrinsicPadding ? intrinsicPaddingTop() : 0);}int RenderTableCell::paddingBottom(bool includeIntrinsicPadding) const{    return RenderBlock::paddingBottom() + (includeIntrinsicPadding ? intrinsicPaddingBottom() : 0);}void RenderTableCell::setOverrideSize(int size){    clearIntrinsicPadding();    RenderBlock::setOverrideSize(size);}IntRect RenderTableCell::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer){    // If the table grid is dirty, we cannot get reliable information about adjoining cells,    // so we ignore outside borders. This should not be a problem because it means that    // the table is going to recalculate the grid, relayout and repaint its current rect, which    // includes any outside borders of this cell.    if (!table()->collapseBorders() || table()->needsSectionRecalc())        return RenderBlock::clippedOverflowRectForRepaint(repaintContainer);    bool rtl = table()->style()->direction() == RTL;    int outlineSize = style()->outlineSize();    int left = max(borderHalfLeft(true), outlineSize);    int right = max(borderHalfRight(true), outlineSize);    int top = max(borderHalfTop(true), outlineSize);    int bottom = max(borderHalfBottom(true), outlineSize);    if (left && !rtl || right && rtl) {        if (RenderTableCell* before = table()->cellBefore(this)) {            top = max(top, before->borderHalfTop(true));            bottom = max(bottom, before->borderHalfBottom(true));        }    }    if (left && rtl || right && !rtl) {        if (RenderTableCell* after = table()->cellAfter(this)) {            top = max(top, after->borderHalfTop(true));            bottom = max(bottom, after->borderHalfBottom(true));        }    }    if (top) {        if (RenderTableCell* above = table()->cellAbove(this)) {            left = max(left, above->borderHalfLeft(true));            right = max(right, above->borderHalfRight(true));        }    }    if (bottom) {        if (RenderTableCell* below = table()->cellBelow(this)) {            left = max(left, below->borderHalfLeft(true));            right = max(right, below->borderHalfRight(true));        }    }    left = max(left, -overflowLeft(false));    top = max(top, -overflowTop(false));    IntRect r(-left, - top, left + max(width() + right, overflowWidth(false)), top + max(height() + bottom, overflowHeight(false)));    if (RenderView* v = view()) {        // FIXME: layoutDelta needs to be applied in parts before/after transforms and        // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308        r.move(v->layoutDelta());    }    computeRectForRepaint(repaintContainer, r);    return r;}void RenderTableCell::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& r, bool fixed){    if (repaintContainer == this)        return;    r.setY(r.y());    RenderView* v = view();    if ((!v || !v->layoutStateEnabled()) && parent())        r.move(-parentBox()->x(), -parentBox()->y()); // Rows are in the same coordinate space, so don't add their offset in.    RenderBlock::computeRectForRepaint(repaintContainer, r, fixed);}void RenderTableCell::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const{    if (repaintContainer == this)        return;    RenderView* v = view();    if ((!v || !v->layoutStateEnabled()) && parent()) {        // Rows are in the same coordinate space, so don't add their offset in.        // FIXME: this is wrong with transforms        transformState.move(-parentBox()->x(), -parentBox()->y());    }    RenderBlock::mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);}void RenderTableCell::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const{    RenderBlock::mapAbsoluteToLocalPoint(fixed, useTransforms, transformState);    if (parent()) {        // Rows are in the same coordinate space, so add their offset back in.        // FIXME: this is wrong with transforms        transformState.move(parentBox()->x(), parentBox()->y());    }}int RenderTableCell::baselinePosition(bool firstLine, bool isRootLineBox) const{    if (isRootLineBox)        return RenderBox::baselinePosition(firstLine, isRootLineBox);    // <http://www.w3.org/TR/2007/CR-CSS21-20070719/tables.html#height-layout>: The baseline of a cell is the baseline of    // the first in-flow line box in the cell, or the first in-flow table-row in the cell, whichever comes first. If there    // is no such line box or table-row, the baseline is the bottom of content edge of the cell box.    int firstLineBaseline = firstLineBoxBaseline();    if (firstLineBaseline != -1)        return firstLineBaseline;    return paddingTop() + borderTop() + contentHeight();}void RenderTableCell::styleWillChange(StyleDifference diff, const RenderStyle* newStyle){    if (parent() && section() && style() && style()->height() != newStyle->height())        section()->setNeedsCellRecalc();    ASSERT(newStyle->display() == TABLE_CELL);    RenderBlock::styleWillChange(diff, newStyle);}void RenderTableCell::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle){    RenderBlock::styleDidChange(diff, oldStyle);    setHasBoxDecorations(true);}// The following rules apply for resolving conflicts and figuring out which border// to use.// (1) Borders with the 'border-style' of 'hidden' take precedence over all other conflicting // borders. Any border with this value suppresses all borders at this location.// (2) Borders with a style of 'none' have the lowest priority. Only if the border properties of all // the elements meeting at this edge are 'none' will the border be omitted (but note that 'none' is // the default value for the border style.)// (3) If none of the styles are 'hidden' and at least one of them is not 'none', then narrow borders // are discarded in favor of wider ones. If several have the same 'border-width' then styles are preferred // in this order: 'double', 'solid', 'dashed', 'dotted', 'ridge', 'outset', 'groove', and the lowest: 'inset'.// (4) If border styles differ only in color, then a style set on a cell wins over one on a row, // which wins over a row group, column, column group and, lastly, table. It is undefined which color // is used when two elements of the same type disagree.static CollapsedBorderValue compareBorders(const CollapsedBorderValue& border1, const CollapsedBorderValue& border2){    // Sanity check the values passed in.  If either is null, return the other.    if (!border2.exists())        return border1;    if (!border1.exists())        return border2;    // Rule #1 above.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -