Example #1
0
PRBool
nsSubDocumentFrame::ReflowFinished()
{
  nsCOMPtr<nsIDocShell> docShell;
  GetDocShell(getter_AddRefs(docShell));

  nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell));

  // resize the sub document
  if (baseWindow) {
    PRInt32 x = 0;
    PRInt32 y = 0;

    nsWeakFrame weakFrame(this);
    
    nsPresContext* presContext = PresContext();
    baseWindow->GetPositionAndSize(&x, &y, nsnull, nsnull);

    if (!weakFrame.IsAlive()) {
      // GetPositionAndSize() killed us
      return PR_FALSE;
    }

    // GetPositionAndSize might have resized us.  So now is the time to
    // get our size.
    mPostedReflowCallback = PR_FALSE;
  
    nsSize innerSize(GetSize());
    if (IsInline()) {
      nsMargin usedBorderPadding = GetUsedBorderAndPadding();

      // Sadly, XUL smacks the frame size without changing the used
      // border and padding, so we can't trust those.  Subtracting
      // them might make things negative.
      innerSize.width  -= usedBorderPadding.LeftRight();
      innerSize.width = PR_MAX(innerSize.width, 0);
      
      innerSize.height -= usedBorderPadding.TopBottom();
      innerSize.height = PR_MAX(innerSize.height, 0);
    }  

    PRInt32 cx = presContext->AppUnitsToDevPixels(innerSize.width);
    PRInt32 cy = presContext->AppUnitsToDevPixels(innerSize.height);
    baseWindow->SetPositionAndSize(x, y, cx, cy, PR_FALSE);
  } else {
    // Make sure that we can post a reflow callback in the future.
    mPostedReflowCallback = PR_FALSE;
  }

  return PR_FALSE;
}
Example #2
0
DrawResult
ClippedImage::DrawSingleTile(gfxContext* aContext,
                             const nsIntSize& aSize,
                             const ImageRegion& aRegion,
                             uint32_t aWhichFrame,
                             GraphicsFilter aFilter,
                             const Maybe<SVGImageContext>& aSVGContext,
                             uint32_t aFlags)
{
  MOZ_ASSERT(!MustCreateSurface(aContext, aSize, aRegion, aFlags),
             "Shouldn't need to create a surface");

  gfxRect clip(mClip.x, mClip.y, mClip.width, mClip.height);
  nsIntSize size(aSize), innerSize(aSize);
  if (NS_SUCCEEDED(InnerImage()->GetWidth(&innerSize.width)) &&
      NS_SUCCEEDED(InnerImage()->GetHeight(&innerSize.height))) {
    double scaleX = aSize.width / clip.width;
    double scaleY = aSize.height / clip.height;

    // Map the clip and size to the scale requested by the caller.
    clip.Scale(scaleX, scaleY);
    size = innerSize;
    size.Scale(scaleX, scaleY);
  } else {
    MOZ_ASSERT(false,
               "If ShouldClip() led us to draw then we should never get here");
  }

  // We restrict our drawing to only the clipping region, and translate so that
  // the clipping region is placed at the position the caller expects.
  ImageRegion region(aRegion);
  region.MoveBy(clip.x, clip.y);
  region = region.Intersect(clip);

  gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
  aContext->Multiply(gfxMatrix::Translation(-clip.x, -clip.y));

  return InnerImage()->Draw(aContext, size, region,
                            aWhichFrame, aFilter,
                            aSVGContext.map(UnclipViewport,
                                            make_pair(innerSize, mClip.Size())),
                            aFlags);
}
Example #3
0
NS_IMETHODIMP
nsSubDocumentFrame::Reflow(nsPresContext*           aPresContext,
                           nsHTMLReflowMetrics&     aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
                           nsReflowStatus&          aStatus)
{
  DO_GLOBAL_REFLOW_COUNT("nsSubDocumentFrame");
  DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
  // printf("OuterFrame::Reflow %X (%d,%d) \n", this, aReflowState.availableWidth, aReflowState.availableHeight);
  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
     ("enter nsSubDocumentFrame::Reflow: maxSize=%d,%d",
      aReflowState.availableWidth, aReflowState.availableHeight));

  aStatus = NS_FRAME_COMPLETE;

  NS_ASSERTION(aPresContext->GetPresShell()->GetPrimaryFrameFor(mContent) == this,
               "Shouldn't happen");

  // "offset" is the offset of our content area from our frame's
  // top-left corner.
  nsPoint offset(0, 0);
  
  if (IsInline()) {
    // XUL <iframe> or <browser>, or HTML <iframe>, <object> or <embed>
    nsresult rv = nsLeafFrame::DoReflow(aPresContext, aDesiredSize, aReflowState,
                                        aStatus);
    NS_ENSURE_SUCCESS(rv, rv);

    offset = nsPoint(aReflowState.mComputedBorderPadding.left,
                     aReflowState.mComputedBorderPadding.top);
  } else {
    // HTML <frame>
    SizeToAvailSize(aReflowState, aDesiredSize);
  }

  nsSize innerSize(aDesiredSize.width, aDesiredSize.height);
  if (IsInline()) {
    innerSize.width  -= aReflowState.mComputedBorderPadding.LeftRight();
    innerSize.height -= aReflowState.mComputedBorderPadding.TopBottom();
  }

  if (mInnerView) {
    nsIViewManager* vm = mInnerView->GetViewManager();
    vm->MoveViewTo(mInnerView, offset.x, offset.y);
    vm->ResizeView(mInnerView, nsRect(nsPoint(0, 0), innerSize), PR_TRUE);
  }

  // Determine if we need to repaint our border, background or outline
  CheckInvalidateSizeChange(aDesiredSize);

  FinishAndStoreOverflow(&aDesiredSize);

  // Invalidate the frame contents
  // XXX is this really needed?
  nsRect rect(nsPoint(0, 0), GetSize());
  Invalidate(rect);

  if (!aPresContext->IsPaginated() && !mPostedReflowCallback) {
    PresContext()->PresShell()->PostReflowCallback(this);
    mPostedReflowCallback = PR_TRUE;
  }

  // printf("OuterFrame::Reflow DONE %X (%d,%d)\n", this,
  //        aDesiredSize.width, aDesiredSize.height);

  NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
     ("exit nsSubDocumentFrame::Reflow: size=%d,%d status=%x",
      aDesiredSize.width, aDesiredSize.height, aStatus));

  NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
  return NS_OK;
}
Example #4
0
void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<UIQuad>& quads, const IntRect& currentScissor, const IntVector2& offset)
{
    bool allOpaque = true;
    if (GetDerivedOpacity() < 1.0f || color_[C_TOPLEFT].a_ < 1.0f || color_[C_TOPRIGHT].a_ < 1.0f ||
        color_[C_BOTTOMLEFT].a_ < 1.0f || color_[C_BOTTOMRIGHT].a_ < 1.0f)
        allOpaque = false;
        
    UIBatch batch(blendMode_ == BLEND_REPLACE && !allOpaque ? BLEND_ALPHA : static_cast<BlendMode>(blendMode_), currentScissor, texture_, &quads);
    
    // Calculate size of the inner rect, and texture dimensions of the inner rect
    const IntVector2& size = GetSize();
    IntVector2 innerSize(
        Max(size.x_ - border_.left_ - border_.right_, 0), 
        Max(size.y_ - border_.top_ - border_.bottom_, 0));
    IntVector2 innerTextureSize(
        Max(imageRect_.right_ - imageRect_.left_ - border_.left_ - border_.right_, 0),
        Max(imageRect_.bottom_ - imageRect_.top_ - border_.top_ - border_.bottom_, 0));
    
    IntVector2 topLeft(imageRect_.left_, imageRect_.top_);
    topLeft += offset;
    
    // Top
    if (border_.top_)
    {
        if (border_.left_)
            batch.AddQuad(*this, 0, 0, border_.left_, border_.top_, topLeft.x_, topLeft.y_);
        if (innerSize.x_)
            batch.AddQuad(*this, border_.left_, 0, innerSize.x_, border_.top_,
            topLeft.x_ + border_.left_, topLeft.y_, innerTextureSize.x_, border_.top_, tiled_);
        if (border_.right_)
            batch.AddQuad(*this, border_.left_ + innerSize.x_, 0, border_.right_, border_.top_,
            topLeft.x_ + border_.left_ + innerTextureSize.x_, topLeft.y_);
    }
    // Middle
    if (innerSize.y_)
    {
        if (border_.left_)
            batch.AddQuad(*this, 0, border_.top_, border_.left_, innerSize.y_,
            topLeft.x_, topLeft.y_ + border_.top_, border_.left_, innerTextureSize.y_, tiled_);
        if (innerSize.x_)
            batch.AddQuad(*this, border_.left_, border_.top_, innerSize.x_, innerSize.y_,
            topLeft.x_ + border_.left_, topLeft.y_ + border_.top_, innerTextureSize.x_, innerTextureSize.y_, tiled_);
        if (border_.right_)
            batch.AddQuad(*this, border_.left_ + innerSize.x_, border_.top_, border_.right_,
            innerSize.y_, topLeft.x_ + border_.left_ + innerTextureSize.x_, topLeft.y_ + border_.top_,
            border_.right_, innerTextureSize.y_, tiled_);
    }
    // Bottom
    if (border_.bottom_)
    {
        if (border_.left_)
            batch.AddQuad(*this, 0, border_.top_ + innerSize.y_, border_.left_, border_.bottom_,
            topLeft.x_, topLeft.y_ + border_.top_ + innerTextureSize.y_);
        if (innerSize.x_)
            batch.AddQuad(*this, border_.left_, border_.top_ + innerSize.y_, innerSize.x_,
            border_.bottom_, topLeft.x_ + border_.left_, topLeft.y_ + border_.top_ + innerTextureSize.y_,
            innerTextureSize.x_, border_.bottom_, tiled_);
        if (border_.right_)
            batch.AddQuad(*this, border_.left_ + innerSize.x_, border_.top_ + innerSize.y_,
            border_.right_, border_.bottom_, topLeft.x_ + border_.left_ + innerTextureSize.x_, 
            topLeft.y_ + border_.top_ + innerTextureSize.y_);
    }
    
    UIBatch::AddOrMerge(batch, batches);
    
    // Reset hovering for next frame
    hovering_ = false;
}
Example #5
0
void BorderImage::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor,
                             const IntVector2& offset)
{
    bool allOpaque = true;
    if (GetDerivedOpacity() < 1.0f || color_[C_TOPLEFT].a_ < 1.0f || color_[C_TOPRIGHT].a_ < 1.0f ||
            color_[C_BOTTOMLEFT].a_ < 1.0f || color_[C_BOTTOMRIGHT].a_ < 1.0f)
        allOpaque = false;

    UIBatch
    batch(this, blendMode_ == BLEND_REPLACE && !allOpaque ? BLEND_ALPHA : blendMode_, currentScissor, texture_, &vertexData);

    // Calculate size of the inner rect, and texture dimensions of the inner rect
    const IntRect& uvBorder = (imageBorder_ == IntRect::ZERO) ? border_ : imageBorder_;
    int x = GetIndentWidth();
    IntVector2 size = GetSize();
    size.x_ -= x;
    IntVector2 innerSize(
        Max(size.x_ - border_.left_ - border_.right_, 0),
        Max(size.y_ - border_.top_ - border_.bottom_, 0));
    IntVector2 innerUvSize(
        Max(imageRect_.right_ - imageRect_.left_ - uvBorder.left_ - uvBorder.right_, 0),
        Max(imageRect_.bottom_ - imageRect_.top_ - uvBorder.top_ - uvBorder.bottom_, 0));

    IntVector2 uvTopLeft(imageRect_.left_, imageRect_.top_);
    uvTopLeft += offset;

    // Top
    if (border_.top_)
    {
        if (border_.left_)
            batch.AddQuad(x, 0, border_.left_, border_.top_, uvTopLeft.x_, uvTopLeft.y_, uvBorder.left_, uvBorder.top_);
        if (innerSize.x_)
            batch.AddQuad(x + border_.left_, 0, innerSize.x_, border_.top_, uvTopLeft.x_ + uvBorder.left_, uvTopLeft.y_,
                          innerUvSize.x_, uvBorder.top_, tiled_);
        if (border_.right_)
            batch.AddQuad(x + border_.left_ + innerSize.x_, 0, border_.right_, border_.top_,
                          uvTopLeft.x_ + uvBorder.left_ + innerUvSize.x_, uvTopLeft.y_, uvBorder.right_, uvBorder.top_);
    }
    // Middle
    if (innerSize.y_)
    {
        if (border_.left_)
            batch.AddQuad(x, border_.top_, border_.left_, innerSize.y_, uvTopLeft.x_, uvTopLeft.y_ + uvBorder.top_,
                          uvBorder.left_, innerUvSize.y_, tiled_);
        if (innerSize.x_)
            batch.AddQuad(x + border_.left_, border_.top_, innerSize.x_, innerSize.y_, uvTopLeft.x_ + uvBorder.left_,
                          uvTopLeft.y_ + uvBorder.top_, innerUvSize.x_, innerUvSize.y_, tiled_);
        if (border_.right_)
            batch.AddQuad(x + border_.left_ + innerSize.x_, border_.top_, border_.right_, innerSize.y_,
                          uvTopLeft.x_ + uvBorder.left_ + innerUvSize.x_, uvTopLeft.y_ + uvBorder.top_, uvBorder.right_, innerUvSize.y_,
                          tiled_);
    }
    // Bottom
    if (border_.bottom_)
    {
        if (border_.left_)
            batch.AddQuad(x, border_.top_ + innerSize.y_, border_.left_, border_.bottom_, uvTopLeft.x_,
                          uvTopLeft.y_ + uvBorder.top_ + innerUvSize.y_, uvBorder.left_, uvBorder.bottom_);
        if (innerSize.x_)
            batch.AddQuad(x + border_.left_, border_.top_ + innerSize.y_, innerSize.x_, border_.bottom_,
                          uvTopLeft.x_ + uvBorder.left_, uvTopLeft.y_ + uvBorder.top_ + innerUvSize.y_, innerUvSize.x_, uvBorder.bottom_,
                          tiled_);
        if (border_.right_)
            batch.AddQuad(x + border_.left_ + innerSize.x_, border_.top_ + innerSize.y_, border_.right_, border_.bottom_,
                          uvTopLeft.x_ + uvBorder.left_ + innerUvSize.x_, uvTopLeft.y_ + uvBorder.top_ + innerUvSize.y_, uvBorder.right_,
                          uvBorder.bottom_);
    }

    UIBatch::AddOrMerge(batch, batches);

    // Reset hovering for next frame
    hovering_ = false;
}
Example #6
0
DrawResult
ClippedImage::DrawSingleTile(gfxContext* aContext,
                             const nsIntSize& aSize,
                             const ImageRegion& aRegion,
                             uint32_t aWhichFrame,
                             SamplingFilter aSamplingFilter,
                             const Maybe<SVGImageContext>& aSVGContext,
                             uint32_t aFlags)
{
  MOZ_ASSERT(!MustCreateSurface(aContext, aSize, aRegion, aFlags),
             "Shouldn't need to create a surface");

  gfxRect clip(mClip.x, mClip.y, mClip.width, mClip.height);
  nsIntSize size(aSize), innerSize(aSize);
  bool needScale = false;
  if (mSVGViewportSize && !mSVGViewportSize->IsEmpty()) {
    innerSize = *mSVGViewportSize;
    needScale = true;
  } else if (NS_SUCCEEDED(InnerImage()->GetWidth(&innerSize.width)) &&
             NS_SUCCEEDED(InnerImage()->GetHeight(&innerSize.height))) {
    needScale = true;
  } else {
    MOZ_ASSERT_UNREACHABLE(
               "If ShouldClip() led us to draw then we should never get here");
  }

  if (needScale) {
    double scaleX = aSize.width / clip.width;
    double scaleY = aSize.height / clip.height;

    // Map the clip and size to the scale requested by the caller.
    clip.Scale(scaleX, scaleY);
    size = innerSize;
    size.Scale(scaleX, scaleY);
  }

  // We restrict our drawing to only the clipping region, and translate so that
  // the clipping region is placed at the position the caller expects.
  ImageRegion region(aRegion);
  region.MoveBy(clip.x, clip.y);
  region = region.Intersect(clip);

  gfxContextMatrixAutoSaveRestore saveMatrix(aContext);
  aContext->Multiply(gfxMatrix::Translation(-clip.x, -clip.y));

  auto unclipViewport = [&](const SVGImageContext& aOldContext) {
    // Map the viewport to the inner image. Note that we don't take the aSize
    // parameter of imgIContainer::Draw into account, just the clipping region.
    // The size in pixels at which the output will ultimately be drawn is
    // irrelevant here since the purpose of the SVG viewport size is to
    // determine what *region* of the SVG document will be drawn.
    CSSIntSize vSize(aOldContext.GetViewportSize());
    vSize.width = ceil(vSize.width * double(innerSize.width) / mClip.width);
    vSize.height =
      ceil(vSize.height * double(innerSize.height) / mClip.height);

    return SVGImageContext(vSize,
                           aOldContext.GetPreserveAspectRatio());
  };

  return InnerImage()->Draw(aContext, size, region,
                            aWhichFrame, aSamplingFilter,
                            aSVGContext.map(unclipViewport),
                            aFlags);
}