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

📄 table_layout.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		if ( cell == (RenderTableCell *)-1 )		    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 = QMAX(l.minWidth, 1);                    l.maxWidth = QMAX(l.maxWidth, 1);		    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();		    if ( w.value > 32760 )			w.value = 32760;		    if ( w.value < 0 )			w.value = 0;		    switch( w.type ) {		    case Fixed:			// ignore width=0			if ( w.value > 0 && (int)l.width.type != Percent ) {                            int wval = w.value + (cell->paddingLeft()+cell->paddingRight());			    if ( l.width.type == Fixed ) {                                // Nav/IE weirdness				if ((wval > l.width.value) ||				    ((l.width.value == wval) && (maxContributor == cell))) {				    l.width.value = wval;				    fixedContributor = cell;				}			    } else {                                l.width.type = Fixed;				l.width.value = wval;				fixedContributor = cell;			    }			}			break;		    case Percent:                        hasPercent = true;                        if ( w.value > 0 && (l.width.type != Percent || w.value > l.width.value ) )                            l.width = w;			break;		    case Relative:			if ( w.type == Variable || (w.type == Relative && 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 = QMAX(l.minWidth, 1);                        l.maxWidth = QMAX(l.maxWidth, 1);			insertSpanCell( cell );                    }		    last = cell;		}	    }	}	child = child->nextSibling();    }    // Nav/IE weirdness    if ( l.width.type == Fixed ) {	if ( table->style()->htmlHacks()	     && (l.maxWidth > l.width.value) && (fixedContributor != maxContributor)) {	    l.width = Length();	    fixedContributor = 0;	}    }    l.maxWidth = kMax(l.maxWidth, 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.type == Fixed && w.value == 0) ||		     (w.type == Percent && 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 ( (int)w.type != Variable && 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.type == Percent ) {            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 = maxWidth;    table->m_minWidth = minWidth;#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->hBorderSpacing();#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.type == Relative) && 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 behaviour anyway. mozilla doesn't do this so I decided we don't neither.                    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.type != Percent) {                    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.type == Percent ) {	    if ( totalPercent > w.value || allColsArePercent ) {		// can't satify this condition, treat as variable		w = Length();	    } else {		int spanMax = QMAX( maxWidth, cMaxWidth );#ifdef DEBUG_LAYOUT		qDebug("    adjusting tMaxWidth (%d): spanMax=%d, value=%d, totalPercent=%d", tMaxWidth, spanMax, w.value, totalPercent );#endif		tMaxWidth = QMAX( tMaxWidth, spanMax * 100 / w.value );		// all non percent columns in the span get percent vlaues to sum up correctly.		int percentMissing = w.value - totalPercent;		int totalWidth = 0;		for ( unsigned int pos = col; pos < lastCol; pos++ ) {		    if ( !(layoutStruct[pos].width.type == Percent ) )			totalWidth += layoutStruct[pos].effMaxWidth;		}		for ( unsigned int pos = col; pos < lastCol && totalWidth > 0; pos++ ) {		    if ( !(layoutStruct[pos].width.type == Percent ) ) {			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 = QMAX( 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 {#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.type == Fixed && haveVariable && fixedWidth <= cMinWidth ) {			int w = QMAX( 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;                        layoutStruct[pos].effMinWidth = w;                    }		}                for ( unsigned int pos = col; maxw > 0 && pos < lastCol && minw < cMinWidth; pos++ ) {		    if ( !(layoutStruct[pos].width.type == Fixed && haveVariable && fixedWidth <= cMinWidth) ) {

⌨️ 快捷键说明

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