2007-08-02 Ada Chan <adachan@apple.com>
authoradachan <adachan@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Aug 2007 18:24:05 +0000 (18:24 +0000)
committeradachan <adachan@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Aug 2007 18:24:05 +0000 (18:24 +0000)
        Reviewed by Steve.

WebCore:
        <rdar://problem/5079175> Added parameters headerHeight and footerHeight to
        computePageRectsForFrame() so we can account for the header and footer when
        calculating page heights for this frame.

        * bridge/win/FrameWin.cpp:
        (WebCore::computePageRectsForFrame):
        * bridge/win/FrameWin.h:

WebKit/win:
        <rdar://problem/5079175> Printing header and footer

        * Interfaces/IWebUIDelegate.idl: added methods for header/footer drawing.
        * WebFrame.cpp:
        (WebFrame::headerAndFooterHeights): ask client for the header and
        footer heights via IWebUIDelegate2 methods.
        (WebFrame::computePageRects): pass in header and footer heights when
        calculating page rect heights.
        (WebFrame::spoolPages): ask client to draw header and footer via
        IWebUIDelegate2 methods.
        * WebFrame.h:
        * WebKitGraphics.cpp:
        (DrawTextAtPoint): the code assumes color has 4 components - might as well
        assert it.

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

WebCore/ChangeLog
WebCore/bridge/win/FrameWin.cpp
WebCore/bridge/win/FrameWin.h
WebKit/win/ChangeLog
WebKit/win/Interfaces/IWebUIDelegate.idl
WebKit/win/WebFrame.cpp
WebKit/win/WebFrame.h
WebKit/win/WebKitGraphics.cpp

index a0610cfbc584e27f315615cbe62e071f96119e2c..b298bfe8da2f57f2131796a674b9aaacc6f756d4 100644 (file)
@@ -1,3 +1,15 @@
+2007-08-02  Ada Chan  <adachan@apple.com>
+
+        Reviewed by Steve.
+
+        <rdar://problem/5079175> Added parameters headerHeight and footerHeight to 
+        computePageRectsForFrame() so we can account for the header and footer when
+        calculating page heights for this frame.
+
+        * bridge/win/FrameWin.cpp:
+        (WebCore::computePageRectsForFrame):
+        * bridge/win/FrameWin.h:
+
 2007-08-02  Alice Liu  <alice.liu@apple.com>
 
         Reviewed by Kevin McCullough.
index f830ea18c3b7487e8abb16e0700618b39949ef53..ae6312c3e9760650ec2765e13f91166079f4d957 100644 (file)
@@ -84,7 +84,7 @@ KJS::Bindings::Instance* Frame::createScriptInstanceForWidget(Widget* widget)
 }
 
 
-Vector<IntRect> computePageRectsForFrame(Frame* frame, const IntRect& printRect, float userScaleFactor)
+Vector<IntRect> computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor)
 {
     ASSERT(frame);
 
@@ -108,6 +108,7 @@ Vector<IntRect> computePageRectsForFrame(Frame* frame, const IntRect& printRect,
  
     float pageWidth  = (float) root->docWidth();
     float pageHeight = pageWidth * ratio;
+    pageHeight -= (headerHeight + footerHeight);
 
     if (pageHeight <= 0) {
         LOG_ERROR("pageHeight has bad value %.2f", pageHeight);
index e57d2f6f35ff9a3eb05b4cfc0ca63a2a2ccf3f69..caa0cd6c1bc4f3e0da907244f217e166c7b6ad45 100644 (file)
@@ -34,7 +34,7 @@ typedef struct HBITMAP__* HBITMAP;
 namespace WebCore {
 
     HBITMAP imageFromSelection(Frame* frame, bool forceWhiteText);
-    Vector<IntRect> computePageRectsForFrame(Frame*, const IntRect& printRect, float userScaleFactor);
+    Vector<IntRect> computePageRectsForFrame(Frame*, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor);
 
 }
 
index f9f652fb2be699ebcbe9b92a64c4ba9b5ef7066a..db9a30aedf7b8adb5e8e8f7dc54e0d6e55ede809 100644 (file)
@@ -1,3 +1,22 @@
+2007-08-02  Ada Chan  <adachan@apple.com>
+
+        Reviewed by Steve.
+        
+        <rdar://problem/5079175> Printing header and footer
+
+        * Interfaces/IWebUIDelegate.idl: added methods for header/footer drawing.
+        * WebFrame.cpp:
+        (WebFrame::headerAndFooterHeights): ask client for the header and 
+        footer heights via IWebUIDelegate2 methods.
+        (WebFrame::computePageRects): pass in header and footer heights when
+        calculating page rect heights.
+        (WebFrame::spoolPages): ask client to draw header and footer via
+        IWebUIDelegate2 methods.
+        * WebFrame.h:
+        * WebKitGraphics.cpp:
+        (DrawTextAtPoint): the code assumes color has 4 components - might as well
+        assert it.
+
 2007-08-01  Steve Falkenburg  <sfalken@apple.com>
 
         Build mod: Fix sln to match configs in vcproj.
index 271edc7a72858c022d0f7da7d455d29d12aa9341..f0bd1240c54db16a8b0fa722bc6ec97589dc31b8 100644 (file)
@@ -736,4 +736,47 @@ interface IWebUIDelegate2 : IWebUIDelegate
     first WebView that displayed a directory listing, so this will only be called once.
 */
     HRESULT ftpDirectoryTemplatePath([in] IWebView* webView, [out, retval] BSTR* path);
+
+/*!
+    @method webViewHeaderHeight:
+    @param webView The WebView sending the delegate method
+    @abstract Reserve a height for the printed page header.
+    @result The height to reserve for the printed page header, return 0.0 to not reserve any space for a header.
+    @discussion The height returned will be used to calculate the rect passed to webView:drawHeaderInRect:.
+
+    - (float)webViewHeaderHeight:(WebView *)sender;
+*/
+    HRESULT webViewHeaderHeight([in] IWebView* webView, [out, retval] float* result);
+
+/*!
+    @method webViewFooterHeight:
+    @param webView The WebView sending the delegate method
+    @abstract Reserve a height for the printed page footer.
+    @result The height to reserve for the printed page footer, return 0.0 to not reserve any space for a footer.
+    @discussion The height returned will be used to calculate the rect passed to webView:drawFooterInRect:.
+
+    - (float)webViewFooterHeight:(WebView *)sender;
+*/
+    HRESULT webViewFooterHeight([in] IWebView* webView, [out, retval] float* result);
+
+/*!
+    @method webView:drawHeaderInRect:
+    @param webView The WebView sending the delegate method
+    @param rect The NSRect reserved for the header of the page
+    @abstract The delegate should draw a header for the sender in the supplied rect.
+
+    - (void)webView:(WebView *)sender drawHeaderInRect:(NSRect)rect;
+*/
+    HRESULT drawHeaderInRect([in] IWebView* webView, [in] RECT* rect, [in] OLE_HANDLE drawingContext);
+
+/*!
+    @method webView:drawFooterInRect:
+    @param webView The WebView sending the delegate method
+    @param rect The NSRect reserved for the footer of the page
+    @abstract The delegate should draw a footer for the sender in the supplied rect.
+
+    - (void)webView:(WebView *)sender drawFooterInRect:(NSRect)rect;
+*/
+    HRESULT drawFooterInRect([in] IWebView* webView, [in] RECT* rect, [in] OLE_HANDLE drawingContext, [in] UINT pageIndex, [in] UINT pageCount);
+
 }
index 8d4c94e188a761d4c67fc8a167d8c64dd84ea0f7..dccd5a87ad00ba7f43bffa5cd30a08c9605087d1 100644 (file)
@@ -2426,6 +2426,25 @@ HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode(
     return S_OK;
 }
 
+void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight)
+{
+    if (headerHeight)
+        *headerHeight = 0;
+    if (footerHeight)
+        *footerHeight = 0;
+    float height = 0;
+    COMPtr<IWebUIDelegate> ui;
+    if (FAILED(d->webView->uiDelegate(&ui)))
+        return;
+    COMPtr<IWebUIDelegate2> ui2;
+    if (FAILED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
+        return;
+    if (headerHeight && SUCCEEDED(ui2->webViewHeaderHeight(d->webView, &height)))
+        *headerHeight = height;
+    if (footerHeight && SUCCEEDED(ui2->webViewFooterHeight(d->webView, &height)))
+        *footerHeight = height;
+}
+
 const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC)
 {
     ASSERT(m_inPrintingMode);
@@ -2440,7 +2459,10 @@ const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC)
     if (!printDC)
         return m_pageRects;
 
-    m_pageRects = computePageRectsForFrame(coreFrame, printerRect(printDC), 1.0);
+    // adjust the page rect by the header and footer
+    float headerHeight = 0, footerHeight = 0;
+    headerAndFooterHeights(&headerHeight, &footerHeight);
+    m_pageRects = computePageRectsForFrame(coreFrame, printerRect(printDC), headerHeight, footerHeight, 1.0);
     
     return m_pageRects;
 }
@@ -2491,9 +2513,10 @@ HRESULT STDMETHODCALLTYPE WebFrame::spoolPages(
     if (!coreFrame || !coreFrame->document())
         return E_FAIL;
 
+    UINT pageCount = (UINT) m_pageRects.size();
     PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx;
 
-    if (m_pageRects.size() == 0 || startPage > m_pageRects.size()) {
+    if (!pageCount || startPage > pageCount) {
         ASSERT_NOT_REACHED();
         return E_FAIL;
     }
@@ -2502,8 +2525,18 @@ HRESULT STDMETHODCALLTYPE WebFrame::spoolPages(
         startPage--;
 
     if (endPage == 0)
-        endPage = (UINT)m_pageRects.size();
+        endPage = pageCount;
 
+    COMPtr<IWebUIDelegate> ui;
+    if (FAILED(d->webView->uiDelegate(&ui)))
+        return E_FAIL;
+    // FIXME: we can return early after the updated app is released
+    COMPtr<IWebUIDelegate2> ui2;
+    if (FAILED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
+        ui2 = 0;
+
+    float headerHeight = 0, footerHeight = 0;
+    headerAndFooterHeights(&headerHeight, &footerHeight);
     GraphicsContext spoolCtx(pctx);
 
     for (UINT ii = startPage; ii < endPage; ii++) {
@@ -2522,13 +2555,30 @@ HRESULT STDMETHODCALLTYPE WebFrame::spoolPages(
         CGFloat scale = (float)mediaBox.size.width/ (float)pageRect.width();
         CGAffineTransform ctm = CGContextGetBaseCTM(pctx);
         ctm = CGAffineTransformScale(ctm, -scale, -scale);
-        ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()));
+        ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header
         CGContextScaleCTM(pctx, scale, scale);
-        CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()));
+        CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight));   // reserves space for header
         CGContextSetBaseCTM(pctx, ctm);
 
         coreFrame->paint(&spoolCtx, pageRect);
 
+        if (ui2) {
+            CGContextTranslateCTM(pctx, CGFloat(pageRect.x()), CGFloat(pageRect.y())-headerHeight);
+
+            int x = pageRect.x();
+            int y = 0;
+            if (headerHeight) {
+                RECT headerRect = {x, y, x+pageRect.width(), y+(int)headerHeight};
+                ui2->drawHeaderInRect(d->webView, &headerRect, (OLE_HANDLE)(LONG64)pctx);
+            }
+
+            if (footerHeight) {
+                y = (int)(mediaBox.size.height/scale - footerHeight);
+                RECT footerRect = {x, y, x+pageRect.width(), y+(int)footerHeight};
+                ui2->drawFooterInRect(d->webView, &footerRect, (OLE_HANDLE)(LONG64)pctx, ii+1, pageCount);
+            }
+        }
+
         CGContextEndPage(pctx);
         CGContextRestoreGState(pctx);
     }
index c9dae2c791837f602aa1edc732d298cad9480ce9..d67b1032fba5f6d15fff2b14f056c2103444ed86 100644 (file)
@@ -346,6 +346,7 @@ protected:
     void loadURLIntoChild(const WebCore::KURL&, const WebCore::String& referrer, WebFrame* childFrame);
     const Vector<WebCore::IntRect>& computePageRects(HDC printDC);
     void setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize);
+    void headerAndFooterHeights(float*, float*);
 
 protected:
     ULONG               m_refCount;
index 3156857b45341d50fcaddf23fdfefd2d9e8a2c34..0a35108545c30b0f7368280609839b0974d7f908 100644 (file)
@@ -69,6 +69,7 @@ void DrawTextAtPoint(CGContextRef cgContext, LPCTSTR text, int length, POINT poi
 {
     GraphicsContext context(cgContext);
 
+    ASSERT(CGColorGetNumberOfComponents(color) == 4);   // this code assumes the CGColorRef has 4 components
     const CGFloat* components = CGColorGetComponents(color);
     Color textColor((int)(components[0] * 255), (int)(components[1] * 255), (int)(components[2] * 255), (int)(components[3] * 255));