📄 render_table.cpp
字号:
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: default: 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: percent->fixed->relative->variable */ toAdd = distributeWidth(toAdd,Percent,numPercent); toAdd = distributeWidth(toAdd,Fixed,numFixed); 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); toAdd = distributeRest(toAdd,Fixed,maxFixed); /* * 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 << " colpos = " << columnPos[totalCols] << endl;#endif}int RenderTable::distributeWidth(int distrib, LengthType type, int typeCols ){ int olddis=0; int c=0; int tdis = distrib;#ifdef TABLE_DEBUG kdDebug( 6040 ) << "DISTRIBUTING " << distrib << " pixels to type " << type << " cols" << endl;#endif while(tdis>0) { if (colType[c]==type) { int delta = KMIN(distrib/typeCols,colMaxWidth[c]-actColWidth[c]); delta = KMIN(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;#ifdef TABLE_DEBUG kdDebug( 6040 ) << "DISTRIBUTING rest, " << distrib << " pixels to type " << type << " cols" << endl;#endif int olddis=0; int c=0; int tdis = distrib; while(tdis>0) { if (colType[c]==type) { int delta = (colMaxWidth[c] * distrib) / divider; delta=KMIN(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->baselinePosition(); 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];}void RenderTable::layout(){ recalcCells();//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->setPos(m_height, tCaption->marginLeft()); tCaption->layout(); m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom(); } // layout rows layoutRows(m_height); m_height += rowHeights[totalRows]; m_height += borderBottom(); if(tCaption && tCaption->style()->captionSide()==CAPBOTTOM) { tCaption->setPos(tCaption->marginLeft(), m_height); 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; // table can be containing block of positioned elements. layoutSpecialObjects(); setLayouted();}void RenderTable::layoutRows(int yoff){ int rHeight; int indx, rindx; for ( unsigned int r = 0; r < totalRows; 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; cell->calcVerticalMargins(); cell->layout(); cell->setCellTopExtra(0); cell->setCellBottomExtra(0); } calcRowHeight(r); } // html tables with percent height are relative to view 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 { // check we or not inside a table RenderObject* ro = parent(); for (; ro && !ro->isTableCell(); ro=ro->parent()); if (!ro) { th = h.width(viewRect().height())-5; // not really, but this way the view height change // gets propagated correctly setContainsPositioned(true); } } } if (th && totalRows && rowHeights[totalRows]) { th-=(totalRows+1)*spacing; int dh = th-rowHeights[totalRows]; if (dh>0) { int tot=rowHeights[totalRows]; int add=0; int prev=rowHeights[0]; for ( unsigned int r = 0; r < totalRows; r++ ) { //weight with the original height add+=dh*(rowHeights[r+1]-prev)/tot; prev=rowHeights[r+1]; rowHeights[r+1]+=add; } rowHeights[totalRows]=th; } } for ( unsigned int r = 0; r < totalRows; 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-cell->colSpan()+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->baselinePosition() ; break; case TOP: te = 0; break; case MIDDLE: te = (rHeight - cell->height())/2; break; case BOTTOM: te = rHeight - cell->height(); break; default: break; } #ifdef DEBUG_LAYOUT kdDebug( 6040 ) << "CELL te=" << te << ", be=" << rHeight - cell->height() - te << ", rHeight=" << rHeight << ", valign=" << va << endl; #endif cell->setCellTopExtra( te ); cell->setCellBottomExtra( rHeight - cell->height() - te); if (style()->direction()==RTL) { cell->setPos( columnPos[(int)totalCols] - columnPos[(int)(indx+cell->colSpan())] + borderLeft(), rowHeights[rindx]+yoff ); } else cell->setPos( columnPos[indx] + borderLeft(), rowHeights[rindx]+yoff ); cell->setRowHeight(rHeight); // ### // cell->setHeight(cellHeight); } }}void RenderTable::setCellWidths(){#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << renderName() << "(Table, this=0x" << this << ")::setCellWidths()" << endl;#endif int indx; FOR_EACH_CELL( r, c, cell) { if ( ( indx = c-cell->colSpan()+1) < 0 ) indx = 0; int w = columnPos[c+1] - columnPos[ indx ] - spacing ; //- padding*2;#ifdef TABLE_DEBUG kdDebug( 6040 ) << "0x" << this << ": setting width " << r << "/" << indx << "-" << c << " (0x" << cell << "): " << w << " " << endl;#endif if (cell->width() != w) cell->setLayouted(false); cell->setWidth( w ); } END_FOR_EACH}void RenderTable::print( QPainter *p, int _x, int _y, int _w, int _h, int _tx, int _ty){// if(!layouted()) return; _tx += xPos(); _ty += yPos();#ifdef TABLE_PRINT kdDebug( 6040 ) << "RenderTable::print() w/h = (" << width() << "/" << height() << ")" << endl;#endif if (!containsPositioned() && !isRelPositioned() && !isPositioned()) { if((_ty > _y + _h) || (_ty + height() < _y)) return; if((_tx > _x + _w) || (_tx + width() < _x)) return; }#ifdef TABLE_PRINT kdDebug( 6040 ) << "RenderTable::print(2) " << _tx << "/" << _ty << " (" << _x << "/" << _y << ")" << endl;#endif if(isVisible()) printBoxDecorations(p, _x, _y, _w, _h, _tx, _ty); if ( tCaption ) tCaption->print( p, _x, _y, _w, _h, _tx, _ty ); // draw the cells FOR_EACH_CELL(r, c, cell) {#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << "printing cell " << r << "/" << c << endl;#endif cell->print( p, _x, _y, _w, _h, _tx, _ty); } END_FOR_EACH if ( specialObjects ) printSpecialObjects( p, _x, _y, _w, _h, _tx, _ty);#ifdef BOX_DEBUG outlineBox(p, _tx, _ty, "blue");#endif}void RenderTable::calcMinMaxWidth(){ recalcCells();#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << renderName() << "(Table)::calcMinMaxWidth() known=" << minMaxKnown() << endl;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -