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

📄 autotablelayout.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2002 Lars Knoll (knoll@kde.org) *           (C) 2002 Dirk Mueller (mueller@kde.org) * Copyright (C) 2003, 2006, 2008 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. * * 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 "AutoTableLayout.h"#include "RenderTable.h"#include "RenderTableCell.h"#include "RenderTableCol.h"#include "RenderTableSection.h"using namespace std;namespace WebCore {AutoTableLayout::AutoTableLayout(RenderTable* table)    : TableLayout(table)    , m_hasPercent(false)    , m_percentagesDirty(true)    , m_effWidthDirty(true)    , m_totalPercent(0){}AutoTableLayout::~AutoTableLayout(){}/* recalculates the full structure needed to do layouting and minmax calculations.   This is usually calculated on the fly, but needs to be done fully when table cells change   dynamically*/void AutoTableLayout::recalcColumn(int effCol){    Layout &l = m_layoutStruct[effCol];    RenderObject* child = m_table->firstChild();    // first we iterate over all rows.    RenderTableCell* fixedContributor = 0;    RenderTableCell* maxContributor = 0;    while (child) {        if (child->isTableSection()) {            RenderTableSection* section = static_cast<RenderTableSection*>(child);            int numRows = section->numRows();            RenderTableCell* last = 0;            for (int i = 0; i < numRows; i++) {                RenderTableSection::CellStruct current = section->cellAt(i, effCol);                RenderTableCell* cell = current.cell;                                bool cellHasContent = cell && (cell->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding());                if (cellHasContent)                    l.emptyCellsOnly = false;                                    if (current.inColSpan)                    continue;                if (cell && cell->colSpan() == 1) {                    // A cell originates in this column.  Ensure we have                    // a min/max width of at least 1px for this column now.                    l.minWidth = max(l.minWidth, cellHasContent ? 1 : 0);                    l.maxWidth = max(l.maxWidth, 1);                    if (cell->prefWidthsDirty())                        cell->calcPrefWidths();                    l.minWidth = max(cell->minPrefWidth(), l.minWidth);                    if (cell->maxPrefWidth() > l.maxWidth) {                        l.maxWidth = cell->maxPrefWidth();                        maxContributor = cell;                    }                    Length w = cell->styleOrColWidth();                    // FIXME: What is this arbitrary value?                    if (w.rawValue() > 32760)                        w.setRawValue(32760);                    if (w.isNegative())                        w.setValue(0);                    switch(w.type()) {                    case Fixed:                        // ignore width=0                        if (w.value() > 0 && (int)l.width.type() != Percent) {                            int wval = cell->calcBorderBoxWidth(w.value());                            if (l.width.isFixed()) {                                // Nav/IE weirdness                                if ((wval > l.width.value()) ||                                    ((l.width.value() == wval) && (maxContributor == cell))) {                                    l.width.setValue(wval);                                    fixedContributor = cell;                                }                            } else {                                l.width.setValue(Fixed, wval);                                fixedContributor = cell;                            }                        }                        break;                    case Percent:                        m_hasPercent = true;                        if (w.isPositive() && (!l.width.isPercent() || w.rawValue() > l.width.rawValue()))                            l.width = w;                        break;                    case Relative:                        // FIXME: Need to understand this case and whether it makes sense to compare values                        // which are not necessarily of the same type.                        if (w.isAuto() || (w.isRelative() && w.value() > l.width.rawValue()))                            l.width = w;                    default:                        break;                    }                } else {                    if (cell && (!effCol || section->cellAt(i, effCol-1).cell != cell)) {                        // This spanning cell originates in this column.  Ensure we have                        // a min/max width of at least 1px for this column now.                        l.minWidth = max(l.minWidth, cellHasContent ? 1 : 0);                        l.maxWidth = max(l.maxWidth, 1);                        insertSpanCell(cell);                    }                    last = cell;                }            }        }        child = child->nextSibling();    }    // Nav/IE weirdness    if (l.width.isFixed()) {        if (m_table->style()->htmlHacks() && l.maxWidth > l.width.value() && fixedContributor != maxContributor) {            l.width = Length();            fixedContributor = 0;        }    }    l.maxWidth = max(l.maxWidth, l.minWidth);    // ### we need to add col elements as well}void AutoTableLayout::fullRecalc(){    m_percentagesDirty = true;    m_hasPercent = false;    m_effWidthDirty = true;    int nEffCols = m_table->numEffCols();    m_layoutStruct.resize(nEffCols);    m_layoutStruct.fill(Layout());    m_spanCells.fill(0);    RenderObject *child = m_table->firstChild();    Length grpWidth;    int cCol = 0;    while (child) {        if (child->isTableCol()) {            RenderTableCol *col = static_cast<RenderTableCol*>(child);            int span = col->span();            if (col->firstChild()) {                grpWidth = col->style()->width();            } else {                Length w = col->style()->width();                if (w.isAuto())                    w = grpWidth;                if ((w.isFixed() || w.isPercent()) && w.isZero())                    w = Length();                int cEffCol = m_table->colToEffCol(cCol);                if (!w.isAuto() && span == 1 && cEffCol < nEffCols) {                    if (m_table->spanOfEffCol(cEffCol) == 1) {                        m_layoutStruct[cEffCol].width = w;                        if (w.isFixed() && m_layoutStruct[cEffCol].maxWidth < w.value())                            m_layoutStruct[cEffCol].maxWidth = w.value();                    }                }                cCol += span;            }        } else {            break;        }        RenderObject *next = child->firstChild();        if (!next)            next = child->nextSibling();        if (!next && child->parent()->isTableCol()) {            next = child->parent()->nextSibling();            grpWidth = Length();        }        child = next;    }    for (int i = 0; i < nEffCols; i++)        recalcColumn(i);}static bool shouldScaleColumns(RenderTable* table){    // A special case.  If this table is not fixed width and contained inside    // a cell, then don't bloat the maxwidth by examining percentage growth.    bool scale = true;    while (table) {        Length tw = table->style()->width();        if ((tw.isAuto() || tw.isPercent()) && !table->isPositioned()) {            RenderBlock* cb = table->containingBlock();            while (cb && !cb->isRenderView() && !cb->isTableCell() &&                cb->style()->width().isAuto() && !cb->isPositioned())                cb = cb->containingBlock();            table = 0;            if (cb && cb->isTableCell() &&                (cb->style()->width().isAuto() || cb->style()->width().isPercent())) {                if (tw.isPercent())                    scale = false;                else {                    RenderTableCell* cell = static_cast<RenderTableCell*>(cb);                    if (cell->colSpan() > 1 || cell->table()->style()->width().isAuto())                        scale = false;                    else                        table = cell->table();                }            }        }        else            table = 0;    }    return scale;}void AutoTableLayout::calcPrefWidths(int& minWidth, int& maxWidth){    fullRecalc();    int spanMaxWidth = calcEffectiveWidth();    minWidth = 0;    maxWidth = 0;    float maxPercent = 0;    float maxNonPercent = 0;    bool scaleColumns = shouldScaleColumns(m_table);    // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two places below to avoid division by zero.    // FIXME: Handle the 0% cases properly.    const int epsilon = 1;    int remainingPercent = 100 * percentScaleFactor;    for (unsigned int i = 0; i < m_layoutStruct.size(); i++) {        minWidth += m_layoutStruct[i].effMinWidth;        maxWidth += m_layoutStruct[i].effMaxWidth;        if (scaleColumns) {            if (m_layoutStruct[i].effWidth.isPercent()) {

⌨️ 快捷键说明

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