<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[24826] trunk</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/24826">24826</a></dd>
<dt>Author</dt> <dd>adachan</dd>
<dt>Date</dt> <dd>2007-08-02 11:24:05 -0700 (Thu, 02 Aug 2007)</dd>
</dl>

<h3>Log Message</h3>
<pre>2007-08-02  Ada Chan  &lt;adachan@apple.com&gt;

        Reviewed by Steve.

WebCore:
        &lt;rdar://problem/5079175&gt; 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:
        &lt;rdar://problem/5079175&gt; 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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebCoreChangeLog">trunk/WebCore/ChangeLog</a></li>
<li><a href="#trunkWebCorebridgewinFrameWincpp">trunk/WebCore/bridge/win/FrameWin.cpp</a></li>
<li><a href="#trunkWebCorebridgewinFrameWinh">trunk/WebCore/bridge/win/FrameWin.h</a></li>
<li><a href="#trunkWebKitwinChangeLog">trunk/WebKit/win/ChangeLog</a></li>
<li><a href="#trunkWebKitwinInterfacesIWebUIDelegateidl">trunk/WebKit/win/Interfaces/IWebUIDelegate.idl</a></li>
<li><a href="#trunkWebKitwinWebFramecpp">trunk/WebKit/win/WebFrame.cpp</a></li>
<li><a href="#trunkWebKitwinWebFrameh">trunk/WebKit/win/WebFrame.h</a></li>
<li><a href="#trunkWebKitwinWebKitGraphicscpp">trunk/WebKit/win/WebKitGraphics.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/ChangeLog (24825 => 24826)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/ChangeLog        2007-08-02 14:08:32 UTC (rev 24825)
+++ trunk/WebCore/ChangeLog        2007-08-02 18:24:05 UTC (rev 24826)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2007-08-02  Ada Chan  &lt;adachan@apple.com&gt;
+
+        Reviewed by Steve.
+
+        &lt;rdar://problem/5079175&gt; 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:
+
</ins><span class="cx"> 2007-08-02  Alice Liu  &lt;alice.liu@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Reviewed by Kevin McCullough.
</span></span></pre></div>
<a id="trunkWebCorebridgewinFrameWincpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/bridge/win/FrameWin.cpp (24825 => 24826)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/bridge/win/FrameWin.cpp        2007-08-02 14:08:32 UTC (rev 24825)
+++ trunk/WebCore/bridge/win/FrameWin.cpp        2007-08-02 18:24:05 UTC (rev 24826)
</span><span class="lines">@@ -84,7 +84,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-Vector&lt;IntRect&gt; computePageRectsForFrame(Frame* frame, const IntRect&amp; printRect, float userScaleFactor)
</del><ins>+Vector&lt;IntRect&gt; computePageRectsForFrame(Frame* frame, const IntRect&amp; printRect, float headerHeight, float footerHeight, float userScaleFactor)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(frame);
</span><span class="cx"> 
</span><span class="lines">@@ -108,6 +108,7 @@
</span><span class="cx">  
</span><span class="cx">     float pageWidth  = (float) root-&gt;docWidth();
</span><span class="cx">     float pageHeight = pageWidth * ratio;
</span><ins>+    pageHeight -= (headerHeight + footerHeight);
</ins><span class="cx"> 
</span><span class="cx">     if (pageHeight &lt;= 0) {
</span><span class="cx">         LOG_ERROR(&quot;pageHeight has bad value %.2f&quot;, pageHeight);
</span></span></pre></div>
<a id="trunkWebCorebridgewinFrameWinh"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/bridge/win/FrameWin.h (24825 => 24826)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/bridge/win/FrameWin.h        2007-08-02 14:08:32 UTC (rev 24825)
+++ trunk/WebCore/bridge/win/FrameWin.h        2007-08-02 18:24:05 UTC (rev 24826)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx">     HBITMAP imageFromSelection(Frame* frame, bool forceWhiteText);
</span><del>-    Vector&lt;IntRect&gt; computePageRectsForFrame(Frame*, const IntRect&amp; printRect, float userScaleFactor);
</del><ins>+    Vector&lt;IntRect&gt; computePageRectsForFrame(Frame*, const IntRect&amp; printRect, float headerHeight, float footerHeight, float userScaleFactor);
</ins><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebKitwinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/WebKit/win/ChangeLog (24825 => 24826)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKit/win/ChangeLog        2007-08-02 14:08:32 UTC (rev 24825)
+++ trunk/WebKit/win/ChangeLog        2007-08-02 18:24:05 UTC (rev 24826)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2007-08-02  Ada Chan  &lt;adachan@apple.com&gt;
+
+        Reviewed by Steve.
+        
+        &lt;rdar://problem/5079175&gt; 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.
+
</ins><span class="cx"> 2007-08-01  Steve Falkenburg  &lt;sfalken@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Build mod: Fix sln to match configs in vcproj.
</span></span></pre></div>
<a id="trunkWebKitwinInterfacesIWebUIDelegateidl"></a>
<div class="modfile"><h4>Modified: trunk/WebKit/win/Interfaces/IWebUIDelegate.idl (24825 => 24826)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKit/win/Interfaces/IWebUIDelegate.idl        2007-08-02 14:08:32 UTC (rev 24825)
+++ trunk/WebKit/win/Interfaces/IWebUIDelegate.idl        2007-08-02 18:24:05 UTC (rev 24826)
</span><span class="lines">@@ -736,4 +736,47 @@
</span><span class="cx">     first WebView that displayed a directory listing, so this will only be called once.
</span><span class="cx"> */
</span><span class="cx">     HRESULT ftpDirectoryTemplatePath([in] IWebView* webView, [out, retval] BSTR* path);
</span><ins>+
+/*!
+    @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);
+
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkWebKitwinWebFramecpp"></a>
<div class="modfile"><h4>Modified: trunk/WebKit/win/WebFrame.cpp (24825 => 24826)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKit/win/WebFrame.cpp        2007-08-02 14:08:32 UTC (rev 24825)
+++ trunk/WebKit/win/WebFrame.cpp        2007-08-02 18:24:05 UTC (rev 24826)
</span><span class="lines">@@ -2426,6 +2426,25 @@
</span><span class="cx">     return S_OK;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight)
+{
+    if (headerHeight)
+        *headerHeight = 0;
+    if (footerHeight)
+        *footerHeight = 0;
+    float height = 0;
+    COMPtr&lt;IWebUIDelegate&gt; ui;
+    if (FAILED(d-&gt;webView-&gt;uiDelegate(&amp;ui)))
+        return;
+    COMPtr&lt;IWebUIDelegate2&gt; ui2;
+    if (FAILED(ui-&gt;QueryInterface(IID_IWebUIDelegate2, (void**) &amp;ui2)))
+        return;
+    if (headerHeight &amp;&amp; SUCCEEDED(ui2-&gt;webViewHeaderHeight(d-&gt;webView, &amp;height)))
+        *headerHeight = height;
+    if (footerHeight &amp;&amp; SUCCEEDED(ui2-&gt;webViewFooterHeight(d-&gt;webView, &amp;height)))
+        *footerHeight = height;
+}
+
</ins><span class="cx"> const Vector&lt;WebCore::IntRect&gt;&amp; WebFrame::computePageRects(HDC printDC)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_inPrintingMode);
</span><span class="lines">@@ -2440,7 +2459,10 @@
</span><span class="cx">     if (!printDC)
</span><span class="cx">         return m_pageRects;
</span><span class="cx"> 
</span><del>-    m_pageRects = computePageRectsForFrame(coreFrame, printerRect(printDC), 1.0);
</del><ins>+    // adjust the page rect by the header and footer
+    float headerHeight = 0, footerHeight = 0;
+    headerAndFooterHeights(&amp;headerHeight, &amp;footerHeight);
+    m_pageRects = computePageRectsForFrame(coreFrame, printerRect(printDC), headerHeight, footerHeight, 1.0);
</ins><span class="cx">     
</span><span class="cx">     return m_pageRects;
</span><span class="cx"> }
</span><span class="lines">@@ -2491,9 +2513,10 @@
</span><span class="cx">     if (!coreFrame || !coreFrame-&gt;document())
</span><span class="cx">         return E_FAIL;
</span><span class="cx"> 
</span><ins>+    UINT pageCount = (UINT) m_pageRects.size();
</ins><span class="cx">     PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx;
</span><span class="cx"> 
</span><del>-    if (m_pageRects.size() == 0 || startPage &gt; m_pageRects.size()) {
</del><ins>+    if (!pageCount || startPage &gt; pageCount) {
</ins><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">         return E_FAIL;
</span><span class="cx">     }
</span><span class="lines">@@ -2502,8 +2525,18 @@
</span><span class="cx">         startPage--;
</span><span class="cx"> 
</span><span class="cx">     if (endPage == 0)
</span><del>-        endPage = (UINT)m_pageRects.size();
</del><ins>+        endPage = pageCount;
</ins><span class="cx"> 
</span><ins>+    COMPtr&lt;IWebUIDelegate&gt; ui;
+    if (FAILED(d-&gt;webView-&gt;uiDelegate(&amp;ui)))
+        return E_FAIL;
+    // FIXME: we can return early after the updated app is released
+    COMPtr&lt;IWebUIDelegate2&gt; ui2;
+    if (FAILED(ui-&gt;QueryInterface(IID_IWebUIDelegate2, (void**) &amp;ui2)))
+        ui2 = 0;
+
+    float headerHeight = 0, footerHeight = 0;
+    headerAndFooterHeights(&amp;headerHeight, &amp;footerHeight);
</ins><span class="cx">     GraphicsContext spoolCtx(pctx);
</span><span class="cx"> 
</span><span class="cx">     for (UINT ii = startPage; ii &lt; endPage; ii++) {
</span><span class="lines">@@ -2522,13 +2555,30 @@
</span><span class="cx">         CGFloat scale = (float)mediaBox.size.width/ (float)pageRect.width();
</span><span class="cx">         CGAffineTransform ctm = CGContextGetBaseCTM(pctx);
</span><span class="cx">         ctm = CGAffineTransformScale(ctm, -scale, -scale);
</span><del>-        ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()));
</del><ins>+        ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header
</ins><span class="cx">         CGContextScaleCTM(pctx, scale, scale);
</span><del>-        CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()));
</del><ins>+        CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight));   // reserves space for header
</ins><span class="cx">         CGContextSetBaseCTM(pctx, ctm);
</span><span class="cx"> 
</span><span class="cx">         coreFrame-&gt;paint(&amp;spoolCtx, pageRect);
</span><span class="cx"> 
</span><ins>+        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-&gt;drawHeaderInRect(d-&gt;webView, &amp;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-&gt;drawFooterInRect(d-&gt;webView, &amp;footerRect, (OLE_HANDLE)(LONG64)pctx, ii+1, pageCount);
+            }
+        }
+
</ins><span class="cx">         CGContextEndPage(pctx);
</span><span class="cx">         CGContextRestoreGState(pctx);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkWebKitwinWebFrameh"></a>
<div class="modfile"><h4>Modified: trunk/WebKit/win/WebFrame.h (24825 => 24826)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKit/win/WebFrame.h        2007-08-02 14:08:32 UTC (rev 24825)
+++ trunk/WebKit/win/WebFrame.h        2007-08-02 18:24:05 UTC (rev 24826)
</span><span class="lines">@@ -346,6 +346,7 @@
</span><span class="cx">     void loadURLIntoChild(const WebCore::KURL&amp;, const WebCore::String&amp; referrer, WebFrame* childFrame);
</span><span class="cx">     const Vector&lt;WebCore::IntRect&gt;&amp; computePageRects(HDC printDC);
</span><span class="cx">     void setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize);
</span><ins>+    void headerAndFooterHeights(float*, float*);
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     ULONG               m_refCount;
</span></span></pre></div>
<a id="trunkWebKitwinWebKitGraphicscpp"></a>
<div class="modfile"><h4>Modified: trunk/WebKit/win/WebKitGraphics.cpp (24825 => 24826)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKit/win/WebKitGraphics.cpp        2007-08-02 14:08:32 UTC (rev 24825)
+++ trunk/WebKit/win/WebKitGraphics.cpp        2007-08-02 18:24:05 UTC (rev 24826)
</span><span class="lines">@@ -69,6 +69,7 @@
</span><span class="cx"> {
</span><span class="cx">     GraphicsContext context(cgContext);
</span><span class="cx"> 
</span><ins>+    ASSERT(CGColorGetNumberOfComponents(color) == 4);   // this code assumes the CGColorRef has 4 components
</ins><span class="cx">     const CGFloat* components = CGColorGetComponents(color);
</span><span class="cx">     Color textColor((int)(components[0] * 255), (int)(components[1] * 255), (int)(components[2] * 255), (int)(components[3] * 255));
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>