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

📄 autotablelayout.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                int percent = min(m_layoutStruct[i].effWidth.rawValue(), remainingPercent);                float pw = static_cast<float>(m_layoutStruct[i].effMaxWidth) * 100 * percentScaleFactor / max(percent, epsilon);                maxPercent = max(pw,  maxPercent);                remainingPercent -= percent;            } else                maxNonPercent += m_layoutStruct[i].effMaxWidth;        }    }    if (scaleColumns) {        maxNonPercent = maxNonPercent * 100 * percentScaleFactor / max(remainingPercent, epsilon);        maxWidth = max(maxWidth, static_cast<int>(min(maxNonPercent, INT_MAX / 2.0f)));        maxWidth = max(maxWidth, static_cast<int>(min(maxPercent, INT_MAX / 2.0f)));    }    maxWidth = max(maxWidth, spanMaxWidth);        int bs = m_table->bordersPaddingAndSpacing();    minWidth += bs;    maxWidth += bs;    Length tw = m_table->style()->width();    if (tw.isFixed() && tw.value() > 0) {        minWidth = max(minWidth, tw.value());        maxWidth = minWidth;    }}/*  This method takes care of colspans.  effWidth is the same as width for cells without colspans. If we have colspans, they get modified. */int AutoTableLayout::calcEffectiveWidth(){    float tMaxWidth = 0;    unsigned int nEffCols = m_layoutStruct.size();    int hspacing = m_table->hBorderSpacing();    for (unsigned int i = 0; i < nEffCols; i++) {        m_layoutStruct[i].effWidth = m_layoutStruct[i].width;        m_layoutStruct[i].effMinWidth = m_layoutStruct[i].minWidth;        m_layoutStruct[i].effMaxWidth = m_layoutStruct[i].maxWidth;    }    for (unsigned int i = 0; i < m_spanCells.size(); i++) {        RenderTableCell *cell = m_spanCells[i];        if (!cell)            break;        int span = cell->colSpan();        Length w = cell->styleOrColWidth();        if (!w.isRelative() && w.isZero())            w = Length(); // make it Auto        int col = m_table->colToEffCol(cell->col());        unsigned int lastCol = col;        int cMinWidth = cell->minPrefWidth() + hspacing;        float cMaxWidth = cell->maxPrefWidth() + hspacing;        int totalPercent = 0;        int minWidth = 0;        float maxWidth = 0;        bool allColsArePercent = true;        bool allColsAreFixed = true;        bool haveAuto = false;        bool spanHasEmptyCellsOnly = true;        int fixedWidth = 0;        while (lastCol < nEffCols && span > 0) {            switch (m_layoutStruct[lastCol].width.type()) {            case Percent:                totalPercent += m_layoutStruct[lastCol].width.rawValue();                allColsAreFixed = false;                break;            case Fixed:                if (m_layoutStruct[lastCol].width.value() > 0) {                    fixedWidth += m_layoutStruct[lastCol].width.value();                    allColsArePercent = false;                    // IE resets effWidth to Auto here, but this breaks the konqueror about page and seems to be some bad                    // legacy behaviour anyway. mozilla doesn't do this so I decided we don't neither.                    break;                }                // fall through            case Auto:                haveAuto = true;                // fall through            default:                // If the column is a percentage width, do not let the spanning cell overwrite the                // width value.  This caused a mis-rendering on amazon.com.                // Sample snippet:                // <table border=2 width=100%><                //   <tr><td>1</td><td colspan=2>2-3</tr>                //   <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr>                // </table>                if (!m_layoutStruct[lastCol].effWidth.isPercent()) {                    m_layoutStruct[lastCol].effWidth = Length();                    allColsArePercent = false;                }                else                    totalPercent += m_layoutStruct[lastCol].effWidth.rawValue();                allColsAreFixed = false;            }            if (!m_layoutStruct[lastCol].emptyCellsOnly)                spanHasEmptyCellsOnly = false;            span -= m_table->spanOfEffCol(lastCol);            minWidth += m_layoutStruct[lastCol].effMinWidth;            maxWidth += m_layoutStruct[lastCol].effMaxWidth;            lastCol++;            cMinWidth -= hspacing;            cMaxWidth -= hspacing;        }        // adjust table max width if needed        if (w.isPercent()) {            if (totalPercent > w.rawValue() || allColsArePercent) {                // can't satify this condition, treat as variable                w = Length();            } else {                float spanMax = max(maxWidth, cMaxWidth);                tMaxWidth = max(tMaxWidth, spanMax * 100 * percentScaleFactor / w.rawValue());                // all non percent columns in the span get percent vlaues to sum up correctly.                int percentMissing = w.rawValue() - totalPercent;                float totalWidth = 0;                for (unsigned int pos = col; pos < lastCol; pos++) {                    if (!(m_layoutStruct[pos].effWidth.isPercent()))                        totalWidth += m_layoutStruct[pos].effMaxWidth;                }                for (unsigned int pos = col; pos < lastCol && totalWidth > 0; pos++) {                    if (!(m_layoutStruct[pos].effWidth.isPercent())) {                        int percent = static_cast<int>(percentMissing * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / totalWidth);                        totalWidth -= m_layoutStruct[pos].effMaxWidth;                        percentMissing -= percent;                        if (percent > 0)                            m_layoutStruct[pos].effWidth.setRawValue(Percent, percent);                        else                            m_layoutStruct[pos].effWidth = Length();                    }                }            }        }        // make sure minWidth and maxWidth of the spanning cell are honoured        if (cMinWidth > minWidth) {            if (allColsAreFixed) {                for (unsigned int pos = col; fixedWidth > 0 && pos < lastCol; pos++) {                    int w = max(m_layoutStruct[pos].effMinWidth, cMinWidth * m_layoutStruct[pos].width.value() / fixedWidth);                    fixedWidth -= m_layoutStruct[pos].width.value();                    cMinWidth -= w;                    m_layoutStruct[pos].effMinWidth = w;                }            } else {                float maxw = maxWidth;                int minw = minWidth;                                // Give min to variable first, to fixed second, and to others third.                for (unsigned int pos = col; maxw >= 0 && pos < lastCol; pos++) {                    if (m_layoutStruct[pos].width.isFixed() && haveAuto && fixedWidth <= cMinWidth) {                        int w = max(m_layoutStruct[pos].effMinWidth, m_layoutStruct[pos].width.value());                        fixedWidth -= m_layoutStruct[pos].width.value();                        minw -= m_layoutStruct[pos].effMinWidth;                        maxw -= m_layoutStruct[pos].effMaxWidth;                        cMinWidth -= w;                        m_layoutStruct[pos].effMinWidth = w;                    }                }                for (unsigned int pos = col; maxw >= 0 && pos < lastCol && minw < cMinWidth; pos++) {                    if (!(m_layoutStruct[pos].width.isFixed() && haveAuto && fixedWidth <= cMinWidth)) {                        int w = max(m_layoutStruct[pos].effMinWidth, static_cast<int>(maxw ? cMinWidth * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / maxw : cMinWidth));                        w = min(m_layoutStruct[pos].effMinWidth+(cMinWidth-minw), w);                                                                        maxw -= m_layoutStruct[pos].effMaxWidth;                        minw -= m_layoutStruct[pos].effMinWidth;                        cMinWidth -= w;                        m_layoutStruct[pos].effMinWidth = w;                    }                }            }        }        if (!(w.isPercent())) {            if (cMaxWidth > maxWidth) {                for (unsigned int pos = col; maxWidth >= 0 && pos < lastCol; pos++) {                    int w = max(m_layoutStruct[pos].effMaxWidth, static_cast<int>(maxWidth ? cMaxWidth * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / maxWidth : cMaxWidth));                    maxWidth -= m_layoutStruct[pos].effMaxWidth;                    cMaxWidth -= w;                    m_layoutStruct[pos].effMaxWidth = w;                }            }        } else {            for (unsigned int pos = col; pos < lastCol; pos++)                m_layoutStruct[pos].maxWidth = max(m_layoutStruct[pos].maxWidth, m_layoutStruct[pos].minWidth);        }        // treat span ranges consisting of empty cells only as if they had content        if (spanHasEmptyCellsOnly)            for (unsigned int pos = col; pos < lastCol; pos++)                m_layoutStruct[pos].emptyCellsOnly = false;    }    m_effWidthDirty = false;    return static_cast<int>(min(tMaxWidth, INT_MAX / 2.0f));}/* gets all cells that originate in a column and have a cellspan > 1   Sorts them by increasing cellspan*/void AutoTableLayout::insertSpanCell(RenderTableCell *cell){    if (!cell || cell->colSpan() == 1)        return;    int size = m_spanCells.size();    if (!size || m_spanCells[size-1] != 0) {        m_spanCells.grow(size + 10);        for (int i = 0; i < 10; i++)            m_spanCells[size+i] = 0;        size += 10;    }    // add them in sort. This is a slow algorithm, and a binary search or a fast sorting after collection would be better    unsigned int pos = 0;    int span = cell->colSpan();    while (pos < m_spanCells.size() && m_spanCells[pos] && span > m_spanCells[pos]->colSpan())        pos++;    memmove(m_spanCells.data()+pos+1, m_spanCells.data()+pos, (size-pos-1)*sizeof(RenderTableCell *));    m_spanCells[pos] = cell;}void AutoTableLayout::layout(){    // table layout based on the values collected in the layout structure.    int tableWidth = m_table->width() - m_table->bordersPaddingAndSpacing();    int available = tableWidth;    int nEffCols = m_table->numEffCols();    if (nEffCols != (int)m_layoutStruct.size()) {        fullRecalc();        nEffCols = m_table->numEffCols();    }    if (m_effWidthDirty)        calcEffectiveWidth();    bool havePercent = false;    bool haveRelative = false;    int totalRelative = 0;    int numAuto = 0;    int numFixed = 0;    float totalAuto = 0;    float totalFixed = 0;    int totalPercent = 0;    int allocAuto = 0;    int numAutoEmptyCellsOnly = 0;    // fill up every cell with its minWidth    for (int i = 0; i < nEffCols; i++) {        int w = m_layoutStruct[i].effMinWidth;        m_layoutStruct[i].calcWidth = w;        available -= w;

⌨️ 快捷键说明

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