diff --git a/mozilla/content/base/src/nsPrintEngine.cpp b/mozilla/content/base/src/nsPrintEngine.cpp index 136442305a8..81dc32c7076 100644 --- a/mozilla/content/base/src/nsPrintEngine.cpp +++ b/mozilla/content/base/src/nsPrintEngine.cpp @@ -552,6 +552,18 @@ nsresult nsPrintEngine::GetSeqFrameAndCountPages(nsIFrame*& aSeqFrame, PRInt32& //-- Section: nsIWebBrowserPrint //--------------------------------------------------------------------------------- +// Foward decl for Debug Helper Functions +#ifdef EXTENDED_DEBUG_PRINTING +int RemoveFilesInDir(const char * aDir); +void GetDocTitleAndURL(nsPrintObject* aPO, char *& aDocStr, char *& aURLStr); +void DumpPrintObjectsTree(nsPrintObject * aPO, int aLevel, FILE* aFD); +void DumpPrintObjectsList(nsVoidArray * aDocList); +void RootFrameList(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent); +void DumpViews(nsIDocShell* aDocShell, FILE* out); +void DumpLayoutData(char* aTitleStr, char* aURLStr, nsIPresContext* aPresContext, nsIDeviceContext * aDC, + nsIFrame * aRootFrame, nsIWebShell * aWebShell, FILE* aFD); +#endif + //--------------------------------------------------------------------------------- NS_IMETHODIMP nsPrintEngine::Print(nsIPrintSettings* aPrintSettings, @@ -2210,25 +2222,18 @@ nsPrintEngine::GetDisplayTitleAndURL(nsPrintObject* aPO, //--------------------------------------------------------------------- nsresult nsPrintEngine::DocumentReadyForPrinting() { - nsresult rv = NS_ERROR_FAILURE; - nsCOMPtr webContainer; + if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) { + CheckForChildFrameSets(mPrt->mPrintObject); + } - webContainer = do_QueryInterface(mContainer); - if(webContainer) { - - if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) { - CheckForChildFrameSets(mPrt->mPrintObject); - } - - // - // Send the document to the printer... - // - rv = SetupToPrintContent(webContainer, mPrt->mPrintDC, mPrt->mCurrentFocusWin); - if (NS_FAILED(rv)) { - // The print job was canceled or there was a problem - // So remove all other documents from the print list - DonePrintingPages(nsnull, rv); - } + // + // Send the document to the printer... + // + nsresult rv = SetupToPrintContent(mPrt->mPrintDC, mPrt->mCurrentFocusWin); + if (NS_FAILED(rv)) { + // The print job was canceled or there was a problem + // So remove all other documents from the print list + DonePrintingPages(nsnull, rv); } return rv; } @@ -2367,12 +2372,10 @@ nsPrintEngine::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrinting) //------------------------------------------------------- nsresult -nsPrintEngine::SetupToPrintContent(nsIWebShell* aParent, - nsIDeviceContext* aDContext, - nsIDOMWindowInternal* aCurrentFocusedDOMWin) +nsPrintEngine::SetupToPrintContent(nsIDeviceContext* aDContext, + nsIDOMWindowInternal* aCurrentFocusedDOMWin) { - NS_ENSURE_ARG_POINTER(aParent); NS_ENSURE_ARG_POINTER(aDContext); // NOTE: aCurrentFocusedDOMWin may be null (which is OK) @@ -2399,27 +2402,33 @@ nsPrintEngine::SetupToPrintContent(nsIWebShell* aParent, doSetPixelScale = PR_TRUE; } + // If we are doing "shrink to fit" then request that the first + // reflow is constrained + if (mPrt->mShrinkToFit && !ppIsShrinkToFit) { + mPrt->mPrintOptions->SetDoUncontrainedReflow(PR_TRUE); + } + // Here we reflow all the PrintObjects nsresult rv = ReflowDocList(mPrt->mPrintObject, doSetPixelScale, mPrt->mShrinkToFit); CHECK_RUNTIME_ERROR_CONDITION(nsIDebugObject::PRT_RUNTIME_REFLOWDOCLIST, rv, NS_ERROR_FAILURE); if (NS_FAILED(rv)) { + mPrt->mPrintOptions->SetDoUncontrainedReflow(PR_FALSE); return NS_ERROR_FAILURE; } // Here is where we do the extra reflow for shrinking the content // But skip this step if we are in PrintPreview if (mPrt->mShrinkToFit && !ppIsShrinkToFit) { + // Turn off the request for unconstrained reflow + mPrt->mPrintOptions->SetDoUncontrainedReflow(PR_FALSE); + + // Now look for the PO that has the smallest percent for shrink to fit if (mPrt->mPrintDocList->Count() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) { - nsPrintObject* xMostPO = FindXMostPO(); - NS_ASSERTION(xMostPO, "There must always be an XMost PO!"); - if (xMostPO) { - // The margin is included in the PO's mRect so we need to subtract it - nsMargin margin(0,0,0,0); - mPrt->mPrintSettings->GetMarginInTwips(margin); - nsRect rect = xMostPO->mRect; - rect.x -= margin.left; + nsPrintObject* smallestPO = FindSmallestSTF(); + NS_ASSERTION(smallestPO, "There must always be an XMost PO!"); + if (smallestPO) { // Calc the shrinkage based on the entire content area - mPrt->mShrinkRatio = float(rect.XMost()) / float(rect.x + xMostPO->mXMost); + mPrt->mShrinkRatio = smallestPO->mShrinkRatio; } } else { // Single document so use the Shrink as calculated for the PO @@ -2460,16 +2469,11 @@ nsPrintEngine::SetupToPrintContent(nsIWebShell* aParent, { float calcRatio; if (mPrt->mPrintDocList->Count() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) { - nsPrintObject* xMostPO = FindXMostPO(); - NS_ASSERTION(xMostPO, "There must always be an XMost PO!"); - if (xMostPO) { - // The margin is included in the PO's mRect so we need to subtract it - nsMargin margin(0,0,0,0); - mPrt->mPrintSettings->GetMarginInTwips(margin); - nsRect rect = xMostPO->mRect; - rect.x -= margin.left; + nsPrintObject* smallestPO = FindSmallestSTF(); + NS_ASSERTION(smallestPO, "There must always be an XMost PO!"); + if (smallestPO) { // Calc the shrinkage based on the entire content area - calcRatio = float(rect.XMost()) / float(rect.x + xMostPO->mXMost); + calcRatio = smallestPO->mShrinkRatio; } } else { // Single document so use the Shrink as calculated for the PO @@ -2634,17 +2638,6 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // If it is hidden don't bother reflow it or any of it's children if (aPO->mIsHidden) return NS_OK; - // Now locate the nsIDocument for the WebShell - nsCOMPtr docShell(do_QueryInterface(aPO->mWebShell)); - NS_ASSERTION(docShell, "The DocShell can't be NULL!"); - - nsCOMPtr wsPresShell; - docShell->GetPresShell(getter_AddRefs(wsPresShell)); - NS_ASSERTION(wsPresShell, "The PresShell can't be NULL!"); - - nsCOMPtr document; - wsPresShell->GetDocument(getter_AddRefs(document)); - // create the PresContext PRBool containerIsSet = PR_FALSE; nsresult rv; @@ -2676,7 +2669,7 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // init it with the DC (aPO->mPresContext)->Init(mPrt->mPrintDocDC); - mDocViewerPrint->CreateStyleSet(document, getter_AddRefs(aPO->mStyleSet)); + mDocViewerPrint->CreateStyleSet(aPO->mDocument, getter_AddRefs(aPO->mStyleSet)); aPO->mViewManager = do_CreateInstance(kViewManagerCID, &rv); if (NS_FAILED(rv)) { @@ -2688,8 +2681,8 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) return rv; } - rv = document->CreateShell(aPO->mPresContext, aPO->mViewManager, - aPO->mStyleSet, getter_AddRefs(aPO->mPresShell)); + rv = aPO->mDocument->CreateShell(aPO->mPresContext, aPO->mViewManager, + aPO->mStyleSet, getter_AddRefs(aPO->mPresShell)); if (NS_FAILED(rv)) { return rv; } @@ -2783,7 +2776,7 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // Setup hierarchical relationship in view manager aPO->mViewManager->SetRootView(aPO->mRootView); - aPO->mPresShell->Init(document, aPO->mPresContext, + aPO->mPresShell->Init(aPO->mDocument, aPO->mPresContext, aPO->mViewManager, aPO->mStyleSet, mode); if (!containerIsSet) { @@ -2854,7 +2847,7 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // Transfer Selection Ranges to the new Print PresShell nsCOMPtr selection; nsCOMPtr selectionPS; - nsresult rvv = mDocViewerPrint->GetDocumentSelection(getter_AddRefs(selection), wsPresShell); + nsresult rvv = mDocViewerPrint->GetDocumentSelection(getter_AddRefs(selection), aPO->mDisplayPresShell); if (NS_SUCCEEDED(rvv) && selection) { rvv = mDocViewerPrint->GetDocumentSelection(getter_AddRefs(selectionPS), aPO->mPresShell); if (NS_SUCCEEDED(rvv) && selectionPS) { @@ -2875,69 +2868,12 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // this is the frame where the right-hand side of the frame extends // the furthest if (mPrt->mShrinkToFit) { - // First find the seq frame - nsIFrame* rootFrame; - aPO->mPresShell->GetRootFrame(&rootFrame); - NS_ASSERTION(rootFrame, "There has to be a root frame!"); - if (rootFrame) { - nsIFrame* seqFrame; - rootFrame->FirstChild(aPO->mPresContext, nsnull, &seqFrame); - while (seqFrame) { - nsCOMPtr frameType; - seqFrame->GetFrameType(getter_AddRefs(frameType)); - if (nsLayoutAtoms::sequenceFrame == frameType.get()) { - break; - } - seqFrame->FirstChild(aPO->mPresContext, nsnull, &seqFrame); - } - NS_ASSERTION(seqFrame, "There has to be a Sequence frame!"); - if (seqFrame) { - // Get the first page of all the pages - nsIFrame* pageFrame; - seqFrame->FirstChild(aPO->mPresContext, nsnull, &pageFrame); - NS_ASSERTION(pageFrame, "There has to be a Page Frame!"); - // loop thru all the Page Frames - nscoord overallMaxWidth = 0; - nscoord overMaxRectWidth = 0; - while (pageFrame) { - nsIFrame* child; - // Now get it's first child (for HTML docs it is an area frame) - // then gets it size which would be the size it is suppose to be to fit - pageFrame->FirstChild(aPO->mPresContext, nsnull, &child); - NS_ASSERTION(child, "There has to be a child frame!"); - - nsRect rect; - child->GetRect(rect); - // Create a RenderingContext and set the PresContext - // appropriately if we are printing selection - nsCOMPtr rc; - if (nsIPrintSettings::kRangeSelection == printRangeType) { - aPO->mPresContext->SetIsRenderingOnlySelection(PR_TRUE); - mPrt->mPrintDocDC->CreateRenderingContext(*getter_AddRefs(rc)); - } - // Find the Size of the XMost frame - // then calc the ratio for shrinkage - nscoord maxWidth = 0; - FindXMostFrameSize(aPO->mPresContext, rc, child, 0, 0, maxWidth); - if (maxWidth > overallMaxWidth) { - overallMaxWidth = maxWidth; - overMaxRectWidth = rect.width; - } - pageFrame->GetNextSibling(&pageFrame); - } // while - // Now calc the ratio from the widest frames from all the pages - float ratio = 1.0f; - NS_ASSERTION(overallMaxWidth, "Overall Max Width must be bigger than zero"); - if (overallMaxWidth > 0) { - ratio = float(overMaxRectWidth) / float(overallMaxWidth); - aPO->mXMost = overallMaxWidth; - aPO->mShrinkRatio = PR_MIN(ratio, 1.0f); + nsIPageSequenceFrame* pageSequence; + aPO->mPresShell->GetPageSequenceFrame(&pageSequence); + pageSequence->GetSTFPercent(aPO->mShrinkRatio); #ifdef EXTENDED_DEBUG_PRINTING - printf("PO %p ****** RW: %d MW: %d xMost %d width: %d %10.4f\n", aPO, overMaxRectWidth, overallMaxWidth, aPO->mXMost, overMaxRectWidth, ratio*100.0); + printf("PO %p ****** STF Ratio %10.4f\n", aPO, aPO->mShrinkRatio*100.0f); #endif - } - } - } } } @@ -3218,7 +3154,6 @@ nsPrintEngine::DoPrint(nsPrintObject * aPO, PRBool aDoSyncPrinting, PRBool& aDon nsIPresContext* poPresContext = aPO->mPresContext; nsIView* poRootView = aPO->mRootView; - nsCOMPtr webContainer(do_QueryInterface(mContainer)); NS_ASSERTION(webShell, "The WebShell can't be NULL!"); if (mPrt->mPrintProgressParams) { @@ -3378,7 +3313,7 @@ nsPrintEngine::DoPrint(nsPrintObject * aPO, PRBool aDoSyncPrinting, PRBool& aDon char * docStr; char * urlStr; GetDocTitleAndURL(aPO, docStr, urlStr); - DumpLayoutData(docStr, urlStr, poPresContext, mPrt->mPrintDocDC, rootFrame, webShell); + DumpLayoutData(docStr, urlStr, poPresContext, mPrt->mPrintDocDC, rootFrame, webShell, nsnull); if (docStr) nsMemory::Free(docStr); if (urlStr) nsMemory::Free(urlStr); } @@ -4483,125 +4418,30 @@ nsPrintEngine::EnablePOsForPrinting() return NS_OK; } -//------------------------------------------------------- -// Find the Frame in a Frame List that is XMost -void -nsPrintEngine::FindXMostFrameInList(nsIPresContext* aPresContext, - nsIRenderingContext* aRC, - nsIAtom* aList, - nsIFrame* aFrame, - nscoord aX, - nscoord aY, - PRInt32& aMaxWidth) -{ - nsIFrame * child; - aFrame->FirstChild(aPresContext, aList, &child); - while (child) { - PRBool isVisible = PR_TRUE; - // If the aRC is nsnull, then we skip the more expensive check and - // just check visibility - if (aRC) { - child->IsVisibleForPainting(aPresContext, *aRC, PR_TRUE, &isVisible); - } else { - nsCOMPtr sc; - child->GetStyleContext(getter_AddRefs(sc)); - if (sc) { - const nsStyleVisibility* vis = (const nsStyleVisibility*)sc->GetStyleData(eStyleStruct_Visibility); - isVisible = vis->IsVisible(); - } - } - - if (isVisible) { - nsRect rect; - child->GetRect(rect); - rect.x += aX; - rect.y += aY; - nscoord xMost = rect.XMost(); - // make sure we have a reasonable value - NS_ASSERTION(xMost < NS_UNCONSTRAINEDSIZE, "Some frame's size is bad."); - if (xMost >= NS_UNCONSTRAINEDSIZE) { - xMost = 0; - } - -#ifdef DEBUG_PRINTING_X // keep this here but leave it turned off - nsAutoString tmp; - nsIFrameDebug* frameDebug; - if (NS_SUCCEEDED(CallQueryInterface(child, &frameDebug))) { - frameDebug->GetFrameName(tmp); - } - printf("%p - %d,%d,%d,%d %s (%d > %d)\n", child, rect.x, rect.y, rect.width, rect.height, NS_LossyConvertUCS2toASCII(tmp).get(), xMost, aMaxWidth); -#endif - - if (xMost > aMaxWidth) { - aMaxWidth = xMost; -#ifdef DEBUG_PRINTING_X // keep this here but leave it turned off - printf("%p - %d %s ", child, aMaxWidth, NS_LossyConvertUCS2toASCII(tmp).get()); - if (aList == nsLayoutAtoms::overflowList) printf(" nsLayoutAtoms::overflowList\n"); - if (aList == nsLayoutAtoms::floaterList) printf(" nsLayoutAtoms::floaterList\n"); - if (aList == nsLayoutAtoms::fixedList) printf(" nsLayoutAtoms::fixedList\n"); - if (aList == nsLayoutAtoms::absoluteList) printf(" nsLayoutAtoms::absoluteList\n"); - if (aList == nsnull) printf(" nsnull\n"); -#endif - } - FindXMostFrameSize(aPresContext, aRC, child, rect.x, rect.y, aMaxWidth); - } - child->GetNextSibling(&child); - } -} - -//------------------------------------------------------- -// Find the Frame that is XMost -void -nsPrintEngine::FindXMostFrameSize(nsIPresContext* aPresContext, - nsIRenderingContext* aRC, - nsIFrame* aFrame, - nscoord aX, - nscoord aY, - PRInt32& aMaxWidth) -{ - NS_ASSERTION(aPresContext, "Pointer is null!"); - NS_ASSERTION(aFrame, "Pointer is null!"); - - // loop thru named child lists - nsIAtom* childListName = nsnull; - PRInt32 childListIndex = 0; - do { - FindXMostFrameInList(aPresContext, aRC, childListName, aFrame, aX, aY, aMaxWidth); - NS_IF_RELEASE(childListName); - aFrame->GetAdditionalChildListName(childListIndex++, &childListName); - } while (childListName); - -} - - //------------------------------------------------------- // Return the nsPrintObject with that is XMost (The widest frameset frame) AND // contains the XMost (widest) layout frame nsPrintObject* -nsPrintEngine::FindXMostPO() +nsPrintEngine::FindSmallestSTF() { - nscoord xMostForPO = 0; - nscoord xMost = 0; - nsPrintObject* xMostPO = nsnull; + float smallestRatio = 1.0f; + nsPrintObject* smallestPO = nsnull; for (PRInt32 i=0;imPrintDocList->Count();i++) { nsPrintObject* po = (nsPrintObject*)mPrt->mPrintDocList->ElementAt(i); NS_ASSERTION(po, "nsPrintObject can't be null!"); if (po->mFrameType != eFrameSet && po->mFrameType != eIFrame) { - if (po->mRect.XMost() >= xMostForPO) { - if (po->mRect.XMost() > xMostForPO || (po->mRect.XMost() == xMostForPO && po->mXMost > xMost)) { - xMostForPO = po->mRect.XMost(); - xMost = po->mXMost; - xMostPO = po; - } + if (po->mShrinkRatio < smallestRatio) { + smallestRatio = po->mShrinkRatio; + smallestPO = po; } } } #ifdef EXTENDED_DEBUG_PRINTING - if (xMostPO) printf("*PO: %p Type: %d XM: %d XM2: %d %10.3f\n", xMostPO, xMostPO->mFrameType, xMostPO->mRect.XMost(), xMostPO->mXMost, xMostPO->mShrinkRatio); + if (smallestPO) printf("*PO: %p Type: %d %10.3f\n", smallestPO, smallestPO->mFrameType, smallestPO->mShrinkRatio); #endif - return xMostPO; + return smallestPO; } //------------------------------------------------------- @@ -4981,7 +4821,7 @@ DumpViews(nsIDocShell* aDocShell, FILE* out) if (nsnull != aDocShell) { fprintf(out, "docshell=%p \n", aDocShell); - nsIPresShell* shell = GetPresShellFor(aDocShell); + nsIPresShell* shell = nsPrintEngine::GetPresShellFor(aDocShell); if (nsnull != shell) { nsCOMPtr vm; shell->GetViewManager(getter_AddRefs(vm)); @@ -5107,7 +4947,7 @@ static void DumpPrintObjectsList(nsVoidArray * aDocList) } //------------------------------------------------------------- -static void DumpPrintObjectsTree(nsPrintObject * aPO, int aLevel= 0, FILE* aFD = nsnull) +static void DumpPrintObjectsTree(nsPrintObject * aPO, int aLevel, FILE* aFD) { if (!kPrintingLogMod || kPrintingLogMod->level != DUMP_LAYOUT_LEVEL) return; @@ -5162,7 +5002,7 @@ static void GetDocTitleAndURL(nsPrintObject* aPO, char *& aDocStr, char *& aURLS //------------------------------------------------------------- static void DumpPrintObjectsTreeLayout(nsPrintObject * aPO, nsIDeviceContext * aDC, - int aLevel= 0, FILE * aFD = nsnull) + int aLevel, FILE * aFD) { if (!kPrintingLogMod || kPrintingLogMod->level != DUMP_LAYOUT_LEVEL) return; diff --git a/mozilla/content/base/src/nsPrintEngine.h b/mozilla/content/base/src/nsPrintEngine.h index 91a2cfb0639..1475c3043a2 100644 --- a/mozilla/content/base/src/nsPrintEngine.h +++ b/mozilla/content/base/src/nsPrintEngine.h @@ -131,18 +131,10 @@ public: nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc); - nsresult SetupToPrintContent(nsIWebShell* aParent, - nsIDeviceContext* aDContext, + nsresult SetupToPrintContent(nsIDeviceContext* aDContext, nsIDOMWindowInternal* aCurrentFocusedDOMWin); nsresult EnablePOsForPrinting(); - nsPrintObject* FindXMostPO(); - void FindXMostFrameSize(nsIPresContext* aPresContext, - nsIRenderingContext* aRC, nsIFrame* aFrame, - nscoord aX, nscoord aY, PRInt32& aMaxWidth); - void FindXMostFrameInList(nsIPresContext* aPresContext, - nsIRenderingContext* aRC, nsIAtom* aList, - nsIFrame* aFrame, nscoord aX, nscoord aY, - PRInt32& aMaxWidth); + nsPrintObject* FindSmallestSTF(); PRBool PrintDocContent(nsPrintObject* aPO, nsresult& aStatus); nsresult DoPrint(nsPrintObject * aPO, PRBool aDoSyncPrinting, @@ -237,7 +229,7 @@ public: void GetWebShellTitleAndURL(nsIWebShell* aWebShell, nsIDocument* aDoc, PRUnichar** aTitle, PRUnichar** aURLStr); - void GetDisplayTitleAndURL(nsPrintObject* aPO, + static void GetDisplayTitleAndURL(nsPrintObject* aPO, nsIPrintSettings* aPrintSettings, const PRUnichar* aBrandName, PRUnichar** aTitle, @@ -267,6 +259,8 @@ public: nsCOMPtr& aVM, nsCOMPtr& aW); + static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell); + // These calls also update the DocViewer void SetIsPrinting(PRBool aIsPrinting) { mIsDoingPrinting = aIsPrinting; } PRBool GetIsPrinting() { return mIsDoingPrinting; } @@ -289,7 +283,6 @@ protected: #endif protected: - static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell); void FirePrintCompletionEvent(); nsresult ShowDocListInternal(nsPrintObject* aPO, PRBool aShow); nsresult GetSeqFrameAndCountPagesInternal(nsPrintObject* aPO, @@ -324,7 +317,7 @@ protected: nsIDeviceContext* mDeviceContext; // not ref counted nsIPresContext* mPresContext; // not ref counted nsCOMPtr mWindow; - + nsPrintData* mPrt; nsPagePrintTimer* mPagePrintTimer; nsIPageSequenceFrame* mPageSeqFrame; @@ -339,7 +332,6 @@ protected: PRBool mIsCachingPresentation; CachedPresentationObj* mCachedPresObj; - FILE* mDebugFile; private: diff --git a/mozilla/gfx/idl/nsIPrintOptions.idl b/mozilla/gfx/idl/nsIPrintOptions.idl index 8f2596f6d28..d96484a9f14 100644 --- a/mozilla/gfx/idl/nsIPrintOptions.idl +++ b/mozilla/gfx/idl/nsIPrintOptions.idl @@ -95,6 +95,10 @@ interface nsIPrintOptions : nsISupports /* Purposely made this an "in" arg */ [noscript] void GetDefaultFont(in nsNativeFontRef aFont); + /* caches bool value so we know how to reflow + This will get picked by the nsSequencePageFrame */ + [noscript] attribute boolean doUncontrainedReflow; + /** * Native data constants */ diff --git a/mozilla/gfx/src/nsPrintOptionsImpl.cpp b/mozilla/gfx/src/nsPrintOptionsImpl.cpp index dfed57e5b79..c666cb0b65e 100644 --- a/mozilla/gfx/src/nsPrintOptionsImpl.cpp +++ b/mozilla/gfx/src/nsPrintOptionsImpl.cpp @@ -113,7 +113,8 @@ nsFont* nsPrintOptions::sDefaultFont = nsnull; * See documentation in nsPrintOptionsImpl.h * @update 6/21/00 dwc */ -nsPrintOptions::nsPrintOptions() +nsPrintOptions::nsPrintOptions() : + mDoUncontrainedReflow(PR_FALSE) { NS_INIT_ISUPPORTS(); @@ -259,6 +260,21 @@ nsPrintOptions::GetDefaultFont(nsFont &aFont) return NS_OK; } +/* [noscript] attribute boolean doUncontrainedReflow; */ +NS_IMETHODIMP +nsPrintOptions::GetDoUncontrainedReflow(PRBool *aDoUncontrainedReflow) +{ + NS_ENSURE_ARG_POINTER(aDoUncontrainedReflow); + *aDoUncontrainedReflow = mDoUncontrainedReflow; + return NS_OK; +} +NS_IMETHODIMP +nsPrintOptions::SetDoUncontrainedReflow(PRBool aDoUncontrainedReflow) +{ + mDoUncontrainedReflow = aDoUncontrainedReflow; + return NS_OK; +} + /** --------------------------------------------------- * See documentation in nsPrintOptionsImpl.h * @update 6/21/00 dwc diff --git a/mozilla/gfx/src/nsPrintOptionsImpl.h b/mozilla/gfx/src/nsPrintOptionsImpl.h index bf85d3115fe..fdb55e25fb9 100644 --- a/mozilla/gfx/src/nsPrintOptionsImpl.h +++ b/mozilla/gfx/src/nsPrintOptionsImpl.h @@ -69,6 +69,7 @@ protected: nsCOMPtr mGlobalPrintSettings; nsCString mPrefName; + PRBool mDoUncontrainedReflow; static nsFont* sDefaultFont; }; diff --git a/mozilla/layout/base/public/nsIPageSequenceFrame.h b/mozilla/layout/base/public/nsIPageSequenceFrame.h index ca667f97445..43548601216 100644 --- a/mozilla/layout/base/public/nsIPageSequenceFrame.h +++ b/mozilla/layout/base/public/nsIPageSequenceFrame.h @@ -154,6 +154,9 @@ public: // Gets the dead space (the gray area) around the Print Preview Page NS_IMETHOD GetDeadSpaceValue(nscoord* aValue) = 0; + + // For Shrink To Fit + NS_IMETHOD GetSTFPercent(float& aSTFPercent) = 0; private: NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; diff --git a/mozilla/layout/generic/nsIPageSequenceFrame.h b/mozilla/layout/generic/nsIPageSequenceFrame.h index ca667f97445..43548601216 100644 --- a/mozilla/layout/generic/nsIPageSequenceFrame.h +++ b/mozilla/layout/generic/nsIPageSequenceFrame.h @@ -154,6 +154,9 @@ public: // Gets the dead space (the gray area) around the Print Preview Page NS_IMETHOD GetDeadSpaceValue(nscoord* aValue) = 0; + + // For Shrink To Fit + NS_IMETHOD GetSTFPercent(float& aSTFPercent) = 0; private: NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; diff --git a/mozilla/layout/generic/nsPageContentFrame.cpp b/mozilla/layout/generic/nsPageContentFrame.cpp index 51580c5cfd5..4cd3ab957e1 100644 --- a/mozilla/layout/generic/nsPageContentFrame.cpp +++ b/mozilla/layout/generic/nsPageContentFrame.cpp @@ -47,6 +47,7 @@ #include "nsIDeviceContext.h" #include "nsReadableUtils.h" #include "nsIPrintPreviewContext.h" +#include "nsSimplePageSequence.h" #include "nsIView.h" @@ -90,9 +91,32 @@ NS_IMETHODIMP nsPageContentFrame::Reflow(nsIPresContext* aPresContext, nsSize maxSize(aReflowState.availableWidth, aReflowState.availableHeight); nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize); - // Get the child's desired size + // Check to see if we need to do an unconstrained reflow + // If so, then cache the size the page was SUPPOSE to be reflowed to + // so we can use it later to determine a percentage. + PRBool doUnconstrained = PR_FALSE; + if (mPD && mPD->mPrintOptions) { + mPD->mPrintOptions->GetDoUncontrainedReflow(&doUnconstrained); + if (doUnconstrained) { + mPD->mPageContextSize = aReflowState.availableWidth; + maxSize.width = NS_UNCONSTRAINEDSIZE; + kidReflowState.availableWidth = NS_UNCONSTRAINEDSIZE; + kidReflowState.mComputedWidth = NS_UNCONSTRAINEDSIZE; + } + } + + // Reflow the page content area to get the child's desired size ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus); + // This is where we cache the true uncontrained size of the document + // each page may end up with a different constrained size, + // so we must only keep the largest size of all the pages + if (doUnconstrained) { + if (mPD->mPageContextSizeUC == 0 || mPD->mPageContextSizeUC < aDesiredSize.width) { + mPD->mPageContextSizeUC = aDesiredSize.width; + } + } + // Place and size the child FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, 0, 0, 0); diff --git a/mozilla/layout/generic/nsPageContentFrame.h b/mozilla/layout/generic/nsPageContentFrame.h index 2e11f9bc836..f0cdb5cd4da 100644 --- a/mozilla/layout/generic/nsPageContentFrame.h +++ b/mozilla/layout/generic/nsPageContentFrame.h @@ -39,6 +39,7 @@ #include "nsContainerFrame.h" class nsPageFrame; +class nsSharedPageData; // Page frame class used by the simple page sequence frame class nsPageContentFrame : public nsContainerFrame { @@ -63,6 +64,8 @@ public: virtual void SetClipRect(nsRect* aClipRect) { mClipRect = *aClipRect; } + virtual void SetSharedPageData(nsSharedPageData* aPD) { mPD = aPD; } + /** * Get the "type" of the frame * @@ -78,6 +81,7 @@ public: protected: nsPageContentFrame(); nsRect mClipRect; + nsSharedPageData* mPD; }; #endif /* nsPageContentFrame_h___ */ diff --git a/mozilla/layout/generic/nsPageFrame.cpp b/mozilla/layout/generic/nsPageFrame.cpp index 682e4b48f29..dad8726455e 100644 --- a/mozilla/layout/generic/nsPageFrame.cpp +++ b/mozilla/layout/generic/nsPageFrame.cpp @@ -756,6 +756,18 @@ nsPageFrame::DrawBackground(nsIPresContext* aPresContext, } } +void +nsPageFrame::SetSharedPageData(nsSharedPageData* aPD) +{ + mPD = aPD; + // Set the shared data into the page frame before reflow + nsPageContentFrame * pcf = NS_STATIC_CAST(nsPageContentFrame*, mFrames.FirstChild()); + if (pcf) { + pcf->SetSharedPageData(mPD); + } + +} + nsresult NS_NewPageBreakFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) { diff --git a/mozilla/layout/generic/nsPageFrame.h b/mozilla/layout/generic/nsPageFrame.h index 9479c068da4..0470a4d4fe8 100644 --- a/mozilla/layout/generic/nsPageFrame.h +++ b/mozilla/layout/generic/nsPageFrame.h @@ -88,7 +88,7 @@ public: virtual void SuppressHeadersAndFooters(PRBool aDoSup) { mSupressHF = aDoSup; } virtual void SetClipRect(nsRect* aClipRect); - virtual void SetSharedPageData(nsSharedPageData* aPD) { mPD = aPD; } + virtual void SetSharedPageData(nsSharedPageData* aPD); // XXX Part of Temporary fix for Bug 127263 static void SetCreateWidget(PRBool aDoCreateWidget) { mDoCreateWidget = aDoCreateWidget; } diff --git a/mozilla/layout/generic/nsSimplePageSequence.cpp b/mozilla/layout/generic/nsSimplePageSequence.cpp index e0472e8c1b2..9a656226364 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.cpp +++ b/mozilla/layout/generic/nsSimplePageSequence.cpp @@ -1131,3 +1131,18 @@ nsSimplePageSequenceFrame::SetPageSizes(const nsRect& aRect, const nsMargin& aMa mPageData->mReflowMargin = aMarginRect; } +//------------------------------------------------------------------------------ +// For Shrink To Fit +// +// Return the percentage that the page needs to shrink to +// +NS_IMETHODIMP +nsSimplePageSequenceFrame::GetSTFPercent(float& aSTFPercent) +{ + NS_ENSURE_TRUE(mPageData, NS_ERROR_UNEXPECTED); + aSTFPercent = 1.0f; + if (mPageData && (mPageData->mPageContextSizeUC > mPageData->mPageContextSize)) { + aSTFPercent = float(mPageData->mPageContextSize) / float(mPageData->mPageContextSizeUC); + } + return NS_OK; +} diff --git a/mozilla/layout/generic/nsSimplePageSequence.h b/mozilla/layout/generic/nsSimplePageSequence.h index 5809e5361e5..8c6c9b93f55 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.h +++ b/mozilla/layout/generic/nsSimplePageSequence.h @@ -67,6 +67,9 @@ public: nsCOMPtr mPrintSettings; nsCOMPtr mPrintOptions; + + nscoord mPageContextSizeUC; // unconstrained size (width) + nscoord mPageContextSize; // constrained size (width) }; // Simple page sequence frame class. Used when we're in paginated mode @@ -98,6 +101,8 @@ public: // Gets the dead space (the gray area) around the Print Preview Page NS_IMETHOD GetDeadSpaceValue(nscoord* aValue) { *aValue = NS_INCHES_TO_TWIPS(0.25); return NS_OK; }; + // For Shrink To Fit + NS_IMETHOD GetSTFPercent(float& aSTFPercent); // Async Printing NS_IMETHOD StartPrint(nsIPresContext* aPresContext, diff --git a/mozilla/layout/html/base/src/nsPageContentFrame.cpp b/mozilla/layout/html/base/src/nsPageContentFrame.cpp index 51580c5cfd5..4cd3ab957e1 100644 --- a/mozilla/layout/html/base/src/nsPageContentFrame.cpp +++ b/mozilla/layout/html/base/src/nsPageContentFrame.cpp @@ -47,6 +47,7 @@ #include "nsIDeviceContext.h" #include "nsReadableUtils.h" #include "nsIPrintPreviewContext.h" +#include "nsSimplePageSequence.h" #include "nsIView.h" @@ -90,9 +91,32 @@ NS_IMETHODIMP nsPageContentFrame::Reflow(nsIPresContext* aPresContext, nsSize maxSize(aReflowState.availableWidth, aReflowState.availableHeight); nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize); - // Get the child's desired size + // Check to see if we need to do an unconstrained reflow + // If so, then cache the size the page was SUPPOSE to be reflowed to + // so we can use it later to determine a percentage. + PRBool doUnconstrained = PR_FALSE; + if (mPD && mPD->mPrintOptions) { + mPD->mPrintOptions->GetDoUncontrainedReflow(&doUnconstrained); + if (doUnconstrained) { + mPD->mPageContextSize = aReflowState.availableWidth; + maxSize.width = NS_UNCONSTRAINEDSIZE; + kidReflowState.availableWidth = NS_UNCONSTRAINEDSIZE; + kidReflowState.mComputedWidth = NS_UNCONSTRAINEDSIZE; + } + } + + // Reflow the page content area to get the child's desired size ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus); + // This is where we cache the true uncontrained size of the document + // each page may end up with a different constrained size, + // so we must only keep the largest size of all the pages + if (doUnconstrained) { + if (mPD->mPageContextSizeUC == 0 || mPD->mPageContextSizeUC < aDesiredSize.width) { + mPD->mPageContextSizeUC = aDesiredSize.width; + } + } + // Place and size the child FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, 0, 0, 0); diff --git a/mozilla/layout/html/base/src/nsPageContentFrame.h b/mozilla/layout/html/base/src/nsPageContentFrame.h index 2e11f9bc836..f0cdb5cd4da 100644 --- a/mozilla/layout/html/base/src/nsPageContentFrame.h +++ b/mozilla/layout/html/base/src/nsPageContentFrame.h @@ -39,6 +39,7 @@ #include "nsContainerFrame.h" class nsPageFrame; +class nsSharedPageData; // Page frame class used by the simple page sequence frame class nsPageContentFrame : public nsContainerFrame { @@ -63,6 +64,8 @@ public: virtual void SetClipRect(nsRect* aClipRect) { mClipRect = *aClipRect; } + virtual void SetSharedPageData(nsSharedPageData* aPD) { mPD = aPD; } + /** * Get the "type" of the frame * @@ -78,6 +81,7 @@ public: protected: nsPageContentFrame(); nsRect mClipRect; + nsSharedPageData* mPD; }; #endif /* nsPageContentFrame_h___ */ diff --git a/mozilla/layout/html/base/src/nsPageFrame.cpp b/mozilla/layout/html/base/src/nsPageFrame.cpp index 682e4b48f29..dad8726455e 100644 --- a/mozilla/layout/html/base/src/nsPageFrame.cpp +++ b/mozilla/layout/html/base/src/nsPageFrame.cpp @@ -756,6 +756,18 @@ nsPageFrame::DrawBackground(nsIPresContext* aPresContext, } } +void +nsPageFrame::SetSharedPageData(nsSharedPageData* aPD) +{ + mPD = aPD; + // Set the shared data into the page frame before reflow + nsPageContentFrame * pcf = NS_STATIC_CAST(nsPageContentFrame*, mFrames.FirstChild()); + if (pcf) { + pcf->SetSharedPageData(mPD); + } + +} + nsresult NS_NewPageBreakFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) { diff --git a/mozilla/layout/html/base/src/nsPageFrame.h b/mozilla/layout/html/base/src/nsPageFrame.h index 9479c068da4..0470a4d4fe8 100644 --- a/mozilla/layout/html/base/src/nsPageFrame.h +++ b/mozilla/layout/html/base/src/nsPageFrame.h @@ -88,7 +88,7 @@ public: virtual void SuppressHeadersAndFooters(PRBool aDoSup) { mSupressHF = aDoSup; } virtual void SetClipRect(nsRect* aClipRect); - virtual void SetSharedPageData(nsSharedPageData* aPD) { mPD = aPD; } + virtual void SetSharedPageData(nsSharedPageData* aPD); // XXX Part of Temporary fix for Bug 127263 static void SetCreateWidget(PRBool aDoCreateWidget) { mDoCreateWidget = aDoCreateWidget; } diff --git a/mozilla/layout/html/base/src/nsSimplePageSequence.cpp b/mozilla/layout/html/base/src/nsSimplePageSequence.cpp index e0472e8c1b2..9a656226364 100644 --- a/mozilla/layout/html/base/src/nsSimplePageSequence.cpp +++ b/mozilla/layout/html/base/src/nsSimplePageSequence.cpp @@ -1131,3 +1131,18 @@ nsSimplePageSequenceFrame::SetPageSizes(const nsRect& aRect, const nsMargin& aMa mPageData->mReflowMargin = aMarginRect; } +//------------------------------------------------------------------------------ +// For Shrink To Fit +// +// Return the percentage that the page needs to shrink to +// +NS_IMETHODIMP +nsSimplePageSequenceFrame::GetSTFPercent(float& aSTFPercent) +{ + NS_ENSURE_TRUE(mPageData, NS_ERROR_UNEXPECTED); + aSTFPercent = 1.0f; + if (mPageData && (mPageData->mPageContextSizeUC > mPageData->mPageContextSize)) { + aSTFPercent = float(mPageData->mPageContextSize) / float(mPageData->mPageContextSizeUC); + } + return NS_OK; +} diff --git a/mozilla/layout/html/base/src/nsSimplePageSequence.h b/mozilla/layout/html/base/src/nsSimplePageSequence.h index 5809e5361e5..8c6c9b93f55 100644 --- a/mozilla/layout/html/base/src/nsSimplePageSequence.h +++ b/mozilla/layout/html/base/src/nsSimplePageSequence.h @@ -67,6 +67,9 @@ public: nsCOMPtr mPrintSettings; nsCOMPtr mPrintOptions; + + nscoord mPageContextSizeUC; // unconstrained size (width) + nscoord mPageContextSize; // constrained size (width) }; // Simple page sequence frame class. Used when we're in paginated mode @@ -98,6 +101,8 @@ public: // Gets the dead space (the gray area) around the Print Preview Page NS_IMETHOD GetDeadSpaceValue(nscoord* aValue) { *aValue = NS_INCHES_TO_TWIPS(0.25); return NS_OK; }; + // For Shrink To Fit + NS_IMETHOD GetSTFPercent(float& aSTFPercent); // Async Printing NS_IMETHOD StartPrint(nsIPresContext* aPresContext, diff --git a/mozilla/layout/printing/nsPrintEngine.cpp b/mozilla/layout/printing/nsPrintEngine.cpp index 136442305a8..81dc32c7076 100644 --- a/mozilla/layout/printing/nsPrintEngine.cpp +++ b/mozilla/layout/printing/nsPrintEngine.cpp @@ -552,6 +552,18 @@ nsresult nsPrintEngine::GetSeqFrameAndCountPages(nsIFrame*& aSeqFrame, PRInt32& //-- Section: nsIWebBrowserPrint //--------------------------------------------------------------------------------- +// Foward decl for Debug Helper Functions +#ifdef EXTENDED_DEBUG_PRINTING +int RemoveFilesInDir(const char * aDir); +void GetDocTitleAndURL(nsPrintObject* aPO, char *& aDocStr, char *& aURLStr); +void DumpPrintObjectsTree(nsPrintObject * aPO, int aLevel, FILE* aFD); +void DumpPrintObjectsList(nsVoidArray * aDocList); +void RootFrameList(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent); +void DumpViews(nsIDocShell* aDocShell, FILE* out); +void DumpLayoutData(char* aTitleStr, char* aURLStr, nsIPresContext* aPresContext, nsIDeviceContext * aDC, + nsIFrame * aRootFrame, nsIWebShell * aWebShell, FILE* aFD); +#endif + //--------------------------------------------------------------------------------- NS_IMETHODIMP nsPrintEngine::Print(nsIPrintSettings* aPrintSettings, @@ -2210,25 +2222,18 @@ nsPrintEngine::GetDisplayTitleAndURL(nsPrintObject* aPO, //--------------------------------------------------------------------- nsresult nsPrintEngine::DocumentReadyForPrinting() { - nsresult rv = NS_ERROR_FAILURE; - nsCOMPtr webContainer; + if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) { + CheckForChildFrameSets(mPrt->mPrintObject); + } - webContainer = do_QueryInterface(mContainer); - if(webContainer) { - - if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) { - CheckForChildFrameSets(mPrt->mPrintObject); - } - - // - // Send the document to the printer... - // - rv = SetupToPrintContent(webContainer, mPrt->mPrintDC, mPrt->mCurrentFocusWin); - if (NS_FAILED(rv)) { - // The print job was canceled or there was a problem - // So remove all other documents from the print list - DonePrintingPages(nsnull, rv); - } + // + // Send the document to the printer... + // + nsresult rv = SetupToPrintContent(mPrt->mPrintDC, mPrt->mCurrentFocusWin); + if (NS_FAILED(rv)) { + // The print job was canceled or there was a problem + // So remove all other documents from the print list + DonePrintingPages(nsnull, rv); } return rv; } @@ -2367,12 +2372,10 @@ nsPrintEngine::ShowPrintErrorDialog(nsresult aPrintError, PRBool aIsPrinting) //------------------------------------------------------- nsresult -nsPrintEngine::SetupToPrintContent(nsIWebShell* aParent, - nsIDeviceContext* aDContext, - nsIDOMWindowInternal* aCurrentFocusedDOMWin) +nsPrintEngine::SetupToPrintContent(nsIDeviceContext* aDContext, + nsIDOMWindowInternal* aCurrentFocusedDOMWin) { - NS_ENSURE_ARG_POINTER(aParent); NS_ENSURE_ARG_POINTER(aDContext); // NOTE: aCurrentFocusedDOMWin may be null (which is OK) @@ -2399,27 +2402,33 @@ nsPrintEngine::SetupToPrintContent(nsIWebShell* aParent, doSetPixelScale = PR_TRUE; } + // If we are doing "shrink to fit" then request that the first + // reflow is constrained + if (mPrt->mShrinkToFit && !ppIsShrinkToFit) { + mPrt->mPrintOptions->SetDoUncontrainedReflow(PR_TRUE); + } + // Here we reflow all the PrintObjects nsresult rv = ReflowDocList(mPrt->mPrintObject, doSetPixelScale, mPrt->mShrinkToFit); CHECK_RUNTIME_ERROR_CONDITION(nsIDebugObject::PRT_RUNTIME_REFLOWDOCLIST, rv, NS_ERROR_FAILURE); if (NS_FAILED(rv)) { + mPrt->mPrintOptions->SetDoUncontrainedReflow(PR_FALSE); return NS_ERROR_FAILURE; } // Here is where we do the extra reflow for shrinking the content // But skip this step if we are in PrintPreview if (mPrt->mShrinkToFit && !ppIsShrinkToFit) { + // Turn off the request for unconstrained reflow + mPrt->mPrintOptions->SetDoUncontrainedReflow(PR_FALSE); + + // Now look for the PO that has the smallest percent for shrink to fit if (mPrt->mPrintDocList->Count() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) { - nsPrintObject* xMostPO = FindXMostPO(); - NS_ASSERTION(xMostPO, "There must always be an XMost PO!"); - if (xMostPO) { - // The margin is included in the PO's mRect so we need to subtract it - nsMargin margin(0,0,0,0); - mPrt->mPrintSettings->GetMarginInTwips(margin); - nsRect rect = xMostPO->mRect; - rect.x -= margin.left; + nsPrintObject* smallestPO = FindSmallestSTF(); + NS_ASSERTION(smallestPO, "There must always be an XMost PO!"); + if (smallestPO) { // Calc the shrinkage based on the entire content area - mPrt->mShrinkRatio = float(rect.XMost()) / float(rect.x + xMostPO->mXMost); + mPrt->mShrinkRatio = smallestPO->mShrinkRatio; } } else { // Single document so use the Shrink as calculated for the PO @@ -2460,16 +2469,11 @@ nsPrintEngine::SetupToPrintContent(nsIWebShell* aParent, { float calcRatio; if (mPrt->mPrintDocList->Count() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) { - nsPrintObject* xMostPO = FindXMostPO(); - NS_ASSERTION(xMostPO, "There must always be an XMost PO!"); - if (xMostPO) { - // The margin is included in the PO's mRect so we need to subtract it - nsMargin margin(0,0,0,0); - mPrt->mPrintSettings->GetMarginInTwips(margin); - nsRect rect = xMostPO->mRect; - rect.x -= margin.left; + nsPrintObject* smallestPO = FindSmallestSTF(); + NS_ASSERTION(smallestPO, "There must always be an XMost PO!"); + if (smallestPO) { // Calc the shrinkage based on the entire content area - calcRatio = float(rect.XMost()) / float(rect.x + xMostPO->mXMost); + calcRatio = smallestPO->mShrinkRatio; } } else { // Single document so use the Shrink as calculated for the PO @@ -2634,17 +2638,6 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // If it is hidden don't bother reflow it or any of it's children if (aPO->mIsHidden) return NS_OK; - // Now locate the nsIDocument for the WebShell - nsCOMPtr docShell(do_QueryInterface(aPO->mWebShell)); - NS_ASSERTION(docShell, "The DocShell can't be NULL!"); - - nsCOMPtr wsPresShell; - docShell->GetPresShell(getter_AddRefs(wsPresShell)); - NS_ASSERTION(wsPresShell, "The PresShell can't be NULL!"); - - nsCOMPtr document; - wsPresShell->GetDocument(getter_AddRefs(document)); - // create the PresContext PRBool containerIsSet = PR_FALSE; nsresult rv; @@ -2676,7 +2669,7 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // init it with the DC (aPO->mPresContext)->Init(mPrt->mPrintDocDC); - mDocViewerPrint->CreateStyleSet(document, getter_AddRefs(aPO->mStyleSet)); + mDocViewerPrint->CreateStyleSet(aPO->mDocument, getter_AddRefs(aPO->mStyleSet)); aPO->mViewManager = do_CreateInstance(kViewManagerCID, &rv); if (NS_FAILED(rv)) { @@ -2688,8 +2681,8 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) return rv; } - rv = document->CreateShell(aPO->mPresContext, aPO->mViewManager, - aPO->mStyleSet, getter_AddRefs(aPO->mPresShell)); + rv = aPO->mDocument->CreateShell(aPO->mPresContext, aPO->mViewManager, + aPO->mStyleSet, getter_AddRefs(aPO->mPresShell)); if (NS_FAILED(rv)) { return rv; } @@ -2783,7 +2776,7 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // Setup hierarchical relationship in view manager aPO->mViewManager->SetRootView(aPO->mRootView); - aPO->mPresShell->Init(document, aPO->mPresContext, + aPO->mPresShell->Init(aPO->mDocument, aPO->mPresContext, aPO->mViewManager, aPO->mStyleSet, mode); if (!containerIsSet) { @@ -2854,7 +2847,7 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // Transfer Selection Ranges to the new Print PresShell nsCOMPtr selection; nsCOMPtr selectionPS; - nsresult rvv = mDocViewerPrint->GetDocumentSelection(getter_AddRefs(selection), wsPresShell); + nsresult rvv = mDocViewerPrint->GetDocumentSelection(getter_AddRefs(selection), aPO->mDisplayPresShell); if (NS_SUCCEEDED(rvv) && selection) { rvv = mDocViewerPrint->GetDocumentSelection(getter_AddRefs(selectionPS), aPO->mPresShell); if (NS_SUCCEEDED(rvv) && selectionPS) { @@ -2875,69 +2868,12 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink) // this is the frame where the right-hand side of the frame extends // the furthest if (mPrt->mShrinkToFit) { - // First find the seq frame - nsIFrame* rootFrame; - aPO->mPresShell->GetRootFrame(&rootFrame); - NS_ASSERTION(rootFrame, "There has to be a root frame!"); - if (rootFrame) { - nsIFrame* seqFrame; - rootFrame->FirstChild(aPO->mPresContext, nsnull, &seqFrame); - while (seqFrame) { - nsCOMPtr frameType; - seqFrame->GetFrameType(getter_AddRefs(frameType)); - if (nsLayoutAtoms::sequenceFrame == frameType.get()) { - break; - } - seqFrame->FirstChild(aPO->mPresContext, nsnull, &seqFrame); - } - NS_ASSERTION(seqFrame, "There has to be a Sequence frame!"); - if (seqFrame) { - // Get the first page of all the pages - nsIFrame* pageFrame; - seqFrame->FirstChild(aPO->mPresContext, nsnull, &pageFrame); - NS_ASSERTION(pageFrame, "There has to be a Page Frame!"); - // loop thru all the Page Frames - nscoord overallMaxWidth = 0; - nscoord overMaxRectWidth = 0; - while (pageFrame) { - nsIFrame* child; - // Now get it's first child (for HTML docs it is an area frame) - // then gets it size which would be the size it is suppose to be to fit - pageFrame->FirstChild(aPO->mPresContext, nsnull, &child); - NS_ASSERTION(child, "There has to be a child frame!"); - - nsRect rect; - child->GetRect(rect); - // Create a RenderingContext and set the PresContext - // appropriately if we are printing selection - nsCOMPtr rc; - if (nsIPrintSettings::kRangeSelection == printRangeType) { - aPO->mPresContext->SetIsRenderingOnlySelection(PR_TRUE); - mPrt->mPrintDocDC->CreateRenderingContext(*getter_AddRefs(rc)); - } - // Find the Size of the XMost frame - // then calc the ratio for shrinkage - nscoord maxWidth = 0; - FindXMostFrameSize(aPO->mPresContext, rc, child, 0, 0, maxWidth); - if (maxWidth > overallMaxWidth) { - overallMaxWidth = maxWidth; - overMaxRectWidth = rect.width; - } - pageFrame->GetNextSibling(&pageFrame); - } // while - // Now calc the ratio from the widest frames from all the pages - float ratio = 1.0f; - NS_ASSERTION(overallMaxWidth, "Overall Max Width must be bigger than zero"); - if (overallMaxWidth > 0) { - ratio = float(overMaxRectWidth) / float(overallMaxWidth); - aPO->mXMost = overallMaxWidth; - aPO->mShrinkRatio = PR_MIN(ratio, 1.0f); + nsIPageSequenceFrame* pageSequence; + aPO->mPresShell->GetPageSequenceFrame(&pageSequence); + pageSequence->GetSTFPercent(aPO->mShrinkRatio); #ifdef EXTENDED_DEBUG_PRINTING - printf("PO %p ****** RW: %d MW: %d xMost %d width: %d %10.4f\n", aPO, overMaxRectWidth, overallMaxWidth, aPO->mXMost, overMaxRectWidth, ratio*100.0); + printf("PO %p ****** STF Ratio %10.4f\n", aPO, aPO->mShrinkRatio*100.0f); #endif - } - } - } } } @@ -3218,7 +3154,6 @@ nsPrintEngine::DoPrint(nsPrintObject * aPO, PRBool aDoSyncPrinting, PRBool& aDon nsIPresContext* poPresContext = aPO->mPresContext; nsIView* poRootView = aPO->mRootView; - nsCOMPtr webContainer(do_QueryInterface(mContainer)); NS_ASSERTION(webShell, "The WebShell can't be NULL!"); if (mPrt->mPrintProgressParams) { @@ -3378,7 +3313,7 @@ nsPrintEngine::DoPrint(nsPrintObject * aPO, PRBool aDoSyncPrinting, PRBool& aDon char * docStr; char * urlStr; GetDocTitleAndURL(aPO, docStr, urlStr); - DumpLayoutData(docStr, urlStr, poPresContext, mPrt->mPrintDocDC, rootFrame, webShell); + DumpLayoutData(docStr, urlStr, poPresContext, mPrt->mPrintDocDC, rootFrame, webShell, nsnull); if (docStr) nsMemory::Free(docStr); if (urlStr) nsMemory::Free(urlStr); } @@ -4483,125 +4418,30 @@ nsPrintEngine::EnablePOsForPrinting() return NS_OK; } -//------------------------------------------------------- -// Find the Frame in a Frame List that is XMost -void -nsPrintEngine::FindXMostFrameInList(nsIPresContext* aPresContext, - nsIRenderingContext* aRC, - nsIAtom* aList, - nsIFrame* aFrame, - nscoord aX, - nscoord aY, - PRInt32& aMaxWidth) -{ - nsIFrame * child; - aFrame->FirstChild(aPresContext, aList, &child); - while (child) { - PRBool isVisible = PR_TRUE; - // If the aRC is nsnull, then we skip the more expensive check and - // just check visibility - if (aRC) { - child->IsVisibleForPainting(aPresContext, *aRC, PR_TRUE, &isVisible); - } else { - nsCOMPtr sc; - child->GetStyleContext(getter_AddRefs(sc)); - if (sc) { - const nsStyleVisibility* vis = (const nsStyleVisibility*)sc->GetStyleData(eStyleStruct_Visibility); - isVisible = vis->IsVisible(); - } - } - - if (isVisible) { - nsRect rect; - child->GetRect(rect); - rect.x += aX; - rect.y += aY; - nscoord xMost = rect.XMost(); - // make sure we have a reasonable value - NS_ASSERTION(xMost < NS_UNCONSTRAINEDSIZE, "Some frame's size is bad."); - if (xMost >= NS_UNCONSTRAINEDSIZE) { - xMost = 0; - } - -#ifdef DEBUG_PRINTING_X // keep this here but leave it turned off - nsAutoString tmp; - nsIFrameDebug* frameDebug; - if (NS_SUCCEEDED(CallQueryInterface(child, &frameDebug))) { - frameDebug->GetFrameName(tmp); - } - printf("%p - %d,%d,%d,%d %s (%d > %d)\n", child, rect.x, rect.y, rect.width, rect.height, NS_LossyConvertUCS2toASCII(tmp).get(), xMost, aMaxWidth); -#endif - - if (xMost > aMaxWidth) { - aMaxWidth = xMost; -#ifdef DEBUG_PRINTING_X // keep this here but leave it turned off - printf("%p - %d %s ", child, aMaxWidth, NS_LossyConvertUCS2toASCII(tmp).get()); - if (aList == nsLayoutAtoms::overflowList) printf(" nsLayoutAtoms::overflowList\n"); - if (aList == nsLayoutAtoms::floaterList) printf(" nsLayoutAtoms::floaterList\n"); - if (aList == nsLayoutAtoms::fixedList) printf(" nsLayoutAtoms::fixedList\n"); - if (aList == nsLayoutAtoms::absoluteList) printf(" nsLayoutAtoms::absoluteList\n"); - if (aList == nsnull) printf(" nsnull\n"); -#endif - } - FindXMostFrameSize(aPresContext, aRC, child, rect.x, rect.y, aMaxWidth); - } - child->GetNextSibling(&child); - } -} - -//------------------------------------------------------- -// Find the Frame that is XMost -void -nsPrintEngine::FindXMostFrameSize(nsIPresContext* aPresContext, - nsIRenderingContext* aRC, - nsIFrame* aFrame, - nscoord aX, - nscoord aY, - PRInt32& aMaxWidth) -{ - NS_ASSERTION(aPresContext, "Pointer is null!"); - NS_ASSERTION(aFrame, "Pointer is null!"); - - // loop thru named child lists - nsIAtom* childListName = nsnull; - PRInt32 childListIndex = 0; - do { - FindXMostFrameInList(aPresContext, aRC, childListName, aFrame, aX, aY, aMaxWidth); - NS_IF_RELEASE(childListName); - aFrame->GetAdditionalChildListName(childListIndex++, &childListName); - } while (childListName); - -} - - //------------------------------------------------------- // Return the nsPrintObject with that is XMost (The widest frameset frame) AND // contains the XMost (widest) layout frame nsPrintObject* -nsPrintEngine::FindXMostPO() +nsPrintEngine::FindSmallestSTF() { - nscoord xMostForPO = 0; - nscoord xMost = 0; - nsPrintObject* xMostPO = nsnull; + float smallestRatio = 1.0f; + nsPrintObject* smallestPO = nsnull; for (PRInt32 i=0;imPrintDocList->Count();i++) { nsPrintObject* po = (nsPrintObject*)mPrt->mPrintDocList->ElementAt(i); NS_ASSERTION(po, "nsPrintObject can't be null!"); if (po->mFrameType != eFrameSet && po->mFrameType != eIFrame) { - if (po->mRect.XMost() >= xMostForPO) { - if (po->mRect.XMost() > xMostForPO || (po->mRect.XMost() == xMostForPO && po->mXMost > xMost)) { - xMostForPO = po->mRect.XMost(); - xMost = po->mXMost; - xMostPO = po; - } + if (po->mShrinkRatio < smallestRatio) { + smallestRatio = po->mShrinkRatio; + smallestPO = po; } } } #ifdef EXTENDED_DEBUG_PRINTING - if (xMostPO) printf("*PO: %p Type: %d XM: %d XM2: %d %10.3f\n", xMostPO, xMostPO->mFrameType, xMostPO->mRect.XMost(), xMostPO->mXMost, xMostPO->mShrinkRatio); + if (smallestPO) printf("*PO: %p Type: %d %10.3f\n", smallestPO, smallestPO->mFrameType, smallestPO->mShrinkRatio); #endif - return xMostPO; + return smallestPO; } //------------------------------------------------------- @@ -4981,7 +4821,7 @@ DumpViews(nsIDocShell* aDocShell, FILE* out) if (nsnull != aDocShell) { fprintf(out, "docshell=%p \n", aDocShell); - nsIPresShell* shell = GetPresShellFor(aDocShell); + nsIPresShell* shell = nsPrintEngine::GetPresShellFor(aDocShell); if (nsnull != shell) { nsCOMPtr vm; shell->GetViewManager(getter_AddRefs(vm)); @@ -5107,7 +4947,7 @@ static void DumpPrintObjectsList(nsVoidArray * aDocList) } //------------------------------------------------------------- -static void DumpPrintObjectsTree(nsPrintObject * aPO, int aLevel= 0, FILE* aFD = nsnull) +static void DumpPrintObjectsTree(nsPrintObject * aPO, int aLevel, FILE* aFD) { if (!kPrintingLogMod || kPrintingLogMod->level != DUMP_LAYOUT_LEVEL) return; @@ -5162,7 +5002,7 @@ static void GetDocTitleAndURL(nsPrintObject* aPO, char *& aDocStr, char *& aURLS //------------------------------------------------------------- static void DumpPrintObjectsTreeLayout(nsPrintObject * aPO, nsIDeviceContext * aDC, - int aLevel= 0, FILE * aFD = nsnull) + int aLevel, FILE * aFD) { if (!kPrintingLogMod || kPrintingLogMod->level != DUMP_LAYOUT_LEVEL) return; diff --git a/mozilla/layout/printing/nsPrintEngine.h b/mozilla/layout/printing/nsPrintEngine.h index 91a2cfb0639..1475c3043a2 100644 --- a/mozilla/layout/printing/nsPrintEngine.h +++ b/mozilla/layout/printing/nsPrintEngine.h @@ -131,18 +131,10 @@ public: nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc); - nsresult SetupToPrintContent(nsIWebShell* aParent, - nsIDeviceContext* aDContext, + nsresult SetupToPrintContent(nsIDeviceContext* aDContext, nsIDOMWindowInternal* aCurrentFocusedDOMWin); nsresult EnablePOsForPrinting(); - nsPrintObject* FindXMostPO(); - void FindXMostFrameSize(nsIPresContext* aPresContext, - nsIRenderingContext* aRC, nsIFrame* aFrame, - nscoord aX, nscoord aY, PRInt32& aMaxWidth); - void FindXMostFrameInList(nsIPresContext* aPresContext, - nsIRenderingContext* aRC, nsIAtom* aList, - nsIFrame* aFrame, nscoord aX, nscoord aY, - PRInt32& aMaxWidth); + nsPrintObject* FindSmallestSTF(); PRBool PrintDocContent(nsPrintObject* aPO, nsresult& aStatus); nsresult DoPrint(nsPrintObject * aPO, PRBool aDoSyncPrinting, @@ -237,7 +229,7 @@ public: void GetWebShellTitleAndURL(nsIWebShell* aWebShell, nsIDocument* aDoc, PRUnichar** aTitle, PRUnichar** aURLStr); - void GetDisplayTitleAndURL(nsPrintObject* aPO, + static void GetDisplayTitleAndURL(nsPrintObject* aPO, nsIPrintSettings* aPrintSettings, const PRUnichar* aBrandName, PRUnichar** aTitle, @@ -267,6 +259,8 @@ public: nsCOMPtr& aVM, nsCOMPtr& aW); + static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell); + // These calls also update the DocViewer void SetIsPrinting(PRBool aIsPrinting) { mIsDoingPrinting = aIsPrinting; } PRBool GetIsPrinting() { return mIsDoingPrinting; } @@ -289,7 +283,6 @@ protected: #endif protected: - static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell); void FirePrintCompletionEvent(); nsresult ShowDocListInternal(nsPrintObject* aPO, PRBool aShow); nsresult GetSeqFrameAndCountPagesInternal(nsPrintObject* aPO, @@ -324,7 +317,7 @@ protected: nsIDeviceContext* mDeviceContext; // not ref counted nsIPresContext* mPresContext; // not ref counted nsCOMPtr mWindow; - + nsPrintData* mPrt; nsPagePrintTimer* mPagePrintTimer; nsIPageSequenceFrame* mPageSeqFrame; @@ -339,7 +332,6 @@ protected: PRBool mIsCachingPresentation; CachedPresentationObj* mCachedPresObj; - FILE* mDebugFile; private: