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; }
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); }
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; }
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; }
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; }
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); }