예제 #1
0
DrawResult
TableBackgroundPainter::PaintRow(nsTableRowFrame* aFrame,
                                 const TableBackgroundData& aRowGroupBGData,
                                 TableBackgroundData aRowBGData,
                                 bool             aPassThrough)
{
  MOZ_ASSERT(aFrame, "null frame");

  /* Load row data */
  WritingMode wm = aFrame->GetWritingMode();
  if (aPassThrough) {
    aRowBGData.MakeInvisible();
  } else {
    if (mIsBorderCollapse && aRowBGData.ShouldSetBCBorder()) {
      LogicalMargin border(wm);
      nsTableRowFrame* nextRow = aFrame->GetNextRow();
      if (nextRow) { //outer bStart after us is inner bEnd for us
        border.BEnd(wm) = nextRow->GetOuterBStartContBCBorderWidth();
      }
      else { //acquire rg's bEnd border
        nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame->GetParent());
        rowGroup->GetContinuousBCBorderWidth(wm, border);
      }
      //get the rest of the borders; will overwrite all but bEnd
      aFrame->GetContinuousBCBorderWidth(wm, border);

      aRowBGData.SetBCBorder(border.GetPhysicalMargin(wm));
    }
    aPassThrough = !aRowBGData.IsVisible();
  }

  /* Translate */
  if (eOrigin_TableRow == mOrigin) {
    /* If we originate from the row, then make the row the origin. */
    aRowBGData.mRect.MoveTo(0, 0);
  }
  //else: Use row group's coord system -> no translation necessary

  DrawResult result = DrawResult::SUCCESS;

  for (nsTableCellFrame* cell = aFrame->GetFirstCell(); cell; cell = cell->GetNextCell()) {
    nsRect cellBGRect, rowBGRect, rowGroupBGRect, colBGRect;
    ComputeCellBackgrounds(cell, aRowGroupBGData, aRowBGData,
                           cellBGRect, rowBGRect,
                           rowGroupBGRect, colBGRect);

    // Find the union of all the cell background layers.
    nsRect combinedRect(cellBGRect);
    combinedRect.UnionRect(combinedRect, rowBGRect);
    combinedRect.UnionRect(combinedRect, rowGroupBGRect);
    combinedRect.UnionRect(combinedRect, colBGRect);

    if (combinedRect.Intersects(mDirtyRect)) {
      bool passCell = aPassThrough || cell->IsPseudoStackingContextFromStyle();
      DrawResult cellResult =
        PaintCell(cell, aRowGroupBGData, aRowBGData,
                  cellBGRect, rowBGRect, rowGroupBGRect, colBGRect, passCell);

      UpdateDrawResult(&result, cellResult);
    }
  }

  return result;
}
예제 #2
0
DrawResult
TableBackgroundPainter::PaintRowGroup(nsTableRowGroupFrame* aFrame,
                                      TableBackgroundData   aRowGroupBGData,
                                      bool                  aPassThrough)
{
  MOZ_ASSERT(aFrame, "null frame");

  nsTableRowFrame* firstRow = aFrame->GetFirstRow();
  WritingMode wm = aFrame->GetWritingMode();

  /* Load row group data */
  if (aPassThrough) {
    aRowGroupBGData.MakeInvisible();
  } else {
    if (mIsBorderCollapse && aRowGroupBGData.ShouldSetBCBorder()) {
      LogicalMargin border(wm);
      if (firstRow) {
        //pick up first row's bstart border (= rg bstart border)
        firstRow->GetContinuousBCBorderWidth(wm, border);
        /* (row group doesn't store its bstart border) */
      }
      //overwrite sides+bottom borders with rg's own
      aFrame->GetContinuousBCBorderWidth(wm, border);
      aRowGroupBGData.SetBCBorder(border.GetPhysicalMargin(wm));
    }
    aPassThrough = !aRowGroupBGData.IsVisible();
  }

  /* translate everything into row group coord system*/
  if (eOrigin_TableRowGroup != mOrigin) {
    TranslateContext(aRowGroupBGData.mRect.x, aRowGroupBGData.mRect.y);
  }
  nsRect rgRect = aRowGroupBGData.mRect;
  aRowGroupBGData.mRect.MoveTo(0, 0);

  /* Find the right row to start with */

  // Note that mDirtyRect  - mRenderPt is guaranteed to be in the row
  // group's coordinate system here, so passing its .y to
  // GetFirstRowContaining is ok.
  nscoord overflowAbove;
  nsIFrame* cursor = aFrame->GetFirstRowContaining(mDirtyRect.y - mRenderPt.y, &overflowAbove);

  // Sadly, it seems like there may be non-row frames in there... or something?
  // There are certainly null-checks in GetFirstRow() and GetNextRow().  :(
  while (cursor && cursor->GetType() != nsGkAtoms::tableRowFrame) {
    cursor = cursor->GetNextSibling();
  }

  // It's OK if cursor is null here.
  nsTableRowFrame* row = static_cast<nsTableRowFrame*>(cursor);
  if (!row) {
    // No useful cursor; just start at the top.  Don't bother to set up a
    // cursor; if we've gotten this far then we've already built the display
    // list for the rowgroup, so not having a cursor means that there's some
    // good reason we don't have a cursor and we shouldn't create one here.
    row = firstRow;
  }

  DrawResult result = DrawResult::SUCCESS;

  /* Finally paint */
  for (; row; row = row->GetNextRow()) {
    TableBackgroundData rowBackgroundData(row);

    // Be sure to consider our positions both pre- and post-relative
    // positioning, since we potentially need to paint at both places.
    nscoord rowY = std::min(rowBackgroundData.mRect.y, row->GetNormalPosition().y);

    // Intersect wouldn't handle rowspans.
    if (cursor &&
        (mDirtyRect.YMost() - mRenderPt.y) <= (rowY - overflowAbove)) {
      // All done; cells originating in later rows can't intersect mDirtyRect.
      break;
    }

    DrawResult rowResult =
      PaintRow(row, aRowGroupBGData, rowBackgroundData,
               aPassThrough || row->IsPseudoStackingContextFromStyle());

    UpdateDrawResult(&result, rowResult);
  }

  /* translate back into table coord system */
  if (eOrigin_TableRowGroup != mOrigin) {
    TranslateContext(-rgRect.x, -rgRect.y);
  }

  return result;
}