📄 render_table.cpp
字号:
} m_width = QMAX (m_width, m_minWidth); // PHASE 4, calculate maximums for percent and relative columns for ( unsigned int s=0; (int)s<maxColSpan ; ++s) { ColInfoLine* spanCols = colInfos[s]; for ( unsigned int c=0; c<totalCols-s; ++c) { ColInfo* col; col = spanCols->at(c); if (!col || col->span==0) continue; if (col->type==Fixed || col->type==Variable) continue; calcFinalColMax(c, col); } } // PHASE 5, set table min and max to final values if(m_style->width().type == Fixed) { m_minWidth = m_maxWidth = m_width; } else if(m_style->width().type == Variable && hasPercent) { int tot = QMIN(99,totalPercent); int mx; if (hasFixed) mx = (maxFixed + minVar + minRel) * 100 /(100 - tot); else mx = (minVar + minRel)*100/(100-tot); if (mx>0) m_maxWidth=mx; } if (m_style->width().type == Percent) { if (realMaxWidth > m_maxWidth) m_maxWidth = realMaxWidth; } m_minWidth += borderLeft() + borderRight(); m_maxWidth += borderLeft() + borderRight(); m_width += borderLeft() + borderRight();/* kdDebug( 6040 ) << "TABLE width=" << m_width << " TABLE m_minWidth=" << m_minWidth << " TABLE m_maxWidth=" << m_maxWidth << endl;*/// setMinMaxKnown(true); int cw = containingBlockWidth(); m_marginRight=0; m_marginLeft=0; calcHorizontalMargins(ml,mr,cw);}void RenderTable::calcWidth(){ Length ml = m_style->marginLeft(); Length mr = m_style->marginRight(); int cw = containingBlockWidth(); m_marginLeft = ml.minWidth(cw); m_marginRight = mr.minWidth(cw);}void RenderTable::calcColWidth(void){#ifdef TABLE_DEBUG kdDebug( 6040 ) << "START calcColWidth() this = " << this << endl; kdDebug( 6040 ) << "---- " << totalColInfos << " ----" << endl; kdDebug( 6040 ) << "maxColSpan = " << maxColSpan << endl;#endif if (totalCols==0) return; /* * Calculate min and max width for every column, * and the width of the table */ calcColMinMax(); /* * Set actColWidth[] to column minimums, it will * grow from there. * Collect same statistics for future use. */ int actWidth = spacing + borderLeft() + borderRight(); int minFixed = 0; int minPercent = 0; int minRel = 0; int minVar = 0; int maxFixed = 0; int maxPercent = 0; int maxRel = 0; int maxVar = 0; int numFixed = 0; int numPercent = 0; int numRel = 0; int numVar = 0; actColWidth.fill(0); unsigned int i; for(i = 0; i < totalCols; i++) { actColWidth[i] = colMinWidth[i]; actWidth += actColWidth[i] + spacing; switch(colType[i]) { case Fixed: minFixed += colMinWidth[i]; maxFixed += colMaxWidth[i]; numFixed++; break; case Percent: minPercent += colMinWidth[i]; maxPercent += colMaxWidth[i]; numPercent++; break; case Relative: minRel += colMinWidth[i]; maxRel += colMaxWidth[i]; numRel++; break; case Undefined: case Variable: minVar += colMinWidth[i]; maxVar += colMaxWidth[i]; numVar++; } }#ifdef TABLE_DEBUG for(int i = 1; i <= (int)totalCols; i++) { kdDebug( 6040 ) << "Start->target " << i << ": " << actColWidth[i-1] << "->" << colMaxWidth[i-1] << endl; }#endif int toAdd = m_width - actWidth; // what we can add#ifdef TABLE_DEBUG kdDebug( 6040 ) << "toAdd = width - actwidth: " << toAdd << " = " << m_width << " - " << actWidth << endl;#endif /* * distribute the free width among the columns so that * they reach their max width. * Order: fixed->percent->relative->variable */ toAdd = distributeWidth(toAdd,Fixed,numFixed); toAdd = distributeWidth(toAdd,Percent,numPercent); toAdd = distributeWidth(toAdd,Relative,numRel); toAdd = distributeWidth(toAdd,Variable,numVar); /* * Some width still left? * Reverse order, variable->relative->percent */ toAdd = distributeRest(toAdd,Variable,maxVar); toAdd = distributeRest(toAdd,Relative,maxRel); toAdd = distributeRest(toAdd,Percent,maxPercent); /* * If something remains, put it to the last column */ actColWidth[totalCols-1] += toAdd; /* * Calculate the placement of colums */ columnPos.fill(0); columnPos[0] = spacing; for(i = 1; i <= totalCols; i++) { columnPos[i] += columnPos[i-1] + actColWidth[i-1] + spacing;#ifdef TABLE_DEBUG kdDebug( 6040 ) << "Actual width col " << i << ": " << actColWidth[i-1] << " pos = " << columnPos[i-1] << endl;#endif }#ifdef TABLE_DEBUG if(m_width != columnPos[totalCols] ) kdDebug( 6040 ) << "========> table layout error!!! <===============================" << endl; kdDebug( 6040 ) << "total width = " << m_width << endl;#endif}int RenderTable::distributeWidth(int distrib, LengthType type, int typeCols ){ int olddis=0; int c=0; int tdis = distrib;// kdDebug( 6040 ) << "DISTRIBUTING " << distrib << " pixels to type " << type << " cols" << endl; while(tdis>0) { if (colType[c]==type) { int delta = QMIN(distrib/typeCols,colMaxWidth[c]-actColWidth[c]); delta = QMIN(tdis,delta); if (delta==0 && tdis && colMaxWidth[c]>actColWidth[c]) delta=1; actColWidth[c]+=delta; tdis-=delta; } if (++c == (int)totalCols) { c=0; if (olddis==tdis) break; olddis=tdis; } } return tdis;}int RenderTable::distributeRest(int distrib, LengthType type, int divider ){ if (!divider) return distrib;// kdDebug( 6040 ) << "DISTRIBUTING rest, " << distrib << " pixels to type " << type << " cols" << endl; int olddis=0; int c=0; int tdis = distrib; while(tdis>0) { if (colType[c]==type) { int delta = (colMaxWidth[c] * distrib) / divider; delta=QMIN(delta,tdis); if (delta==0 && tdis) delta=1; actColWidth[c] += delta; tdis -= delta; } if (++c == (int)totalCols) { c=0; if (olddis==tdis) break; olddis=tdis; } } return tdis;}void RenderTable::calcRowHeight(int r){ unsigned int c; int indx;//, borderExtra = border ? 1 : 0; RenderTableCell *cell; rowHeights.resize( totalRows+1 ); rowBaselines.resize( totalRows ); rowHeights[0] = spacing + borderTop(); //int oldheight = rowHeights[r+1] - rowHeights[r]; rowHeights[r+1] = 0; int baseline=0; int bdesc=0; int ch; for ( c = 0; c < totalCols; c++ ) { if ( ( cell = cells[r][c] ) == 0 ) continue; if ( c < totalCols - 1 && cell == cells[r][c+1] ) continue; if ( r < (int)totalRows - 1 && cells[r+1][c] == cell ) continue; if ( ( indx = r - cell->rowSpan() + 1 ) < 0 ) indx = 0; ch = cell->style()->height().width(0); if ( cell->height() > ch) ch = cell->height(); int rowPos = rowHeights[ indx ] + ch + spacing ; // + padding if ( rowPos > rowHeights[r+1] ) rowHeights[r+1] = rowPos; // find out the baseline EVerticalAlign va = cell->style()->verticalAlign(); if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP || va == SUPER || va == SUB) { int b=cell->baselineOffset(); if (b>baseline) baseline=b; int td = rowHeights[ indx ] + ch - b; if (td>bdesc) bdesc = td; } } //do we have baseline aligned elements? if (baseline) { // increase rowheight if baseline requires int bRowPos = baseline + bdesc + spacing ; // + 2*padding if (rowHeights[r+1]<bRowPos) rowHeights[r+1]=bRowPos; rowBaselines[r]=baseline; } if ( rowHeights[r+1] < rowHeights[r] ) rowHeights[r+1] = rowHeights[r]; // html tables with percent height are relative to view if (r+1 == (int)totalRows) { Length h = style()->height(); int th=0; if (h.isFixed()) th = h.value; else if (h.isPercent()) { Length ch = containingBlock()->style()->height(); RenderObject *containing = containingBlock(); if (ch.isFixed()) th = h.width(ch.value); else if (containing->parent() && containing->parent()->parent() && containing->parent()->parent()->isRoot()) { th = h.width(viewRect().height()); // not really, but this way the view height change // gets propagated correctly setContainsPositioned(true); } } if (rowHeights[r+1]<th) rowHeights[r+1]=th; }}void RenderTable::layout(){//kdDebug( 6040 ) << renderName() << "(Table)"<< this << " ::layout0() width=" << width() << ", layouted=" << layouted() << endl; if (layouted() && !containsPositioned() && _lastParentWidth == containingBlockWidth()) return; _lastParentWidth = containingBlockWidth(); m_height = 0;#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << renderName() << "(Table)::layout1() width=" << width() << ", layouted=" << layouted() << endl;#endif FOR_EACH_CELL( r, c, cell) { cell->calcMinMaxWidth(); } END_FOR_EACH calcColWidth(); setCellWidths(); // ### collapse caption margin, left, right if(tCaption && tCaption->style()->captionSide() != CAPBOTTOM) { tCaption->setYPos(m_height); tCaption->setXPos(tCaption->marginLeft()); tCaption->layout(); m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom(); } // layout rows for ( unsigned int r = 0; r < totalRows; r++ ) { layoutRow(r,m_height); } m_height += rowHeights[totalRows]; m_height += borderBottom(); if(tCaption && tCaption->style()->captionSide()==CAPBOTTOM) { tCaption->setYPos(m_height); tCaption->setXPos(tCaption->marginLeft()); tCaption->layout(); m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom(); } //kdDebug(0) << "table height: " << m_height << endl; calcHeight(); //kdDebug(0) << "table height: " << m_height << endl; setLayouted();}void RenderTable::layoutRow(int r, int yoff){ int rHeight; int indx, rindx; for ( unsigned int c = 0; c < totalCols; c++ ) { RenderTableCell *cell = cells[r][c]; if (!cell) continue; if ( c < totalCols - 1 && cell == cells[r][c+1] ) continue; if ( r < (int)totalRows - 1 && cell == cells[r+1][c] ) continue; cell->layout(); cell->setCellTopExtra(0); cell->setCellBottomExtra(0); } calcRowHeight(r); for ( unsigned int c = 0; c < totalCols; c++ ) { RenderTableCell *cell = cells[r][c]; if (!cell) continue; if ( c < totalCols - 1 && cell == cells[r][c+1] ) continue; if ( r < (int)totalRows - 1 && cell == cells[r+1][c] ) continue; if ( ( indx = c-realSpan(cell)+1 ) < 0 ) indx = 0; if ( ( rindx = r-cell->rowSpan()+1 ) < 0 ) rindx = 0; //kdDebug( 6040 ) << "setting position " << r << "/" << indx << "-" << c << ": " << //columnPos[indx] + padding << "/" << rowHeights[rindx] << " " << endl; rHeight = rowHeights[r+1] - rowHeights[rindx] - spacing; EVerticalAlign va = cell->style()->verticalAlign(); int te=0; switch (va) { case SUB: case SUPER: case TEXT_TOP: case TEXT_BOTTOM: case BASELINE: te = getBaseline(r) - cell->baselineOffset() ; break; case TOP:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -