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

📄 render_table.cpp

📁 最新Nokia手机浏览器全套源代码完美版。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        return 0;
    return cell->section()->cellAt(cell->row(), effCol).cell;
}

RenderBlock* RenderTable::firstLineBlock() const
{
    return 0;
}

void RenderTable::updateFirstLetter()
{}

#ifndef NDEBUG
void RenderTable::dump(QTextStream *stream, QString ind) const
{
    if (tCaption)
  *stream << " tCaption";
    if (head)
  *stream << " head";
    if (foot)
  *stream << " foot";

    //*stream << endl << ind << "cspans:";
    for ( unsigned int i = 0; i < columns.size(); i++ )
  *stream << " " << columns[i].span;
   // *stream << endl << ind;

    RenderBlock::dump(stream,ind);
}
#endif

// --------------------------------------------------------------------------

RenderTableSection::RenderTableSection(DOM::NodeImpl* node)
    : RenderContainer(node)
{
    // init RenderObject attributes
    setInline(false);   // our object is not Inline
    gridRows = 0;
    cCol = 0;
    cRow = -1;
    needCellRecalc = false;
}

RenderTableSection::~RenderTableSection()
{
    clearGrid();
}

void RenderTableSection::detach()
{
    // recalc cell info because RenderTable has unguarded pointers
    // stored that point to this RenderTableSection.
    if (table())
        table()->setNeedSectionRecalc();

    RenderContainer::detach();
}

void RenderTableSection::setStyle(RenderStyle* _style)
{
    // we don't allow changing this one
    if (style())
        _style->setDisplay(style()->display());
    else if (_style->display() != TABLE_FOOTER_GROUP && _style->display() != TABLE_HEADER_GROUP)
        _style->setDisplay(TABLE_ROW_GROUP);

    RenderContainer::setStyle(_style);
}

void RenderTableSection::addChild(RenderObject *child, RenderObject *beforeChild)
{
#ifdef DEBUG_LAYOUT
    kdDebug( 6040 ) << renderName() << "(TableSection)::addChild( " << child->renderName()  << ", beforeChild=" <<
                       (beforeChild ? beforeChild->renderName() : "0") << " )" << endl;
#endif
    RenderObject *row = child;

    if (child->element() && child->element()->id() == ID_FORM) {
        RenderContainer::addChild(child,beforeChild);
        return;
    }

    if ( !child->isTableRow() ) {

        if( !beforeChild )
            beforeChild = lastChild();

        if( beforeChild && beforeChild->isAnonymous() )
            row = beforeChild;
        else {
      RenderObject *lastBox = beforeChild;
      while ( lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableRow() )
    lastBox = lastBox->parent();
      if ( lastBox && lastBox->isAnonymous() ) {
    lastBox->addChild( child, beforeChild );
    return;
      } else {
    //kdDebug( 6040 ) << "creating anonymous table row" << endl;
    row = new (renderArena()) RenderTableRow(document() /* anonymous table */);
    RenderStyle *newStyle = new (renderArena()) RenderStyle();
    newStyle->inheritFrom(style());
    newStyle->setDisplay( TABLE_ROW );
    row->setStyle(newStyle);
    addChild(row, beforeChild);
      }
        }
        row->addChild(child);
        child->setNeedsLayoutAndMinMaxRecalc();
        return;
    }

    if (beforeChild)
  setNeedCellRecalc();

    cRow++;
    cCol = 0;

    ensureRows( cRow+1 );

    if (!beforeChild) {
        grid[cRow].height = child->style()->height();
        if ( grid[cRow].height.type == Relative )
            grid[cRow].height = Length();
    }


    RenderContainer::addChild(child,beforeChild);
}

bool RenderTableSection::ensureRows(int numRows)
{
    int nRows = gridRows;
    if (numRows > nRows) {
        if (numRows > static_cast<int>(grid.size()))
            if (!grid.resize(numRows*2+1))
                return false;

        gridRows = numRows;
        int nCols = table()->numEffCols();
        CellStruct emptyCellStruct;
        emptyCellStruct.cell = 0;
        emptyCellStruct.inColSpan = false;
  for (int r = nRows; r < numRows; r++ ) {
      grid[r].row = new Row(nCols);
      grid[r].row->fill(emptyCellStruct);
      grid[r].baseLine = 0;
      grid[r].height = Length();
  }
    }

    return true;
}

void RenderTableSection::addCell( RenderTableCell *cell )
{
    int rSpan = cell->rowSpan();
    int cSpan = cell->colSpan();
    QMemArray<RenderTable::ColumnStruct> &columns = table()->columns;
    int nCols = columns.size();

    // ### mozilla still seems to do the old HTML way, even for strict DTD
    // (see the annotation on table cell layouting in the CSS specs and the testcase below:
    // <TABLE border>
    // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4
    // <TR><TD colspan="2">5
    // </TABLE>

    while (cCol < nCols && (cellAt(cRow, cCol).cell || cellAt(cRow, cCol).inColSpan))
  cCol++;

    if ( rSpan == 1 ) {
  // we ignore height settings on rowspan cells
  Length height = cell->style()->height();
  if ( height.value > 0 || (height.type == Relative && height.value >= 0) ) {
      Length cRowHeight = grid[cRow].height;
      switch( height.type ) {
      case Percent:
    if ( !(cRowHeight.type == Percent) ||
         ( cRowHeight.type == Percent && cRowHeight.value < height.value ) )
        grid[cRow].height = height;
         break;
      case Fixed:
    if ( cRowHeight.type < Percent ||
         ( cRowHeight.type == Fixed && cRowHeight.value < height.value ) )
        grid[cRow].height = height;
    break;
      case Relative:
#if 0
    // we treat this as variable. This is correct according to HTML4, as it only specifies length for the height.
    if ( cRowHeight.type == Variable ||
         ( cRowHeight.type == Relative && cRowHeight.value < height.value ) )
         grid[cRow].height = height;
         break;
#endif
      default:
    break;
      }
  }
    }

    // make sure we have enough rows
    if (!ensureRows( cRow + rSpan ))
        return;

    int col = cCol;
    // tell the cell where it is
    CellStruct currentCell;
    currentCell.cell = cell;
    currentCell.inColSpan = false;
    while (cSpan) {
  int currentSpan;
  if (cCol >= nCols) {
      table()->appendColumn(cSpan);
      currentSpan = cSpan;
  } else {
      if (cSpan < columns[cCol].span)
    table()->splitColumn(cCol, cSpan);
      currentSpan = columns[cCol].span;
  }

  for (int r = 0; r < rSpan; r++) {
            CellStruct& c = cellAt(cRow + r, cCol);
            if (currentCell.cell && !c.cell)
                c.cell = currentCell.cell;
            if (currentCell.inColSpan)
                c.inColSpan = true;
  }
  cCol++;
  cSpan -= currentSpan;
        currentCell.cell = 0;
  currentCell.inColSpan = true;
    }
    if (cell) {
  cell->setRow(cRow);
  cell->setCol(table()->effColToCol(col));
    }
}



void RenderTableSection::setCellWidths()
{
#ifdef DEBUG_LAYOUT
    kdDebug( 6040 ) << renderName() << "(Table, this=0x" << this << ")::setCellWidths()" << endl;
#endif
    QMemArray<int> &columnPos = table()->columnPos;

    int rows = gridRows;
    for ( int i = 0; i < rows; i++ ) {
  Row &row = *grid[i].row;
  int cols = row.size();
  for ( int j = 0; j < cols; j++ ) {
      CellStruct current = row[j];
            RenderTableCell *cell = current.cell;

      if (!cell)
    continue;
      int endCol = j;
      int cspan = cell->colSpan();
      while (cspan && endCol < cols) {
    cspan -= table()->columns[endCol].span;
    endCol++;
      }
      int w = columnPos[endCol] - columnPos[j] - table()->hBorderSpacing();
#ifdef DEBUG_LAYOUT
      kdDebug( 6040 ) << "setting width of cell " << cell << " " << cell->row() << "/" << cell->col() << " to " << w << " colspan=" << cell->colSpan() << " start=" << j << " end=" << endCol << endl;
#endif
      int oldWidth = cell->width();
      if ( w != oldWidth ) {
    cell->setNeedsLayout(true);
    cell->setWidth( w );
      }
  }
    }
}


void RenderTableSection::calcRowHeight()
{
    int indx;
    RenderTableCell *cell;

    int totalRows = gridRows;
    int spacing = table()->vBorderSpacing();

    rowPos.resize( totalRows + 1 );
    rowPos[0] = spacing;

    for ( int r = 0; r < totalRows; r++ ) {
  rowPos[r+1] = 0;

  int baseline=0;
  int bdesc = 0;
//  qDebug("height of row %d is %d/%d", r, grid[r].height.value, grid[r].height.type );
  int ch = grid[r].height.minWidth( 0 );
  int pos = rowPos[ r+1 ] + ch + spacing;

  if ( pos > rowPos[r+1] )
      rowPos[r+1] = pos;

  Row *row = grid[r].row;
  int totalCols = row->size();
  int totalRows = gridRows;

  for (int c = 0; c < totalCols; c++) {
      CellStruct current = cellAt(r, c);
            cell = current.cell;
      if (!cell || current.inColSpan)
    continue;
      if (r < totalRows - 1 && cellAt(r + 1, c).cell == cell)
    continue;

      if ((indx = r - cell->rowSpan() + 1) < 0)
    indx = 0;

            if (cell->overrideSize() != -1) {
                cell->setOverrideSize(-1);
                cell->setChildNeedsLayout(true, false);
                cell->layoutIfNeeded();
            }

            // Explicit heights use the border box in quirks mode.  In strict mode do the right
            // thing and actually add in the border and padding.
      ch = cell->style()->height().width(0) +
                (cell->style()->htmlHacks() ? 0 : (cell->paddingTop() + cell->paddingBottom() +
                                                   cell->borderTop() + cell->borderBottom()));
      if (cell->height() > ch)
    ch = cell->height();

            pos = rowPos[ indx ] + ch + spacing;

      if ( pos > rowPos[r+1] )
    rowPos[r+1] = pos;

      // 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 > cell->borderTop() + cell->paddingTop()) {
                    if (b>baseline)
                        baseline=b;

                    int td = rowPos[ 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 (rowPos[r+1]<bRowPos)
    rowPos[r+1]=bRowPos;

      grid[r].baseLine = baseline;
  }

  if ( rowPos[r+1] < rowPos[r] )
      rowPos[r+1] = rowPos[r];
//    qDebug("rowpos(%d)=%d",  r, rowPos[r] );
    }
}

int RenderTableSection::layoutRows( int toAdd )
{
    int rHeight;
    int rindx;
    int totalRows = gridRows;
    int hspacing = table()->hBorderSpacing();
    int vspacing = table()->vBorderSpacing();

    if (toAdd && totalRows && (rowPos[totalRows] || !nextSibling())) {

  int totalHeight = rowPos[totalRows] + toAdd;
//  qDebug("layoutRows: totalHeight = %d",  totalHeight );

        int dh = toAdd;
  int totalPercent = 0;
  int numVariable = 0;
  for ( int r = 0; r < totalRows; r++ ) {
      if ( grid[r].height.type == Variable )
    numVariable++;
      else if ( grid[r].height.type == Percent )
    totalPercent += grid[r].height.value;
  }
  if ( totalPercent ) {
//      qDebug("distributing %d over percent rows totalPercent=%d", dh,  totalPercent );
      // try to satisfy percent
      int add = 0;
      if ( totalPercent > 100 )

⌨️ 快捷键说明

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