Exemple #1
0
NS_IMETHODIMP nsViewManager::InvalidateViewNoSuppression(nsIView *aView,
                                                         const nsRect &aRect)
{
  NS_PRECONDITION(nsnull != aView, "null view");

  nsView* view = static_cast<nsView*>(aView);

  NS_ASSERTION(view->GetViewManager() == this,
               "InvalidateViewNoSuppression called on view we don't own");

  nsRect damagedRect(aRect);
  if (damagedRect.IsEmpty()) {
    return NS_OK;
  }

  nsView* displayRoot = static_cast<nsView*>(GetDisplayRootFor(view));
  nsViewManager* displayRootVM = displayRoot->GetViewManager();
  // Propagate the update to the displayRoot, since iframes, for example,
  // can overlap each other and be translucent.  So we have to possibly
  // invalidate our rect in each of the widgets we have lying about.
  damagedRect.MoveBy(view->GetOffsetTo(displayRoot));
  PRInt32 rootAPD = displayRootVM->AppUnitsPerDevPixel();
  PRInt32 APD = AppUnitsPerDevPixel();
  damagedRect = damagedRect.ConvertAppUnitsRoundOut(APD, rootAPD);

  // accumulate this rectangle in the view's dirty region, so we can
  // process it later.
  AddDirtyRegion(displayRoot, nsRegion(damagedRect));

  return NS_OK;
}
Exemple #2
0
//------------------------------------------------------------------------------
void
nsSimplePageSequenceFrame::PaintPageSequence(nsRenderingContext& aRenderingContext,
                                             const nsRect&        aDirtyRect,
                                             nsPoint              aPt) {
  nsRect rect = aDirtyRect;
  float scale = PresContext()->GetPrintPreviewScale();
  aRenderingContext.PushState();
  nsPoint framePos = aPt;
  aRenderingContext.Translate(framePos);
  rect -= framePos;
  aRenderingContext.Scale(scale, scale);
  rect.ScaleRoundOut(1.0f / scale);

  // Now the rect and the rendering coordinates are are relative to this frame.
  // Loop over the pages and paint them.
  nsIFrame* child = GetFirstChild(nsnull);
  while (child) {
    nsPoint pt = child->GetPosition();
    // The rendering context has to be translated before each call to PaintFrame
    aRenderingContext.PushState();
    aRenderingContext.Translate(pt);
    nsLayoutUtils::PaintFrame(&aRenderingContext, child,
                              nsRegion(rect - pt), NS_RGBA(0,0,0,0),
                              nsLayoutUtils::PAINT_SYNC_DECODE_IMAGES);
    aRenderingContext.PopState();
    child = child->GetNextSibling();
  }

  aRenderingContext.PopState();
}
Exemple #3
0
void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
        bool aFlushDirtyRegion)
{
    NS_ASSERTION(IsRootVM(), "Updates will be missed");

    // Protect against a null-view.
    if (!aView) {
        return;
    }

    if (aView->HasWidget()) {
        aView->ResetWidgetBounds(false, true);
    }

    // process pending updates in child view.
    for (nsView* childView = aView->GetFirstChild(); childView;
            childView = childView->GetNextSibling()) {
        ProcessPendingUpdatesForView(childView, aFlushDirtyRegion);
    }

    // Push out updates after we've processed the children; ensures that
    // damage is applied based on the final widget geometry
    if (aFlushDirtyRegion) {
        nsIWidget *widget = aView->GetWidget();
        if (widget && widget->NeedsPaint()) {
            // If an ancestor widget was hidden and then shown, we could
            // have a delayed resize to handle.
            for (nsViewManager *vm = this; vm;
                    vm = vm->mRootView->GetParent()
                         ? vm->mRootView->GetParent()->GetViewManager()
                         : nullptr) {
                if (vm->mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) &&
                        vm->mRootView->IsEffectivelyVisible() &&
                        mPresShell && mPresShell->IsVisible()) {
                    vm->FlushDelayedResize(true);
                    vm->InvalidateView(vm->mRootView);
                }
            }

            NS_ASSERTION(aView->HasWidget(), "Must have a widget!");

#ifdef DEBUG_INVALIDATIONS
            printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
#endif
            nsAutoScriptBlocker scriptBlocker;
            NS_ASSERTION(aView->HasWidget(), "Must have a widget!");
            aView->GetWidget()->WillPaint();
            SetPainting(true);
            mPresShell->Paint(aView, nsRegion(),
                              nsIPresShell::PAINT_LAYERS |
                              nsIPresShell::PAINT_WILL_SEND_DID_PAINT);
#ifdef DEBUG_INVALIDATIONS
            printf("---- PAINT END ----\n");
#endif
            aView->SetForcedRepaint(false);
            SetPainting(false);
        }
        FlushDirtyRegionToWidget(aView);
    }
}
Exemple #4
0
bool nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
                                                 bool aFlushDirtyRegion)
{
  NS_ASSERTION(IsRootVM(), "Updates will be missed");

  // Protect against a null-view.
  if (!aView) {
    return false;
  }

  if (aView->HasWidget()) {
    aView->ResetWidgetBounds(false, true);
  }

  // process pending updates in child view.
  bool skipped = false;
  for (nsView* childView = aView->GetFirstChild(); childView;
       childView = childView->GetNextSibling()) {
    skipped |= ProcessPendingUpdatesForView(childView, aFlushDirtyRegion);
  }

  // Push out updates after we've processed the children; ensures that
  // damage is applied based on the final widget geometry
  if (aFlushDirtyRegion) {
    nsIWidget *widget = aView->GetWidget();
    if (widget && widget->NeedsPaint()) {
      if (aView->PendingRefresh() && aView->SkippedPaints() < 5) {
        aView->SkippedPaint();
        skipped = true;
      } else {
        aView->ClearSkippedPaints();
        aView->SetPendingRefresh(false);
        widget->SetNeedsPaint(false);
        SetPainting(true);
#ifdef DEBUG_INVALIDATIONS
        printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
#endif
        nsAutoScriptBlocker scriptBlocker;
        mPresShell->Paint(aView, nsRegion(), nsIPresShell::PaintType_NoComposite, false);
#ifdef DEBUG_INVALIDATIONS
        printf("---- PAINT END ----\n");
#endif
        SetPainting(false);
      }
    }
    FlushDirtyRegionToWidget(aView);
  }
  return skipped;
}
//------------------------------------------------------------------------------
void
nsPageFrame::PaintPageContent(nsIRenderingContext& aRenderingContext,
                              const nsRect&        aDirtyRect,
                              nsPoint              aPt) {
  nsIFrame* pageContentFrame  = mFrames.FirstChild();
  nsRect rect = aDirtyRect;
  float scale = PresContext()->GetPageScale();
  aRenderingContext.PushState();
  nsPoint framePos = aPt + pageContentFrame->GetOffsetTo(this);
  aRenderingContext.Translate(framePos.x, framePos.y);
  // aPt translates to coords relative to this, then margins translate to
  // pageContentFrame's coords
  rect -= framePos;
  aRenderingContext.Scale(scale, scale);
  rect.ScaleRoundOut(1.0f / scale);
  // Make sure we don't draw where we aren't supposed to draw, especially
  // when printing selection
  nsRect clipRect(nsPoint(0, 0), pageContentFrame->GetSize());
  // Note: this computation matches how we compute maxSize.height
  // in nsPageFrame::Reflow
  nscoord expectedPageContentHeight = 
    NSToCoordCeil((GetSize().height - mPD->mReflowMargin.TopBottom()) / scale);
  if (clipRect.height > expectedPageContentHeight) {
    // We're doing print-selection, with one long page-content frame.
    // Clip to the appropriate page-content slice for the current page.
    NS_ASSERTION(mPageNum > 0, "page num should be positive");
    // Note: The pageContentFrame's y-position has been set such that a zero
    // y-value matches the top edge of the current page.  So, to clip to the
    // current page's content (in coordinates *relative* to the page content
    // frame), we just negate its y-position and add the top margin.
    clipRect.y = NSToCoordCeil((-pageContentFrame->GetRect().y + 
                                mPD->mReflowMargin.top) / scale);
    clipRect.height = expectedPageContentHeight;
    NS_ASSERTION(clipRect.y < pageContentFrame->GetSize().height,
                 "Should be clipping to region inside the page content bounds");
  }
  aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);

  nsRect backgroundRect = nsRect(nsPoint(0, 0), pageContentFrame->GetSize());
  nsCSSRendering::PaintBackground(PresContext(), aRenderingContext, this,
                                  rect, backgroundRect,
                                  nsCSSRendering::PAINTBG_SYNC_DECODE_IMAGES);

  nsLayoutUtils::PaintFrame(&aRenderingContext, pageContentFrame,
                            nsRegion(rect), NS_RGBA(0,0,0,0),
                            nsLayoutUtils::PAINT_SYNC_DECODE_IMAGES);

  aRenderingContext.PopState();
}
Exemple #6
0
//------------------------------------------------------------------------------
void
nsPageFrame::PaintPageContent(nsIRenderingContext& aRenderingContext,
                              const nsRect&        aDirtyRect,
                              nsPoint              aPt) {
  nsIFrame* pageContentFrame  = mFrames.FirstChild();
  nsRect rect = aDirtyRect;
  float scale = PresContext()->GetPageScale();
  aRenderingContext.PushState();
  nsPoint framePos = aPt + pageContentFrame->GetOffsetTo(this);
  aRenderingContext.Translate(framePos.x, framePos.y);
  // aPt translates to coords relative to this, then margins translate to
  // pageContentFrame's coords
  rect -= framePos;
  aRenderingContext.Scale(scale, scale);
  rect.ScaleRoundOut(1.0f / scale);
  // Make sure we don't draw where we aren't supposed to draw, especially
  // when printing selection
  nsRect clipRect(nsPoint(0, 0), pageContentFrame->GetSize());
  // Note: this computation matches how we compute maxSize.height
  // in nsPageFrame::Reflow
  nscoord expectedPageContentHeight = 
    NSToCoordCeil((GetSize().height - mPD->mReflowMargin.TopBottom()) / scale);
  if (clipRect.height > expectedPageContentHeight) {
    // We're doing print-selection, with one long page-content frame.
    // Clip to the appropriate page-content slice for the current page.
    NS_ASSERTION(mPageNum > 0, "page num should be positive");
    clipRect.y =  expectedPageContentHeight * (mPageNum - 1);
    clipRect.height = expectedPageContentHeight;
    NS_ASSERTION(clipRect.y < pageContentFrame->GetSize().height,
                 "Should be clipping to region inside the page content bounds");
  }
  aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect);

  const nsStyleBorder* border = GetStyleBorder();
  const nsStylePadding* padding = GetStylePadding();
  nsRect backgroundRect = nsRect(nsPoint(0, 0), pageContentFrame->GetSize());
  nsCSSRendering::PaintBackground(PresContext(), aRenderingContext, this,
                                  rect, backgroundRect, *border, *padding,
                                  PR_TRUE);

  nsLayoutUtils::PaintFrame(&aRenderingContext, pageContentFrame,
                            nsRegion(rect), NS_RGBA(0,0,0,0));

  aRenderingContext.PopState();
}
Exemple #7
0
NS_IMETHODIMP
nsSVGForeignObjectFrame::PaintSVG(nsRenderingContext *aContext,
                                  const nsIntRect *aDirtyRect)
{
  if (IsDisabled())
    return NS_OK;

  nsIFrame* kid = GetFirstPrincipalChild();
  if (!kid)
    return NS_OK;

  gfxMatrix matrixForChildren = GetCanvasTMForChildren();
  gfxMatrix matrix = GetCanvasTM();

  if (matrixForChildren.IsSingular()) {
    NS_WARNING("Can't render foreignObject element!");
    return NS_ERROR_FAILURE;
  }

  nsRect kidDirtyRect = kid->GetVisualOverflowRect();

  /* Check if we need to draw anything. */
  if (aDirtyRect) {
    // Transform the dirty rect into app units in our userspace.
    gfxMatrix invmatrix = matrix;
    invmatrix.Invert();
    NS_ASSERTION(!invmatrix.IsSingular(),
                 "inverse of non-singular matrix should be non-singular");

    gfxRect transDirtyRect = gfxRect(aDirtyRect->x, aDirtyRect->y,
                                     aDirtyRect->width, aDirtyRect->height);
    transDirtyRect = invmatrix.TransformBounds(transDirtyRect);

    kidDirtyRect.IntersectRect(kidDirtyRect,
      nsLayoutUtils::RoundGfxRectToAppRect(transDirtyRect,
                       PresContext()->AppUnitsPerCSSPixel()));

    // XXX after bug 614732 is fixed, we will compare mRect with aDirtyRect,
    // not with kidDirtyRect. I.e.
    // PRInt32 appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
    // mRect.ToOutsidePixels(appUnitsPerDevPx).Intersects(*aDirtyRect)
    if (kidDirtyRect.IsEmpty())
      return NS_OK;
  }

  gfxContext *gfx = aContext->ThebesContext();

  gfx->Save();

  if (GetStyleDisplay()->IsScrollableOverflow()) {
    float x, y, width, height;
    static_cast<nsSVGElement*>(mContent)->
      GetAnimatedLengthValues(&x, &y, &width, &height, nsnull);

    gfxRect clipRect =
      nsSVGUtils::GetClipRectForFrame(this, 0.0f, 0.0f, width, height);
    nsSVGUtils::SetClipRect(gfx, matrix, clipRect);
  }

  gfx->Multiply(matrixForChildren);

  PRUint32 flags = nsLayoutUtils::PAINT_IN_TRANSFORM;
  if (SVGAutoRenderState::IsPaintingToWindow(aContext)) {
    flags |= nsLayoutUtils::PAINT_TO_WINDOW;
  }
  nsresult rv = nsLayoutUtils::PaintFrame(aContext, kid, nsRegion(kidDirtyRect),
                                          NS_RGBA(0,0,0,0), flags);

  gfx->Restore();

  return rv;
}
Exemple #8
0
NS_IMETHODIMP
nsSVGForeignObjectFrame::PaintSVG(nsSVGRenderState *aContext,
                                  const nsIntRect *aDirtyRect)
{
  if (IsDisabled())
    return NS_OK;

  nsIFrame* kid = GetFirstChild(nsnull);
  if (!kid)
    return NS_OK;

  gfxMatrix matrixForChildren = GetCanvasTMForChildren();
  gfxMatrix matrix = GetCanvasTM();

  nsRenderingContext *ctx = aContext->GetRenderingContext(this);

  if (!ctx || matrixForChildren.IsSingular()) {
    NS_WARNING("Can't render foreignObject element!");
    return NS_ERROR_FAILURE;
  }

  /* Check if we need to draw anything. */
  if (aDirtyRect) {
    PRInt32 appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
    if (!mRect.ToOutsidePixels(appUnitsPerDevPx).Intersects(*aDirtyRect))
      return NS_OK;
  }

  gfxContext *gfx = aContext->GetGfxContext();

  gfx->Save();

  if (GetStyleDisplay()->IsScrollableOverflow()) {
    float x, y, width, height;
    static_cast<nsSVGElement*>(mContent)->
      GetAnimatedLengthValues(&x, &y, &width, &height, nsnull);

    gfxRect clipRect =
      nsSVGUtils::GetClipRectForFrame(this, 0.0f, 0.0f, width, height);
    nsSVGUtils::SetClipRect(gfx, matrix, clipRect);
  }

  gfx->Multiply(matrixForChildren);

  // Transform the dirty rect into the rectangle containing the
  // transformed dirty rect.
  gfxMatrix invmatrix = matrix.Invert();
  NS_ASSERTION(!invmatrix.IsSingular(),
               "inverse of non-singular matrix should be non-singular");

  gfxRect transDirtyRect = gfxRect(aDirtyRect->x, aDirtyRect->y,
                                   aDirtyRect->width, aDirtyRect->height);
  transDirtyRect = invmatrix.TransformBounds(transDirtyRect);

  transDirtyRect.Scale(nsPresContext::AppUnitsPerCSSPixel());
  nsPoint tl(NSToCoordFloor(transDirtyRect.X()),
             NSToCoordFloor(transDirtyRect.Y()));
  nsPoint br(NSToCoordCeil(transDirtyRect.XMost()),
             NSToCoordCeil(transDirtyRect.YMost()));
  nsRect kidDirtyRect(tl.x, tl.y, br.x - tl.x, br.y - tl.y);

  kidDirtyRect.IntersectRect(kidDirtyRect, kid->GetRect());

  PRUint32 flags = nsLayoutUtils::PAINT_IN_TRANSFORM;
  if (aContext->IsPaintingToWindow()) {
    flags |= nsLayoutUtils::PAINT_TO_WINDOW;
  }
  nsresult rv = nsLayoutUtils::PaintFrame(ctx, kid, nsRegion(kidDirtyRect),
                                          NS_RGBA(0,0,0,0), flags);

  gfx->Restore();

  return rv;
}