Bug 966419 - Update the global ShrinkToFitRatio when the current page overflows and requires additional scaling to fit horizontally on the page in Print/Preview. r=dholbert
authorMats Palmgren <matspal@gmail.com>
Tue, 04 Feb 2014 02:12:13 +0000
changeset 166699 0b8fdcee7a26e0ea75e2dff4b8960d093e0d0ece
parent 166698 ce3f48acc24498b0fb7cb82fb304c8584a6ebe34
child 166700 53489b3e14f154401cd62ea6e9f5c66d4ae24d50
push idunknown
push userunknown
push dateunknown
reviewersdholbert
bugs966419
milestone30.0a1
Bug 966419 - Update the global ShrinkToFitRatio when the current page overflows and requires additional scaling to fit horizontally on the page in Print/Preview. r=dholbert
layout/generic/nsPageContentFrame.cpp
layout/generic/nsSimplePageSequence.cpp
layout/generic/nsSimplePageSequence.h
layout/reftests/printing/966419-1-ref.html
layout/reftests/printing/966419-1.html
layout/reftests/printing/966419-2-ref.html
layout/reftests/printing/966419-2.html
layout/reftests/printing/reftest.list
--- a/layout/generic/nsPageContentFrame.cpp
+++ b/layout/generic/nsPageContentFrame.cpp
@@ -44,18 +44,16 @@ nsPageContentFrame::Reflow(nsPresContext
   // A PageContentFrame must always have one child: the canvas frame.
   // Resize our frame allowing it only to be as big as we are
   // XXX Pay attention to the page's border and padding...
   if (mFrames.NotEmpty()) {
     nsIFrame* frame = mFrames.FirstChild();
     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize);
     kidReflowState.SetComputedHeight(maxSize.height);
 
-    mPD->mPageContentSize = maxSize.width;
-
     // Reflow the page content area
     rv = ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, 0, 0, 0, aStatus);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // The document element's background should cover the entire canvas, so
     // take into account the combined area and any space taken up by
     // absolutely positioned elements
     nsMargin padding(0,0,0,0);
@@ -68,20 +66,21 @@ nsPageContentFrame::Reflow(nsPresContext
     // scrollable overflow, since the purpose of shrink to fit is to
     // make the content that ought to be reachable (represented by the
     // scrollable overflow) fit in the page.
     if (frame->HasOverflowAreas()) {
       // The background covers the content area and padding area, so check
       // for children sticking outside the child frame's padding edge
       nscoord xmost = aDesiredSize.ScrollableOverflow().XMost();
       if (xmost > aDesiredSize.Width()) {
-        mPD->mPageContentXMost =
-          xmost +
-          kidReflowState.mStyleBorder->GetComputedBorderWidth(NS_SIDE_RIGHT) +
-          padding.right;
+        nscoord widthToFit = xmost + padding.right +
+          kidReflowState.mStyleBorder->GetComputedBorderWidth(NS_SIDE_RIGHT);
+        float ratio = float(maxSize.width) / widthToFit;
+        NS_ASSERTION(ratio >= 0.0 && ratio < 1.0, "invalid shrink-to-fit ratio");
+        mPD->mShrinkToFitRatio = std::min(mPD->mShrinkToFitRatio, ratio);
       }
     }
 
     // Place and size the child
     FinishReflowChild(frame, aPresContext, aDesiredSize, &kidReflowState, 0, 0, 0);
 
     NS_ASSERTION(aPresContext->IsDynamic() || !NS_FRAME_IS_FULLY_COMPLETE(aStatus) ||
                   !frame->GetNextInFlow(), "bad child flow list");
--- a/layout/generic/nsSimplePageSequence.cpp
+++ b/layout/generic/nsSimplePageSequence.cpp
@@ -836,14 +836,11 @@ nsSimplePageSequenceFrame::SetDateTimeSt
 // 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->mPageContentXMost > mPageData->mPageContentSize)) {
-    aSTFPercent = float(mPageData->mPageContentSize) / float(mPageData->mPageContentXMost);
-  }
+  aSTFPercent = mPageData->mShrinkToFitRatio;
   return NS_OK;
 }
--- a/layout/generic/nsSimplePageSequence.h
+++ b/layout/generic/nsSimplePageSequence.h
@@ -24,21 +24,17 @@ class HTMLCanvasElement;
 //-----------------------------------------------
 // This class maintains all the data that 
 // is used by all the page frame
 // It lives while the nsSimplePageSequenceFrame lives
 class nsSharedPageData {
 public:
   // This object a shared by all the nsPageFrames
   // parented to a SimplePageSequenceFrame
-  nsSharedPageData() :
-    mPageContentXMost(0),
-    mPageContentSize(0)
-  {
-  }
+  nsSharedPageData() : mShrinkToFitRatio(1.0f) {}
 
   nsString    mDateTimeStr;
   nsString    mPageNumFormat;
   nsString    mPageNumAndTotalsFormat;
   nsString    mDocTitle;
   nsString    mDocURL;
   nsFont      mHeadFootFont;
 
@@ -47,18 +43,20 @@ public:
   // Margin for headers and footers; it defaults to 4/100 of an inch on UNIX 
   // and 0 elsewhere; I think it has to do with some inconsistency in page size
   // computations
   nsMargin    mEdgePaperMargin;
 
   nsCOMPtr<nsIPrintSettings> mPrintSettings;
   nsCOMPtr<nsIPrintOptions> mPrintOptions;
 
-  nscoord      mPageContentXMost;      // xmost size from Reflow(width)
-  nscoord      mPageContentSize;       // constrained size (width)
+  // The scaling ratio we need to apply to make all pages fit horizontally.  It's
+  // the minimum "ComputedWidth / OverflowWidth" ratio of all page content frames
+  // that overflowed.  It's 1.0 if none overflowed horizontally.
+  float mShrinkToFitRatio;
 };
 
 // Simple page sequence frame class. Used when we're in paginated mode
 class nsSimplePageSequenceFrame : public nsContainerFrame,
                                   public nsIPageSequenceFrame {
 public:
   friend nsIFrame* NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/printing/966419-1-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html class="reftest-print">
+<head><meta charset="utf-8"></head>
+<body>
+<div style="width:8in; border:solid blue">line</div>
+<div style="page-break-before:always"></div>
+<div style="width:1in;height:1em"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/printing/966419-1.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html class="reftest-print">
+<head><meta charset="utf-8"></head>
+<body>
+<div style="width:8in; border:solid blue">line</div>
+<div style="page-break-before:always"></div>
+<div style="width:6in;height:1em"></div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/printing/966419-2-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html class="reftest-print">
+<head><meta charset="utf-8"></head>
+<body>
+<div style="width:1in;height:1em"></div>
+<div style="page-break-before:always"></div>
+<div style="width:8in; border:solid blue">line</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/printing/966419-2.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html class="reftest-print">
+<head><meta charset="utf-8"></head>
+<body>
+<div style="width:6in;height:1em"></div>
+<div style="page-break-before:always"></div>
+<div style="width:8in; border:solid blue">line</div>
+</body>
+</html>
--- a/layout/reftests/printing/reftest.list
+++ b/layout/reftests/printing/reftest.list
@@ -21,8 +21,10 @@
 == 626395-2d.html 626395-2-ref.html
 == 652178-1.html 652178-1-ref.html
 == 115199-1.html 115199-1-ref.html
 == 115199-2a.html 115199-2-ref.html
 == 115199-2b.html 115199-2-ref.html
 == 652178-1.html 652178-1-ref2.html
 fuzzy-if(cocoaWidget,1,5000) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),255,100) == 745025-1.html 745025-1-ref.html
 == 820496-1.html 820496-1-ref.html
+== 966419-1.html 966419-1-ref.html
+== 966419-2.html 966419-2-ref.html