Пример #1
0
void AutoTableLayout::fullRecalc()
{
    percentagesDirty = true;
    hasPercent = false;
    effWidthDirty = true;

    int nEffCols = table->numEffCols();
    layoutStruct.resize( nEffCols );
    layoutStruct.fill( Layout() );
    spanCells.fill( 0 );

    RenderObject *child = 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.isVariable() )
		    w = grpWidth;
		if ( (w.isFixed() && w.value() == 0) ||
		     (w.isPercent() && w.value() == 0) )
		    w = Length();
		int cEffCol = table->colToEffCol( cCol );
#ifdef DEBUG_LAYOUT
		qDebug("    col element %d (eff=%d): Length=%d(%d), span=%d, effColSpan=%d",  cCol, cEffCol, w.value(), w.type(), span, table->spanOfEffCol(cEffCol ) );
#endif
		if ( !w.isVariable() && span == 1 && cEffCol < nEffCols ) {
		    if ( table->spanOfEffCol( cEffCol ) == 1 ) {
			layoutStruct[cEffCol].width = w;
                        if (w.isFixed() && layoutStruct[cEffCol].maxWidth < w.value())
                            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 );
}
Пример #2
0
int FixedTableLayout::calcWidthArray()
{
    // FIXME: We might want to wait until we have all of the first row before computing for the first time.
    int usedWidth = 0;

    // iterate over all <col> elements
    unsigned nEffCols = m_table->numEffCols();
    m_width.resize(nEffCols);
    m_width.fill(Length(Auto));

    unsigned currentEffectiveColumn = 0;
    for (RenderTableCol* col = m_table->firstColumn(); col; col = col->nextColumn()) {
        // RenderTableCols don't have the concept of preferred logical width, but we need to clear their dirty bits
        // so that if we call setPreferredWidthsDirty(true) on a col or one of its descendants, we'll mark it's
        // ancestors as dirty.
        col->clearPreferredLogicalWidthsDirtyBits();

        // Width specified by column-groups that have column child does not affect column width in fixed layout tables
        if (col->isTableColumnGroupWithColumnChildren())
            continue;

        Length colStyleLogicalWidth = col->style().logicalWidth();
        int effectiveColWidth = 0;
        if (colStyleLogicalWidth.isFixed() && colStyleLogicalWidth.value() > 0)
            effectiveColWidth = colStyleLogicalWidth.value();

        unsigned span = col->span();
        while (span) {
            unsigned spanInCurrentEffectiveColumn;
            if (currentEffectiveColumn >= nEffCols) {
                m_table->appendColumn(span);
                nEffCols++;
                m_width.append(Length());
                spanInCurrentEffectiveColumn = span;
            } else {
                if (span < m_table->spanOfEffCol(currentEffectiveColumn)) {
                    m_table->splitColumn(currentEffectiveColumn, span);
                    nEffCols++;
                    m_width.append(Length());
                }
                spanInCurrentEffectiveColumn = m_table->spanOfEffCol(currentEffectiveColumn);
            }
            if ((colStyleLogicalWidth.isFixed() || colStyleLogicalWidth.isPercent()) && colStyleLogicalWidth.isPositive()) {
                m_width[currentEffectiveColumn] = colStyleLogicalWidth;
                m_width[currentEffectiveColumn] *= spanInCurrentEffectiveColumn;
                usedWidth += effectiveColWidth * spanInCurrentEffectiveColumn;
            }
            span -= spanInCurrentEffectiveColumn;
            currentEffectiveColumn++;
        }
    }

    // Iterate over the first row in case some are unspecified.
    RenderTableSection* section = m_table->topNonEmptySection();
    if (!section)
        return usedWidth;

    unsigned currentColumn = 0;

    RenderTableRow* firstRow = section->firstRow();
    for (RenderTableCell* cell = firstRow->firstCell(); cell; cell = cell->nextCell()) {
        Length logicalWidth = cell->styleOrColLogicalWidth();
        unsigned span = cell->colSpan();
        int fixedBorderBoxLogicalWidth = 0;
        // FIXME: Support other length types. If the width is non-auto, it should probably just use
        // RenderBox::computeLogicalWidthInRegionUsing to compute the width.
        if (logicalWidth.isFixed() && logicalWidth.isPositive()) {
            fixedBorderBoxLogicalWidth = cell->adjustBorderBoxLogicalWidthForBoxSizing(logicalWidth.value());
            logicalWidth.setValue(Fixed, fixedBorderBoxLogicalWidth);
        }

        unsigned usedSpan = 0;
        while (usedSpan < span && currentColumn < nEffCols) {
            float eSpan = m_table->spanOfEffCol(currentColumn);
            // Only set if no col element has already set it.
            if (m_width[currentColumn].isAuto() && logicalWidth.type() != Auto) {
                m_width[currentColumn] = logicalWidth;
                m_width[currentColumn] *= eSpan / span;
                usedWidth += fixedBorderBoxLogicalWidth * eSpan / span;
            }
            usedSpan += eSpan;
            ++currentColumn;
        }

        // FixedTableLayout doesn't use min/maxPreferredLogicalWidths, but we need to clear the
        // dirty bit on the cell so that we'll correctly mark its ancestors dirty
        // in case we later call setPreferredLogicalWidthsDirty(true) on it later.
        if (cell->preferredLogicalWidthsDirty())
            cell->setPreferredLogicalWidthsDirty(false);
    }

    return usedWidth;
}
Пример #3
0
int FixedTableLayout::calcWidthArray(int)
{
    int usedWidth = 0;

    // iterate over all <col> elements
    unsigned nEffCols = m_table->numEffCols();
    m_width.resize(nEffCols);
    m_width.fill(Length(Auto));

    unsigned currentEffectiveColumn = 0;
    for (RenderTableCol* col = m_table->firstColumn(); col; col = col->nextColumn()) {
        col->computePreferredLogicalWidths();

        // Width specified by column-groups that have column child does not affect column width in fixed layout tables
        if (col->isTableColumnGroupWithColumnChildren())
            continue;

        Length colStyleLogicalWidth = col->style()->logicalWidth();
        int effectiveColWidth = 0;
        if (colStyleLogicalWidth.isFixed() && colStyleLogicalWidth.value() > 0)
            effectiveColWidth = colStyleLogicalWidth.value();

        unsigned span = col->span();
        while (span) {
            unsigned spanInCurrentEffectiveColumn;
            if (currentEffectiveColumn >= nEffCols) {
                m_table->appendColumn(span);
                nEffCols++;
                m_width.append(Length());
                spanInCurrentEffectiveColumn = span;
            } else {
                if (span < m_table->spanOfEffCol(currentEffectiveColumn)) {
                    m_table->splitColumn(currentEffectiveColumn, span);
                    nEffCols++;
                    m_width.append(Length());
                }
                spanInCurrentEffectiveColumn = m_table->spanOfEffCol(currentEffectiveColumn);
            }
            if ((colStyleLogicalWidth.isFixed() || colStyleLogicalWidth.isPercent()) && colStyleLogicalWidth.isPositive()) {
                m_width[currentEffectiveColumn] = colStyleLogicalWidth;
                m_width[currentEffectiveColumn] *= spanInCurrentEffectiveColumn;
                usedWidth += effectiveColWidth * spanInCurrentEffectiveColumn;
            }
            span -= spanInCurrentEffectiveColumn;
            currentEffectiveColumn++;
        }
    }

    // Iterate over the first row in case some are unspecified.
    RenderTableSection* section = m_table->topNonEmptySection();
    if (!section)
        return usedWidth;

    unsigned currentColumn = 0;

    RenderObject* firstRow = section->firstChild();
    for (RenderObject* child = firstRow->firstChild(); child; child = child->nextSibling()) {
        if (!child->isTableCell())
            continue;

        RenderTableCell* cell = toRenderTableCell(child);
        if (cell->preferredLogicalWidthsDirty())
            cell->computePreferredLogicalWidths();

        Length logicalWidth = cell->styleOrColLogicalWidth();
        unsigned span = cell->colSpan();
        int fixedBorderBoxLogicalWidth = 0;
        if (logicalWidth.isFixed() && logicalWidth.isPositive()) {
            fixedBorderBoxLogicalWidth = cell->adjustBorderBoxLogicalWidthForBoxSizing(logicalWidth.value());
            logicalWidth.setValue(fixedBorderBoxLogicalWidth);
        }

        unsigned usedSpan = 0;
        while (usedSpan < span && currentColumn < nEffCols) {
            float eSpan = m_table->spanOfEffCol(currentColumn);
            // Only set if no col element has already set it.
            if (m_width[currentColumn].isAuto() && logicalWidth.type() != Auto) {
                m_width[currentColumn] = logicalWidth;
                m_width[currentColumn] *= eSpan / span;
                usedWidth += fixedBorderBoxLogicalWidth * eSpan / span;
            }
            usedSpan += eSpan;
            ++currentColumn;
        }
    }

    return usedWidth;
}
Пример #4
0
int FixedTableLayout::calcWidthArray()
{
    int usedWidth = 0;

    // iterate over all <col> elements
    RenderObject *child = table->firstChild();
    int cCol = 0;
    int nEffCols = table->numEffCols();
    width.resize( nEffCols );
    width.fill( Length( Variable ) );

#ifdef DEBUG_LAYOUT
    qDebug("FixedTableLayout::calcWidthArray()" );
    qDebug("    col elements:");
#endif

    Length grpWidth;
    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.isVariable() )
		    w = grpWidth;
		int effWidth = 0;
		if ( w.isFixed() && w.value() > 0 ) {
                    effWidth = w.value();
		    effWidth = KMIN( effWidth, 32760 );
		}
#ifdef DEBUG_LAYOUT
		qDebug("    col element: effCol=%d, span=%d: %d w=%d type=%d",
                       cCol, span, effWidth,  w.value(), w.type());
#endif
		int usedSpan = 0;
		int i = 0;
		while ( usedSpan < span ) {
		    if( cCol + i >= nEffCols ) {
			table->appendColumn( span - usedSpan );
			nEffCols++;
			width.resize( nEffCols );
			width[nEffCols-1] = Length();
		    }
		    int eSpan = table->spanOfEffCol( cCol+i );
		    if ( (w.isFixed() || w.isPercent()) && w.value() > 0 ) {
			width[cCol+i] = Length( w.value() * eSpan, w.type() );
			usedWidth += effWidth * eSpan;
#ifdef DEBUG_LAYOUT
			qDebug("    setting effCol %d (span=%d) to width %d(type=%d)",
                               cCol+i, eSpan, width[cCol+i].value(), width[cCol+i].type() );
#endif
		    }
		    usedSpan += eSpan;
		    i++;
		}
		cCol += i;
	    }
	} else {
	    break;
	}

	RenderObject *next = child->firstChild();
	if ( !next )
	    next = child->nextSibling();
	if ( !next && child->parent()->isTableCol() ) {
	    next = child->parent()->nextSibling();
	    grpWidth = Length();
	}
	child = next;
    }

#ifdef DEBUG_LAYOUT
    qDebug("    first row:");
#endif
    // iterate over the first row in case some are unspecified.
    RenderTableSection *section = table->head;
    if ( !section )
	section = table->firstBody;
    if ( !section )
	section = table->foot;
    if ( section && section->firstChild() ) {
	cCol = 0;
	// get the first cell in the first row
	child = section->firstChild()->firstChild();
	while ( child ) {
	    if ( child->isTableCell() ) {
		RenderTableCell *cell = static_cast<RenderTableCell *>(child);
		Length w = cell->styleOrColWidth();
		int span = cell->colSpan();
		int effWidth = 0;
		if ( (w.isFixed() || w.isPercent()) && w.value() > 0 ) {
                    effWidth = w.value();
		    effWidth = kMin( effWidth, 32760 );
		}
#ifdef DEBUG_LAYOUT
		qDebug("    table cell: effCol=%d, span=%d: %d",  cCol, span, effWidth);
#endif
		int usedSpan = 0;
		int i = 0;
		while ( usedSpan < span ) {
		    Q_ASSERT( cCol + i < nEffCols );
		    int eSpan = table->spanOfEffCol( cCol+i );
		    // only set if no col element has already set it.
		    if ( width[cCol+i].isVariable() && !w.isVariable() ) {
			width[cCol+i] = Length( w.value()*eSpan, w.type() );
			usedWidth += effWidth*eSpan;
#ifdef DEBUG_LAYOUT
			qDebug("    setting effCol %d (span=%d) to width %d(type=%d)",
                               cCol+i, eSpan, width[cCol+i].value(), width[cCol+i].type() );
#endif
		    }
#ifdef DEBUG_LAYOUT
		    else {
			qDebug("    width of col %d already defined (span=%d)", cCol, table->spanOfEffCol( cCol ) );
		    }
#endif
		    usedSpan += eSpan;
		    i++;
		}
		cCol += i;
	    } else {
		Q_ASSERT( false );
	    }
	    child = child->nextSibling();
	}
    }

    return usedWidth;

}
Пример #5
0
int FixedTableLayout::calcWidthArray(int)
{
    int usedWidth = 0;

    // iterate over all <col> elements
    RenderObject* child = m_table->firstChild();
    int nEffCols = m_table->numEffCols();
    m_width.resize(nEffCols);
    m_width.fill(Length(Auto));

    int currentEffectiveColumn = 0;
    Length grpWidth;
    while (child && child->isTableCol()) {
        RenderTableCol* col = toRenderTableCol(child);
        if (col->firstChild())
            grpWidth = col->style()->logicalWidth();
        else {
            Length w = col->style()->logicalWidth();
            if (w.isAuto())
                w = grpWidth;
            int effWidth = 0;
            if (w.isFixed() && w.value() > 0)
                effWidth = w.value();

            int span = col->span();
            while (span) {
                int spanInCurrentEffectiveColumn;
                if (currentEffectiveColumn >= nEffCols) {
                    m_table->appendColumn(span);
                    nEffCols++;
                    m_width.append(Length());
                    spanInCurrentEffectiveColumn = span;
                } else {
                    if (span < m_table->spanOfEffCol(currentEffectiveColumn)) {
                        m_table->splitColumn(currentEffectiveColumn, span);
                        nEffCols++;
                        m_width.append(Length());
                    }
                    spanInCurrentEffectiveColumn = m_table->spanOfEffCol(currentEffectiveColumn);
                }
                if ((w.isFixed() || w.isPercent()) && w.isPositive()) {
                    m_width[currentEffectiveColumn] = w;
                    m_width[currentEffectiveColumn] *= spanInCurrentEffectiveColumn;
                    usedWidth += effWidth * spanInCurrentEffectiveColumn;
                }
                span -= spanInCurrentEffectiveColumn;
                currentEffectiveColumn++;
            }
        }
        col->computePreferredLogicalWidths();

        RenderObject* next = child->firstChild();
        if (!next)
            next = child->nextSibling();
        if (!next && child->parent()->isTableCol()) {
            next = child->parent()->nextSibling();
            grpWidth = Length();
        }
        child = next;
    }

    // Iterate over the first row in case some are unspecified.
    RenderTableSection* section = m_table->topNonEmptySection();
    if (section) {
        int cCol = 0;
        RenderObject* firstRow = section->firstChild();
        child = firstRow->firstChild();
        while (child) {
            if (child->isTableCell()) {
                RenderTableCell* cell = toRenderTableCell(child);
                if (cell->preferredLogicalWidthsDirty())
                    cell->computePreferredLogicalWidths();

                Length w = cell->styleOrColLogicalWidth();
                int span = cell->colSpan();
                int effWidth = 0;
                if (w.isFixed() && w.isPositive())
                    effWidth = w.value();

                int usedSpan = 0;
                int i = 0;
                while (usedSpan < span && cCol + i < nEffCols) {
                    float eSpan = m_table->spanOfEffCol(cCol + i);
                    // Only set if no col element has already set it.
                    if (m_width[cCol + i].isAuto() && w.type() != Auto) {
                        m_width[cCol + i] = w;
                        m_width[cCol + i] *= eSpan / span;
                        usedWidth += effWidth * eSpan / span;
                    }
                    usedSpan += eSpan;
                    i++;
                }
                cCol += i;
            }
            child = child->nextSibling();
        }
    }

    return usedWidth;
}
int FixedTableLayout::calcWidthArray(int tableWidth)
{
    int usedWidth = 0;

    // iterate over all <col> elements
    RenderObject* child = m_table->firstChild();
    int cCol = 0;
    int nEffCols = m_table->numEffCols();
    m_width.resize(nEffCols);
    m_width.fill(Length(Auto));

    Length grpWidth;
    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;
                int effWidth = 0;
                if (w.isFixed() && w.value() > 0)
                    effWidth = w.value();
                
                int usedSpan = 0;
                int i = 0;
                while (usedSpan < span) {
                    if(cCol + i >= nEffCols) {
                        m_table->appendColumn(span - usedSpan);
                        nEffCols++;
                        m_width.resize(nEffCols);
                        m_width[nEffCols-1] = Length();
                    }
                    int eSpan = m_table->spanOfEffCol(cCol+i);
                    if ((w.isFixed() || w.isPercent()) && w.isPositive()) {
                        m_width[cCol + i].setRawValue(w.type(), w.rawValue() * eSpan);
                        usedWidth += effWidth * eSpan;
                    }
                    usedSpan += eSpan;
                    i++;
                }
                cCol += i;
            }
        } else
            break;

        RenderObject *next = child->firstChild();
        if (!next)
            next = child->nextSibling();
        if (!next && child->parent()->isTableCol()) {
            next = child->parent()->nextSibling();
            grpWidth = Length();
        }
        child = next;
    }

    // Iterate over the first row in case some are unspecified.
    RenderTableSection* section = m_table->header();
    if (!section)
        section = m_table->firstBody();
    if (!section)
        section = m_table->footer();
    if (section && !section->numRows())
        section = m_table->sectionBelow(section, true);
    if (section) {
        cCol = 0;
        RenderObject* firstRow = section->firstChild();
        child = firstRow->firstChild();
        while (child) {
            if (child->isTableCell()) {
                RenderTableCell* cell = static_cast<RenderTableCell*>(child);
                if (cell->prefWidthsDirty())
                    cell->calcPrefWidths();

                Length w = cell->styleOrColWidth();
                int span = cell->colSpan();
                int effWidth = 0;
                if (w.isFixed() && w.isPositive())
                    effWidth = w.value();
                
                int usedSpan = 0;
                int i = 0;
                while (usedSpan < span) {
                    ASSERT(cCol + i < nEffCols);
                    int eSpan = m_table->spanOfEffCol(cCol + i);
                    // Only set if no col element has already set it.
                    if (m_width[cCol + i].isAuto() && w.type() != Auto) {
                        m_width[cCol + i].setRawValue(w.type(), w.rawValue() * eSpan / span);
                        usedWidth += effWidth * eSpan / span;
                    }
                    usedSpan += eSpan;
                    i++;
                }
                cCol += i;
            }
            child = child->nextSibling();
        }
    }

    return usedWidth;
}