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

📄 table_layout.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		    if ( !cell->minMaxKnown() )			cell->calcMinMaxWidth();		    if ( cell->minWidth() > l.minWidth )			l.minWidth = cell->minWidth();		    if ( cell->maxWidth() > l.maxWidth ) {			l.maxWidth = cell->maxWidth();			maxContributor = cell;		    }		    Length w = cell->style()->width();                    w.l.value = kMin( 32767, kMax( 0, w.value() ) );		    switch( w.type() ) {		    case Fixed:			// ignore width=0			if ( w.value() > 0 && !l.width.isPercent() ) {                            // ### we should use box'es paddings here I guess.                            int wval = w.value() + cell->paddingLeft() + cell->paddingRight();			    if ( l.width.isFixed() ) {                                // Nav/IE weirdness				if ((wval > l.width.value()) ||				    ((l.width.value() == wval) && (maxContributor == cell))) {				    l.width.l.value = wval;				    fixedContributor = cell;				}			    } else {                                l.width = Length( wval, Fixed );				fixedContributor = cell;			    }			}			break;		    case Percent:                        hasPercent = true;                        if ( w.value() > 0 && (!l.width.isPercent() || w.value() > l.width.value() ) )                            l.width = w;			break;		    case Relative:			if ( w.isVariable() || (w.isRelative() && w.value() > l.width.value() ) )				l.width = w;		    default:			break;		    }		} else {		    if ( cell && (!effCol || section->cellAt( i, effCol-1 ) != 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 = kMax(int( l.minWidth ), 1);                        l.maxWidth = kMax(int( l.maxWidth ), 1);			insertSpanCell( cell );		    }		    last = cell;		}	    }	}	child = child->nextSibling();    }    // Nav/IE weirdness    if ( l.width.isFixed() ) {	if ( table->style()->htmlHacks()	     && (l.maxWidth > l.width.value()) && (fixedContributor != maxContributor)) {	    l.width = Length();	    fixedContributor = 0;	}    }    l.maxWidth = kMax(l.maxWidth, int(l.minWidth));#ifdef DEBUG_LAYOUT    qDebug("col %d, final min=%d, max=%d, width=%d(%d)", effCol, l.minWidth, l.maxWidth, l.width.value(),  l.width.type() );#endif    // ### we need to add col elements aswell}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 );}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.isVariable() || tw.isPercent()) && !table->isPositioned()) {            RenderBlock* cb = table->containingBlock();            while (cb && !cb->isCanvas() && !cb->isTableCell() &&                cb->style()->width().isVariable() && !cb->isPositioned())                cb = cb->containingBlock();            table = 0;            if (cb && cb->isTableCell() &&                (cb->style()->width().isVariable() || cb->style()->width().isPercent())) {                if (tw.isPercent())                    scale = false;                else {                    RenderTableCell* cell = static_cast<RenderTableCell*>(cb);                    if (cell->colSpan() > 1 || cell->table()->style()->width().isVariable())                        scale = false;                    else                        table = cell->table();                }            }        }        else            table = 0;    }    return scale;}void AutoTableLayout::calcMinMaxWidth(){#ifdef DEBUG_LAYOUT    qDebug("AutoTableLayout::calcMinMaxWidth");#endif    fullRecalc();    int spanMaxWidth = calcEffectiveWidth();    int minWidth = 0;    int maxWidth = 0;    int maxPercent = 0;    int maxNonPercent = 0;    int remainingPercent = 100;    for ( unsigned int i = 0; i < layoutStruct.size(); i++ ) {	minWidth += layoutStruct[i].effMinWidth;	maxWidth += layoutStruct[i].effMaxWidth;	if ( layoutStruct[i].effWidth.isPercent() ) {            int percent = kMin(layoutStruct[i].effWidth.value(), remainingPercent);            int pw = ( layoutStruct[i].effMaxWidth * 100) / kMax(percent, 1);            remainingPercent -= percent;	    maxPercent = kMax( pw,  maxPercent );	} else {	    maxNonPercent += layoutStruct[i].effMaxWidth;	}    }    if (shouldScaleColumns(table)) {        maxNonPercent = (maxNonPercent * 100 + 50) / kMax(remainingPercent, 1);	maxWidth = kMax( maxNonPercent, maxWidth );	maxWidth = kMax( maxWidth, maxPercent );    }    maxWidth = kMax( maxWidth, spanMaxWidth );    int bs = table->bordersPaddingAndSpacing();    minWidth += bs;    maxWidth += bs;    Length tw = table->style()->width();    if ( tw.isFixed() && tw.value() > 0 ) {	minWidth = kMax( minWidth, int( tw.value() ) );	maxWidth = minWidth;    }    table->m_maxWidth = kMin(maxWidth, 0x7fff);    table->m_minWidth = kMin(minWidth, 0x7fff);#ifdef DEBUG_LAYOUT    qDebug("    minWidth=%d, maxWidth=%d", table->m_minWidth, table->m_maxWidth );#endif}/*  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(){    int tMaxWidth = 0;    unsigned int nEffCols = layoutStruct.size();    int hspacing = table->borderHSpacing();#ifdef DEBUG_LAYOUT    qDebug("AutoTableLayout::calcEffectiveWidth for %d cols", nEffCols );#endif    for ( unsigned int i = 0; i < nEffCols; i++ ) {	layoutStruct[i].effWidth = layoutStruct[i].width;	layoutStruct[i].effMinWidth = layoutStruct[i].minWidth;	layoutStruct[i].effMaxWidth = layoutStruct[i].maxWidth;    }    for ( unsigned int i = 0; i < spanCells.size(); i++ ) {	RenderTableCell *cell = spanCells[i];	if ( !cell || cell == (RenderTableCell *)-1 )	    break;	int span = cell->colSpan();	Length w = cell->style()->width();	if ( !w.isRelative() && w.value() == 0 )	    w = Length(); // make it Variable	int col = table->colToEffCol( cell->col() );	unsigned int lastCol = col;	int cMinWidth = cell->minWidth() + hspacing;	int cMaxWidth = cell->maxWidth() + hspacing;	int totalPercent = 0;	int minWidth = 0;	int maxWidth = 0;	bool allColsArePercent = true;	bool allColsAreFixed = true;	bool haveVariable = false;	int fixedWidth = 0;#ifdef DEBUG_LAYOUT	int cSpan = span;#endif	while ( lastCol < nEffCols && span > 0 ) {	    switch( layoutStruct[lastCol].width.type() ) {	    case Percent:		totalPercent += layoutStruct[lastCol].width.value();		allColsAreFixed = false;		break;	    case Fixed:                if (layoutStruct[lastCol].width.value() > 0) {                    fixedWidth += layoutStruct[lastCol].width.value();                    allColsArePercent = false;                    // IE resets effWidth to Variable here, but this breaks the konqueror about page and seems to be some bad                    // legacy behavior anyway. mozilla doesn't do this so I decided we don't either.                    break;                }                // fall through	    case Variable:		haveVariable = 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 (!layoutStruct[lastCol].effWidth.isPercent()) {                    layoutStruct[lastCol].effWidth = Length();                    allColsArePercent = false;                }                else                    totalPercent += layoutStruct[lastCol].effWidth.value();                allColsAreFixed = false;            }            span -= table->spanOfEffCol( lastCol );	    minWidth += layoutStruct[lastCol].effMinWidth;	    maxWidth += layoutStruct[lastCol].effMaxWidth;	    lastCol++;	    cMinWidth -= hspacing;	    cMaxWidth -= hspacing;	}#ifdef DEBUG_LAYOUT	qDebug("    colspan cell %p at effCol %d, span %d, type %d, value %d cmin=%d min=%d fixedwidth=%d", cell, col, cSpan, w.type(), w.value(), cMinWidth, minWidth, fixedWidth );#endif	// adjust table max width if needed	if ( w.isPercent() ) {	    if ( totalPercent > w.value() || allColsArePercent ) {		// can't satify this condition, treat as variable		w = Length();	    } else {		int spanMax = kMax( maxWidth, cMaxWidth );#ifdef DEBUG_LAYOUT		qDebug("    adjusting tMaxWidth (%d): spanMax=%d, value=%d, totalPercent=%d", tMaxWidth, spanMax, w.value(), totalPercent );#endif		tMaxWidth = kMax( tMaxWidth, spanMax * 100 / w.value() );		// all non percent columns in the span get percent values to sum up correctly.		int percentMissing = w.value() - totalPercent;		int totalWidth = 0;		for ( unsigned int pos = col; pos < lastCol; pos++ ) {		    if ( !(layoutStruct[pos].width.isPercent() ) )			totalWidth += layoutStruct[pos].effMaxWidth;		}		for ( unsigned int pos = col; pos < lastCol && totalWidth > 0; pos++ ) {		    if ( !(layoutStruct[pos].width.isPercent() ) ) {			int percent = percentMissing * layoutStruct[pos].effMaxWidth / totalWidth;#ifdef DEBUG_LAYOUT			qDebug("   col %d: setting percent value %d effMaxWidth=%d totalWidth=%d", pos, percent, layoutStruct[pos].effMaxWidth, totalWidth );#endif			totalWidth -= layoutStruct[pos].effMaxWidth;			percentMissing -= percent;			if ( percent > 0 )			    layoutStruct[pos].effWidth = Length( percent, Percent );			else			    layoutStruct[pos].effWidth = Length();		    }		}	    }	}	// make sure minWidth and maxWidth of the spanning cell are honoured	if ( cMinWidth > minWidth ) {	    if ( allColsAreFixed ) {#ifdef DEBUG_LAYOUT		qDebug("extending minWidth of cols %d-%d to %dpx currentMin=%d accroding to fixed sum %d", col, lastCol-1, cMinWidth, minWidth, fixedWidth );#endif		for ( unsigned int pos = col; fixedWidth > 0 && pos < lastCol; pos++ ) {		    int w = kMax( int( layoutStruct[pos].effMinWidth ), cMinWidth * layoutStruct[pos].width.value() / fixedWidth );#ifdef DEBUG_LAYOUT		    qDebug("   col %d: min=%d, effMin=%d, new=%d", pos, layoutStruct[pos].effMinWidth, layoutStruct[pos].effMinWidth, w );#endif		    fixedWidth -= layoutStruct[pos].width.value();		    cMinWidth -= w;		    layoutStruct[pos].effMinWidth = w;		}            } else if ( allColsArePercent ) {                int maxw = maxWidth;                int minw = minWidth;                int cminw = cMinWidth;                for ( unsigned int pos = col; maxw > 0 && pos < lastCol; pos++ ) {                    if ( layoutStruct[pos].effWidth.isPercent() && layoutStruct[pos].effWidth.value()>0 && fixedWidth <= cMinWidth) {                        int w = layoutStruct[pos].effMinWidth;                        w = kMax( w, cminw*layoutStruct[pos].effWidth.value()/totalPercent );                        w = kMin(layoutStruct[pos].effMinWidth+(cMinWidth-minw), w);#ifdef DEBUG_LAYOUT                        qDebug("   col %d: min=%d, effMin=%d, new=%d", pos, layoutStruct[pos].effMinWidth, layoutStruct[pos].effMinWidth, w#endif                        maxw -= layoutStruct[pos].effMaxWidth;                        minw -= layoutStruct[pos].effMinWidth;                        cMinWidth -= w;                        layoutStruct[pos].effMinWidth = w;                    }                }	    } else {#ifdef DEBUG_LAYOUT		qDebug("extending minWidth of cols %d-%d to %dpx currentMin=%d", col, lastCol-1, cMinWidth, minWidth );#endif		int 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 ( layoutStruct[pos].width.isFixed() && haveVariable && fixedWidth <= cMinWidth ) {			int w = kMax( int( layoutStruct[pos].effMinWidth ), layoutStruct[pos].width.value() );			fixedWidth -= layoutStruct[pos].width.value();                        minw -= layoutStruct[pos].effMinWidth;#ifdef DEBUG_LAYOUT			qDebug("   col %d: min=%d, effMin=%d, new=%d", pos, layoutStruct[pos].effMinWidth, layoutStruct[pos].effMinWidth, w );#endif			maxw -= layoutStruct[pos].effMaxWidth;			cMinWidth -= w;

⌨️ 快捷键说明

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