https://bugs.webkit.org/show_bug.cgi?id=46422, make printing and pagination work
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Feb 2011 18:44:10 +0000 (18:44 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 Feb 2011 18:44:10 +0000 (18:44 +0000)
with vertical text.

Reviewed by Darin Adler.

../WebCore:

Change printing functions to check writing-mode and properly swap width and height
as needed.

Fix the setScrollOrigin function so that the origin doesn't cause
scroll spasming during printing (this is only partially successful, but it's better
than it was).

Rewrite computePageRects to handle both RTL documents properly as well as vertical
text documents properly.

* WebCore.exp.in:
* page/FrameView.cpp:
(WebCore::FrameView::adjustViewSize):
(WebCore::FrameView::forceLayoutForPagination):
* page/PrintContext.cpp:
(WebCore::PrintContext::computePageRects):
(WebCore::PrintContext::computePageRectsWithPageSizeInternal):
(WebCore::PrintContext::computeAutomaticScaleFactor):
(WebCore::PrintContext::spoolPage):
(WebCore::PrintContext::spoolRect):
* page/PrintContext.h:
* page/mac/WebCoreFrameView.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::wheelEvent):
* platform/ScrollView.h:
* platform/mac/ScrollViewMac.mm:
(WebCore::ScrollView::platformSetScrollOrigin):
* rendering/RenderView.cpp:
(WebCore::RenderView::layout):

../WebKit/mac:

Change printing functions to check writing-mode and properly swap width and height
as needed.

* WebView/WebDynamicScrollBarsView.mm:
(-[WebDynamicScrollBarsView setScrollOrigin:updatePositionAtAll:immediately:]):
* WebView/WebFrame.mm:
(-[WebFrame _computePageRectsWithPrintScaleFactor:pageSize:]):
* WebView/WebFrameInternal.h:
* WebView/WebHTMLView.mm:
(-[WebHTMLView _web_setPrintingModeRecursive]):
(-[WebHTMLView _web_clearPrintingModeRecursive]):
(-[WebHTMLView _web_setPrintingModeRecursiveAndAdjustViewSize]):
(-[WebHTMLView _beginPrintModeWithMinimumPageWidth:height:maximumPageWidth:]):
(-[WebHTMLView _beginPrintModeWithPageWidth:height:shrinkToFit:]):
(-[WebHTMLView _endPrintMode]):
(-[WebHTMLView _beginScreenPaginationModeWithPageSize:shrinkToFit:]):
(-[WebHTMLView _endScreenPaginationMode]):
(-[WebHTMLView layoutToMinimumPageWidth:height:maximumPageWidth:adjustingViewSize:]):
(-[WebHTMLView _setPrinting:minimumPageLogicalWidth:logicalHeight:maximumPageLogicalWidth:adjustViewSize:paginateScreenContent:]):
(-[WebHTMLView adjustPageHeightNew:top:bottom:limit:]):
(-[WebHTMLView _scaleFactorForPrintOperation:]):
(-[WebHTMLView setPageWidthForPrinting:]):
(-[WebHTMLView knowsPageRange:]):

../WebKit2:

Change printing functions to check writing-mode and properly swap width and height
as needed.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::computePagesForPrinting):

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

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/PrintContext.cpp
Source/WebCore/page/PrintContext.h
Source/WebCore/page/mac/WebCoreFrameView.h
Source/WebCore/platform/ScrollView.cpp
Source/WebCore/platform/ScrollView.h
Source/WebCore/platform/mac/ScrollViewMac.mm
Source/WebCore/rendering/RenderView.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebDynamicScrollBarsView.mm
Source/WebKit/mac/WebView/WebFrame.mm
Source/WebKit/mac/WebView/WebFrameInternal.h
Source/WebKit/mac/WebView/WebHTMLView.mm
Source/WebKit2/ChangeLog
Source/WebKit2/Platform/CoreIPC/Connection.cpp

index 675d3e5..9f8f153 100644 (file)
@@ -1,3 +1,40 @@
+2011-02-01  Dave Hyatt  <hyatt@apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=46422, make printing and pagination work
+        with vertical text.
+
+        Change printing functions to check writing-mode and properly swap width and height
+        as needed.
+        
+        Fix the setScrollOrigin function so that the origin doesn't cause
+        scroll spasming during printing (this is only partially successful, but it's better
+        than it was).
+
+        Rewrite computePageRects to handle both RTL documents properly as well as vertical
+        text documents properly.
+
+        * WebCore.exp.in:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::adjustViewSize):
+        (WebCore::FrameView::forceLayoutForPagination):
+        * page/PrintContext.cpp:
+        (WebCore::PrintContext::computePageRects):
+        (WebCore::PrintContext::computePageRectsWithPageSizeInternal):
+        (WebCore::PrintContext::computeAutomaticScaleFactor):
+        (WebCore::PrintContext::spoolPage):
+        (WebCore::PrintContext::spoolRect):
+        * page/PrintContext.h:
+        * page/mac/WebCoreFrameView.h:
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::wheelEvent):
+        * platform/ScrollView.h:
+        * platform/mac/ScrollViewMac.mm:
+        (WebCore::ScrollView::platformSetScrollOrigin):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::layout):
+
 2011-02-01  Mikhail Naganov  <mnaganov@chromium.org>
 
         Reviewed by Pavel Feldman.
 2011-02-01  Mikhail Naganov  <mnaganov@chromium.org>
 
         Reviewed by Pavel Feldman.
index c70aae0..eac0c84 100644 (file)
@@ -266,7 +266,7 @@ __ZN7WebCore12PrintContext16computePageRectsERKNS_9FloatRectEfffRfb
 __ZN7WebCore12PrintContext16isPageBoxVisibleEPNS_5FrameEi
 __ZN7WebCore12PrintContext20pageNumberForElementEPNS_7ElementERKNS_9FloatSizeE
 __ZN7WebCore12PrintContext26pageSizeAndMarginsInPixelsEPNS_5FrameEiiiiiii
 __ZN7WebCore12PrintContext16isPageBoxVisibleEPNS_5FrameEi
 __ZN7WebCore12PrintContext20pageNumberForElementEPNS_7ElementERKNS_9FloatSizeE
 __ZN7WebCore12PrintContext26pageSizeAndMarginsInPixelsEPNS_5FrameEiiiiiii
-__ZN7WebCore12PrintContext27computeAutomaticScaleFactorEf
+__ZN7WebCore12PrintContext27computeAutomaticScaleFactorERKNS_9FloatSizeE
 __ZN7WebCore12PrintContext27spoolAllPagesWithBoundariesEPNS_5FrameERNS_15GraphicsContextERKNS_9FloatSizeE
 __ZN7WebCore12PrintContext28computePageRectsWithPageSizeERKNS_9FloatSizeEb
 __ZN7WebCore12PrintContext3endEv
 __ZN7WebCore12PrintContext27spoolAllPagesWithBoundariesEPNS_5FrameERNS_15GraphicsContextERKNS_9FloatSizeE
 __ZN7WebCore12PrintContext28computePageRectsWithPageSizeERKNS_9FloatSizeEb
 __ZN7WebCore12PrintContext3endEv
@@ -1221,6 +1221,12 @@ __ZTVN7WebCore12ChromeClientE
 __ZTVN7WebCore17FileChooserClientE
 __ZTVN7WebCore17FrameLoaderClientE
 __ZTVN7WebCore25HistoryPropertyListWriterE
 __ZTVN7WebCore17FileChooserClientE
 __ZTVN7WebCore17FrameLoaderClientE
 __ZTVN7WebCore25HistoryPropertyListWriterE
+__ZNK7WebCore12RenderObject4viewEv
+__ZNK7WebCore10RenderView7docLeftEv
+__ZNK7WebCore10RenderView6docTopEv
+__ZNK7WebCore10RenderView8docRightEv
+__ZNK7WebCore10RenderView9docBottomEv
+__ZNK7WebCore8Document10renderViewEv
 _filenameByFixingIllegalCharacters
 _hasCaseInsensitiveSubstring
 _hasCaseInsensitiveSuffix
 _filenameByFixingIllegalCharacters
 _hasCaseInsensitiveSubstring
 _hasCaseInsensitiveSuffix
@@ -1436,7 +1442,6 @@ __ZN7WebCore16ScriptController20windowScriptNPObjectEv
 __ZN7WebCore16ScriptController29cleanupScriptObjectsForPluginEPv
 __ZN7WebCore16jsStringSlowCaseEPN3JSC9ExecStateERNS0_9WeakGCMapIPN3WTF10StringImplENS0_8JSStringEEES6_
 __ZN7WebCore17HTMLPlugInElement11getNPObjectEv
 __ZN7WebCore16ScriptController29cleanupScriptObjectsForPluginEPv
 __ZN7WebCore16jsStringSlowCaseEPN3JSC9ExecStateERNS0_9WeakGCMapIPN3WTF10StringImplENS0_8JSStringEEES6_
 __ZN7WebCore17HTMLPlugInElement11getNPObjectEv
-__ZNK7WebCore12RenderObject4viewEv
 __ZNK7WebCore14SecurityOrigin9canAccessEPKS0_
 __ZNK7WebCore4KURL10protocolIsEPKc
 __ZNK7WebCore4KURL7hasPathEv
 __ZNK7WebCore14SecurityOrigin9canAccessEPKS0_
 __ZNK7WebCore4KURL10protocolIsEPKc
 __ZNK7WebCore4KURL7hasPathEv
index ac1e2c9..cc74899 100644 (file)
@@ -453,7 +453,7 @@ void FrameView::adjustViewSize()
 
     IntSize size = IntSize(root->docWidth(), root->docHeight());
 
 
     IntSize size = IntSize(root->docWidth(), root->docHeight());
 
-    ScrollView::setScrollOrigin(IntPoint(-root->docLeft(), -root->docTop()), size == contentsSize());
+    ScrollView::setScrollOrigin(IntPoint(-root->docLeft(), -root->docTop()), !m_frame->document()->printing(), size == contentsSize());
     
     setContentsSize(size);
 }
     
     setContentsSize(size);
 }
@@ -2277,27 +2277,38 @@ void FrameView::forceLayoutForPagination(const FloatSize& pageSize, float maximu
     // the state of things before and after the layout
     RenderView *root = toRenderView(m_frame->document()->renderer());
     if (root) {
     // the state of things before and after the layout
     RenderView *root = toRenderView(m_frame->document()->renderer());
     if (root) {
-        int pageW = ceilf(pageSize.width());
-        root->setWidth(pageW);
-        root->setPageLogicalHeight(pageSize.height());
+        float pageLogicalWidth = root->style()->isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
+        float pageLogicalHeight = root->style()->isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
+
+        int flooredPageLogicalWidth = static_cast<int>(pageLogicalWidth);
+        root->setLogicalWidth(flooredPageLogicalWidth);
+        root->setPageLogicalHeight(pageLogicalHeight);
         root->setNeedsLayoutAndPrefWidthsRecalc();
         forceLayout();
         root->setNeedsLayoutAndPrefWidthsRecalc();
         forceLayout();
-
+        
         // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
         // page width when shrunk, we will lay out at maximum shrink and clip extra content.
         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
         // implementation should not do this!
         // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
         // page width when shrunk, we will lay out at maximum shrink and clip extra content.
         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
         // implementation should not do this!
-        int docWidth = root->docWidth();
-        if (docWidth > pageSize.width()) {
-            pageW = std::min<int>(docWidth, ceilf(pageSize.width() * maximumShrinkFactor));
-            if (pageSize.height())
-                root->setPageLogicalHeight(pageW / pageSize.width() * pageSize.height());
-            root->setWidth(pageW);
+        int docLogicalWidth = root->style()->isHorizontalWritingMode() ? root->docWidth() : root->docHeight();
+        if (docLogicalWidth > pageLogicalWidth) {
+            flooredPageLogicalWidth = std::min<int>(docLogicalWidth, pageLogicalWidth * maximumShrinkFactor);
+            if (pageLogicalHeight)
+                root->setPageLogicalHeight(flooredPageLogicalWidth / pageSize.width() * pageSize.height());
+            root->setLogicalWidth(flooredPageLogicalWidth);
             root->setNeedsLayoutAndPrefWidthsRecalc();
             forceLayout();
             root->setNeedsLayoutAndPrefWidthsRecalc();
             forceLayout();
-            int docHeight = root->docHeight();
             root->clearLayoutOverflow();
             root->clearLayoutOverflow();
-            root->addLayoutOverflow(IntRect(0, 0, pageW, docHeight)); // This is how we clip in case we overflow again.
+            int docLogicalHeight = root->style()->isHorizontalWritingMode() ? root->docHeight() : root->docWidth();
+            int docLogicalTop = root->style()->isHorizontalWritingMode() ? root->docTop() : root->docLeft();
+            int docLogicalRight = root->style()->isHorizontalWritingMode() ? root->docRight() : root->docBottom();
+            int clippedLogicalLeft = 0;
+            if (!root->style()->isLeftToRightDirection())
+                clippedLogicalLeft = docLogicalRight - flooredPageLogicalWidth;
+            IntRect overflow(clippedLogicalLeft, docLogicalTop, flooredPageLogicalWidth, docLogicalHeight);
+            if (!root->style()->isHorizontalWritingMode())
+                overflow = overflow.transposedRect();
+            root->addLayoutOverflow(overflow); // This is how we clip in case we overflow again.
         }
     }
 
         }
     }
 
index 760b6af..3cd59a7 100644 (file)
@@ -80,10 +80,20 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig
 
     RenderView* view = toRenderView(m_frame->document()->renderer());
 
 
     RenderView* view = toRenderView(m_frame->document()->renderer());
 
-    float ratio = printRect.height() / printRect.width();
+    bool isHorizontal = view->style()->isHorizontalWritingMode();
+
+    float pageWidth;
+    float pageHeight;
+    if (isHorizontal) {
+        float ratio = printRect.height() / printRect.width();
+        pageWidth = view->docWidth();
+        pageHeight = floorf(pageWidth * ratio);
+    } else {
+        float ratio = printRect.width() / printRect.height();
+        pageHeight = view->docHeight();
+        pageWidth = floorf(pageHeight * ratio);
+    }
 
 
-    float pageWidth  = view->docWidth();
-    float pageHeight = floorf(pageWidth * ratio);
     outPageHeight = pageHeight; // this is the height of the page adjusted by margins
     pageHeight -= headerHeight + footerHeight;
 
     outPageHeight = pageHeight; // this is the height of the page adjusted by margins
     pageHeight -= headerHeight + footerHeight;
 
@@ -101,7 +111,7 @@ void PrintContext::computePageRectsWithPageSize(const FloatSize& pageSizeInPixel
     computePageRectsWithPageSizeInternal(pageSizeInPixels, allowHorizontalTiling);
 }
 
     computePageRectsWithPageSizeInternal(pageSizeInPixels, allowHorizontalTiling);
 }
 
-void PrintContext::computePageRectsWithPageSizeInternal(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling)
+void PrintContext::computePageRectsWithPageSizeInternal(const FloatSize& pageSizeInPixels, bool allowInlineDirectionTiling)
 {
     if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer())
         return;
 {
     if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer())
         return;
@@ -113,13 +123,60 @@ void PrintContext::computePageRectsWithPageSizeInternal(const FloatSize& pageSiz
     int pageWidth = pageSizeInPixels.width();
     int pageHeight = pageSizeInPixels.height();
 
     int pageWidth = pageSizeInPixels.width();
     int pageHeight = pageSizeInPixels.height();
 
-    unsigned pageCount = ceilf((float)docRect.height() / pageHeight);
+    bool isHorizontal = view->style()->isHorizontalWritingMode();
+
+    int docLogicalHeight = isHorizontal ? docRect.height() : docRect.width();
+    int pageLogicalHeight = isHorizontal ? pageHeight : pageWidth;
+    int pageLogicalWidth = isHorizontal ? pageWidth : pageHeight;
+
+    int inlineDirectionStart;
+    int inlineDirectionEnd;
+    int blockDirectionStart;
+    int blockDirectionEnd;
+    if (isHorizontal) {
+        if (view->style()->isFlippedBlocksWritingMode()) {
+            blockDirectionStart = docRect.bottom();
+            blockDirectionEnd = docRect.y();
+        } else {
+            blockDirectionStart = docRect.y();
+            blockDirectionEnd = docRect.bottom();
+        }
+        inlineDirectionStart = view->style()->isLeftToRightDirection() ? docRect.x() : docRect.right();
+        inlineDirectionEnd = view->style()->isLeftToRightDirection() ? docRect.right() : docRect.x();
+    } else {
+        if (view->style()->isFlippedBlocksWritingMode()) {
+            blockDirectionStart = docRect.right();
+            blockDirectionEnd = docRect.x();
+        } else {
+            blockDirectionStart = docRect.x();
+            blockDirectionEnd = docRect.right();
+        }
+        inlineDirectionStart = view->style()->isLeftToRightDirection() ? docRect.y() : docRect.bottom();
+        inlineDirectionEnd = view->style()->isLeftToRightDirection() ? docRect.bottom() : docRect.y();
+    }
+
+    unsigned pageCount = ceilf((float)docLogicalHeight / pageLogicalHeight);
     for (unsigned i = 0; i < pageCount; ++i) {
     for (unsigned i = 0; i < pageCount; ++i) {
-        if (allowHorizontalTiling) {
-            for (int currentX = docRect.x(); currentX < docRect.right(); currentX += pageWidth)
-                m_pageRects.append(IntRect(currentX, docRect.y() + i * pageHeight, pageWidth, pageHeight));
-        } else
-            m_pageRects.append(IntRect(docRect.x(), docRect.y() + i * pageHeight, pageWidth, pageHeight));
+        int pageLogicalTop = blockDirectionEnd > blockDirectionStart ?
+                                blockDirectionStart + i * pageLogicalHeight : 
+                                blockDirectionStart - (i + 1) * pageLogicalHeight;
+        if (allowInlineDirectionTiling) {
+            for (int currentInlinePosition = inlineDirectionStart;
+                 inlineDirectionEnd > inlineDirectionStart ? currentInlinePosition < inlineDirectionEnd : currentInlinePosition > inlineDirectionEnd;
+                 currentInlinePosition += (inlineDirectionEnd > inlineDirectionStart ? pageLogicalWidth : -pageLogicalWidth)) {
+                int pageLogicalLeft = inlineDirectionEnd > inlineDirectionStart ? currentInlinePosition : currentInlinePosition - pageLogicalWidth;
+                IntRect pageRect(pageLogicalLeft, pageLogicalTop, pageLogicalWidth, pageLogicalHeight);
+                if (!isHorizontal)
+                    pageRect = pageRect.transposedRect();
+                m_pageRects.append(pageRect);
+            }
+        } else {
+            int pageLogicalLeft = inlineDirectionEnd > inlineDirectionStart ? inlineDirectionStart : inlineDirectionStart - pageLogicalWidth;
+            IntRect pageRect(pageLogicalLeft, pageLogicalTop, pageLogicalWidth, pageLogicalHeight);
+            if (!isHorizontal)
+                pageRect = pageRect.transposedRect();
+            m_pageRects.append(pageRect);
+        }
     }
 }
 
     }
 }
 
@@ -135,22 +192,27 @@ void PrintContext::begin(float width, float height)
     m_frame->setPrinting(true, FloatSize(minLayoutWidth, minLayoutHeight), printingMaximumShrinkFactor / printingMinimumShrinkFactor, Frame::AdjustViewSize);
 }
 
     m_frame->setPrinting(true, FloatSize(minLayoutWidth, minLayoutHeight), printingMaximumShrinkFactor / printingMinimumShrinkFactor, Frame::AdjustViewSize);
 }
 
-float PrintContext::computeAutomaticScaleFactor(float availablePaperWidth)
+float PrintContext::computeAutomaticScaleFactor(const FloatSize& availablePaperSize)
 {
     if (!m_frame->view())
         return 1;
 
 {
     if (!m_frame->view())
         return 1;
 
-    float viewWidth = m_frame->view()->contentsWidth();
-    if (viewWidth < 1)
+    bool useViewWidth = true;
+    if (m_frame->document() && m_frame->document()->renderView())
+        useViewWidth = m_frame->document()->renderView()->style()->isHorizontalWritingMode();
+
+    float viewLogicalWidth = useViewWidth ? m_frame->view()->contentsWidth() : m_frame->view()->contentsHeight();
+    if (viewLogicalWidth < 1)
         return 1;
 
     float maxShrinkToFitScaleFactor = 1 / printingMaximumShrinkFactor;
         return 1;
 
     float maxShrinkToFitScaleFactor = 1 / printingMaximumShrinkFactor;
-    float shrinkToFitScaleFactor = availablePaperWidth / viewWidth;
+    float shrinkToFitScaleFactor = (useViewWidth ? availablePaperSize.width() : availablePaperSize.height()) / viewLogicalWidth;
     return max(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor);
 }
 
 void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
 {
     return max(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor);
 }
 
 void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
 {
+    // FIXME: Not correct for vertical text.
     IntRect pageRect = m_pageRects[pageNumber];
     float scale = width / pageRect.width();
 
     IntRect pageRect = m_pageRects[pageNumber];
     float scale = width / pageRect.width();
 
@@ -164,6 +226,7 @@ void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
 
 void PrintContext::spoolRect(GraphicsContext& ctx, const IntRect& rect)
 {
 
 void PrintContext::spoolRect(GraphicsContext& ctx, const IntRect& rect)
 {
+    // FIXME: Not correct for vertical text.
     ctx.save();
     ctx.translate(-rect.x(), -rect.y());
     ctx.clip(rect);
     ctx.save();
     ctx.translate(-rect.x(), -rect.y());
     ctx.clip(rect);
index ce2554a..1b235c3 100644 (file)
@@ -54,7 +54,7 @@ public:
     const IntRect& pageRect(size_t pageNumber) const;
     const Vector<IntRect>& pageRects() const { return m_pageRects; }
 
     const IntRect& pageRect(size_t pageNumber) const;
     const Vector<IntRect>& pageRects() const { return m_pageRects; }
 
-    float computeAutomaticScaleFactor(float availablePaperWidth);
+    float computeAutomaticScaleFactor(const FloatSize& availablePaperSize);
 
     // Enter print mode, updating layout for new page size.
     // This function can be called multiple times to apply new print options without going back to screen mode.
 
     // Enter print mode, updating layout for new page size.
     // This function can be called multiple times to apply new print options without going back to screen mode.
index b76350d..93a0296 100644 (file)
@@ -33,7 +33,7 @@ namespace WebCore {
 - (void)setScrollingModes:(WebCore::ScrollbarMode)hMode vertical:(WebCore::ScrollbarMode)vMode andLock:(BOOL)lock;
 - (void)scrollingModes:(WebCore::ScrollbarMode*)hMode vertical:(WebCore::ScrollbarMode*)vMode;
 - (void)setScrollBarsSuppressed:(BOOL)suppressed repaintOnUnsuppress:(BOOL)repaint;
 - (void)setScrollingModes:(WebCore::ScrollbarMode)hMode vertical:(WebCore::ScrollbarMode)vMode andLock:(BOOL)lock;
 - (void)scrollingModes:(WebCore::ScrollbarMode*)hMode vertical:(WebCore::ScrollbarMode*)vMode;
 - (void)setScrollBarsSuppressed:(BOOL)suppressed repaintOnUnsuppress:(BOOL)repaint;
-- (void)setScrollOrigin:(NSPoint)origin updatePosition:(BOOL)updatePosition;
+- (void)setScrollOrigin:(NSPoint)origin updatePositionAtAll:(BOOL)updatePositionAtAll immediately:(BOOL)updatePositionImmediately;
 - (NSPoint)scrollOrigin;
 @end
 
 - (NSPoint)scrollOrigin;
 @end
 
index 3fdca58..6161090 100644 (file)
@@ -1094,7 +1094,7 @@ void ScrollView::removePanScrollIcon()
     hostWindow()->invalidateContentsAndWindow(IntRect(m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)), true /*immediate*/);
 }
 
     hostWindow()->invalidateContentsAndWindow(IntRect(m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)), true /*immediate*/);
 }
 
-void ScrollView::setScrollOrigin(const IntPoint& origin, bool updatePosition)
+void ScrollView::setScrollOrigin(const IntPoint& origin, bool updatePositionAtAll, bool updatePositionSynchronously)
 {
     if (m_scrollOrigin == origin)
         return;
 {
     if (m_scrollOrigin == origin)
         return;
@@ -1102,12 +1102,12 @@ void ScrollView::setScrollOrigin(const IntPoint& origin, bool updatePosition)
     m_scrollOrigin = origin;
 
     if (platformWidget()) {
     m_scrollOrigin = origin;
 
     if (platformWidget()) {
-        platformSetScrollOrigin(origin, updatePosition);
+        platformSetScrollOrigin(origin, updatePositionAtAll, updatePositionSynchronously);
         return;
     }
     
     // Update if the scroll origin changes, since our position will be different if the content size did not change.
         return;
     }
     
     // Update if the scroll origin changes, since our position will be different if the content size did not change.
-    if (updatePosition)
+    if (updatePositionAtAll && updatePositionSynchronously)
         updateScrollbars(scrollOffset());
 }
 
         updateScrollbars(scrollOffset());
 }
 
@@ -1141,7 +1141,7 @@ void ScrollView::platformSetScrollbarsSuppressed(bool)
 {
 }
 
 {
 }
 
-void ScrollView::platformSetScrollOrigin(const IntPoint&, bool updatePosition)
+void ScrollView::platformSetScrollOrigin(const IntPoint&, bool updatePositionAtAll, bool updatePositionSynchronously)
 {
 }
 
 {
 }
 
index cb7e647..1b6de53 100644 (file)
@@ -296,7 +296,7 @@ protected:
     // Scroll the content by invalidating everything.
     virtual void scrollContentsSlowPath(const IntRect& updateRect);
 
     // Scroll the content by invalidating everything.
     virtual void scrollContentsSlowPath(const IntRect& updateRect);
 
-    void setScrollOrigin(const IntPoint&, bool updatePosition);
+    void setScrollOrigin(const IntPoint&, bool updatePositionAtAll, bool updatePositionSynchronously);
     IntPoint scrollOrigin() { return m_scrollOrigin; }
 
     // Subclassed by FrameView to check the writing-mode of the document.
     IntPoint scrollOrigin() { return m_scrollOrigin; }
 
     // Subclassed by FrameView to check the writing-mode of the document.
@@ -383,7 +383,7 @@ private:
     void platformRepaintContentRectangle(const IntRect&, bool now);
     bool platformIsOffscreen() const;
    
     void platformRepaintContentRectangle(const IntRect&, bool now);
     bool platformIsOffscreen() const;
    
-    void platformSetScrollOrigin(const IntPoint&, bool updatePosition);
+    void platformSetScrollOrigin(const IntPoint&, bool updatePositionAtAll, bool updatePositionSynchronously);
 
 #if PLATFORM(MAC) && defined __OBJC__
 public:
 
 #if PLATFORM(MAC) && defined __OBJC__
 public:
index 93ec971..ff2e14e 100644 (file)
@@ -203,10 +203,10 @@ bool ScrollView::platformIsOffscreen() const
     return ![platformWidget() window] || ![[platformWidget() window] isVisible];
 }
 
     return ![platformWidget() window] || ![[platformWidget() window] isVisible];
 }
 
-void ScrollView::platformSetScrollOrigin(const IntPoint& origin, bool updatePosition)
+void ScrollView::platformSetScrollOrigin(const IntPoint& origin, bool updatePositionAtAll, bool updatePositionSynchronously)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    [scrollView() setScrollOrigin:origin updatePosition:updatePosition];
+    [scrollView() setScrollOrigin:origin updatePositionAtAll:updatePositionAtAll immediately:updatePositionSynchronously];
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
index 44ba4af..d76b85d 100644 (file)
@@ -105,7 +105,7 @@ void RenderView::layout()
         setPageLogicalHeight(0);
 
     if (printing())
         setPageLogicalHeight(0);
 
     if (printing())
-        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = width();
+        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth();
 
     // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
     bool relayoutChildren = !printing() && (!m_frameView || width() != viewWidth() || height() != viewHeight());
 
     // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
     bool relayoutChildren = !printing() && (!m_frameView || width() != viewWidth() || height() != viewHeight());
index 617d912..97f5459 100644 (file)
@@ -1,3 +1,34 @@
+2011-02-01  Dave Hyatt  <hyatt@apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=46422, make printing and pagination work
+        with vertical text.
+
+        Change printing functions to check writing-mode and properly swap width and height
+        as needed.
+
+        * WebView/WebDynamicScrollBarsView.mm:
+        (-[WebDynamicScrollBarsView setScrollOrigin:updatePositionAtAll:immediately:]):
+        * WebView/WebFrame.mm:
+        (-[WebFrame _computePageRectsWithPrintScaleFactor:pageSize:]):
+        * WebView/WebFrameInternal.h:
+        * WebView/WebHTMLView.mm:
+        (-[WebHTMLView _web_setPrintingModeRecursive]):
+        (-[WebHTMLView _web_clearPrintingModeRecursive]):
+        (-[WebHTMLView _web_setPrintingModeRecursiveAndAdjustViewSize]):
+        (-[WebHTMLView _beginPrintModeWithMinimumPageWidth:height:maximumPageWidth:]):
+        (-[WebHTMLView _beginPrintModeWithPageWidth:height:shrinkToFit:]):
+        (-[WebHTMLView _endPrintMode]):
+        (-[WebHTMLView _beginScreenPaginationModeWithPageSize:shrinkToFit:]):
+        (-[WebHTMLView _endScreenPaginationMode]):
+        (-[WebHTMLView layoutToMinimumPageWidth:height:maximumPageWidth:adjustingViewSize:]):
+        (-[WebHTMLView _setPrinting:minimumPageLogicalWidth:logicalHeight:maximumPageLogicalWidth:adjustViewSize:paginateScreenContent:]):
+        (-[WebHTMLView adjustPageHeightNew:top:bottom:limit:]):
+        (-[WebHTMLView _scaleFactorForPrintOperation:]):
+        (-[WebHTMLView setPageWidthForPrinting:]):
+        (-[WebHTMLView knowsPageRange:]):
+
 2011-01-31  Oliver Hunt  <oliver@apple.com>
 
         Convert markstack to a slot visitor API
 2011-01-31  Oliver Hunt  <oliver@apple.com>
 
         Convert markstack to a slot visitor API
index b8edef8..610cd40 100644 (file)
@@ -568,7 +568,7 @@ static const unsigned cMaxUpdateScrollbarsPass = 2;
     return YES;
 }
 
     return YES;
 }
 
-- (void)setScrollOrigin:(NSPoint)scrollOrigin updatePosition:(BOOL)updatePosition
+- (void)setScrollOrigin:(NSPoint)scrollOrigin updatePositionAtAll:(BOOL)updatePositionAtAll immediately:(BOOL)updatePositionSynchronously
 {
     // The cross-platform ScrollView call already checked to see if the old/new scroll origins were the same or not
     // so we don't have to check for equivalence here.
 {
     // The cross-platform ScrollView call already checked to see if the old/new scroll origins were the same or not
     // so we don't have to check for equivalence here.
@@ -579,12 +579,13 @@ static const unsigned cMaxUpdateScrollbarsPass = 2;
 
     [docView setBoundsOrigin:NSMakePoint(-scrollOrigin.x, -scrollOrigin.y)];
 
 
     [docView setBoundsOrigin:NSMakePoint(-scrollOrigin.x, -scrollOrigin.y)];
 
-    _private->scrollOriginChanged = true;
+    if (updatePositionAtAll)
+        _private->scrollOriginChanged = true;
 
     // Maintain our original position in the presence of the new scroll origin.
     _private->scrollPositionExcludingOrigin = NSMakePoint(visibleRect.origin.x + scrollOrigin.x, visibleRect.origin.y + scrollOrigin.y);
 
 
     // Maintain our original position in the presence of the new scroll origin.
     _private->scrollPositionExcludingOrigin = NSMakePoint(visibleRect.origin.x + scrollOrigin.x, visibleRect.origin.y + scrollOrigin.y);
 
-    if (updatePosition) // Otherwise we'll just let the snap happen when we update for the resize.
+    if (updatePositionAtAll && updatePositionSynchronously) // Otherwise we'll just let the snap happen when we update for the resize.
         [self adjustForScrollOriginChange];
 }
 
         [self adjustForScrollOriginChange];
 }
 
index 154156a..9616f03 100644 (file)
@@ -587,16 +587,11 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
 }
 
 // Used by pagination code called from AppKit when a standalone web page is printed.
 }
 
 // Used by pagination code called from AppKit when a standalone web page is printed.
-- (NSArray*)_computePageRectsWithPrintWidthScaleFactor:(float)printWidthScaleFactor printHeight:(float)printHeight
+- (NSArray*)_computePageRectsWithPrintScaleFactor:(float)printScaleFactor pageSize:(NSSize)pageSize
 {
     NSMutableArray* pages = [NSMutableArray arrayWithCapacity:5];
 {
     NSMutableArray* pages = [NSMutableArray arrayWithCapacity:5];
-    if (printWidthScaleFactor <= 0) {
-        LOG_ERROR("printWidthScaleFactor has bad value %.2f", printWidthScaleFactor);
-        return pages;
-    }
-    
-    if (printHeight <= 0) {
-        LOG_ERROR("printHeight has bad value %.2f", printHeight);
+    if (printScaleFactor <= 0) {
+        LOG_ERROR("printScaleFactor has bad value %.2f", printScaleFactor);
         return pages;
     }
 
         return pages;
     }
 
@@ -612,8 +607,11 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
     if (!documentView)
         return pages;
 
     if (!documentView)
         return pages;
 
-    float docWidth = root->layer()->width();
-    float printWidth = docWidth / printWidthScaleFactor;
+    float docWidth = root->docWidth();
+    float docHeight = root->docHeight();
+
+    float printWidth = root->style()->isHorizontalWritingMode() ? docWidth / printScaleFactor : pageSize.width;
+    float printHeight = root->style()->isHorizontalWritingMode() ? pageSize.height : docHeight / printScaleFactor;
 
     PrintContext printContext(_private->coreFrame);
     printContext.computePageRectsWithPageSize(FloatSize(printWidth, printHeight), true);
 
     PrintContext printContext(_private->coreFrame);
     printContext.computePageRectsWithPageSize(FloatSize(printWidth, printHeight), true);
index 7ff5e75..83870ec 100644 (file)
@@ -124,7 +124,7 @@ WebView *getWebView(WebFrame *webFrame);
 - (BOOL)_needsLayout;
 - (void)_drawRect:(NSRect)rect contentsOnly:(BOOL)contentsOnly;
 - (BOOL)_getVisibleRect:(NSRect*)rect;
 - (BOOL)_needsLayout;
 - (void)_drawRect:(NSRect)rect contentsOnly:(BOOL)contentsOnly;
 - (BOOL)_getVisibleRect:(NSRect*)rect;
-- (NSArray*)_computePageRectsWithPrintWidthScaleFactor:(float)printWidthScaleFactor printHeight:(float)printHeight;
+- (NSArray*)_computePageRectsWithPrintScaleFactor:(float)printWidthScaleFactor pageSize:(NSSize)pageSize;
 
 - (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string;
 - (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture;
 
 - (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string;
 - (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture;
index 35b3def..4a53f0c 100644 (file)
 #import <WebCore/PlatformKeyboardEvent.h>
 #import <WebCore/Range.h>
 #import <WebCore/RenderWidget.h>
 #import <WebCore/PlatformKeyboardEvent.h>
 #import <WebCore/Range.h>
 #import <WebCore/RenderWidget.h>
+#import <WebCore/RenderView.h>
 #import <WebCore/RuntimeApplicationChecks.h>
 #import <WebCore/SelectionController.h>
 #import <WebCore/SharedBuffer.h>
 #import <WebCore/RuntimeApplicationChecks.h>
 #import <WebCore/SelectionController.h>
 #import <WebCore/SharedBuffer.h>
@@ -428,7 +429,7 @@ static CachedResourceClient* promisedDataClient()
 #endif
 
 @interface WebHTMLView (WebForwardDeclaration) // FIXME: Put this in a normal category and stop doing the forward declaration trick.
 #endif
 
 @interface WebHTMLView (WebForwardDeclaration) // FIXME: Put this in a normal category and stop doing the forward declaration trick.
-- (void)_setPrinting:(BOOL)printing minimumPageWidth:(float)minPageWidth height:(float)minPageHeight maximumPageWidth:(float)maxPageWidth adjustViewSize:(BOOL)adjustViewSize paginateScreenContent:(BOOL)paginateScreenContent;
+- (void)_setPrinting:(BOOL)printing minimumPageLogicalWidth:(float)minPageWidth logicalHeight:(float)minPageHeight maximumPageLogicalWidth:(float)maxPageWidth adjustViewSize:(BOOL)adjustViewSize paginateScreenContent:(BOOL)paginateScreenContent;
 @end
 
 @class NSTextInputContext;
 @end
 
 @class NSTextInputContext;
@@ -1080,7 +1081,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
 - (void)_web_setPrintingModeRecursive
 {
 
 - (void)_web_setPrintingModeRecursive
 {
-    [self _setPrinting:YES minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
 
 #ifndef NDEBUG
     _private->enumeratingSubviews = YES;
 
 #ifndef NDEBUG
     _private->enumeratingSubviews = YES;
@@ -1092,7 +1093,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
     unsigned count = [descendantWebHTMLViews count];
     for (unsigned i = 0; i < count; ++i)
 
     unsigned count = [descendantWebHTMLViews count];
     for (unsigned i = 0; i < count; ++i)
-        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:YES minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
 
     [descendantWebHTMLViews release];
 
 
     [descendantWebHTMLViews release];
 
@@ -1103,7 +1104,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
 - (void)_web_clearPrintingModeRecursive
 {
 
 - (void)_web_clearPrintingModeRecursive
 {
-    [self _setPrinting:NO minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
 
 #ifndef NDEBUG
     _private->enumeratingSubviews = YES;
 
 #ifndef NDEBUG
     _private->enumeratingSubviews = YES;
@@ -1115,7 +1116,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
     unsigned count = [descendantWebHTMLViews count];
     for (unsigned i = 0; i < count; ++i)
 
     unsigned count = [descendantWebHTMLViews count];
     for (unsigned i = 0; i < count; ++i)
-        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:NO minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
 
     [descendantWebHTMLViews release];
 
 
     [descendantWebHTMLViews release];
 
@@ -1126,7 +1127,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
 - (void)_web_setPrintingModeRecursiveAndAdjustViewSize
 {
 
 - (void)_web_setPrintingModeRecursiveAndAdjustViewSize
 {
-    [self _setPrinting:YES minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
 
 #ifndef NDEBUG
     _private->enumeratingSubviews = YES;
 
 #ifndef NDEBUG
     _private->enumeratingSubviews = YES;
@@ -1138,7 +1139,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
 
     unsigned count = [descendantWebHTMLViews count];
     for (unsigned i = 0; i < count; ++i)
 
     unsigned count = [descendantWebHTMLViews count];
     for (unsigned i = 0; i < count; ++i)
-        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:YES minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+        [[descendantWebHTMLViews objectAtIndex:i] _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
 
     [descendantWebHTMLViews release];
 
 
     [descendantWebHTMLViews release];
 
@@ -2201,7 +2202,7 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
         maximumPageWidth = 0;
     }
 
         maximumPageWidth = 0;
     }
 
-    [self _setPrinting:YES minimumPageWidth:minimumPageWidth height:minimumPageHeight maximumPageWidth:maximumPageWidth adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:YES minimumPageLogicalWidth:minimumPageWidth logicalHeight:minimumPageHeight maximumPageLogicalWidth:maximumPageWidth adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
     return YES;
 }
 
     return YES;
 }
 
@@ -2211,25 +2212,28 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
     if (!frame)
         return NO;
 
     if (!frame)
         return NO;
 
-    float minLayoutWidth = 0;
-    float minLayoutHeight = 0;
-    float maxLayoutWidth = 0;
+    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;
 
     // If we are a frameset just print with the layout we have onscreen, otherwise relayout
     // according to the page width.
 
     // If we are a frameset just print with the layout we have onscreen, otherwise relayout
     // according to the page width.
-    if (!frame->document() || !frame->document()->isFrameSet()) {
-        minLayoutWidth = shrinkToFit ? pageWidth * _WebHTMLViewPrintingMinimumShrinkFactor : pageWidth;
-        minLayoutHeight = shrinkToFit ? pageHeight * _WebHTMLViewPrintingMinimumShrinkFactor : pageHeight;
-        maxLayoutWidth = shrinkToFit ? pageWidth * _WebHTMLViewPrintingMaximumShrinkFactor : pageWidth;
+    if (shrinkToFit && (!frame->document() || !frame->document()->isFrameSet())) {
+        minLayoutLogicalWidth *= _WebHTMLViewPrintingMinimumShrinkFactor;
+        minLayoutLogicalHeight *= _WebHTMLViewPrintingMinimumShrinkFactor;
+        maxLayoutLogicalWidth *= _WebHTMLViewPrintingMaximumShrinkFactor;
     }
     }
-    [self _setPrinting:YES minimumPageWidth:minLayoutWidth height:minLayoutHeight maximumPageWidth:maxLayoutWidth adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:YES minimumPageLogicalWidth:minLayoutLogicalWidth logicalHeight:minLayoutLogicalHeight maximumPageLogicalWidth:maxLayoutLogicalWidth adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
 
     return YES;
 }
 
 - (void)_endPrintMode
 {
 
     return YES;
 }
 
 - (void)_endPrintMode
 {
-    [self _setPrinting:NO minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+    [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
 }
 
 - (BOOL)_isInScreenPaginationMode
 }
 
 - (BOOL)_isInScreenPaginationMode
@@ -2243,25 +2247,28 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
     if (!frame)
         return NO;
 
     if (!frame)
         return NO;
 
-    CGFloat minLayoutWidth = 0;
-    CGFloat minLayoutHeight = 0;
-    CGFloat maxLayoutWidth = 0;
+    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;
 
 
-    // If we are a frameset just print with the layout we have on the screen. Otherwise do a relayout
+    // If we are a frameset just print with the layout we have onscreen, otherwise relayout
     // according to the page width.
     // according to the page width.
-    if (!frame->document() || !frame->document()->isFrameSet()) {
-        minLayoutWidth = shrinkToFit ? pageSize.width * _WebHTMLViewPrintingMinimumShrinkFactor : pageSize.width;
-        minLayoutHeight = shrinkToFit ? pageSize.height * _WebHTMLViewPrintingMinimumShrinkFactor : pageSize.height;
-        maxLayoutWidth = shrinkToFit ? pageSize.width * _WebHTMLViewPrintingMaximumShrinkFactor : pageSize.width;
+    if (shrinkToFit && (!frame->document() || !frame->document()->isFrameSet())) {
+        minLayoutLogicalWidth *= _WebHTMLViewPrintingMinimumShrinkFactor;
+        minLayoutLogicalHeight *= _WebHTMLViewPrintingMinimumShrinkFactor;
+        maxLayoutLogicalWidth *= _WebHTMLViewPrintingMaximumShrinkFactor;
     }
     }
-    [self _setPrinting:[self _isInPrintMode] minimumPageWidth:minLayoutWidth height:minLayoutHeight maximumPageWidth:maxLayoutWidth adjustViewSize:YES paginateScreenContent:YES];
+    [self _setPrinting:[self _isInPrintMode] minimumPageLogicalWidth:minLayoutLogicalWidth logicalHeight:minLayoutLogicalHeight maximumPageLogicalWidth:maxLayoutLogicalWidth adjustViewSize:YES paginateScreenContent:YES];
 
     return YES;
 }
 
 - (void)_endScreenPaginationMode
 {
 
     return YES;
 }
 
 - (void)_endScreenPaginationMode
 {
-    [self _setPrinting:[self _isInPrintMode] minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:YES paginateScreenContent:NO];
+    [self _setPrinting:[self _isInPrintMode] minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:YES paginateScreenContent:NO];
 }
 
 - (CGFloat)_adjustedBottomOfPageWithTop:(CGFloat)top bottom:(CGFloat)bottom limit:(CGFloat)bottomLimit
 }
 
 - (CGFloat)_adjustedBottomOfPageWithTop:(CGFloat)top bottom:(CGFloat)bottom limit:(CGFloat)bottomLimit
@@ -3117,7 +3124,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
 
 // 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)minPageWidth height:(float)minPageHeight maximumPageWidth:(float)maxPageWidth adjustingViewSize:(BOOL)adjustViewSize
+- (void)layoutToMinimumPageWidth:(float)minPageLogicalWidth height:(float)minPageLogicalHeight maximumPageWidth:(float)maxPageLogicalWidth adjustingViewSize:(BOOL)adjustViewSize
 {    
     if (![self _needsLayout])
         return;
 {    
     if (![self _needsLayout])
         return;
@@ -3133,9 +3140,12 @@ WEBCORE_COMMAND(yankAndSelect)
         return;
 
     if (FrameView* coreView = coreFrame->view()) {
         return;
 
     if (FrameView* coreView = coreFrame->view()) {
-        if (minPageWidth > 0.0)
-            coreView->forceLayoutForPagination(FloatSize(minPageWidth, minPageHeight), maxPageWidth / minPageWidth, adjustViewSize ? Frame::AdjustViewSize : Frame::DoNotAdjustViewSize);
-        else {
+        if (minPageLogicalWidth > 0.0) {
+            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 ? Frame::AdjustViewSize : Frame::DoNotAdjustViewSize);
+        } else {
             coreView->forceLayout(!adjustViewSize);
             if (adjustViewSize)
                 coreView->adjustViewSize();
             coreView->forceLayout(!adjustViewSize);
             if (adjustViewSize)
                 coreView->adjustViewSize();
@@ -3877,7 +3887,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
 
 // Does setNeedsDisplay:NO as a side effect when printing is ending.
 // pageWidth != 0 implies we will relayout to a new width
 
 // 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 minimumPageWidth:(float)minPageWidth height:(float)minPageHeight maximumPageWidth:(float)maxPageWidth adjustViewSize:(BOOL)adjustViewSize paginateScreenContent:(BOOL)paginateScreenContent
+- (void)_setPrinting:(BOOL)printing minimumPageLogicalWidth:(float)minPageLogicalWidth logicalHeight:(float)minPageLogicalHeight maximumPageLogicalWidth:(float)maxPageLogicalWidth adjustViewSize:(BOOL)adjustViewSize paginateScreenContent:(BOOL)paginateScreenContent
 {
     if (printing == _private->printing && paginateScreenContent == _private->paginateScreenContent)
         return;
 {
     if (printing == _private->printing && paginateScreenContent == _private->paginateScreenContent)
         return;
@@ -3890,7 +3900,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
         WebFrame *subframe = [subframes objectAtIndex:i];
         WebFrameView *frameView = [subframe frameView];
         if ([[subframe _dataSource] _isDocumentHTML]) {
         WebFrame *subframe = [subframes objectAtIndex:i];
         WebFrameView *frameView = [subframe frameView];
         if ([[subframe _dataSource] _isDocumentHTML]) {
-            [(WebHTMLView *)[frameView documentView] _setPrinting:printing minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:adjustViewSize paginateScreenContent:paginateScreenContent];
+            [(WebHTMLView *)[frameView documentView] _setPrinting:printing minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:adjustViewSize paginateScreenContent:paginateScreenContent];
         }
     }
 
         }
     }
 
@@ -3911,7 +3921,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
     }
 
     [self setNeedsLayout:YES];
     }
 
     [self setNeedsLayout:YES];
-    [self layoutToMinimumPageWidth:minPageWidth height:minPageHeight maximumPageWidth:maxPageWidth adjustingViewSize:adjustViewSize];
+    [self layoutToMinimumPageWidth:minPageLogicalWidth height:minPageLogicalHeight maximumPageWidth:maxPageLogicalWidth adjustingViewSize:adjustViewSize];
     if (!printing) {
         // Can't do this when starting printing or nested printing won't work, see 3491427.
         [self setNeedsDisplay:NO];
     if (!printing) {
         // Can't do this when starting printing or nested printing won't work, see 3491427.
         [self setNeedsDisplay:NO];
@@ -3931,7 +3941,7 @@ static BOOL isInPasswordField(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)
     // 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 minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+        [self _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
 
     *newBottom = [self _adjustedBottomOfPageWithTop:oldTop bottom:oldBottom limit:bottomLimit];
 
 
     *newBottom = [self _adjustedBottomOfPageWithTop:oldTop bottom:oldBottom limit:bottomLimit];
 
@@ -3942,21 +3952,29 @@ static BOOL isInPasswordField(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 performSelector:@selector(_delayedEndPrintMode:) withObject:currenPrintOperation afterDelay:0];
         else
             // not sure if this is actually ever invoked, it probably shouldn't be
-            [self _setPrinting:NO minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
+            [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 maximumPageLogicalWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
     }
 }
 
 - (float)_scaleFactorForPrintOperation:(NSPrintOperation *)printOperation
 {
     }
 }
 
 - (float)_scaleFactorForPrintOperation:(NSPrintOperation *)printOperation
 {
-    float viewWidth = NSWidth([self bounds]);
-    if (viewWidth < 1) {
-        LOG_ERROR("%@ has no width when printing", self);
+    bool useViewWidth = true;
+    Frame* coreFrame = core([self _frame]);
+    if (coreFrame) {
+        Document* document = coreFrame->document();
+        if (document && document->renderView())
+            useViewWidth = document->renderView()->style()->isHorizontalWritingMode();
+    }
+
+    float viewLogicalWidth = useViewWidth ? NSWidth([self bounds]) : NSHeight([self bounds]);
+    if (viewLogicalWidth < 1) {
+        LOG_ERROR("%@ has no logical width when printing", self);
         return 1.0f;
     }
 
     float userScaleFactor = [printOperation _web_pageSetupScaleFactor];
     float maxShrinkToFitScaleFactor = 1.0f / _WebHTMLViewPrintingMaximumShrinkFactor;
         return 1.0f;
     }
 
     float userScaleFactor = [printOperation _web_pageSetupScaleFactor];
     float maxShrinkToFitScaleFactor = 1.0f / _WebHTMLViewPrintingMaximumShrinkFactor;
-    float shrinkToFitScaleFactor = [printOperation _web_availablePaperWidth] / viewWidth;
+    float shrinkToFitScaleFactor = (useViewWidth ? [printOperation _web_availablePaperWidth] :  [printOperation _web_availablePaperHeight]) / viewLogicalWidth;
     return userScaleFactor * max(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor);
 }
 
     return userScaleFactor * max(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor);
 }
 
@@ -3971,8 +3989,8 @@ static BOOL isInPasswordField(Frame* coreFrame)
 // This is used for Carbon printing. At some point we might want to make this public API.
 - (void)setPageWidthForPrinting:(float)pageWidth
 {
 // This is used for Carbon printing. At some point we might want to make this public API.
 - (void)setPageWidthForPrinting:(float)pageWidth
 {
-    [self _setPrinting:NO minimumPageWidth:0 height:0 maximumPageWidth:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
-    [self _setPrinting:YES minimumPageWidth:pageWidth height:0 maximumPageWidth:pageWidth adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
+    [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]];
 }
 
 - (void)_endPrintModeAndRestoreWindowAutodisplay
 }
 
 - (void)_endPrintModeAndRestoreWindowAutodisplay
@@ -4036,9 +4054,10 @@ static BOOL isInPasswordField(Frame* coreFrame)
     float totalScaleFactor = [self _scaleFactorForPrintOperation:printOperation];
     float userScaleFactor = [printOperation _web_pageSetupScaleFactor];
     [_private->pageRects release];
     float totalScaleFactor = [self _scaleFactorForPrintOperation:printOperation];
     float userScaleFactor = [printOperation _web_pageSetupScaleFactor];
     [_private->pageRects release];
+    float fullPageWidth = floorf([printOperation _web_availablePaperWidth] / totalScaleFactor);
     float fullPageHeight = floorf([printOperation _web_availablePaperHeight] / totalScaleFactor);
     WebFrame *frame = [self _frame];
     float fullPageHeight = floorf([printOperation _web_availablePaperHeight] / totalScaleFactor);
     WebFrame *frame = [self _frame];
-    NSArray *newPageRects = [frame _computePageRectsWithPrintWidthScaleFactor:userScaleFactor printHeight:fullPageHeight];
+    NSArray *newPageRects = [frame _computePageRectsWithPrintScaleFactor:userScaleFactor pageSize:NSMakeSize(fullPageWidth, fullPageHeight)];
     
     // AppKit gets all messed up if you give it a zero-length page count (see 3576334), so if we
     // hit that case we'll pass along a degenerate 1 pixel square to print. This will print
     
     // AppKit gets all messed up if you give it a zero-length page count (see 3576334), so if we
     // hit that case we'll pass along a degenerate 1 pixel square to print. This will print
index 282dd4c..9a06458 100644 (file)
@@ -1,3 +1,16 @@
+2011-02-01  Dave Hyatt  <hyatt@apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=46422, make printing and pagination work
+        with vertical text.
+
+        Change printing functions to check writing-mode and properly swap width and height
+        as needed.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::computePagesForPrinting):
+
 2011-01-31  Alexey Proskuryakov  <ap@apple.com>
 
         Reviewed by Maciej Stachowiak.
 2011-01-31  Alexey Proskuryakov  <ap@apple.com>
 
         Reviewed by Maciej Stachowiak.
index 369ae9b..c6cdbde 100644 (file)
@@ -275,14 +275,15 @@ void Connection::processIncomingMessage(MessageID messageID, PassOwnPtr<Argument
     // Check if this is a sync reply.
     if (messageID == MessageID(CoreIPCMessage::SyncMessageReply)) {
         MutexLocker locker(m_syncReplyStateMutex);
     // Check if this is a sync reply.
     if (messageID == MessageID(CoreIPCMessage::SyncMessageReply)) {
         MutexLocker locker(m_syncReplyStateMutex);
-        ASSERT(!m_pendingSyncReplies.isEmpty());
-
-        PendingSyncReply& pendingSyncReply = m_pendingSyncReplies.last();
-        ASSERT(pendingSyncReply.syncRequestID == arguments->destinationID());
+        if (!m_pendingSyncReplies.isEmpty()) {
+            ASSERT(!m_pendingSyncReplies.isEmpty());
 
 
-        pendingSyncReply.replyDecoder = arguments.leakPtr();
-        pendingSyncReply.didReceiveReply = true;
+            PendingSyncReply& pendingSyncReply = m_pendingSyncReplies.last();
+            ASSERT(pendingSyncReply.syncRequestID == arguments->destinationID());
 
 
+            pendingSyncReply.replyDecoder = arguments.leakPtr();
+            pendingSyncReply.didReceiveReply = true;
+        }
         m_waitForSyncReplySemaphore.signal();
         return;
     }
         m_waitForSyncReplySemaphore.signal();
         return;
     }