Change STF to use an unconstrainad reflow instead of searching for the widest frame

Bug 168961 r=dcone sr=kin
This commit is contained in:
rods%netscape.com 2002-09-19 21:45:07 +00:00
parent d9c5e77922
commit 16849ef0da
21 changed files with 294 additions and 483 deletions

View File

@ -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<nsIWebShell> 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<nsIDocShell> docShell(do_QueryInterface(aPO->mWebShell));
NS_ASSERTION(docShell, "The DocShell can't be NULL!");
nsCOMPtr<nsIPresShell> wsPresShell;
docShell->GetPresShell(getter_AddRefs(wsPresShell));
NS_ASSERTION(wsPresShell, "The PresShell can't be NULL!");
nsCOMPtr<nsIDocument> 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<nsISelection> selection;
nsCOMPtr<nsISelection> 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<nsIAtom> 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<nsIRenderingContext> 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<nsIWebShell> 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<nsIStyleContext> 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;i<mPrt->mPrintDocList->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<nsIViewManager> 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;

View File

@ -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<nsIViewManager>& aVM,
nsCOMPtr<nsIWidget>& 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<nsIWidget> mWindow;
nsPrintData* mPrt;
nsPagePrintTimer* mPagePrintTimer;
nsIPageSequenceFrame* mPageSeqFrame;
@ -339,7 +332,6 @@ protected:
PRBool mIsCachingPresentation;
CachedPresentationObj* mCachedPresObj;
FILE* mDebugFile;
private:

View File

@ -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
*/

View File

@ -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

View File

@ -69,6 +69,7 @@ protected:
nsCOMPtr<nsIPrintSettings> mGlobalPrintSettings;
nsCString mPrefName;
PRBool mDoUncontrainedReflow;
static nsFont* sDefaultFont;
};

View File

@ -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;

View File

@ -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;

View File

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

View File

@ -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___ */

View File

@ -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)
{

View File

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

View File

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

View File

@ -67,6 +67,9 @@ public:
nsCOMPtr<nsIPrintSettings> mPrintSettings;
nsCOMPtr<nsIPrintOptions> 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,

View File

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

View File

@ -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___ */

View File

@ -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)
{

View File

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

View File

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

View File

@ -67,6 +67,9 @@ public:
nsCOMPtr<nsIPrintSettings> mPrintSettings;
nsCOMPtr<nsIPrintOptions> 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,

View File

@ -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<nsIWebShell> 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<nsIDocShell> docShell(do_QueryInterface(aPO->mWebShell));
NS_ASSERTION(docShell, "The DocShell can't be NULL!");
nsCOMPtr<nsIPresShell> wsPresShell;
docShell->GetPresShell(getter_AddRefs(wsPresShell));
NS_ASSERTION(wsPresShell, "The PresShell can't be NULL!");
nsCOMPtr<nsIDocument> 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<nsISelection> selection;
nsCOMPtr<nsISelection> 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<nsIAtom> 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<nsIRenderingContext> 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<nsIWebShell> 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<nsIStyleContext> 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;i<mPrt->mPrintDocList->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<nsIViewManager> 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;

View File

@ -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<nsIViewManager>& aVM,
nsCOMPtr<nsIWidget>& 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<nsIWidget> mWindow;
nsPrintData* mPrt;
nsPagePrintTimer* mPagePrintTimer;
nsIPageSequenceFrame* mPageSeqFrame;
@ -339,7 +332,6 @@ protected:
PRBool mIsCachingPresentation;
CachedPresentationObj* mCachedPresObj;
FILE* mDebugFile;
private: