From 6de1b08e94a0816273a1a4fc91fee02510c4fd70 Mon Sep 17 00:00:00 2001 From: "sharparrow1%yahoo.com" Date: Sat, 1 Apr 2006 01:19:28 +0000 Subject: [PATCH] =?UTF-8?q?Bug=20244055:=20Page=20layout=20for=20editor.?= =?UTF-8?q?=20=20There=20is=20no=20UI=20yet,=20and=20caret=20display=20is?= =?UTF-8?q?=20buggy=20at=20the=20moment,=20but=20otherwise=20it=20works.?= =?UTF-8?q?=20=20Patch=20by=20Alexandre=20Tr=C3=A9mon,=20r+sr=3Droc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://10.0.0.236/trunk@193366 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/docshell/base/nsIContentViewer.idl | 7 + mozilla/layout/base/nsCSSFrameConstructor.cpp | 4 +- mozilla/layout/base/nsDocumentViewer.cpp | 87 ++++++++- mozilla/layout/base/nsPresContext.cpp | 21 ++- mozilla/layout/base/nsPresContext.h | 9 +- mozilla/layout/generic/nsPageContentFrame.cpp | 96 +++++----- mozilla/layout/generic/nsPageFrame.cpp | 166 +++++++++--------- .../layout/generic/nsSimplePageSequence.cpp | 17 +- mozilla/layout/generic/nsTextFrame.cpp | 11 +- mozilla/layout/xul/base/src/nsBoxFrame.cpp | 3 +- 10 files changed, 258 insertions(+), 163 deletions(-) diff --git a/mozilla/docshell/base/nsIContentViewer.idl b/mozilla/docshell/base/nsIContentViewer.idl index f30a4f965e6..bb57a405e0e 100644 --- a/mozilla/docshell/base/nsIContentViewer.idl +++ b/mozilla/docshell/base/nsIContentViewer.idl @@ -2,6 +2,7 @@ interface nsIDOMDocument; interface nsISHEntry; +interface nsIPrintSettings; %{ C++ @@ -96,4 +97,10 @@ interface nsIContentViewer : nsISupports * the saved presentation state. */ void clearHistoryEntry(); + + /* + * Change the layout to view the document with page layout (like print preview), but + * dynamic and editable (like Galley layout). + */ + void setPageMode(in PRBool aPageMode, in nsIPrintSettings aPrintSettings); }; diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index d81ead44bcc..2449f31eeeb 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -4779,6 +4779,8 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement, PRBool isPaginated = presContext->IsPaginated(); PRBool isPrintPreview = presContext->Type() == nsPresContext::eContext_PrintPreview; + PRBool isPageLayout = + presContext->Type() == nsPresContext::eContext_PageLayout; nsIFrame* rootFrame = nsnull; nsIAtom* rootPseudo; @@ -4841,7 +4843,7 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIContent* aDocElement, } if (isPaginated) { - if (isPrintPreview) { + if (isPrintPreview || isPageLayout) { isScrollable = presContext->HasPaginatedScrolling(); } else { isScrollable = PR_FALSE; // we are printing diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index 13ebfc98b20..05c8662a5fe 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -198,6 +198,12 @@ static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printset #include "prenv.h" #include +//switch to page layout +#include "nsIDeviceContextSpecFactory.h" +#include "nsIDeviceContextSpec.h" +#include "nsGfxCIID.h" +static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTORY_CID); + #ifdef NS_DEBUG #undef NOISY_VIEWER @@ -363,7 +369,8 @@ private: nsIDeviceContext* aDeviceContext, const nsRect& aBounds, PRBool aDoCreation, - PRBool aInPrintPreview); + PRBool aInPrintPreview, + PRBool aNeedMakeCX = PR_TRUE); nsresult InitPresentationStuff(PRBool aDoInitialReflow); nsresult GetPopupNode(nsIDOMNode** aNode); @@ -451,6 +458,7 @@ protected: nsCString mForceCharacterSet; nsCString mPrevDocCharacterSet; + PRPackedBool mIsPageMode; }; @@ -508,7 +516,8 @@ void DocumentViewerImpl::PrepareToStartLoad() DocumentViewerImpl::DocumentViewerImpl(nsPresContext* aPresContext) : mPresContext(aPresContext), mIsSticky(PR_TRUE), - mHintCharsetSource(kCharsetUninitialized) + mHintCharsetSource(kCharsetUninitialized), + mIsPageMode(PR_FALSE) { PrepareToStartLoad(); } @@ -782,7 +791,8 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, nsIDeviceContext* aDeviceContext, const nsRect& aBounds, PRBool aDoCreation, - PRBool aInPrintPreview) + PRBool aInPrintPreview, + PRBool aNeedMakeCX /*= PR_TRUE*/) { mParentWidget = aParentWidget; // not ref counted @@ -803,9 +813,14 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, if (aDoCreation) { if (aParentWidget && !mPresContext) { // Create presentation context - mPresContext = new nsPresContext(GetIsCreatingPrintPreview() ? - nsPresContext::eContext_PrintPreview : - nsPresContext::eContext_Galley); + if (GetIsCreatingPrintPreview()) + mPresContext = new nsPresContext(nsPresContext::eContext_PrintPreview); + else + if (mIsPageMode) { + //Presentation context already created in SetPageMode which is calling this method + } + else + mPresContext = new nsPresContext(nsPresContext::eContext_Galley); NS_ENSURE_TRUE(mPresContext, NS_ERROR_OUT_OF_MEMORY); nsresult rv = mPresContext->Init(aDeviceContext); @@ -815,7 +830,7 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, } #if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW) - makeCX = !GetIsPrintPreview(); // needs to be true except when we are already in PP + makeCX = !GetIsPrintPreview() && aNeedMakeCX; // needs to be true except when we are already in PP or we are enabling/disabling paginated mode. #else makeCX = PR_TRUE; #endif @@ -832,6 +847,22 @@ DocumentViewerImpl::InitInternal(nsIWidget* aParentWidget, rv = MakeWindow(aParentWidget, aBounds); NS_ENSURE_SUCCESS(rv, rv); Hide(); + + if (mIsPageMode) { + nsCOMPtr devctx; + nsCOMPtr devspec; + nsCOMPtr factory = do_CreateInstance(kDeviceContextSpecFactoryCID); + // mWindow has been initialized by preceding call to MakeWindow + factory->CreateDeviceContextSpec(mWindow, mPresContext->GetPrintSettings(), *getter_AddRefs(devspec), PR_FALSE); + mDeviceContext->GetDeviceContextFor(devspec, *getter_AddRefs(devctx)); + mDeviceContext->SetAltDevice(devctx); + mDeviceContext->SetUseAltDC(kUseAltDCFor_SURFACE_DIM, PR_TRUE); + //Get paper dims: + PRInt32 pageWidth, pageHeight; + devctx->GetDeviceSurfaceDimensions(pageWidth, pageHeight); + mPresContext->SetPageSize(nsSize(pageWidth, pageHeight)); + mPresContext->SetIsRootPaginatedDocument(PR_TRUE); + } } } @@ -4227,3 +4258,45 @@ DocumentViewerImpl::OnDonePrinting() } #endif // NS_PRINTING && NS_PRINT_PREVIEW } + +NS_IMETHODIMP DocumentViewerImpl::SetPageMode(PRBool aPageMode, nsIPrintSettings* aPrintSettings) +{ + mIsPageMode = aPageMode; + // Get the current size of what is being viewed + nsRect bounds; + mWindow->GetBounds(bounds); + + if (mPresShell) { + // Break circular reference (or something) + mPresShell->EndObservingDocument(); + nsCOMPtr selection; + nsresult rv = GetDocumentSelection(getter_AddRefs(selection)); + nsCOMPtr selPrivate(do_QueryInterface(selection)); + if (NS_SUCCEEDED(rv) && selPrivate && mSelectionListener) + selPrivate->RemoveSelectionListener(mSelectionListener); + mPresShell->Destroy(); + } + + if (mPresContext) { + mPresContext->SetContainer(nsnull); + mPresContext->SetLinkHandler(nsnull); + } + + mPresShell = nsnull; + mPresContext = nsnull; + mViewManager = nsnull; + mWindow = nsnull; + + if (aPageMode) + { + mPresContext = new nsPresContext(nsPresContext::eContext_PageLayout); + mPresContext->SetPaginatedScrolling(PR_TRUE); + mPresContext->SetPrintSettings(aPrintSettings); + nsresult rv = mPresContext->Init(mDeviceContext); + } + InitInternal(mParentWidget, nsnull, mDeviceContext, bounds, PR_TRUE, PR_FALSE, PR_FALSE); + mViewManager->EnableRefresh(NS_VMREFRESH_NO_SYNC); + + Show(); + return NS_OK; +} \ No newline at end of file diff --git a/mozilla/layout/base/nsPresContext.cpp b/mozilla/layout/base/nsPresContext.cpp index 3e57b115ec6..6008c024295 100644 --- a/mozilla/layout/base/nsPresContext.cpp +++ b/mozilla/layout/base/nsPresContext.cpp @@ -55,7 +55,6 @@ #include "nsIURL.h" #include "nsIDocument.h" #include "nsStyleContext.h" -#include "nsLayoutAtoms.h" #include "nsILookAndFeel.h" #include "nsWidgetsCID.h" #include "nsIComponentManager.h" @@ -156,8 +155,7 @@ static NS_DEFINE_CID(kSelectionImageService, NS_SELECTIONIMAGESERVICE_CID); // bother initializing members to 0. nsPresContext::nsPresContext(nsPresContextType aType) - : mType(aType), - mTextZoom(1.0), + : mType(aType), mTextZoom(1.0), mPageSize(-1, -1), mIsRootPaginatedDocument(PR_FALSE), mCanPaginatedScroll(PR_TRUE), mViewportStyleOverflow(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO), @@ -205,15 +203,20 @@ nsPresContext::nsPresContext(nsPresContextType aType) mLanguageSpecificTransformType = eLanguageSpecificTransformType_Unknown; if (aType == eContext_Galley) { mMedium = nsLayoutAtoms::screen; - mImageAnimationMode = imgIContainer::kNormalAnimMode; } else { SetBackgroundImageDraw(PR_FALSE); SetBackgroundColorDraw(PR_FALSE); - mImageAnimationMode = imgIContainer::kDontAnimMode; - mNeverAnimate = PR_TRUE; mMedium = nsLayoutAtoms::print; mPaginated = PR_TRUE; } + + if (!IsDynamic()) { + mImageAnimationMode = imgIContainer::kDontAnimMode; + mNeverAnimate = PR_TRUE; + } else { + mImageAnimationMode = imgIContainer::kNormalAnimMode; + mNeverAnimate = PR_FALSE; + } } nsPresContext::~nsPresContext() @@ -765,7 +768,7 @@ nsPresContext::SetShell(nsIPresShell* aShell) if (doc) { nsIURI *docURI = doc->GetDocumentURI(); - if (mMedium != nsLayoutAtoms::print && docURI) { + if (IsDynamic() && docURI) { PRBool isChrome = PR_FALSE; PRBool isRes = PR_FALSE; docURI->SchemeIs("chrome", &isChrome); @@ -910,7 +913,7 @@ nsPresContext::SetImageAnimationModeInternal(PRUint16 aMode) aMode == imgIContainer::kLoopOnceAnimMode, "Wrong Animation Mode is being set!"); // Image animation mode cannot be changed when rendering to a printer. - if (mMedium == nsLayoutAtoms::print) + if (!IsDynamic()) return; // This hash table contains a list of background images @@ -1258,7 +1261,7 @@ nsPresContext::SysColorChanged() void nsPresContext::SetPaginatedScrolling(PRBool aPaginated) { - if (mType == eContext_PrintPreview) + if (mType == eContext_PrintPreview || mType == eContext_PageLayout) mCanPaginatedScroll = aPaginated; } diff --git a/mozilla/layout/base/nsPresContext.h b/mozilla/layout/base/nsPresContext.h index c16901712cc..ca62cbdb378 100644 --- a/mozilla/layout/base/nsPresContext.h +++ b/mozilla/layout/base/nsPresContext.h @@ -59,6 +59,7 @@ #include "nsCRT.h" #include "nsIPrintSettings.h" #include "nsPropertyTable.h" +#include "nsLayoutAtoms.h" #ifdef IBMBIDI class nsBidiPresUtils; #endif // IBMBIDI @@ -136,7 +137,8 @@ public: enum nsPresContextType { eContext_Galley, // unpaginated screen presentation eContext_PrintPreview, // paginated screen presentation - eContext_Print // paginated printer presentation + eContext_Print, // paginated printer presentation + eContext_PageLayout // paginated & editable. }; nsPresContext(nsPresContextType aType) NS_HIDDEN; @@ -631,6 +633,11 @@ public: */ const nscoord* GetBorderWidthTable() { return mBorderWidthTable; } + PRBool IsDynamic() { return (mType == eContext_PageLayout || mType == eContext_Galley); }; + PRBool IsScreen() { return (mMedium == nsLayoutAtoms::screen || + mType == eContext_PageLayout || + mType == eContext_PrintPreview); }; + protected: NS_HIDDEN_(void) SetImgAnimations(nsIContent *aParent, PRUint16 aMode); NS_HIDDEN_(void) GetDocumentColorPreferences(); diff --git a/mozilla/layout/generic/nsPageContentFrame.cpp b/mozilla/layout/generic/nsPageContentFrame.cpp index 16a4ece5ddd..e8a15a6d13c 100644 --- a/mozilla/layout/generic/nsPageContentFrame.cpp +++ b/mozilla/layout/generic/nsPageContentFrame.cpp @@ -69,67 +69,65 @@ NS_IMETHODIMP nsPageContentFrame::Reflow(nsPresContext* aPresContext, DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); aStatus = NS_FRAME_COMPLETE; // initialize out parameter - if (eReflowReason_Incremental != aReflowState.reason) { - // Resize our frame allowing it only to be as big as we are - // XXX Pay attention to the page's border and padding... - if (mFrames.NotEmpty()) { - nsIFrame* frame = mFrames.FirstChild(); - nsSize maxSize(aReflowState.availableWidth, aReflowState.availableHeight); - nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize); + // Resize our frame allowing it only to be as big as we are + // XXX Pay attention to the page's border and padding... + if (mFrames.NotEmpty()) { + nsIFrame* frame = mFrames.FirstChild(); + nsSize maxSize(aReflowState.availableWidth, aReflowState.availableHeight); + nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize); - mPD->mPageContentSize = aReflowState.availableWidth; + mPD->mPageContentSize = aReflowState.availableWidth; - // Reflow the page content area to get the child's desired size - ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus); + // Reflow the page content area to get the child's desired size + ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus); - // The document element's background should cover the entire canvas, so - // take into account the combined area and any space taken up by - // absolutely positioned elements - nsMargin padding(0,0,0,0); + // The document element's background should cover the entire canvas, so + // take into account the combined area and any space taken up by + // absolutely positioned elements + nsMargin padding(0,0,0,0); - // XXXbz this screws up percentage padding (sets padding to zero - // in the percentage padding case) - kidReflowState.mStylePadding->GetPadding(padding); + // XXXbz this screws up percentage padding (sets padding to zero + // in the percentage padding case) + kidReflowState.mStylePadding->GetPadding(padding); - // First check the combined area - if (NS_FRAME_OUTSIDE_CHILDREN & frame->GetStateBits()) { - // The background covers the content area and padding area, so check - // for children sticking outside the child frame's padding edge - if (aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) { - mPD->mPageContentXMost = - aDesiredSize.mOverflowArea.XMost() + - kidReflowState.mStyleBorder->GetBorderWidth(NS_SIDE_RIGHT) + - padding.right; - } + // First check the combined area + if (NS_FRAME_OUTSIDE_CHILDREN & frame->GetStateBits()) { + // The background covers the content area and padding area, so check + // for children sticking outside the child frame's padding edge + if (aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) { + mPD->mPageContentXMost = + aDesiredSize.mOverflowArea.XMost() + + kidReflowState.mStyleBorder->GetBorderWidth(NS_SIDE_RIGHT) + + padding.right; } + } - // Place and size the child - FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, 0, 0, 0); + // Place and size the child + FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, 0, 0, 0); - NS_ASSERTION(!NS_FRAME_IS_COMPLETE(aStatus) || - !frame->GetNextInFlow(), "bad child flow list"); + NS_ASSERTION(aPresContext->IsDynamic() || !NS_FRAME_IS_COMPLETE(aStatus) || + !frame->GetNextInFlow(), "bad child flow list"); #ifdef DEBUG_PRINTING - nsRect r = frame->GetRect(); - printf("PCF: Area Frame %p Bounds: %5d,%5d,%5d,%5d\n", frame, r.x, r.y, r.width, r.height); - nsIView* view = frame->GetView(); - if (view) { - r = view->GetBounds(); - printf("PCF: Area Frame View Bounds: %5d,%5d,%5d,%5d\n", r.x, r.y, r.width, r.height); - } else { - printf("PCF: Area Frame View Bounds: NO VIEW\n"); - } + nsRect r = frame->GetRect(); + printf("PCF: Area Frame %p Bounds: %5d,%5d,%5d,%5d\n", frame, r.x, r.y, r.width, r.height); + nsIView* view = frame->GetView(); + if (view) { + r = view->GetBounds(); + printf("PCF: Area Frame View Bounds: %5d,%5d,%5d,%5d\n", r.x, r.y, r.width, r.height); + } else { + printf("PCF: Area Frame View Bounds: NO VIEW\n"); + } #endif - } - // Reflow our fixed frames - mFixedContainer.Reflow(this, aPresContext, aReflowState, aReflowState.availableWidth, - aReflowState.availableHeight); + } + // Reflow our fixed frames + mFixedContainer.Reflow(this, aPresContext, aReflowState, aReflowState.availableWidth, + aReflowState.availableHeight); - // Return our desired size - aDesiredSize.width = aReflowState.availableWidth; - if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { - aDesiredSize.height = aReflowState.availableHeight; - } + // Return our desired size + aDesiredSize.width = aReflowState.availableWidth; + if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { + aDesiredSize.height = aReflowState.availableHeight; } NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); diff --git a/mozilla/layout/generic/nsPageFrame.cpp b/mozilla/layout/generic/nsPageFrame.cpp index 0806cd4310c..1db68078892 100644 --- a/mozilla/layout/generic/nsPageFrame.cpp +++ b/mozilla/layout/generic/nsPageFrame.cpp @@ -136,97 +136,97 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsPresContext* aPresContext, DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); aStatus = NS_FRAME_COMPLETE; // initialize out parameter - if (eReflowReason_Incremental != aReflowState.reason) { - // Do we have any children? - // XXX We should use the overflow list instead... - nsIFrame* firstFrame = mFrames.FirstChild(); - nsPageContentFrame* contentPage = NS_STATIC_CAST(nsPageContentFrame*, firstFrame); - NS_ASSERTION(contentPage, "There should always be a content page"); - NS_ASSERTION(nsLayoutAtoms::pageContentFrame == firstFrame->GetType(), - "This frame isn't a pageContentFrame"); + // Do we have any children? + // XXX We should use the overflow list instead... + nsIFrame* firstFrame = mFrames.FirstChild(); + nsPageContentFrame* contentPage = NS_STATIC_CAST(nsPageContentFrame*, firstFrame); + NS_ASSERTION(contentPage, "There should always be a content page"); + NS_ASSERTION(nsLayoutAtoms::pageContentFrame == firstFrame->GetType(), + "This frame isn't a pageContentFrame"); - if (contentPage && GetPrevInFlow()) { - nsPageFrame* prevPage = NS_STATIC_CAST(nsPageFrame*, GetPrevInFlow()); - nsPageContentFrame* prevContentPage = NS_STATIC_CAST(nsPageContentFrame*, prevPage->mFrames.FirstChild()); - nsIFrame* prevLastChild = prevContentPage->mFrames.LastChild(); + if (contentPage && GetPrevInFlow() && + eReflowReason_Incremental != aReflowState.reason && + eReflowReason_Dirty != aReflowState.reason) { - // Create a continuing child of the previous page's last child - nsIFrame* newFrame; + nsPageFrame* prevPage = NS_STATIC_CAST(nsPageFrame*, GetPrevInFlow()); + nsPageContentFrame* prevContentPage = NS_STATIC_CAST(nsPageContentFrame*, prevPage->mFrames.FirstChild()); + nsIFrame* prevLastChild = prevContentPage->mFrames.LastChild(); - aPresContext->PresShell()->FrameConstructor()-> - CreateContinuingFrame(aPresContext, prevLastChild, - contentPage, &newFrame); + // Create a continuing child of the previous page's last child + nsIFrame* newFrame; - // Make the new area frame the 1st child of the page content frame. There may already be - // children placeholders which don't get reflowed but must not be destroyed until the - // page content frame is destroyed. - contentPage->mFrames.InsertFrame(contentPage, nsnull, newFrame); + aPresContext->PresShell()->FrameConstructor()-> + CreateContinuingFrame(aPresContext, prevLastChild, + contentPage, &newFrame); + + // Make the new area frame the 1st child of the page content frame. There may already be + // children placeholders which don't get reflowed but must not be destroyed until the + // page content frame is destroyed. + contentPage->mFrames.InsertFrame(contentPage, nsnull, newFrame); + } + + // Resize our frame allowing it only to be as big as we are + // XXX Pay attention to the page's border and padding... + if (mFrames.NotEmpty()) { + nsIFrame* frame = mFrames.FirstChild(); + // When the reflow size is NS_UNCONSTRAINEDSIZE it means we are reflowing + // a single page to print selection. So this means we want to use + // NS_UNCONSTRAINEDSIZE without altering it + nscoord avHeight; + if (mPD->mReflowSize.height == NS_UNCONSTRAINEDSIZE) { + avHeight = NS_UNCONSTRAINEDSIZE; + } else { + avHeight = mPD->mReflowSize.height - mPD->mReflowMargin.TopBottom(); + } + nsSize maxSize(mPD->mReflowSize.width - mPD->mReflowMargin.LeftRight(), + avHeight); + // Get the number of Twips per pixel from the PresContext + nscoord onePixelInTwips = aPresContext->IntScaledPixelsToTwips(1); + // insurance against infinite reflow, when reflowing less than a pixel + // XXX Shouldn't we do something more friendly when invalid margins + // are set? + if (maxSize.width < onePixelInTwips || maxSize.height < onePixelInTwips) { + aDesiredSize.width = 0; + aDesiredSize.height = 0; + NS_WARNING("Reflow aborted; no space for content"); + return NS_OK; } - // Resize our frame allowing it only to be as big as we are - // XXX Pay attention to the page's border and padding... - if (mFrames.NotEmpty()) { - nsIFrame* frame = mFrames.FirstChild(); - // When the reflow size is NS_UNCONSTRAINEDSIZE it means we are reflowing - // a single page to print selection. So this means we want to use - // NS_UNCONSTRAINEDSIZE without altering it - nscoord avHeight; - if (mPD->mReflowSize.height == NS_UNCONSTRAINEDSIZE) { - avHeight = NS_UNCONSTRAINEDSIZE; - } else { - avHeight = mPD->mReflowSize.height - mPD->mReflowMargin.TopBottom(); - } - nsSize maxSize(mPD->mReflowSize.width - mPD->mReflowMargin.LeftRight(), - avHeight); - // Get the number of Twips per pixel from the PresContext - nscoord onePixelInTwips = aPresContext->IntScaledPixelsToTwips(1); - // insurance against infinite reflow, when reflowing less than a pixel - // XXX Shouldn't we do something more friendly when invalid margins - // are set? - if (maxSize.width < onePixelInTwips || maxSize.height < onePixelInTwips) { - aDesiredSize.width = 0; - aDesiredSize.height = 0; - NS_WARNING("Reflow aborted; no space for content"); - return NS_OK; - } + nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize); + kidReflowState.mFlags.mIsTopOfPage = PR_TRUE; - nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize); - kidReflowState.mFlags.mIsTopOfPage = PR_TRUE; + // calc location of frame + nscoord xc = mPD->mReflowMargin.left + mPD->mDeadSpaceMargin.left + mPD->mExtraMargin.left; + nscoord yc = mPD->mReflowMargin.top + mPD->mDeadSpaceMargin.top + mPD->mExtraMargin.top; - // calc location of frame - nscoord xc = mPD->mReflowMargin.left + mPD->mDeadSpaceMargin.left + mPD->mExtraMargin.left; - nscoord yc = mPD->mReflowMargin.top + mPD->mDeadSpaceMargin.top + mPD->mExtraMargin.top; + // Get the child's desired size + ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, xc, yc, 0, aStatus); - // Get the child's desired size - ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, xc, yc, 0, aStatus); + // Place and size the child + FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, xc, yc, 0); - - // Place and size the child - FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, xc, yc, 0); - - // Make sure the child is at least as tall as our max size (the containing window) - if (aDesiredSize.height < aReflowState.availableHeight && - aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { - aDesiredSize.height = aReflowState.availableHeight; - } - - nsIView* view = frame->GetView(); - if (view) { - nsRegion region(nsRect(0, 0, aDesiredSize.width, aDesiredSize.height)); - view->GetViewManager()->SetViewChildClipRegion(view, ®ion); - } - - NS_ASSERTION(!NS_FRAME_IS_COMPLETE(aStatus) || - !frame->GetNextInFlow(), "bad child flow list"); - } - PR_PL(("PageFrame::Reflow %p ", this)); - PR_PL(("[%d,%d][%d,%d]\n", aDesiredSize.width, aDesiredSize.height, aReflowState.availableWidth, aReflowState.availableHeight)); - - // Return our desired size - aDesiredSize.width = aReflowState.availableWidth; - if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { + // Make sure the child is at least as tall as our max size (the containing window) + if (aDesiredSize.height < aReflowState.availableHeight && + aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { aDesiredSize.height = aReflowState.availableHeight; } + + nsIView* view = frame->GetView(); + if (view) { + nsRegion region(nsRect(0, 0, aDesiredSize.width, aDesiredSize.height)); + view->GetViewManager()->SetViewChildClipRegion(view, ®ion); + } + + NS_ASSERTION(!NS_FRAME_IS_COMPLETE(aStatus) || + !frame->GetNextInFlow(), "bad child flow list"); + } + PR_PL(("PageFrame::Reflow %p ", this)); + PR_PL(("[%d,%d][%d,%d]\n", aDesiredSize.width, aDesiredSize.height, aReflowState.availableWidth, aReflowState.availableHeight)); + + // Return our desired size + aDesiredSize.width = aReflowState.availableWidth; + if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { + aDesiredSize.height = aReflowState.availableHeight; } PR_PL(("PageFrame::Reflow %p ", this)); PR_PL(("[%d,%d]\n", aReflowState.availableWidth, aReflowState.availableHeight)); @@ -532,7 +532,7 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, { nsDisplayListCollection set; - if (GetPresContext()->Type() == nsPresContext::eContext_PrintPreview) { + if (GetPresContext()->IsScreen()) { nsresult rv = set.BorderBackground()->AppendNewToTop(new (aBuilder) nsDisplayGeneric(this, ::PaintPrintPreviewBackground, "PrintPreviewBackground")); NS_ENSURE_SUCCESS(rv, rv); @@ -608,11 +608,11 @@ nsPageFrame::PaintHeaderFooter(nsIRenderingContext& aRenderingContext, nsPresContext* pc = GetPresContext(); if (!mPD->mPrintSettings) { - if (pc->Type() == nsPresContext::eContext_PrintPreview) { + if (pc->Type() == nsPresContext::eContext_PrintPreview || pc->IsDynamic()) mPD->mPrintSettings = pc->GetPrintSettings(); - } + if (!mPD->mPrintSettings) + return; } - NS_ASSERTION(mPD->mPrintSettings, "Must have a good PrintSettings here!"); // get the current margin mPD->mPrintSettings->GetMarginInTwips(mMargin); diff --git a/mozilla/layout/generic/nsSimplePageSequence.cpp b/mozilla/layout/generic/nsSimplePageSequence.cpp index fbceb174892..c0caaef21a5 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.cpp +++ b/mozilla/layout/generic/nsSimplePageSequence.cpp @@ -213,12 +213,7 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; // we're always complete - // absolutely ignore all other types of reflows - // we only want to have done the Initial Reflow - if (eReflowReason_Resize == aReflowState.reason || - eReflowReason_Incremental == aReflowState.reason || - eReflowReason_StyleChange == aReflowState.reason || - eReflowReason_Dirty == aReflowState.reason) { + if (eReflowReason_Resize == aReflowState.reason) { // Return our desired size aDesiredSize.height = mSize.height; aDesiredSize.width = mSize.width; @@ -277,7 +272,7 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext, nsMargin deadSpaceMargin(0,0,0,0); nsMargin extraMargin(0,0,0,0); nsSize shadowSize(0,0); - if (isPrintPreview && !suppressMargins) { + if (aPresContext->IsScreen() && !suppressMargins) { deadSpaceMargin.SizeTo(deadSpaceGap, deadSpaceGap, deadSpaceGap, deadSpaceGap); extraMargin.SizeTo(extraGap, extraGap, extraGap, extraGap); nscoord fourPixels = aPresContext->IntScaledPixelsToTwips(4); @@ -294,7 +289,8 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext, nsSize reflowPageSize(0,0); // See if it's an incremental reflow command - if (eReflowReason_Incremental == aReflowState.reason) { + if (!aPresContext->IsDynamic() && + eReflowReason_Incremental == aReflowState.reason) { // XXX Skip Incremental reflow, // in fact, all we want is the initial reflow y = mRect.height; @@ -413,6 +409,11 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext, aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; + aDesiredSize.mOverflowArea = nsRect(0, 0, aDesiredSize.width, + aDesiredSize.height); + + FinishAndStoreOverflow(&aDesiredSize); + // cache the size so we can set the desired size // for the other reflows that happen mSize.width = aDesiredSize.width; diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index 5a6107d39c2..e6ef677a5cd 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -3074,7 +3074,7 @@ nsTextFrame::PaintUnicodeText(nsPresContext* aPresContext, iter.Next(); } } - else if (!isPaginated) + else if (!isPaginated || (aPresContext->Type() == nsPresContext::eContext_PageLayout)) { aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor)); aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); @@ -3916,6 +3916,9 @@ nsTextFrame::PaintAsciiText(nsPresContext* aPresContext, sdptr = sdptr->mNext; } + // isDynamic: textFrame receives user interaction + PRBool isDynamic = aPresContext->IsDynamic(); + if (!hideStandardSelection || displaySelection) { //ITS OK TO CAST HERE THE RESULT WE USE WILLNOT DO BAD CONVERSION DrawSelectionIterator iter(details, (PRUnichar *)text, @@ -3975,10 +3978,10 @@ nsTextFrame::PaintAsciiText(nsPresContext* aPresContext, nsRect rect(currentX, dy, newWidth, mRect.height); aRenderingContext.SetClipRect(rect, nsClipCombine_kIntersect); - if (isPaginated && !iter.IsBeforeOrAfter()) { + if (!isDynamic && !iter.IsBeforeOrAfter()) { aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor)); aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); - } else if (!isPaginated) { + } else if (isDynamic) { aRenderingContext.SetColor(nsCSSRendering::TransformColor(currentFGColor,canDarkenColor)); aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); } @@ -3990,7 +3993,7 @@ nsTextFrame::PaintAsciiText(nsPresContext* aPresContext, iter.Next(); } } - else if (!isPaginated) + else if (isDynamic) { aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor)); aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); diff --git a/mozilla/layout/xul/base/src/nsBoxFrame.cpp b/mozilla/layout/xul/base/src/nsBoxFrame.cpp index 5baf9de1548..a96d2c549a4 100644 --- a/mozilla/layout/xul/base/src/nsBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsBoxFrame.cpp @@ -697,7 +697,8 @@ nsBoxFrame::IsInitialReflowForPrintPreview(nsBoxLayoutState& aState, const nsHTMLReflowState* reflowState = aState.GetReflowState(); if (reflowState->reason == eReflowReason_Initial) { // See if we are doing Print Preview - if (aState.PresContext()->Type() == nsPresContext::eContext_PrintPreview) { + if (aState.PresContext()->Type() == nsPresContext::eContext_PrintPreview || + aState.PresContext()->Type() == nsPresContext::eContext_PageLayout) { // Now, get the current URI to see if we doing chrome nsIPresShell *presShell = aState.PresShell(); if (!presShell) return PR_FALSE;