2011-06-13 Kentaro Hara <haraken@google.com>
authordominicc@chromium.org <dominicc@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Jun 2011 00:22:50 +0000 (00:22 +0000)
committerdominicc@chromium.org <dominicc@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Jun 2011 00:22:50 +0000 (00:22 +0000)
        Reviewed by Alexey Proskuryakov.

        Add a new test for checking rounding error in printing codes
        https://bugs.webkit.org/show_bug.cgi?id=61256

        Add a new test (printing/page-count-with-one-word.html). This test
        checks if only one page is printed for an HTML page with one word for
        various paper sizes around A4 portrait size, i.e. [530px, 560px) for
        width and [730px, 760px) for height.

        * printing/page-count-with-one-word-expected.txt: Added.
        * printing/page-count-with-one-word.html: Added.
2011-06-13  Kentaro Hara  <haraken@google.com>

        Reviewed by Alexey Proskuryakov.

        Add resizePageRectsKeepingRatio(), which expands/shrinks a page, keeping the ratio of the original page
        https://bugs.webkit.org/show_bug.cgi?id=61256

        In order to prevent rounding error caused by expanding/shrinking a page
        using different calculation here and there, I added a common calculation
        method, resizePageRectsKeepingRatio(), which expands/shrinks a page,
        keeping the ratio of width and height of the original page.
        PrintContext::computePageRects() and PrintContext::begin()
        use resizePageRectsKeepingRatio() to expand/shrink a page.

        Test: printing/page-count-with-one-word.html

        * WebCore.exp.in:
        * page/Frame.cpp:
        (WebCore::Frame::resizePageRectsKeepingRatio):
        * page/Frame.h:
        * page/PrintContext.cpp:
        (WebCore::PrintContext::computePageRects):
        (WebCore::PrintContext::begin):
2011-06-13  Kentaro Hara  <haraken@google.com>

        Reviewed by Alexey Proskuryakov.

        Add resizePageRectsKeepingRatio(), which expands/shrinks a page, keeping the ratio of the original page
        https://bugs.webkit.org/show_bug.cgi?id=61256

        In order to prevent rounding error caused by expanding/shrinking a page
        using different calculation here and there, I added a common calculation
        method, resizePageRectsKeepingRatio(), which expands/shrinks a page,
        keeping the ratio of width and height of the original page.
        [WebHTMLView _beginPrintModeWithPageWidth:height:shrinkToFit:]
        and [WebHTMLView _beginScreenPaginationModeWithPageSize:shrinkToFit:]
        use resizePageRectsKeepingRatio() to expand/shrink a page.

        Test: printing/page-count-with-one-word.html

        * WebView/WebHTMLView.mm:
        (-[WebHTMLView _web_setPrintingModeRecursive]):
        (-[WebHTMLView _web_clearPrintingModeRecursive]):
        (-[WebHTMLView _web_setPrintingModeRecursiveAndAdjustViewSize]):
        (-[WebHTMLView _beginPrintModeWithMinimumPageWidth:height:maximumShrinkRatio:]):
        (-[WebHTMLView _beginPrintModeWithPageWidth:height:shrinkToFit:]):
        (-[WebHTMLView _endPrintMode]):
        (-[WebHTMLView _beginScreenPaginationModeWithPageSize:shrinkToFit:]):
        (-[WebHTMLView _endScreenPaginationMode]):
        (-[WebHTMLView layoutToMinimumPageWidth:height:maximumShrinkRatio:adjustingViewSize:]):
        (-[WebHTMLView layout]):
        (-[WebHTMLView _setPrinting:minimumPageLogicalWidth:logicalHeight:maximumShrinkRatio:adjustViewSize:paginateScreenContent:]):
        (-[WebHTMLView adjustPageHeightNew:top:bottom:limit:]):
        (-[WebHTMLView setPageWidthForPrinting:]):
2011-06-13  Kentaro Hara  <haraken@google.com>

        Reviewed by Alexey Proskuryakov.

        Add resizePageRectsKeepingRatio(), which expands/shrinks a page, keeping the ratio of the original page
        https://bugs.webkit.org/show_bug.cgi?id=61256

        In order to prevent rounding error caused by expanding/shrinking a page
        using different calculation here and there, I added a common calculation
        method, resizePageRectsKeepingRatio(), which expands/shrinks a page,
        keeping the ratio of width and height of the original page.
        WebFrame::setInPrintingMode() uses resizePageRectsKeepingRatio() to
        expand/shrink a page.

        Test: printing/page-count-with-one-word.html

        * WebFrame.cpp:
        (WebFrame::setPrinting):
        (WebFrame::setInPrintingMode):
        * WebFrame.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@88737 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
LayoutTests/ChangeLog
LayoutTests/printing/page-count-with-one-word-expected.txt [new file with mode: 0644]
LayoutTests/printing/page-count-with-one-word.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/page/Frame.cpp
Source/WebCore/page/Frame.h
Source/WebCore/page/PrintContext.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebHTMLView.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/WebFrame.cpp
Source/WebKit/win/WebFrame.h

index b8e65de..de6b571 100644 (file)
@@ -1,3 +1,18 @@
+2011-06-13  Kentaro Hara  <haraken@google.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Add a new test for checking rounding error in printing codes
+        https://bugs.webkit.org/show_bug.cgi?id=61256
+
+        Add a new test (printing/page-count-with-one-word.html). This test
+        checks if only one page is printed for an HTML page with one word for
+        various paper sizes around A4 portrait size, i.e. [530px, 560px) for
+        width and [730px, 760px) for height.
+
+        * printing/page-count-with-one-word-expected.txt: Added.
+        * printing/page-count-with-one-word.html: Added.
+
 2011-06-13  Ryosuke Niwa  <rniwa@webkit.org>
 
         Mac, GTK, and Qt rebaselines after r88717.
diff --git a/LayoutTests/printing/page-count-with-one-word-expected.txt b/LayoutTests/printing/page-count-with-one-word-expected.txt
new file mode 100644 (file)
index 0000000..390bf01
--- /dev/null
@@ -0,0 +1,2 @@
+A page with only one line should be printed in one page.
+PASS
diff --git a/LayoutTests/printing/page-count-with-one-word.html b/LayoutTests/printing/page-count-with-one-word.html
new file mode 100644 (file)
index 0000000..d708d80
--- /dev/null
@@ -0,0 +1,29 @@
+<html>
+<body>
+<pre id="console">
+test
+</pre>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+
+    var msg = 'A page with only one line should be printed in one page.\n';
+    var pass = true;
+
+    // Test the range around A4 portrait paper size
+    for (var i = 530; i < 560; i++) {
+        for (var j = 730; j < 760; j++) {
+            var numberOfPages = layoutTestController.numberOfPages(i, j);
+
+            if (numberOfPages != 1) {
+                pass = false;
+                msg += 'width=' + i + ', height=' + j + ': numberOfPages=' + numberOfPages + ' FAIL\n';
+            }
+        }
+    }
+    msg += (pass ? 'PASS' : 'FAIL');
+    document.querySelector('#console').textContent = msg;
+}
+</script>
+</body>
+</html>
index 38c7f44..692a182 100644 (file)
@@ -1,3 +1,27 @@
+2011-06-13  Kentaro Hara  <haraken@google.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Add resizePageRectsKeepingRatio(), which expands/shrinks a page, keeping the ratio of the original page
+        https://bugs.webkit.org/show_bug.cgi?id=61256
+
+        In order to prevent rounding error caused by expanding/shrinking a page
+        using different calculation here and there, I added a common calculation
+        method, resizePageRectsKeepingRatio(), which expands/shrinks a page,
+        keeping the ratio of width and height of the original page.
+        PrintContext::computePageRects() and PrintContext::begin()
+        use resizePageRectsKeepingRatio() to expand/shrink a page.
+
+        Test: printing/page-count-with-one-word.html
+
+        * WebCore.exp.in:
+        * page/Frame.cpp:
+        (WebCore::Frame::resizePageRectsKeepingRatio):
+        * page/Frame.h:
+        * page/PrintContext.cpp:
+        (WebCore::PrintContext::computePageRects):
+        (WebCore::PrintContext::begin):
+
 2011-06-13  Adam Barth  <abarth@webkit.org>
 
         Reviewed by Darin Adler.
index ec87bb0..4cc8805 100644 (file)
@@ -727,6 +727,7 @@ __ZN7WebCore5Frame17setTextZoomFactorEf
 __ZN7WebCore5Frame23visiblePositionForPointERKNS_8IntPointE
 __ZN7WebCore5Frame25matchLabelsAgainstElementEP7NSArrayPNS_7ElementE
 __ZN7WebCore5Frame25setPageAndTextZoomFactorsEff
+__ZN7WebCore5Frame27resizePageRectsKeepingRatioERKNS_9FloatSizeES3_
 __ZN7WebCore5Frame28searchForLabelsBeforeElementEP7NSArrayPNS_7ElementEPmPb
 __ZN7WebCore5Frame6createEPNS_4PageEPNS_21HTMLFrameOwnerElementEPNS_17FrameLoaderClientE
 __ZN7WebCore5Frame7setViewEN3WTF10PassRefPtrINS_9FrameViewEEE
index 90a0007..04173c9 100644 (file)
@@ -568,6 +568,24 @@ void Frame::setPrinting(bool printing, const FloatSize& pageSize, float maximumS
         child->setPrinting(printing, IntSize(), 0, shouldAdjustViewSize);
 }
 
+FloatSize Frame::resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize)
+{
+    FloatSize resultSize;
+    if (!contentRenderer())
+        return FloatSize();
+
+    if (contentRenderer()->style()->isHorizontalWritingMode()) {
+        float ratio = originalSize.height() / originalSize.width();
+        resultSize.setWidth(floorf(expectedSize.width()));
+        resultSize.setHeight(floorf(resultSize.width() * ratio));
+    } else {
+        float ratio = originalSize.width() / originalSize.height();
+        resultSize.setHeight(floorf(expectedSize.height()));
+        resultSize.setWidth(floorf(resultSize.height() * ratio));
+    }
+    return resultSize;
+}
+
 void Frame::injectUserScripts(UserScriptInjectionTime injectionTime)
 {
     if (!m_page)
index 44fe46e..35e4ba5 100644 (file)
@@ -148,6 +148,7 @@ namespace WebCore {
         Settings* settings() const; // can be NULL
 
         void setPrinting(bool printing, const FloatSize& pageSize, float maximumShrinkRatio, AdjustViewSizeOrNot);
+        FloatSize resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize);
 
         bool inViewSourceMode() const;
         void setInViewSourceMode(bool = true);
index 1b08268..7a894ba 100644 (file)
@@ -69,21 +69,10 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig
     }
 
     RenderView* view = toRenderView(m_frame->document()->renderer());
-
-    bool isHorizontal = view->style()->isHorizontalWritingMode();
-
-    float pageWidth;
-    float pageHeight;
     const IntRect& documentRect = view->documentRect();
-    if (isHorizontal) {
-        float ratio = printRect.height() / printRect.width();
-        pageWidth = documentRect.width();
-        pageHeight = floorf(pageWidth * ratio);
-    } else {
-        float ratio = printRect.width() / printRect.height();
-        pageHeight = documentRect.height();
-        pageWidth = floorf(pageHeight * ratio);
-    }
+    FloatSize pageSize = m_frame->resizePageRectsKeepingRatio(FloatSize(printRect.width(), printRect.height()), FloatSize(documentRect.width(), documentRect.height()));
+    float pageWidth = pageSize.width();
+    float pageHeight = pageSize.height();
 
     outPageHeight = pageHeight; // this is the height of the page adjusted by margins
     pageHeight -= headerHeight + footerHeight;
@@ -176,11 +165,10 @@ void PrintContext::begin(float width, float height)
     // This function can be called multiple times to adjust printing parameters without going back to screen mode.
     m_isPrinting = true;
 
-    float minLayoutWidth = width * printingMinimumShrinkFactor;
-    float minLayoutHeight = height * printingMinimumShrinkFactor;
+    FloatSize minLayoutSize = m_frame->resizePageRectsKeepingRatio(FloatSize(width, height), FloatSize(width * printingMinimumShrinkFactor, height * printingMinimumShrinkFactor));
 
     // This changes layout, so callers need to make sure that they don't paint to screen while in printing mode.
-    m_frame->setPrinting(true, FloatSize(minLayoutWidth, minLayoutHeight), printingMaximumShrinkFactor / printingMinimumShrinkFactor, AdjustViewSize);
+    m_frame->setPrinting(true, minLayoutSize, printingMaximumShrinkFactor / printingMinimumShrinkFactor, AdjustViewSize);
 }
 
 float PrintContext::computeAutomaticScaleFactor(const FloatSize& availablePaperSize)
index 982646a..f196fbe 100644 (file)
@@ -1,3 +1,35 @@
+2011-06-13  Kentaro Hara  <haraken@google.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Add resizePageRectsKeepingRatio(), which expands/shrinks a page, keeping the ratio of the original page
+        https://bugs.webkit.org/show_bug.cgi?id=61256
+
+        In order to prevent rounding error caused by expanding/shrinking a page
+        using different calculation here and there, I added a common calculation
+        method, resizePageRectsKeepingRatio(), which expands/shrinks a page,
+        keeping the ratio of width and height of the original page.
+        [WebHTMLView _beginPrintModeWithPageWidth:height:shrinkToFit:]
+        and [WebHTMLView _beginScreenPaginationModeWithPageSize:shrinkToFit:]
+        use resizePageRectsKeepingRatio() to expand/shrink a page.
+
+        Test: printing/page-count-with-one-word.html
+
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView _web_setPrintingModeRecursive]):
+        (-[WebHTMLView _web_clearPrintingModeRecursive]):
+        (-[WebHTMLView _web_setPrintingModeRecursiveAndAdjustViewSize]):
+        (-[WebHTMLView _beginPrintModeWithMinimumPageWidth:height:maximumShrinkRatio:]):
+        (-[WebHTMLView _beginPrintModeWithPageWidth:height:shrinkToFit:]):
+        (-[WebHTMLView _endPrintMode]):
+        (-[WebHTMLView _beginScreenPaginationModeWithPageSize:shrinkToFit:]):
+        (-[WebHTMLView _endScreenPaginationMode]):
+        (-[WebHTMLView layoutToMinimumPageWidth:height:maximumShrinkRatio:adjustingViewSize:]):
+        (-[WebHTMLView layout]):
+        (-[WebHTMLView _setPrinting:minimumPageLogicalWidth:logicalHeight:maximumShrinkRatio:adjustViewSize:paginateScreenContent:]):
+        (-[WebHTMLView adjustPageHeightNew:top:bottom:limit:]):
+        (-[WebHTMLView setPageWidthForPrinting:]):
+
 2011-06-13  Tony Chang  <tony@chromium.org>
 
         Reviewed by Dimitri Glazkov.
index 9414dac..3e89460 100644 (file)
@@ -412,7 +412,7 @@ static CachedResourceClient* promisedDataClient()
 #endif
 
 @interface WebHTMLView (WebForwardDeclaration) // FIXME: Put this in a normal category and stop doing the forward declaration trick.
-- (void)_setPrinting:(BOOL)printing minimumPageLogicalWidth:(float)minPageWidth logicalHeight:(float)minPageHeight maximumPageLogicalWidth:(float)maxPageWidth adjustViewSize:(BOOL)adjustViewSize paginateScreenContent:(BOOL)paginateScreenContent;
+- (void)_setPrinting:(BOOL)printing minimumPageLogicalWidth:(float)minPageWidth logicalHeight:(float)minPageHeight maximumShrinkRatio:(float)maximumShrinkRatio adjustViewSize:(BOOL)adjustViewSize paginateScreenContent:(BOOL)paginateScreenContent;
 - (void)_updateSecureInputState;
 @end
 
@@ -1070,7 +1070,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
 - (void)_web_setPrintingModeRecursive
 {
-    [self _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
 
 #ifndef NDEBUG
     _private->enumeratingSubviews = YES;
@@ -1082,7 +1082,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
     unsigned count = [descendantWebHTMLViews count];
     for (unsigned i = 0; i < count; ++i)
-        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
 
     [descendantWebHTMLViews release];
 
@@ -1093,7 +1093,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
 - (void)_web_clearPrintingModeRecursive
 {
-    [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
 
 #ifndef NDEBUG
     _private->enumeratingSubviews = YES;
@@ -1105,7 +1105,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
     unsigned count = [descendantWebHTMLViews count];
     for (unsigned i = 0; i < count; ++i)
-        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
 
     [descendantWebHTMLViews release];
 
@@ -1116,7 +1116,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
 - (void)_web_setPrintingModeRecursiveAndAdjustViewSize
 {
-    [self _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
 
 #ifndef NDEBUG
     _private->enumeratingSubviews = YES;
@@ -1128,7 +1128,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
     unsigned count = [descendantWebHTMLViews count];
     for (unsigned i = 0; i < count; ++i)
-        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
 
     [descendantWebHTMLViews release];
 
@@ -2126,10 +2126,13 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
     if (frame->document() && frame->document()->isFrameSet()) {
         minimumPageWidth = 0;
         minimumPageHeight = 0;
-        maximumPageWidth = 0;
     }
 
-    [self _setPrinting:YES minimumPageLogicalWidth:minimumPageWidth logicalHeight:minimumPageHeight maximumPageLogicalWidth:maximumPageWidth adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+    float maximumShrinkRatio = 0;
+    if (minimumPageWidth > 0.0)
+        maximumShrinkRatio = maximumPageWidth / minimumPageWidth;
+
+    [self _setPrinting:YES minimumPageLogicalWidth:minimumPageWidth logicalHeight:minimumPageHeight maximumShrinkRatio:maximumShrinkRatio adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
     return YES;
 }
 
@@ -2142,25 +2145,26 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
     Document* document = frame->document();
     bool isHorizontal = !document || !document->renderView() || document->renderView()->style()->isHorizontalWritingMode();
 
-    float minLayoutLogicalWidth = isHorizontal ? pageWidth : pageHeight;
-    float minLayoutLogicalHeight = isHorizontal ? pageHeight : pageWidth;
-    float maxLayoutLogicalWidth = minLayoutLogicalWidth;
+    float pageLogicalWidth = isHorizontal ? pageWidth : pageHeight;
+    float pageLogicalHeight = isHorizontal ? pageHeight : pageWidth;
+    FloatSize minLayoutSize(pageLogicalWidth, pageLogicalHeight);
+    float maximumShrinkRatio = 1;
 
     // If we are a frameset just print with the layout we have onscreen, otherwise relayout
     // according to the page width.
     if (shrinkToFit && (!frame->document() || !frame->document()->isFrameSet())) {
-        minLayoutLogicalWidth *= _WebHTMLViewPrintingMinimumShrinkFactor;
-        minLayoutLogicalHeight *= _WebHTMLViewPrintingMinimumShrinkFactor;
-        maxLayoutLogicalWidth *= _WebHTMLViewPrintingMaximumShrinkFactor;
+        minLayoutSize = frame->resizePageRectsKeepingRatio(FloatSize(pageLogicalWidth, pageLogicalHeight), FloatSize(pageLogicalWidth * _WebHTMLViewPrintingMinimumShrinkFactor, pageLogicalHeight * _WebHTMLViewPrintingMinimumShrinkFactor));
+        maximumShrinkRatio = _WebHTMLViewPrintingMaximumShrinkFactor / _WebHTMLViewPrintingMinimumShrinkFactor;
     }
-    [self _setPrinting:YES minimumPageLogicalWidth:minLayoutLogicalWidth logicalHeight:minLayoutLogicalHeight maximumPageLogicalWidth:maxLayoutLogicalWidth adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+
+    [self _setPrinting:YES minimumPageLogicalWidth:minLayoutSize.width() logicalHeight:minLayoutSize.height() maximumShrinkRatio:maximumShrinkRatio adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
 
     return YES;
 }
 
 - (void)_endPrintMode
 {
-    [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
 }
 
 - (BOOL)_isInScreenPaginationMode
@@ -2177,25 +2181,26 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
     Document* document = frame->document();
     bool isHorizontal = !document || !document->renderView() || document->renderView()->style()->isHorizontalWritingMode();
 
-    float minLayoutLogicalWidth = isHorizontal ? pageSize.width : pageSize.height;
-    float minLayoutLogicalHeight = isHorizontal ? pageSize.height : pageSize.width;
-    float maxLayoutLogicalWidth = minLayoutLogicalWidth;
+    float pageLogicalWidth = isHorizontal ? pageSize.width : pageSize.height;
+    float pageLogicalHeight = isHorizontal ? pageSize.height : pageSize.width;
+    FloatSize minLayoutSize(pageLogicalWidth, pageLogicalHeight);
+    float maximumShrinkRatio = 1;
 
     // If we are a frameset just print with the layout we have onscreen, otherwise relayout
     // according to the page width.
     if (shrinkToFit && (!frame->document() || !frame->document()->isFrameSet())) {
-        minLayoutLogicalWidth *= _WebHTMLViewPrintingMinimumShrinkFactor;
-        minLayoutLogicalHeight *= _WebHTMLViewPrintingMinimumShrinkFactor;
-        maxLayoutLogicalWidth *= _WebHTMLViewPrintingMaximumShrinkFactor;
+        minLayoutSize = frame->resizePageRectsKeepingRatio(FloatSize(pageLogicalWidth, pageLogicalHeight), FloatSize(pageLogicalWidth * _WebHTMLViewPrintingMinimumShrinkFactor, pageLogicalHeight * _WebHTMLViewPrintingMinimumShrinkFactor));
+        maximumShrinkRatio = _WebHTMLViewPrintingMaximumShrinkFactor / _WebHTMLViewPrintingMinimumShrinkFactor;
     }
-    [self _setPrinting:[self _isInPrintMode] minimumPageLogicalWidth:minLayoutLogicalWidth logicalHeight:minLayoutLogicalHeight maximumPageLogicalWidth:maxLayoutLogicalWidth adjustViewSize:YES paginateScreenContent:YES];
+
+    [self _setPrinting:[self _isInPrintMode] minimumPageLogicalWidth:minLayoutSize.width() logicalHeight:minLayoutSize.height() maximumShrinkRatio:maximumShrinkRatio adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
 
     return YES;
 }
 
 - (void)_endScreenPaginationMode
 {
-    [self _setPrinting:[self _isInPrintMode] minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:YES paginateScreenContent:NO];
+    [self _setPrinting:[self _isInPrintMode] minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:YES paginateScreenContent:NO];
 }
 
 - (CGFloat)_adjustedBottomOfPageWithTop:(CGFloat)top bottom:(CGFloat)bottom limit:(CGFloat)bottomLimit
@@ -3014,7 +3019,7 @@ WEBCORE_COMMAND(yankAndSelect)
 
 // Do a layout, but set up a new fixed width for the purposes of doing printing layout.
 // minPageWidth==0 implies a non-printing layout
-- (void)layoutToMinimumPageWidth:(float)minPageLogicalWidth height:(float)minPageLogicalHeight maximumPageWidth:(float)maxPageLogicalWidth adjustingViewSize:(BOOL)adjustViewSize
+- (void)layoutToMinimumPageWidth:(float)minPageLogicalWidth height:(float)minPageLogicalHeight maximumShrinkRatio:(float)maximumShrinkRatio adjustingViewSize:(BOOL)adjustViewSize
 {    
     if (![self _needsLayout])
         return;
@@ -3034,7 +3039,7 @@ WEBCORE_COMMAND(yankAndSelect)
             FloatSize pageSize(minPageLogicalWidth, minPageLogicalHeight);
             if (coreFrame->document() && coreFrame->document()->renderView() && !coreFrame->document()->renderView()->style()->isHorizontalWritingMode())
                 pageSize = FloatSize(minPageLogicalHeight, minPageLogicalWidth);
-            coreView->forceLayoutForPagination(pageSize, maxPageLogicalWidth / minPageLogicalWidth, adjustViewSize ? AdjustViewSize : DoNotAdjustViewSize);
+            coreView->forceLayoutForPagination(pageSize, maximumShrinkRatio, adjustViewSize ? AdjustViewSize : DoNotAdjustViewSize);
         } else {
             coreView->forceLayout(!adjustViewSize);
             if (adjustViewSize)
@@ -3050,7 +3055,7 @@ WEBCORE_COMMAND(yankAndSelect)
 
 - (void)layout
 {
-    [self layoutToMinimumPageWidth:0 height:0 maximumPageWidth:0 adjustingViewSize:NO];
+    [self layoutToMinimumPageWidth:0 height:0 maximumShrinkRatio:0 adjustingViewSize:NO];
 }
 
 // Deliver mouseup events to the DOM for button 2.
@@ -3808,7 +3813,7 @@ static PassRefPtr<KeyboardEvent> currentKeyboardEvent(Frame* coreFrame)
 
 // Does setNeedsDisplay:NO as a side effect when printing is ending.
 // pageWidth != 0 implies we will relayout to a new width
-- (void)_setPrinting:(BOOL)printing minimumPageLogicalWidth:(float)minPageLogicalWidth logicalHeight:(float)minPageLogicalHeight maximumPageLogicalWidth:(float)maxPageLogicalWidth adjustViewSize:(BOOL)adjustViewSize paginateScreenContent:(BOOL)paginateScreenContent
+- (void)_setPrinting:(BOOL)printing minimumPageLogicalWidth:(float)minPageLogicalWidth logicalHeight:(float)minPageLogicalHeight maximumShrinkRatio:(float)maximumShrinkRatio adjustViewSize:(BOOL)adjustViewSize paginateScreenContent:(BOOL)paginateScreenContent
 {
     if (printing == _private->printing && paginateScreenContent == _private->paginateScreenContent)
         return;
@@ -3821,7 +3826,7 @@ static PassRefPtr<KeyboardEvent> currentKeyboardEvent(Frame* coreFrame)
         WebFrame *subframe = [subframes objectAtIndex:i];
         WebFrameView *frameView = [subframe frameView];
         if ([[subframe _dataSource] _isDocumentHTML]) {
-            [(WebHTMLView *)[frameView documentView] _setPrinting:printing minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:adjustViewSize paginateScreenContent:paginateScreenContent];
+            [(WebHTMLView *)[frameView documentView] _setPrinting:printing minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:adjustViewSize paginateScreenContent:paginateScreenContent];
         }
     }
 
@@ -3846,7 +3851,7 @@ static PassRefPtr<KeyboardEvent> currentKeyboardEvent(Frame* coreFrame)
     }
 
     [self setNeedsLayout:YES];
-    [self layoutToMinimumPageWidth:minPageLogicalWidth height:minPageLogicalHeight maximumPageWidth:maxPageLogicalWidth adjustingViewSize:adjustViewSize];
+    [self layoutToMinimumPageWidth:minPageLogicalWidth height:minPageLogicalHeight maximumShrinkRatio:maximumShrinkRatio adjustingViewSize:adjustViewSize];
     if (!printing) {
         // Can't do this when starting printing or nested printing won't work, see 3491427.
         [self setNeedsDisplay:NO];
@@ -3866,7 +3871,7 @@ static PassRefPtr<KeyboardEvent> currentKeyboardEvent(Frame* coreFrame)
     // If the WebHTMLView itself is what we're printing, then we will never have to do this.
     BOOL wasInPrintingMode = _private->printing;
     if (!wasInPrintingMode)
-        [self _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+        [self _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
 
     *newBottom = [self _adjustedBottomOfPageWithTop:oldTop bottom:oldBottom limit:bottomLimit];
 
@@ -3877,7 +3882,7 @@ static PassRefPtr<KeyboardEvent> currentKeyboardEvent(Frame* coreFrame)
             [self performSelector:@selector(_delayedEndPrintMode:) withObject:currenPrintOperation afterDelay:0];
         else
             // not sure if this is actually ever invoked, it probably shouldn't be
-            [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+            [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
     }
 }
 
@@ -3914,8 +3919,8 @@ static PassRefPtr<KeyboardEvent> currentKeyboardEvent(Frame* coreFrame)
 // This is used for Carbon printing. At some point we might want to make this public API.
 - (void)setPageWidthForPrinting:(float)pageWidth
 {
-    [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
-    [self _setPrinting:YES minimumPageLogicalWidth:pageWidth logicalHeight:0 maximumPageLogicalWidth:pageWidth adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumShrinkRatio:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:YES minimumPageLogicalWidth:pageWidth logicalHeight:0 maximumShrinkRatio:1 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
 }
 
 - (void)_endPrintModeAndRestoreWindowAutodisplay
index 2002b48..e58bab6 100644 (file)
@@ -1,3 +1,24 @@
+2011-06-13  Kentaro Hara  <haraken@google.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Add resizePageRectsKeepingRatio(), which expands/shrinks a page, keeping the ratio of the original page
+        https://bugs.webkit.org/show_bug.cgi?id=61256
+
+        In order to prevent rounding error caused by expanding/shrinking a page
+        using different calculation here and there, I added a common calculation
+        method, resizePageRectsKeepingRatio(), which expands/shrinks a page,
+        keeping the ratio of width and height of the original page.
+        WebFrame::setInPrintingMode() uses resizePageRectsKeepingRatio() to
+        expand/shrink a page.
+
+        Test: printing/page-count-with-one-word.html
+
+        * WebFrame.cpp:
+        (WebFrame::setPrinting):
+        (WebFrame::setInPrintingMode):
+        * WebFrame.h:
+
 2011-06-12  MORITA Hajime  <morrita@google.com>
 
         Unreviewed, rolling out r88625.
index 99ba5a8..be05824 100644 (file)
@@ -1994,11 +1994,11 @@ static IntRect printerRect(HDC printDC)
                    GetDeviceCaps(printDC, PHYSICALHEIGHT) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETY));
 }
 
-void WebFrame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, float minPageHeight, bool adjustViewSize)
+void WebFrame::setPrinting(bool printing, float minPageWidth, float minPageHeight, float maximumShrinkRatio, bool adjustViewSize)
 {
     Frame* coreFrame = core(this);
     ASSERT(coreFrame);
-    coreFrame->setPrinting(printing, FloatSize(minPageWidth, minPageHeight), maxPageWidth / minPageWidth, adjustViewSize ? AdjustViewSize : DoNotAdjustViewSize);
+    coreFrame->setPrinting(printing, FloatSize(minPageWidth, minPageHeight), maximumShrinkRatio, adjustViewSize ? AdjustViewSize : DoNotAdjustViewSize);
 }
 
 HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode( 
@@ -2016,9 +2016,7 @@ HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode(
 
     // If we are a frameset just print with the layout we have onscreen, otherwise relayout
     // according to the paper size
-    float minLayoutWidth = 0.0f;
-    float maxLayoutWidth = 0.0f;
-    float minLayoutHeight = 0.0f;
+    FloatSize minLayoutSize(0.0, 0.0);
     if (m_inPrintingMode && !coreFrame->document()->isFrameSet()) {
         if (!printDC) {
             ASSERT_NOT_REACHED();
@@ -2031,12 +2029,11 @@ HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode(
         int paperWidth = printRect.width() * desiredPixelsPerInch / paperHorizontalPixelsPerInch;
         int paperVerticalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSY);
         int paperHeight = printRect.height() * desiredPixelsPerInch / paperVerticalPixelsPerInch;
-        minLayoutWidth = paperWidth * PrintingMinimumShrinkFactor;
-        maxLayoutWidth = paperWidth * PrintingMaximumShrinkFactor;
-        minLayoutHeight = paperHeight * PrintingMinimumShrinkFactor;
+        Frame* coreFrame = core(this);
+        minLayoutSize = coreFrame->resizePageRectsKeepingRatio(FloatSize(paperWidth, paperHeight), FloatSize(paperWidth * PrintingMinimumShrinkFactor, paperHeight * PrintingMinimumShrinkFactor));
     }
 
-    setPrinting(m_inPrintingMode, minLayoutWidth, maxLayoutWidth, minLayoutHeight, true);
+    setPrinting(m_inPrintingMode, minLayoutSize.width(), minLayoutSize.height(), PrintingMaximumShrinkFactor / PrintingMinimumShrinkFactor, true);
 
     if (!m_inPrintingMode)
         m_pageRects.clear();
index 2ceba4e..6552960 100644 (file)
@@ -389,7 +389,7 @@ protected:
     void loadHTMLString(BSTR string, BSTR baseURL, BSTR unreachableURL);
     void loadData(PassRefPtr<WebCore::SharedBuffer>, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL);
     const Vector<WebCore::IntRect>& computePageRects(HDC printDC);
-    void setPrinting(bool printing, float minPageWidth, float maxPageWidth, float minPageHeight, bool adjustViewSize);
+    void setPrinting(bool printing, float minPageWidth, float minPageHeight, float maximumShrinkRatio, bool adjustViewSize);
     void headerAndFooterHeights(float*, float*);
     WebCore::IntRect printerMarginRect(HDC);
     void spoolPage (PlatformGraphicsContext* pctx, WebCore::GraphicsContext* spoolCtx, HDC printDC, IWebUIDelegate*, float headerHeight, float footerHeight, UINT page, UINT pageCount);