1) In DocumentViewer: I did rearrange some of the data members for PrintData

and PrintObject and their initialization order
2) In DocumentViewer: Implemented the shrink to fit feature by calc'ing the
ratios in the first reflow and then reflowing a second time to shrink them
3) In nsPageFrame: This is somewhat unrelated to this bug, but I found where
continuing frame content was being parented to the PageFrame instead of the
PageContentFrame.
4) Although at this time I am not using DumpFrames for debugging I may want to
switch back to it while debugging at anytime.
Bug 100967 r=dcone sr=attinasi
This commit is contained in:
rods%netscape.com 2002-02-19 11:49:27 +00:00
parent db81563416
commit ae0b7240a9
11 changed files with 695 additions and 67 deletions

View File

@ -315,7 +315,9 @@ public:
// Methods
PRBool IsPrintable() { return !mDontPrint; }
void DestroyPresentation();
// Data Members
nsCOMPtr<nsIWebShell> mWebShell;
PrintObjectType mFrameType;
nsCOMPtr<nsIPresContext> mPresContext;
@ -323,7 +325,6 @@ public:
nsCOMPtr<nsIPresShell> mPresShell;
nsCOMPtr<nsIViewManager> mViewManager;
nsCOMPtr<nsIWidget> mWindow;
nsIView *mView;
nsIView *mRootView;
nsIContent *mContent;
@ -346,6 +347,8 @@ public:
PRUint16 mImgAnimationMode;
PRUnichar* mDocTitle;
PRUnichar* mDocURL;
float mShrinkRatio;
nscoord mXMost;
private:
PrintObject& operator=(const PrintObject& aOther); // not implemented
@ -391,13 +394,16 @@ public:
PRPackedBool mIsIFrameSelected;
PRPackedBool mIsParentAFrameSet;
PRPackedBool mPrintingAsIsSubDoc;
PRInt16 mPrintFrameType;
PRPackedBool mOnStartSent;
PRPackedBool mIsAborted;
PRBool mShrinkToFit;
PRInt16 mPrintFrameType;
PRInt32 mNumPrintableDocs;
PRInt32 mNumDocsPrinted;
PRInt32 mNumPrintablePages;
PRInt32 mNumPagesPrinted;
float mShrinkRatio;
float mOrigDCScale;
nsCOMPtr<nsIPrintSettings> mPrintSettings;
nsCOMPtr<nsIPrintOptions> mPrintOptions;
@ -504,14 +510,14 @@ private:
void BuildDocTree(nsIDocShellTreeNode * aParentNode,
nsVoidArray * aDocList,
PrintObject * aPO);
nsresult ReflowDocList(PrintObject * aPO);
nsresult ReflowDocList(PrintObject * aPO, PRBool aSetPixelScale, PRBool aDoCalcShrink);
void SetClipRect(PrintObject* aPO,
const nsRect& aClipRect,
nscoord aOffsetX,
nscoord aOffsetY,
PRBool aDoingSetClip);
nsresult ReflowPrintObject(PrintObject * aPO);
nsresult ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink);
nsresult CalcPageFrameLocation(nsIPresShell * aPresShell,
PrintObject* aPO);
PrintObject * FindPrintObjectByWS(PrintObject* aPO, nsIWebShell * aWebShell);
@ -554,6 +560,10 @@ private:
nsIDeviceContext* aDContext,
nsIDOMWindowInternal* aCurrentFocusedDOMWin);
nsresult EnablePOsForPrinting();
PrintObject* 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);
PRBool PrintDocContent(PrintObject* aPO, nsresult& aStatus);
nsresult DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& aDonePrinting);
@ -782,11 +792,10 @@ static nsresult NS_NewUpdateTimer(nsPagePrintTimer **aResult)
PrintData::PrintData() :
mPrintView(nsnull), mDebugFilePtr(nsnull), mPrintObject(nsnull), mSelectedPO(nsnull),
mShowProgressDialog(PR_TRUE), mPrintDocList(nsnull), mIsIFrameSelected(PR_FALSE),
mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE),
mPrintFrameType(nsIPrintSettings::kFramesAsIs), mOnStartSent(PR_FALSE),
mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE), mOnStartSent(PR_FALSE),
mIsAborted(PR_FALSE), mShrinkToFit(PR_FALSE), mPrintFrameType(nsIPrintSettings::kFramesAsIs),
mNumPrintableDocs(0), mNumDocsPrinted(0), mNumPrintablePages(0), mNumPagesPrinted(0),
mIsAborted(PR_FALSE)
mShrinkRatio(1.0), mOrigDCScale(1.0)
{
#ifdef DEBUG_PRINTING
mDebugFD = fopen("printing.log", "w");
@ -882,16 +891,15 @@ PrintData::DoOnProgressChange(nsVoidArray& aListeners,
//-- PrintObject Class Impl
//---------------------------------------------------
PrintObject::PrintObject() :
mWebShell(nsnull), mFrameType(eFrame),
mView(nsnull), mRootView(nsnull), mContent(nsnull),
mFrameType(eFrame),
mRootView(nsnull), mContent(nsnull),
mSeqFrame(nsnull), mPageFrame(nsnull), mPageNum(-1),
mRect(0,0,0,0), mReflowRect(0,0,0,0),
mParent(nsnull), mHasBeenPrinted(PR_FALSE), mDontPrint(PR_TRUE),
mPrintAsIs(PR_FALSE), mSkippedPageEject(PR_FALSE), mSharedPresShell(PR_FALSE),
mClipRect(-1,-1, -1, -1),
mImgAnimationMode(imgIContainer::kNormalAnimMode),
mDocTitle(nsnull),
mDocURL(nsnull)
mDocTitle(nsnull), mDocURL(nsnull), mShrinkRatio(1.0), mXMost(0)
{
}
@ -916,6 +924,18 @@ PrintObject::~PrintObject()
}
//------------------------------------------------------------------
// Resets PO by destroying the presentation
void PrintObject::DestroyPresentation()
{
mWindow = nsnull;
mPresContext = nsnull;
mPresShell->Destroy();
mPresShell = nsnull;
mViewManager = nsnull;
mStyleSet = nsnull;
}
//------------------------------------------------------------------
// DocumentViewerImpl
//------------------------------------------------------------------
@ -965,7 +985,7 @@ void DocumentViewerImpl::PrepareToStartLoad() {
#ifdef NS_PRINT_PREVIEW
mIsDoingPrintPreview = PR_FALSE;
mPrtPreview = nsnull;
mOldPrtPreview = nsnull;
mOldPrtPreview = nsnull;
#endif
#ifdef NS_DEBUG
@ -1790,6 +1810,29 @@ int RemoveFilesInDir(const char * aDir)
#ifdef DEBUG_PRINTING
/** ---------------------------------------------------
* Dumps Frames for Printing
*/
static void RootFrameList(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent)
{
if((nsnull == aPresContext) || (nsnull == out))
return;
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
if (nsnull != shell) {
nsIFrame* frame;
shell->GetRootFrame(&frame);
if(nsnull != frame) {
nsIFrameDebug* debugFrame;
nsresult rv;
rv = frame->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&debugFrame);
if(NS_SUCCEEDED(rv))
debugFrame->List(aPresContext, out, aIndent);
}
}
}
/** ---------------------------------------------------
* Dumps Frames for Printing
*/
@ -1916,7 +1959,8 @@ void DumpLayoutData(char* aTitleStr,
fprintf(fd, "--------------- Frames ----------------\n");
nsCOMPtr<nsIRenderingContext> renderingContext;
aDC->CreateRenderingContext(*getter_AddRefs(renderingContext));
DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0);
RootFrameList(aPresContext, fd, 0);
//DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0);
fprintf(fd, "---------------------------------------\n\n");
fprintf(fd, "--------------- Views From Root Frame----------------\n");
nsIView * v;
@ -3100,12 +3144,24 @@ DocumentViewerImpl::SetClipRect(PrintObject* aPO,
// Recursively reflow each sub-doc and then calc
// all the frame locations of the sub-docs
nsresult
DocumentViewerImpl::ReflowDocList(PrintObject* aPO)
DocumentViewerImpl::ReflowDocList(PrintObject* aPO, PRBool aSetPixelScale, PRBool aDoCalcShrink)
{
NS_ASSERTION(aPO, "Pointer is null!");
// Here is where we set the shrinkage value into the DC
// and this is what actually makes it shrink
if (aSetPixelScale && aPO->mFrameType != eIFrame) {
float ratio;
if (mPrt->mPrintFrameType == nsIPrintSettings::kFramesAsIs || mPrt->mPrintFrameType == nsIPrintSettings::kNoFrames) {
ratio = mPrt->mShrinkRatio - 0.005f; // round down
} else {
ratio = aPO->mShrinkRatio - 0.005f; // round down
}
mPrt->mPrintDC->SetCanonicalPixelScale(ratio*mPrt->mOrigDCScale);
}
// Reflow the PO
if (NS_FAILED(ReflowPrintObject(aPO))) {
if (NS_FAILED(ReflowPrintObject(aPO, aDoCalcShrink))) {
return NS_ERROR_FAILURE;
}
@ -3116,7 +3172,7 @@ DocumentViewerImpl::ReflowDocList(PrintObject* aPO)
PRInt32 cnt = aPO->mKids.Count();
for (PRInt32 i=0;i<cnt;i++) {
if (NS_FAILED(ReflowDocList((PrintObject *)aPO->mKids[i]))) {
if (NS_FAILED(ReflowDocList((PrintObject *)aPO->mKids[i], aSetPixelScale, aDoCalcShrink))) {
return NS_ERROR_FAILURE;
}
}
@ -3126,7 +3182,7 @@ DocumentViewerImpl::ReflowDocList(PrintObject* aPO)
//-------------------------------------------------------
// Reflow a PrintObject
nsresult
DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO)
DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink)
{
NS_ASSERTION(aPO, "Pointer is null!");
@ -3351,6 +3407,58 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO)
}
}
}
// If we are trying to shrink the contents to fit on the page
// we must first locate the "pageContent" frame
// Then we walk the frame tree and look for the "xmost" frame
// this is the frame where the right-hand side of the frame extends
// the furthest
if (mPrt->mShrinkToFit) {
// find pageContent frame
nsIFrame* rootFrame;
aPO->mPresShell->GetRootFrame(&rootFrame);
NS_ASSERTION(rootFrame, "There has to be a root frame!");
if (rootFrame) {
nsIFrame* child;
rootFrame->FirstChild(aPO->mPresContext, nsnull, &child);
while (child) {
nsCOMPtr<nsIAtom> frameType;
child->GetFrameType(getter_AddRefs(frameType));
if (nsLayoutAtoms::pageContentFrame == frameType.get()) { // placeholder
break;
}
child->FirstChild(aPO->mPresContext, nsnull, &child);
}
NS_ASSERTION(child, "There has to be a page content frame!");
// Now get it's first child (area frame)
// then gets it size which would be the size it is suppose to be to fit
if (child) {
child->FirstChild(aPO->mPresContext, nsnull, &child);
NS_ASSERTION(child, "There has to be a child frame!");
if (child) {
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);
float ratio = float(rect.width) / float(maxWidth);
aPO->mXMost = maxWidth;
aPO->mShrinkRatio = PR_MIN(ratio, 1.0f);
#ifdef DEBUG_PRINTING
printf("PO %p ****** RW: %d MW: %d xMost %d width: %d %10.4f\n", aPO, rect.width, maxWidth, aPO->mXMost, rect.width, ratio*100.0);
#endif
}
}
}
}
}
#ifdef DEBUG_rods
@ -3370,7 +3478,8 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO)
fprintf(fd, "--------------- Frames ----------------\n");
nsCOMPtr<nsIRenderingContext> renderingContext;
mPrt->mPrintDocDC->CreateRenderingContext(*getter_AddRefs(renderingContext));
DumpFrames(fd, aPO->mPresContext, renderingContext, theRootFrame, 0);
RootFrameList(aPO->mPresContext, fd, 0);
//DumpFrames(fd, aPO->mPresContext, renderingContext, theRootFrame, 0);
fprintf(fd, "---------------------------------------\n\n");
fprintf(fd, "--------------- Views From Root Frame----------------\n");
nsIView * v;
@ -3657,6 +3766,122 @@ DocumentViewerImpl::EnablePOsForPrinting()
return NS_OK;
}
//---------------------------------------------------
// Find the Frame in a Frame List that is XMost
void
DocumentViewerImpl::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();
#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
DocumentViewerImpl::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 PrintObject with that is XMost (The widest frameset frame) AND
// contains the XMost (widest) layout frame
PrintObject*
DocumentViewerImpl::FindXMostPO()
{
nscoord xMostForPO = 0;
nscoord xMost = 0;
PrintObject* xMostPO = nsnull;
for (PRInt32 i=0;i<mPrt->mPrintDocList->Count();i++) {
PrintObject* po = (PrintObject*)mPrt->mPrintDocList->ElementAt(i);
NS_ASSERTION(po, "PrintObject 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;
}
}
}
}
#ifdef 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);
#endif
return xMostPO;
}
//-------------------------------------------------------
nsresult
DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent,
@ -3678,11 +3903,62 @@ DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent,
}
DUMP_DOC_LIST("\nAfter Enable------------------------------------------");
// This is an Optimization
// If we are in PP then we already know all the shrinkage information
// so just transfer it to the PrintData and we will skip the extra shrinkage reflow
//
// doSetPixelScale tells Reflow whether to set the shrinkage value into the DC
// The first tru we do not want to do this, the second time thru we do
PRBool doSetPixelScale = PR_FALSE;
PRBool ppIsShrinkToFit = mPrtPreview && mPrtPreview->mShrinkToFit;
if (ppIsShrinkToFit) {
mPrt->mShrinkRatio = mPrtPreview->mShrinkRatio;
doSetPixelScale = PR_TRUE;
}
// Here we reflow all the PrintObjects
if (NS_FAILED(ReflowDocList(mPrt->mPrintObject))) {
if (NS_FAILED(ReflowDocList(mPrt->mPrintObject, doSetPixelScale, mPrt->mShrinkToFit))) {
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) {
if (mPrt->mPrintDocList->Count() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) {
PrintObject* 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;
// Calc the shrinkage based on the entire content area
mPrt->mShrinkRatio = float(rect.XMost()) / float(rect.x + xMostPO->mXMost);
}
} else {
// Single document so use the Shrink as calculated for the PO
mPrt->mShrinkRatio = mPrt->mPrintObject->mShrinkRatio;
}
// Only Shrink if we are smaller
if (mPrt->mShrinkRatio < 1.0f) {
for (PRInt32 i=0;i<mPrt->mPrintDocList->Count();i++) {
PrintObject* po = (PrintObject*)mPrt->mPrintDocList->ElementAt(i);
NS_ASSERTION(po, "PrintObject can't be null!");
// Wipe out the presentation before we reflow
po->DestroyPresentation();
}
// Here we reflow all the PrintObjects a second time
// this time using the shrinkage values
// The last param here tells reflow to NOT calc the shrinkage values
if (NS_FAILED(ReflowDocList(mPrt->mPrintObject, PR_TRUE, PR_FALSE))) {
return NS_ERROR_FAILURE;
}
}
}
DUMP_DOC_LIST("\nAfter Reflow------------------------------------------");
PRINT_DEBUG_MSG1("\n-------------------------------------------------------\n\n");
@ -3718,7 +3994,6 @@ DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent,
#endif
#endif
mPrt->mPrintDocDC = aDContext;
mPrt->mPrintDocDW = aCurrentFocusedDOMWin;
// This will print the webshell document
@ -5294,6 +5569,8 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings)
// Setup print options for UI
rv = NS_ERROR_FAILURE;
if (mPrt->mPrintSettings != nsnull) {
mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);
if (mPrt->mIsParentAFrameSet) {
if (mPrt->mCurrentFocusWin) {
mPrt->mPrintSettings->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAll);
@ -5341,10 +5618,13 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings)
if (NS_SUCCEEDED(rv)) {
mDeviceContext->SetAltDevice(ppDC);
if (mPrt->mPrintSettings != nsnull) {
double scaling;
mPrt->mPrintSettings->GetScaling(&scaling);
if (scaling < 1.0) {
mDeviceContext->SetCanonicalPixelScale(float(scaling));
// Shrink to Fit over rides and scaling values
if (!mPrt->mShrinkToFit) {
double scaling;
mPrt->mPrintSettings->GetScaling(&scaling);
if (scaling < 1.0) {
mDeviceContext->SetCanonicalPixelScale(float(scaling));
}
}
}
ppDC->GetDeviceSurfaceDimensions(width, height);
@ -5363,7 +5643,9 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings)
mPrt->mPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages);
}
mPrt->mPrintDC = mDeviceContext; // XXX why?
mPrt->mPrintDC = mDeviceContext;
// Get the Original PixelScale incase we need to start changing it
mPrt->mPrintDC->GetCanonicalPixelScale(mPrt->mOrigDCScale);
if (mDeviceContext) {
mDeviceContext->SetUseAltDC(kUseAltDCFor_FONTMETRICS, PR_TRUE);
@ -5576,6 +5858,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings,
}
}
mPrt->mPrintSettings->SetIsCancelled(PR_FALSE);
mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);
// Let's print ...
mIsDoingPrinting = PR_TRUE;
@ -5690,12 +5973,15 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings,
if (NS_SUCCEEDED(rv)) {
rv = dx->GetDeviceContextFor(devspec, *getter_AddRefs(mPrt->mPrintDC));
if (NS_SUCCEEDED(rv)) {
double scaling;
mPrt->mPrintSettings->GetScaling(&scaling);
if (scaling <= 1.0) {
float oldScale = 1.0f;
mPrt->mPrintDC->GetCanonicalPixelScale(oldScale);
mPrt->mPrintDC->SetCanonicalPixelScale(float(scaling)*oldScale);
// Get the Original PixelScale incase we need to start changing it
mPrt->mPrintDC->GetCanonicalPixelScale(mPrt->mOrigDCScale);
// Shrink to Fit over rides and scaling values
if (!mPrt->mShrinkToFit) {
double scaling;
mPrt->mPrintSettings->GetScaling(&scaling);
if (scaling <= 1.0) {
mPrt->mPrintDC->SetCanonicalPixelScale(float(scaling)*mPrt->mOrigDCScale);
}
}
if(webContainer) {

View File

@ -167,7 +167,8 @@ interface nsIPrintSettings : nsISupports
attribute boolean isCancelled; /* indicates whether the print job has been cancelled */
attribute short printFrameTypeUsage; /* indicates whether to use the interal value or not */
attribute short printFrameType;
attribute boolean printSilent; /* print without putting up the dialog */
attribute boolean printSilent; /* print without putting up the dialog */
attribute boolean shrinkToFit; /* shrinks content to fit on page */
/* Additional XP Related */
attribute short paperSizeType; /* use native data or is defined here */

View File

@ -69,6 +69,7 @@ nsPrintSettings::nsPrintSettings() :
mPaperHeight(11.0),
mPaperSizeUnit(kPaperSizeInches),
mPrintSilent(PR_FALSE),
mShrinkToFit(PR_FALSE),
mHowToEnableFrameUI(kFrameEnableNone),
mIsCancelled(PR_FALSE)
{
@ -577,6 +578,19 @@ NS_IMETHODIMP nsPrintSettings::SetPrintSilent(PRBool aPrintSilent)
return NS_OK;
}
/* attribute boolean shrinkToFit; */
NS_IMETHODIMP nsPrintSettings::GetShrinkToFit(PRBool *aShrinkToFit)
{
NS_ENSURE_ARG_POINTER(aShrinkToFit);
*aShrinkToFit = mShrinkToFit;
return NS_OK;
}
NS_IMETHODIMP nsPrintSettings::SetShrinkToFit(PRBool aShrinkToFit)
{
mShrinkToFit = aShrinkToFit;
return NS_OK;
}
/* attribute boolean howToEnableFrameUI; */
NS_IMETHODIMP nsPrintSettings::GetHowToEnableFrameUI(PRInt16 *aHowToEnableFrameUI)
{

View File

@ -67,6 +67,7 @@ protected:
PRBool mHowToEnableFrameUI;
PRBool mIsCancelled;
PRBool mPrintSilent;
PRBool mShrinkToFit;
PRInt32 mPrintPageDelay;
nsString mTitle;

View File

@ -315,7 +315,9 @@ public:
// Methods
PRBool IsPrintable() { return !mDontPrint; }
void DestroyPresentation();
// Data Members
nsCOMPtr<nsIWebShell> mWebShell;
PrintObjectType mFrameType;
nsCOMPtr<nsIPresContext> mPresContext;
@ -323,7 +325,6 @@ public:
nsCOMPtr<nsIPresShell> mPresShell;
nsCOMPtr<nsIViewManager> mViewManager;
nsCOMPtr<nsIWidget> mWindow;
nsIView *mView;
nsIView *mRootView;
nsIContent *mContent;
@ -346,6 +347,8 @@ public:
PRUint16 mImgAnimationMode;
PRUnichar* mDocTitle;
PRUnichar* mDocURL;
float mShrinkRatio;
nscoord mXMost;
private:
PrintObject& operator=(const PrintObject& aOther); // not implemented
@ -391,13 +394,16 @@ public:
PRPackedBool mIsIFrameSelected;
PRPackedBool mIsParentAFrameSet;
PRPackedBool mPrintingAsIsSubDoc;
PRInt16 mPrintFrameType;
PRPackedBool mOnStartSent;
PRPackedBool mIsAborted;
PRBool mShrinkToFit;
PRInt16 mPrintFrameType;
PRInt32 mNumPrintableDocs;
PRInt32 mNumDocsPrinted;
PRInt32 mNumPrintablePages;
PRInt32 mNumPagesPrinted;
float mShrinkRatio;
float mOrigDCScale;
nsCOMPtr<nsIPrintSettings> mPrintSettings;
nsCOMPtr<nsIPrintOptions> mPrintOptions;
@ -504,14 +510,14 @@ private:
void BuildDocTree(nsIDocShellTreeNode * aParentNode,
nsVoidArray * aDocList,
PrintObject * aPO);
nsresult ReflowDocList(PrintObject * aPO);
nsresult ReflowDocList(PrintObject * aPO, PRBool aSetPixelScale, PRBool aDoCalcShrink);
void SetClipRect(PrintObject* aPO,
const nsRect& aClipRect,
nscoord aOffsetX,
nscoord aOffsetY,
PRBool aDoingSetClip);
nsresult ReflowPrintObject(PrintObject * aPO);
nsresult ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink);
nsresult CalcPageFrameLocation(nsIPresShell * aPresShell,
PrintObject* aPO);
PrintObject * FindPrintObjectByWS(PrintObject* aPO, nsIWebShell * aWebShell);
@ -554,6 +560,10 @@ private:
nsIDeviceContext* aDContext,
nsIDOMWindowInternal* aCurrentFocusedDOMWin);
nsresult EnablePOsForPrinting();
PrintObject* 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);
PRBool PrintDocContent(PrintObject* aPO, nsresult& aStatus);
nsresult DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& aDonePrinting);
@ -782,11 +792,10 @@ static nsresult NS_NewUpdateTimer(nsPagePrintTimer **aResult)
PrintData::PrintData() :
mPrintView(nsnull), mDebugFilePtr(nsnull), mPrintObject(nsnull), mSelectedPO(nsnull),
mShowProgressDialog(PR_TRUE), mPrintDocList(nsnull), mIsIFrameSelected(PR_FALSE),
mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE),
mPrintFrameType(nsIPrintSettings::kFramesAsIs), mOnStartSent(PR_FALSE),
mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE), mOnStartSent(PR_FALSE),
mIsAborted(PR_FALSE), mShrinkToFit(PR_FALSE), mPrintFrameType(nsIPrintSettings::kFramesAsIs),
mNumPrintableDocs(0), mNumDocsPrinted(0), mNumPrintablePages(0), mNumPagesPrinted(0),
mIsAborted(PR_FALSE)
mShrinkRatio(1.0), mOrigDCScale(1.0)
{
#ifdef DEBUG_PRINTING
mDebugFD = fopen("printing.log", "w");
@ -882,16 +891,15 @@ PrintData::DoOnProgressChange(nsVoidArray& aListeners,
//-- PrintObject Class Impl
//---------------------------------------------------
PrintObject::PrintObject() :
mWebShell(nsnull), mFrameType(eFrame),
mView(nsnull), mRootView(nsnull), mContent(nsnull),
mFrameType(eFrame),
mRootView(nsnull), mContent(nsnull),
mSeqFrame(nsnull), mPageFrame(nsnull), mPageNum(-1),
mRect(0,0,0,0), mReflowRect(0,0,0,0),
mParent(nsnull), mHasBeenPrinted(PR_FALSE), mDontPrint(PR_TRUE),
mPrintAsIs(PR_FALSE), mSkippedPageEject(PR_FALSE), mSharedPresShell(PR_FALSE),
mClipRect(-1,-1, -1, -1),
mImgAnimationMode(imgIContainer::kNormalAnimMode),
mDocTitle(nsnull),
mDocURL(nsnull)
mDocTitle(nsnull), mDocURL(nsnull), mShrinkRatio(1.0), mXMost(0)
{
}
@ -916,6 +924,18 @@ PrintObject::~PrintObject()
}
//------------------------------------------------------------------
// Resets PO by destroying the presentation
void PrintObject::DestroyPresentation()
{
mWindow = nsnull;
mPresContext = nsnull;
mPresShell->Destroy();
mPresShell = nsnull;
mViewManager = nsnull;
mStyleSet = nsnull;
}
//------------------------------------------------------------------
// DocumentViewerImpl
//------------------------------------------------------------------
@ -965,7 +985,7 @@ void DocumentViewerImpl::PrepareToStartLoad() {
#ifdef NS_PRINT_PREVIEW
mIsDoingPrintPreview = PR_FALSE;
mPrtPreview = nsnull;
mOldPrtPreview = nsnull;
mOldPrtPreview = nsnull;
#endif
#ifdef NS_DEBUG
@ -1790,6 +1810,29 @@ int RemoveFilesInDir(const char * aDir)
#ifdef DEBUG_PRINTING
/** ---------------------------------------------------
* Dumps Frames for Printing
*/
static void RootFrameList(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent)
{
if((nsnull == aPresContext) || (nsnull == out))
return;
nsCOMPtr<nsIPresShell> shell;
aPresContext->GetShell(getter_AddRefs(shell));
if (nsnull != shell) {
nsIFrame* frame;
shell->GetRootFrame(&frame);
if(nsnull != frame) {
nsIFrameDebug* debugFrame;
nsresult rv;
rv = frame->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&debugFrame);
if(NS_SUCCEEDED(rv))
debugFrame->List(aPresContext, out, aIndent);
}
}
}
/** ---------------------------------------------------
* Dumps Frames for Printing
*/
@ -1916,7 +1959,8 @@ void DumpLayoutData(char* aTitleStr,
fprintf(fd, "--------------- Frames ----------------\n");
nsCOMPtr<nsIRenderingContext> renderingContext;
aDC->CreateRenderingContext(*getter_AddRefs(renderingContext));
DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0);
RootFrameList(aPresContext, fd, 0);
//DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0);
fprintf(fd, "---------------------------------------\n\n");
fprintf(fd, "--------------- Views From Root Frame----------------\n");
nsIView * v;
@ -3100,12 +3144,24 @@ DocumentViewerImpl::SetClipRect(PrintObject* aPO,
// Recursively reflow each sub-doc and then calc
// all the frame locations of the sub-docs
nsresult
DocumentViewerImpl::ReflowDocList(PrintObject* aPO)
DocumentViewerImpl::ReflowDocList(PrintObject* aPO, PRBool aSetPixelScale, PRBool aDoCalcShrink)
{
NS_ASSERTION(aPO, "Pointer is null!");
// Here is where we set the shrinkage value into the DC
// and this is what actually makes it shrink
if (aSetPixelScale && aPO->mFrameType != eIFrame) {
float ratio;
if (mPrt->mPrintFrameType == nsIPrintSettings::kFramesAsIs || mPrt->mPrintFrameType == nsIPrintSettings::kNoFrames) {
ratio = mPrt->mShrinkRatio - 0.005f; // round down
} else {
ratio = aPO->mShrinkRatio - 0.005f; // round down
}
mPrt->mPrintDC->SetCanonicalPixelScale(ratio*mPrt->mOrigDCScale);
}
// Reflow the PO
if (NS_FAILED(ReflowPrintObject(aPO))) {
if (NS_FAILED(ReflowPrintObject(aPO, aDoCalcShrink))) {
return NS_ERROR_FAILURE;
}
@ -3116,7 +3172,7 @@ DocumentViewerImpl::ReflowDocList(PrintObject* aPO)
PRInt32 cnt = aPO->mKids.Count();
for (PRInt32 i=0;i<cnt;i++) {
if (NS_FAILED(ReflowDocList((PrintObject *)aPO->mKids[i]))) {
if (NS_FAILED(ReflowDocList((PrintObject *)aPO->mKids[i], aSetPixelScale, aDoCalcShrink))) {
return NS_ERROR_FAILURE;
}
}
@ -3126,7 +3182,7 @@ DocumentViewerImpl::ReflowDocList(PrintObject* aPO)
//-------------------------------------------------------
// Reflow a PrintObject
nsresult
DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO)
DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO, PRBool aDoCalcShrink)
{
NS_ASSERTION(aPO, "Pointer is null!");
@ -3351,6 +3407,58 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO)
}
}
}
// If we are trying to shrink the contents to fit on the page
// we must first locate the "pageContent" frame
// Then we walk the frame tree and look for the "xmost" frame
// this is the frame where the right-hand side of the frame extends
// the furthest
if (mPrt->mShrinkToFit) {
// find pageContent frame
nsIFrame* rootFrame;
aPO->mPresShell->GetRootFrame(&rootFrame);
NS_ASSERTION(rootFrame, "There has to be a root frame!");
if (rootFrame) {
nsIFrame* child;
rootFrame->FirstChild(aPO->mPresContext, nsnull, &child);
while (child) {
nsCOMPtr<nsIAtom> frameType;
child->GetFrameType(getter_AddRefs(frameType));
if (nsLayoutAtoms::pageContentFrame == frameType.get()) { // placeholder
break;
}
child->FirstChild(aPO->mPresContext, nsnull, &child);
}
NS_ASSERTION(child, "There has to be a page content frame!");
// Now get it's first child (area frame)
// then gets it size which would be the size it is suppose to be to fit
if (child) {
child->FirstChild(aPO->mPresContext, nsnull, &child);
NS_ASSERTION(child, "There has to be a child frame!");
if (child) {
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);
float ratio = float(rect.width) / float(maxWidth);
aPO->mXMost = maxWidth;
aPO->mShrinkRatio = PR_MIN(ratio, 1.0f);
#ifdef DEBUG_PRINTING
printf("PO %p ****** RW: %d MW: %d xMost %d width: %d %10.4f\n", aPO, rect.width, maxWidth, aPO->mXMost, rect.width, ratio*100.0);
#endif
}
}
}
}
}
#ifdef DEBUG_rods
@ -3370,7 +3478,8 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO)
fprintf(fd, "--------------- Frames ----------------\n");
nsCOMPtr<nsIRenderingContext> renderingContext;
mPrt->mPrintDocDC->CreateRenderingContext(*getter_AddRefs(renderingContext));
DumpFrames(fd, aPO->mPresContext, renderingContext, theRootFrame, 0);
RootFrameList(aPO->mPresContext, fd, 0);
//DumpFrames(fd, aPO->mPresContext, renderingContext, theRootFrame, 0);
fprintf(fd, "---------------------------------------\n\n");
fprintf(fd, "--------------- Views From Root Frame----------------\n");
nsIView * v;
@ -3657,6 +3766,122 @@ DocumentViewerImpl::EnablePOsForPrinting()
return NS_OK;
}
//---------------------------------------------------
// Find the Frame in a Frame List that is XMost
void
DocumentViewerImpl::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();
#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
DocumentViewerImpl::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 PrintObject with that is XMost (The widest frameset frame) AND
// contains the XMost (widest) layout frame
PrintObject*
DocumentViewerImpl::FindXMostPO()
{
nscoord xMostForPO = 0;
nscoord xMost = 0;
PrintObject* xMostPO = nsnull;
for (PRInt32 i=0;i<mPrt->mPrintDocList->Count();i++) {
PrintObject* po = (PrintObject*)mPrt->mPrintDocList->ElementAt(i);
NS_ASSERTION(po, "PrintObject 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;
}
}
}
}
#ifdef 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);
#endif
return xMostPO;
}
//-------------------------------------------------------
nsresult
DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent,
@ -3678,11 +3903,62 @@ DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent,
}
DUMP_DOC_LIST("\nAfter Enable------------------------------------------");
// This is an Optimization
// If we are in PP then we already know all the shrinkage information
// so just transfer it to the PrintData and we will skip the extra shrinkage reflow
//
// doSetPixelScale tells Reflow whether to set the shrinkage value into the DC
// The first tru we do not want to do this, the second time thru we do
PRBool doSetPixelScale = PR_FALSE;
PRBool ppIsShrinkToFit = mPrtPreview && mPrtPreview->mShrinkToFit;
if (ppIsShrinkToFit) {
mPrt->mShrinkRatio = mPrtPreview->mShrinkRatio;
doSetPixelScale = PR_TRUE;
}
// Here we reflow all the PrintObjects
if (NS_FAILED(ReflowDocList(mPrt->mPrintObject))) {
if (NS_FAILED(ReflowDocList(mPrt->mPrintObject, doSetPixelScale, mPrt->mShrinkToFit))) {
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) {
if (mPrt->mPrintDocList->Count() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) {
PrintObject* 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;
// Calc the shrinkage based on the entire content area
mPrt->mShrinkRatio = float(rect.XMost()) / float(rect.x + xMostPO->mXMost);
}
} else {
// Single document so use the Shrink as calculated for the PO
mPrt->mShrinkRatio = mPrt->mPrintObject->mShrinkRatio;
}
// Only Shrink if we are smaller
if (mPrt->mShrinkRatio < 1.0f) {
for (PRInt32 i=0;i<mPrt->mPrintDocList->Count();i++) {
PrintObject* po = (PrintObject*)mPrt->mPrintDocList->ElementAt(i);
NS_ASSERTION(po, "PrintObject can't be null!");
// Wipe out the presentation before we reflow
po->DestroyPresentation();
}
// Here we reflow all the PrintObjects a second time
// this time using the shrinkage values
// The last param here tells reflow to NOT calc the shrinkage values
if (NS_FAILED(ReflowDocList(mPrt->mPrintObject, PR_TRUE, PR_FALSE))) {
return NS_ERROR_FAILURE;
}
}
}
DUMP_DOC_LIST("\nAfter Reflow------------------------------------------");
PRINT_DEBUG_MSG1("\n-------------------------------------------------------\n\n");
@ -3718,7 +3994,6 @@ DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent,
#endif
#endif
mPrt->mPrintDocDC = aDContext;
mPrt->mPrintDocDW = aCurrentFocusedDOMWin;
// This will print the webshell document
@ -5294,6 +5569,8 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings)
// Setup print options for UI
rv = NS_ERROR_FAILURE;
if (mPrt->mPrintSettings != nsnull) {
mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);
if (mPrt->mIsParentAFrameSet) {
if (mPrt->mCurrentFocusWin) {
mPrt->mPrintSettings->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAll);
@ -5341,10 +5618,13 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings)
if (NS_SUCCEEDED(rv)) {
mDeviceContext->SetAltDevice(ppDC);
if (mPrt->mPrintSettings != nsnull) {
double scaling;
mPrt->mPrintSettings->GetScaling(&scaling);
if (scaling < 1.0) {
mDeviceContext->SetCanonicalPixelScale(float(scaling));
// Shrink to Fit over rides and scaling values
if (!mPrt->mShrinkToFit) {
double scaling;
mPrt->mPrintSettings->GetScaling(&scaling);
if (scaling < 1.0) {
mDeviceContext->SetCanonicalPixelScale(float(scaling));
}
}
}
ppDC->GetDeviceSurfaceDimensions(width, height);
@ -5363,7 +5643,9 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings)
mPrt->mPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages);
}
mPrt->mPrintDC = mDeviceContext; // XXX why?
mPrt->mPrintDC = mDeviceContext;
// Get the Original PixelScale incase we need to start changing it
mPrt->mPrintDC->GetCanonicalPixelScale(mPrt->mOrigDCScale);
if (mDeviceContext) {
mDeviceContext->SetUseAltDC(kUseAltDCFor_FONTMETRICS, PR_TRUE);
@ -5576,6 +5858,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings,
}
}
mPrt->mPrintSettings->SetIsCancelled(PR_FALSE);
mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);
// Let's print ...
mIsDoingPrinting = PR_TRUE;
@ -5690,12 +5973,15 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings,
if (NS_SUCCEEDED(rv)) {
rv = dx->GetDeviceContextFor(devspec, *getter_AddRefs(mPrt->mPrintDC));
if (NS_SUCCEEDED(rv)) {
double scaling;
mPrt->mPrintSettings->GetScaling(&scaling);
if (scaling <= 1.0) {
float oldScale = 1.0f;
mPrt->mPrintDC->GetCanonicalPixelScale(oldScale);
mPrt->mPrintDC->SetCanonicalPixelScale(float(scaling)*oldScale);
// Get the Original PixelScale incase we need to start changing it
mPrt->mPrintDC->GetCanonicalPixelScale(mPrt->mOrigDCScale);
// Shrink to Fit over rides and scaling values
if (!mPrt->mShrinkToFit) {
double scaling;
mPrt->mPrintSettings->GetScaling(&scaling);
if (scaling <= 1.0) {
mPrt->mPrintDC->SetCanonicalPixelScale(float(scaling)*mPrt->mOrigDCScale);
}
}
if(webContainer) {

View File

@ -53,6 +53,7 @@ function initDialog()
gDialog.orientation = document.getElementById("orientation");
gDialog.printBGColors = document.getElementById("printBGColors");
gDialog.printBGImages = document.getElementById("printBGImages");
gDialog.shrinkToFit = document.getElementById("shrinkToFit");
gDialog.topInput = document.getElementById("topInput");
gDialog.bottomInput = document.getElementById("bottomInput");
@ -67,6 +68,7 @@ function initDialog()
gDialog.fCenterInput = document.getElementById("fCenterInput");
gDialog.fRightInput = document.getElementById("fRightInput");
gDialog.scalingLabel = document.getElementById("scalingInput");
gDialog.scalingInput = document.getElementById("scalingInput");
gDialog.enabled = false;
@ -92,6 +94,18 @@ function getDoubleStr(val, dec)
return str.substring(0, inx+dec+1);
}
//---------------------------------------------------
function doEnableScaling(value)
{
if (value) {
gDialog.scalingLabel.removeAttribute("disabled");
gDialog.scalingInput.removeAttribute("disabled");
} else {
gDialog.scalingLabel.setAttribute("disabled","true");
gDialog.scalingInput.setAttribute("disabled","true");
}
}
//---------------------------------------------------
function loadDialog()
{
@ -121,7 +135,8 @@ function loadDialog()
gDialog.printBGColors.checked = gPrintSettings.printBGColors;
gDialog.printBGImages.checked = gPrintSettings.printBGImages;
gDialog.shrinkToFit.checked = gPrintSettings.shrinkToFit;
doEnableScaling(!gDialog.shrinkToFit.checked);
if (print_orientation == gPrintSettingsInterface.kPortraitOrientation) {
gDialog.orientation.selectedIndex = 0;
@ -192,6 +207,7 @@ function onAccept()
gPrintSettings.printBGColors = gDialog.printBGColors.checked;
gPrintSettings.printBGImages = gDialog.printBGImages.checked;
gPrintSettings.shrinkToFit = gDialog.shrinkToFit.checked;
var scaling = document.getElementById("scalingInput").value;
if (scaling < 50.0 || scaling > 100.0) {

View File

@ -204,6 +204,9 @@ Contributor(s):
</row>
</rows>
</grid>
<hrow>
<checkbox id="shrinkToFit" label="&shrinkToFitInput.label;" oncommand="doEnableScaling(!this.checked);"/>
</hrow>
</groupbox>
</hbox>
</vbox>

View File

@ -30,3 +30,4 @@
<!ENTITY scalingGroup.label "Page Scaling">
<!ENTITY scalingInput.label "Percent:">
<!ENTITY scalingInputPost.label "(Values in range 50-100)">
<!ENTITY shrinkToFitInput.label "Shrink To Fit Page Width">

View File

@ -53,6 +53,7 @@ function initDialog()
gDialog.orientation = document.getElementById("orientation");
gDialog.printBGColors = document.getElementById("printBGColors");
gDialog.printBGImages = document.getElementById("printBGImages");
gDialog.shrinkToFit = document.getElementById("shrinkToFit");
gDialog.topInput = document.getElementById("topInput");
gDialog.bottomInput = document.getElementById("bottomInput");
@ -67,6 +68,7 @@ function initDialog()
gDialog.fCenterInput = document.getElementById("fCenterInput");
gDialog.fRightInput = document.getElementById("fRightInput");
gDialog.scalingLabel = document.getElementById("scalingInput");
gDialog.scalingInput = document.getElementById("scalingInput");
gDialog.enabled = false;
@ -92,6 +94,18 @@ function getDoubleStr(val, dec)
return str.substring(0, inx+dec+1);
}
//---------------------------------------------------
function doEnableScaling(value)
{
if (value) {
gDialog.scalingLabel.removeAttribute("disabled");
gDialog.scalingInput.removeAttribute("disabled");
} else {
gDialog.scalingLabel.setAttribute("disabled","true");
gDialog.scalingInput.setAttribute("disabled","true");
}
}
//---------------------------------------------------
function loadDialog()
{
@ -121,7 +135,8 @@ function loadDialog()
gDialog.printBGColors.checked = gPrintSettings.printBGColors;
gDialog.printBGImages.checked = gPrintSettings.printBGImages;
gDialog.shrinkToFit.checked = gPrintSettings.shrinkToFit;
doEnableScaling(!gDialog.shrinkToFit.checked);
if (print_orientation == gPrintSettingsInterface.kPortraitOrientation) {
gDialog.orientation.selectedIndex = 0;
@ -192,6 +207,7 @@ function onAccept()
gPrintSettings.printBGColors = gDialog.printBGColors.checked;
gPrintSettings.printBGImages = gDialog.printBGImages.checked;
gPrintSettings.shrinkToFit = gDialog.shrinkToFit.checked;
var scaling = document.getElementById("scalingInput").value;
if (scaling < 50.0 || scaling > 100.0) {

View File

@ -204,6 +204,9 @@ Contributor(s):
</row>
</rows>
</grid>
<hrow>
<checkbox id="shrinkToFit" label="&shrinkToFitInput.label;" oncommand="doEnableScaling(!this.checked);"/>
</hrow>
</groupbox>
</hbox>
</vbox>

View File

@ -30,3 +30,4 @@
<!ENTITY scalingGroup.label "Page Scaling">
<!ENTITY scalingInput.label "Percent:">
<!ENTITY scalingInputPost.label "(Values in range 50-100)">
<!ENTITY shrinkToFitInput.label "Shrink To Fit Page Width">