From 06241c1e45c5e6845a55fe9896eac62b477a0187 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Aug 2010 14:29:01 -0500 Subject: [PATCH] Bug 585817. Part 2: Change nsIPresShell::CreateRenderingContext to GetReferenceRenderingContext, that uses the shared 1x1 surface, and use it all over the place. r=mats,sr=dbaron --- accessible/src/msaa/nsTextAccessibleWrap.cpp | 3 +- layout/base/nsDocumentViewer.cpp | 4 +- layout/base/nsIPresShell.h | 12 ++-- layout/base/nsPresShell.cpp | 59 ++++--------------- layout/generic/nsSimplePageSequence.cpp | 5 +- layout/generic/nsTextFrameThebes.cpp | 5 +- layout/inspector/src/inFlasher.cpp | 29 +++++---- .../svg/base/src/nsSVGForeignObjectFrame.cpp | 4 +- layout/xul/base/src/nsSplitterFrame.cpp | 7 +-- .../xul/base/src/tree/src/nsTreeBodyFrame.cpp | 36 +++++------ 10 files changed, 66 insertions(+), 98 deletions(-) diff --git a/accessible/src/msaa/nsTextAccessibleWrap.cpp b/accessible/src/msaa/nsTextAccessibleWrap.cpp index 4884c0d3f89..9fec3b6fcad 100644 --- a/accessible/src/msaa/nsTextAccessibleWrap.cpp +++ b/accessible/src/msaa/nsTextAccessibleWrap.cpp @@ -259,8 +259,7 @@ __try { return E_FAIL; } - nsCOMPtr rc; - presShell->CreateRenderingContext(frame, getter_AddRefs(rc)); + nsCOMPtr rc = presShell->GetReferenceRenderingContext(); if (!rc) { return E_FAIL; } diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 933a1ab11cc..2feec7fd61a 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -3264,8 +3264,8 @@ NS_IMETHODIMP DocumentViewerImpl::SizeToContent() nscoord prefWidth; { - nsCOMPtr rcx; - presShell->CreateRenderingContext(root, getter_AddRefs(rcx)); + nsCOMPtr rcx = + presShell->GetReferenceRenderingContext(); NS_ENSURE_TRUE(rcx, NS_ERROR_FAILURE); prefWidth = root->GetPrefWidth(rcx); } diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 9d4f92f27db..fa451a73db5 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -139,8 +139,8 @@ typedef struct CapturingContentInfo { } CapturingContentInfo; #define NS_IPRESSHELL_IID \ - { 0xe82aae32, 0x2d68, 0x452a, \ - { 0x88, 0x95, 0x86, 0xc6, 0x07, 0xe1, 0xec, 0x91 } } + { 0xe63a350c, 0x4e04, 0x4056, \ + { 0x8d, 0xa0, 0x51, 0xcc, 0x55, 0x68, 0x68, 0x42 } } // Constants for ScrollContentIntoView() function #define NS_PRESSHELL_SCROLL_TOP 0 @@ -479,11 +479,11 @@ public: virtual NS_HIDDEN_(void) ClearFrameRefs(nsIFrame* aFrame) = 0; /** - * Given a frame, create a rendering context suitable for use with - * the frame. + * Get a reference rendering context. This is a context that should not + * be rendered to, but is suitable for measuring text and performing + * other non-rendering operations. */ - virtual NS_HIDDEN_(nsresult) CreateRenderingContext(nsIFrame *aFrame, - nsIRenderingContext** aContext) = 0; + virtual already_AddRefed GetReferenceRenderingContext() = 0; /** * Informs the pres shell that the document is now at the anchor with diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index dad2c0a4135..8e33d81b6bf 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -753,8 +753,7 @@ public: virtual NS_HIDDEN_(void) CancelReflowCallback(nsIReflowCallback* aCallback); virtual NS_HIDDEN_(void) ClearFrameRefs(nsIFrame* aFrame); - virtual NS_HIDDEN_(nsresult) CreateRenderingContext(nsIFrame *aFrame, - nsIRenderingContext** aContext); + virtual NS_HIDDEN_(already_AddRefed) GetReferenceRenderingContext(); virtual NS_HIDDEN_(nsresult) GoToAnchor(const nsAString& aAnchorName, PRBool aScroll); virtual NS_HIDDEN_(nsresult) ScrollToAnchor(); @@ -3675,51 +3674,22 @@ PresShell::ClearFrameRefs(nsIFrame* aFrame) } } -nsresult -PresShell::CreateRenderingContext(nsIFrame *aFrame, - nsIRenderingContext** aResult) +already_AddRefed +PresShell::GetReferenceRenderingContext() { NS_TIME_FUNCTION_MIN(1.0); - NS_PRECONDITION(nsnull != aResult, "null ptr"); - if (nsnull == aResult) { - return NS_ERROR_NULL_POINTER; - } - - nsIWidget* widget = nsnull; - nsPoint offset(0,0); + nsIDeviceContext* devCtx = mPresContext->DeviceContext(); + nsRefPtr rc; if (mPresContext->IsScreen()) { - // Get the widget to create the rendering context for and calculate - // the offset from the frame to it. - nsPoint viewOffset; - nsIView* view = aFrame->GetClosestView(&viewOffset); - nsPoint widgetOffset; - widget = view->GetNearestWidget(&widgetOffset); - offset = viewOffset + widgetOffset; + devCtx->CreateRenderingContextInstance(*getter_AddRefs(rc)); + if (rc) { + rc->Init(devCtx, gfxPlatform::GetPlatform()->ScreenReferenceSurface()); + } } else { - nsIFrame* pageFrame = nsLayoutUtils::GetPageFrame(aFrame); - // This might not always come up with a frame, i.e. during reflow; - // that's fine, because the translation doesn't matter during reflow. - if (pageFrame) - offset = aFrame->GetOffsetTo(pageFrame); + devCtx->CreateRenderingContext(*getter_AddRefs(rc)); } - - nsresult rv; - nsIRenderingContext* result = nsnull; - nsIDeviceContext *deviceContext = mPresContext->DeviceContext(); - if (widget) { - rv = deviceContext->CreateRenderingContext(widget, result); - } - else { - rv = deviceContext->CreateRenderingContext(result); - } - *aResult = result; - - if (NS_SUCCEEDED(rv)) { - result->Translate(offset.x, offset.y); - } - - return rv; + return rc.forget(); } nsresult @@ -7518,11 +7488,8 @@ PresShell::DoReflow(nsIFrame* target, PRBool aInterruptible) nsIFrame* rootFrame = FrameManager()->GetRootFrame(); - nsCOMPtr rcx; - // Always create the rendering context relative to the root frame during - // reflow; otherwise, it crashes on the mac (I'm not quite sure why) - nsresult rv = CreateRenderingContext(rootFrame, getter_AddRefs(rcx)); - if (NS_FAILED(rv)) { + nsCOMPtr rcx = GetReferenceRenderingContext(); + if (!rcx) { NS_NOTREACHED("CreateRenderingContext failure"); return PR_FALSE; } diff --git a/layout/generic/nsSimplePageSequence.cpp b/layout/generic/nsSimplePageSequence.cpp index b9e1b813d03..bb5838b2c81 100644 --- a/layout/generic/nsSimplePageSequence.cpp +++ b/layout/generic/nsSimplePageSequence.cpp @@ -607,9 +607,8 @@ nsSimplePageSequenceFrame::PrintNextPage() PR_PL(("SeqFr::PrintNextPage -> %p PageNo: %d", pf, mPageNum)); nsCOMPtr renderingContext; - PresContext()->PresShell()-> - CreateRenderingContext(mCurrentPageFrame, - getter_AddRefs(renderingContext)); + dc->CreateRenderingContext(*getter_AddRefs(renderingContext)); + NS_ENSURE_TRUE(renderingContext, NS_ERROR_OUT_OF_MEMORY); #if defined(XP_UNIX) && !defined(XP_MACOSX) // On linux, need to rotate landscape-mode output on printed surfaces diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index f624be7c511..a738894b209 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -1493,9 +1493,8 @@ GetReferenceRenderingContext(nsTextFrame* aTextFrame, nsIRenderingContext* aRC) { nsCOMPtr tmp = aRC; if (!tmp) { - nsresult rv = aTextFrame->PresContext()->PresShell()-> - CreateRenderingContext(aTextFrame, getter_AddRefs(tmp)); - if (NS_FAILED(rv)) + tmp = aTextFrame->PresContext()->PresShell()->GetReferenceRenderingContext(); + if (!tmp) return nsnull; } diff --git a/layout/inspector/src/inFlasher.cpp b/layout/inspector/src/inFlasher.cpp index c744f931f25..79499ca4228 100644 --- a/layout/inspector/src/inFlasher.cpp +++ b/layout/inspector/src/inFlasher.cpp @@ -155,22 +155,25 @@ inFlasher::DrawElementOutline(nsIDOMElement* aElement) PRBool isFirstFrame = PR_TRUE; while (frame) { - nsCOMPtr rcontext; - nsresult rv = - presShell->CreateRenderingContext(frame, getter_AddRefs(rcontext)); - NS_ENSURE_SUCCESS(rv, rv); + nsPoint offset; + nsIWidget* widget = frame->GetNearestWidget(offset); + if (widget) { + nsCOMPtr rcontext; + frame->PresContext()->DeviceContext()-> + CreateRenderingContext(widget, *getter_AddRefs(rcontext)); + if (rcontext) { + nsRect rect(offset, frame->GetSize()); + if (mInvert) { + rcontext->InvertRect(rect); + } - nsRect rect(nsPoint(0,0), frame->GetSize()); - if (mInvert) { - rcontext->InvertRect(rect); + PRBool isLastFrame = frame->GetNextContinuation() == nsnull; + DrawOutline(rect.x, rect.y, rect.width, rect.height, rcontext, + isFirstFrame, isLastFrame); + isFirstFrame = PR_FALSE; + } } - frame = frame->GetNextContinuation(); - - PRBool isLastFrame = (frame == nsnull); - DrawOutline(rect.x, rect.y, rect.width, rect.height, rcontext, - isFirstFrame, isLastFrame); - isFirstFrame = PR_FALSE; } return NS_OK; diff --git a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp index 669985445be..b1d0e493228 100644 --- a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp @@ -569,10 +569,10 @@ nsSVGForeignObjectFrame::DoReflow() // initiate a synchronous reflow here and now: nsSize availableSpace(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); - nsCOMPtr renderingContext; nsIPresShell* presShell = presContext->PresShell(); NS_ASSERTION(presShell, "null presShell"); - presShell->CreateRenderingContext(this,getter_AddRefs(renderingContext)); + nsCOMPtr renderingContext = + presShell->GetReferenceRenderingContext(); if (!renderingContext) return; diff --git a/layout/xul/base/src/nsSplitterFrame.cpp b/layout/xul/base/src/nsSplitterFrame.cpp index 36e120c15da..c49aa3e2f2e 100644 --- a/layout/xul/base/src/nsSplitterFrame.cpp +++ b/layout/xul/base/src/nsSplitterFrame.cpp @@ -664,10 +664,9 @@ nsSplitterFrameInner::MouseDown(nsIDOMEvent* aMouseEvent) if (childIndex == childCount - 1 && GetResizeAfter() != Grow) return NS_OK; - nsCOMPtr rc; - nsresult rv = outerPresContext->PresShell()-> - CreateRenderingContext(mOuter, getter_AddRefs(rc)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr rc = + outerPresContext->PresShell()->GetReferenceRenderingContext(); + NS_ENSURE_TRUE(rc, NS_ERROR_FAILURE); nsBoxLayoutState state(outerPresContext, rc); mCurrentPos = 0; mPressed = PR_TRUE; diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp index b77f69cc8ca..8cacff8ff0c 100644 --- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp +++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp @@ -270,8 +270,10 @@ nsTreeBodyFrame::CalcMaxRowWidth() nscoord rowWidth; nsTreeColumn* col; - nsCOMPtr rc; - PresContext()->PresShell()->CreateRenderingContext(this, getter_AddRefs(rc)); + nsCOMPtr rc = + PresContext()->PresShell()->GetReferenceRenderingContext(); + if (!rc) + return 0; for (PRInt32 row = 0; row < mRowCount; ++row) { rowWidth = 0; @@ -1173,8 +1175,10 @@ nsTreeBodyFrame::GetCoordsForCellItem(PRInt32 aRow, nsITreeColumn* aCol, const n // interfere with our computations. AdjustForBorderPadding(cellContext, cellRect); - nsCOMPtr rc; - presContext->PresShell()->CreateRenderingContext(this, getter_AddRefs(rc)); + nsCOMPtr rc = + presContext->PresShell()->GetReferenceRenderingContext(); + if (!rc) + return NS_ERROR_OUT_OF_MEMORY; // Now we'll start making our way across the cell, starting at the edge of // the cell and proceeding until we hit the right edge. |cellX| is the @@ -1521,6 +1525,12 @@ nsTreeBodyFrame::GetItemWithinCellAt(nscoord aX, const nsRect& aCellRect, // Handle right alignment hit testing. PRBool isRTL = GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL; + nsPresContext* presContext = PresContext(); + nsCOMPtr rc = + presContext->PresShell()->GetReferenceRenderingContext(); + if (!rc) + return nsCSSAnonBoxes::moztreecell; + if (aColumn->IsPrimary()) { // If we're the primary column, we have indentation and a twisty. PRInt32 level; @@ -1548,10 +1558,6 @@ nsTreeBodyFrame::GetItemWithinCellAt(nscoord aX, const nsRect& aCellRect, hasTwisty = PR_TRUE; } - nsPresContext* presContext = PresContext(); - nsCOMPtr rc; - presContext->PresShell()->CreateRenderingContext(this, getter_AddRefs(rc)); - // Resolve style for the twisty. nsStyleContext* twistyContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreetwisty); @@ -1622,12 +1628,9 @@ nsTreeBodyFrame::GetItemWithinCellAt(nscoord aX, const nsRect& aCellRect, AdjustForBorderPadding(textContext, textRect); - nsCOMPtr renderingContext; - PresContext()->PresShell()->CreateRenderingContext(this, getter_AddRefs(renderingContext)); + nsLayoutUtils::SetFontFromStyle(rc, textContext); - nsLayoutUtils::SetFontFromStyle(renderingContext, textContext); - - AdjustForCellText(cellText, aRowIndex, aColumn, *renderingContext, textRect); + AdjustForCellText(cellText, aRowIndex, aColumn, *rc, textRect); if (isRTL) textRect.x = currX + remainingWidth - textRect.width; @@ -1775,10 +1778,9 @@ nsTreeBodyFrame::IsCellCropped(PRInt32 aRow, nsITreeColumn* aCol, PRBool *_retva if (!col) return NS_ERROR_INVALID_ARG; - nsCOMPtr rc; - rv = PresContext()->PresShell()-> - CreateRenderingContext(this, getter_AddRefs(rc)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr rc = + PresContext()->PresShell()->GetReferenceRenderingContext(); + NS_ENSURE_TRUE(rc, NS_ERROR_FAILURE); rv = GetCellWidth(aRow, col, rc, desiredSize, currentSize); NS_ENSURE_SUCCESS(rv, rv);