1/*
2 * Copyright (C) 2009 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2009 Brent Fulgham. All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "stdafx.h"
28#include "PrintWebUIDelegate.h"
29
30#include <commctrl.h>
31#include <commdlg.h>
32#include <objbase.h>
33#include <shlwapi.h>
34#include <wininet.h>
35
36#include <WebKit/WebKitCOMAPI.h>
37
38static const int MARGIN = 20;
39
40HRESULT PrintWebUIDelegate::QueryInterface(REFIID riid, void** ppvObject)
41{
42    *ppvObject = 0;
43    if (IsEqualIID(riid, IID_IUnknown))
44        *ppvObject = static_cast<IWebUIDelegate*>(this);
45    else if (IsEqualIID(riid, IID_IWebUIDelegate))
46        *ppvObject = static_cast<IWebUIDelegate*>(this);
47    else
48        return E_NOINTERFACE;
49
50    AddRef();
51    return S_OK;
52}
53
54ULONG PrintWebUIDelegate::AddRef(void)
55{
56    return ++m_refCount;
57}
58
59ULONG PrintWebUIDelegate::Release(void)
60{
61    ULONG newRef = --m_refCount;
62    if (!newRef)
63        delete this;
64
65    return newRef;
66}
67
68HRESULT PrintWebUIDelegate::webViewPrintingMarginRect(IWebView* view, RECT* rect)
69{
70    if (!view || !rect)
71        return E_POINTER;
72
73    IWebFrame* mainFrame = 0;
74    if (FAILED(view->mainFrame(&mainFrame)))
75        return E_FAIL;
76
77    IWebFramePrivate* privateFrame = 0;
78    if (FAILED(mainFrame->QueryInterface(&privateFrame))) {
79        mainFrame->Release();
80        return E_FAIL;
81    }
82
83    privateFrame->frameBounds(rect);
84
85    rect->left += MARGIN;
86    rect->top += MARGIN;
87    HDC dc = ::GetDC(0);
88    rect->right = (::GetDeviceCaps(dc, LOGPIXELSX) * 6.5) - MARGIN;
89    rect->bottom = (::GetDeviceCaps(dc, LOGPIXELSY) * 11) - MARGIN;
90    ::ReleaseDC(0, dc);
91
92    privateFrame->Release();
93    mainFrame->Release();
94
95    return S_OK;
96}
97
98HRESULT PrintWebUIDelegate::webViewHeaderHeight(IWebView* webView, float* height)
99{
100   if (!webView || !height)
101      return E_POINTER;
102
103   HDC dc = ::GetDC(0);
104
105   TEXTMETRIC textMetric;
106   ::GetTextMetrics(dc, &textMetric);
107   ::ReleaseDC(0, dc);
108
109   *height = 1.1 * textMetric.tmHeight;
110
111   return S_OK;
112}
113
114HRESULT PrintWebUIDelegate::webViewFooterHeight(IWebView* webView, float* height)
115{
116   if (!webView || !height)
117      return E_POINTER;
118
119   HDC dc = ::GetDC(0);
120
121   TEXTMETRIC textMetric;
122   ::GetTextMetrics(dc, &textMetric);
123   ::ReleaseDC(0, dc);
124
125   *height = 1.1 * textMetric.tmHeight;
126
127   return S_OK;
128}
129
130HRESULT PrintWebUIDelegate::drawHeaderInRect(
131            /* [in] */ IWebView *webView,
132            /* [in] */ RECT *rect,
133            /* [in] */ OLE_HANDLE drawingContext)
134{
135   if (!webView || !rect)
136      return E_POINTER;
137
138   // Turn off header for now.
139   HDC dc = reinterpret_cast<HDC>(drawingContext);
140
141   HFONT hFont = (HFONT)::GetStockObject(ANSI_VAR_FONT);
142   HFONT hOldFont = (HFONT)::SelectObject(dc, hFont);
143
144   LPCTSTR header(_T("[Sample Header]"));
145   int length = _tcslen(header);
146
147   int rc = ::DrawText(dc, header, length, rect, DT_LEFT | DT_NOCLIP | DT_VCENTER  | DT_SINGLELINE);
148   ::SelectObject(dc, hOldFont);
149
150   if (!rc)
151      return E_FAIL;
152
153   ::MoveToEx(dc, rect->left, rect->bottom, 0);
154   HPEN hPen = (HPEN)::GetStockObject(BLACK_PEN);
155   HPEN hOldPen = (HPEN)::SelectObject(dc, hPen);
156   ::LineTo(dc, rect->right, rect->bottom);
157   ::SelectObject(dc, hOldPen);
158
159   return S_OK;
160}
161
162HRESULT PrintWebUIDelegate::drawFooterInRect(
163            /* [in] */ IWebView *webView,
164            /* [in] */ RECT *rect,
165            /* [in] */ OLE_HANDLE drawingContext,
166            /* [in] */ UINT pageIndex,
167            /* [in] */ UINT pageCount)
168{
169   if (!webView || !rect)
170      return E_POINTER;
171
172   HDC dc = reinterpret_cast<HDC>(drawingContext);
173
174   HFONT hFont = (HFONT)::GetStockObject(ANSI_VAR_FONT);
175   HFONT hOldFont = (HFONT)::SelectObject(dc, hFont);
176
177   LPCTSTR footer(_T("[Sample Footer]"));
178   int length = _tcslen(footer);
179
180   // Add a line, 1/10th inch above the footer text from left margin to right margin.
181   ::MoveToEx(dc, rect->left, rect->top, 0);
182   HPEN hPen = (HPEN)::GetStockObject(BLACK_PEN);
183   HPEN hOldPen = (HPEN)::SelectObject(dc, hPen);
184   ::LineTo(dc, rect->right, rect->top);
185   ::SelectObject(dc, hOldPen);
186
187   int rc = ::DrawText(dc, footer, length, rect, DT_LEFT | DT_NOCLIP | DT_VCENTER  | DT_SINGLELINE);
188   ::SelectObject(dc, hOldFont);
189
190   if (!rc)
191      return E_FAIL;
192
193   return S_OK;
194}
195