OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "printing/printed_document.h" | 5 #include "printing/printed_document.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/string_util.h" | |
9 #include "base/utf_string_conversions.h" | |
10 #include "printing/page_number.h" | 8 #include "printing/page_number.h" |
11 #include "printing/page_overlays.h" | |
12 #include "printing/printed_pages_source.h" | 9 #include "printing/printed_pages_source.h" |
13 #include "printing/printed_page.h" | 10 #include "printing/printed_page.h" |
14 #include "printing/units.h" | 11 #include "printing/units.h" |
15 #include "skia/ext/platform_device.h" | 12 #include "skia/ext/platform_device.h" |
16 #include "ui/gfx/font.h" | |
17 | 13 |
18 namespace { | 14 namespace { |
19 | 15 |
20 void SimpleModifyWorldTransform(HDC context, | 16 void SimpleModifyWorldTransform(HDC context, |
21 int offset_x, | 17 int offset_x, |
22 int offset_y, | 18 int offset_y, |
23 double shrink_factor) { | 19 double shrink_factor) { |
24 XFORM xform = { 0 }; | 20 XFORM xform = { 0 }; |
25 xform.eDx = static_cast<float>(offset_x); | 21 xform.eDx = static_cast<float>(offset_x); |
26 xform.eDy = static_cast<float>(offset_y); | 22 xform.eDy = static_cast<float>(offset_y); |
27 xform.eM11 = xform.eM22 = static_cast<float>(1. / shrink_factor); | 23 xform.eM11 = xform.eM22 = static_cast<float>(1. / shrink_factor); |
28 BOOL res = ModifyWorldTransform(context, &xform, MWT_LEFTMULTIPLY); | 24 BOOL res = ModifyWorldTransform(context, &xform, MWT_LEFTMULTIPLY); |
29 DCHECK_NE(res, 0); | 25 DCHECK_NE(res, 0); |
30 } | 26 } |
31 | 27 |
32 void DrawRect(HDC context, gfx::Rect rect) { | 28 void DrawRect(HDC context, gfx::Rect rect) { |
33 Rectangle(context, rect.x(), rect.y(), rect.right(), rect.bottom()); | 29 Rectangle(context, rect.x(), rect.y(), rect.right(), rect.bottom()); |
34 } | 30 } |
35 | 31 |
36 // Creates a string interpretation of the time of day represented by the given | |
37 // SYSTEMTIME that's appropriate for the user's default locale. | |
38 // Format can be an empty string (for the default format), or a "format picture" | |
39 // as specified in the Windows documentation for GetTimeFormat(). | |
40 string16 FormatSystemTime(const SYSTEMTIME& time, const string16& format) { | |
41 // If the format string is empty, just use the default format. | |
42 LPCTSTR format_ptr = NULL; | |
43 if (!format.empty()) | |
44 format_ptr = format.c_str(); | |
45 | |
46 int buffer_size = GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &time, format_ptr, | |
47 NULL, 0); | |
48 | |
49 string16 output; | |
50 GetTimeFormat(LOCALE_USER_DEFAULT, NULL, &time, format_ptr, | |
51 WriteInto(&output, buffer_size), buffer_size); | |
52 | |
53 return output; | |
54 } | |
55 | |
56 // Creates a string interpretation of the date represented by the given | |
57 // SYSTEMTIME that's appropriate for the user's default locale. | |
58 // Format can be an empty string (for the default format), or a "format picture" | |
59 // as specified in the Windows documentation for GetDateFormat(). | |
60 string16 FormatSystemDate(const SYSTEMTIME& date, const string16& format) { | |
61 // If the format string is empty, just use the default format. | |
62 LPCTSTR format_ptr = NULL; | |
63 if (!format.empty()) | |
64 format_ptr = format.c_str(); | |
65 | |
66 int buffer_size = GetDateFormat(LOCALE_USER_DEFAULT, NULL, &date, format_ptr, | |
67 NULL, 0); | |
68 | |
69 string16 output; | |
70 GetDateFormat(LOCALE_USER_DEFAULT, NULL, &date, format_ptr, | |
71 WriteInto(&output, buffer_size), buffer_size); | |
72 | |
73 return output; | |
74 } | |
75 | |
76 } // namespace | 32 } // namespace |
77 | 33 |
78 namespace printing { | 34 namespace printing { |
79 | 35 |
80 void PrintedDocument::RenderPrintedPage( | 36 void PrintedDocument::RenderPrintedPage( |
81 const PrintedPage& page, gfx::NativeDrawingContext context) const { | 37 const PrintedPage& page, gfx::NativeDrawingContext context) const { |
82 #ifndef NDEBUG | 38 #ifndef NDEBUG |
83 { | 39 { |
84 // Make sure the page is from our list. | 40 // Make sure the page is from our list. |
85 base::AutoLock lock(lock_); | 41 base::AutoLock lock(lock_); |
(...skipping 29 matching lines...) Expand all Loading... |
115 mutable_.shrink_factor); | 71 mutable_.shrink_factor); |
116 | 72 |
117 if (!page.metafile()->SafePlayback(context)) { | 73 if (!page.metafile()->SafePlayback(context)) { |
118 NOTREACHED(); | 74 NOTREACHED(); |
119 } | 75 } |
120 | 76 |
121 BOOL res = RestoreDC(context, saved_state); | 77 BOOL res = RestoreDC(context, saved_state); |
122 DCHECK_NE(res, 0); | 78 DCHECK_NE(res, 0); |
123 } | 79 } |
124 | 80 |
125 // Print the header and footer. Offset by printable area offset (see comment | |
126 // above). | |
127 SimpleModifyWorldTransform( | |
128 context, | |
129 -page_setup.printable_area().x(), | |
130 -page_setup.printable_area().y(), | |
131 1); | |
132 int base_font_size = gfx::Font().GetHeight(); | |
133 int new_font_size = ConvertUnit(10, | |
134 immutable_.settings_.desired_dpi, | |
135 immutable_.settings_.device_units_per_inch()); | |
136 DCHECK_GT(new_font_size, base_font_size); | |
137 gfx::Font font(gfx::Font().DeriveFont(new_font_size - base_font_size)); | |
138 HGDIOBJ old_font = SelectObject(context, font.GetNativeFont()); | |
139 DCHECK(old_font != NULL); | |
140 // We don't want a white square around the text ever if overflowing. | |
141 SetBkMode(context, TRANSPARENT); | |
142 // Disabling printing the header/footer on Windows for now to make the | |
143 // behavior consistent with Mac/Linux. | |
144 // TODO(thestig) re-enable this for print preview. | |
145 #if 0 | |
146 PrintHeaderFooter(context, page, PageOverlays::LEFT, PageOverlays::TOP, | |
147 font); | |
148 PrintHeaderFooter(context, page, PageOverlays::CENTER, PageOverlays::TOP, | |
149 font); | |
150 PrintHeaderFooter(context, page, PageOverlays::RIGHT, PageOverlays::TOP, | |
151 font); | |
152 PrintHeaderFooter(context, page, PageOverlays::LEFT, PageOverlays::BOTTOM, | |
153 font); | |
154 PrintHeaderFooter(context, page, PageOverlays::CENTER, PageOverlays::BOTTOM, | |
155 font); | |
156 PrintHeaderFooter(context, page, PageOverlays::RIGHT, PageOverlays::BOTTOM, | |
157 font); | |
158 #endif | |
159 int res = RestoreDC(context, saved_state); | |
160 DCHECK_NE(res, 0); | |
161 } | |
162 | |
163 void PrintedDocument::Immutable::SetDocumentDate() { | |
164 // Use the native time formatting for printing on Windows. | |
165 SYSTEMTIME systemtime; | |
166 GetLocalTime(&systemtime); | |
167 date_ = | |
168 WideToUTF16Hack(FormatSystemDate(systemtime, std::wstring())); | |
169 time_ = | |
170 WideToUTF16Hack(FormatSystemTime(systemtime, std::wstring())); | |
171 } | |
172 | |
173 void PrintedDocument::DrawHeaderFooter(gfx::NativeDrawingContext context, | |
174 std::wstring text, | |
175 gfx::Rect bounds) const { | |
176 // Save the state for the clipping region. | |
177 int saved_state = SaveDC(context); | |
178 DCHECK_NE(saved_state, 0); | |
179 | |
180 int result = IntersectClipRect(context, bounds.x(), bounds.y(), | |
181 bounds.right() + 1, bounds.bottom() + 1); | |
182 DCHECK(result == SIMPLEREGION || result == COMPLEXREGION); | |
183 TextOut(context, | |
184 bounds.x(), bounds.y(), | |
185 text.c_str(), | |
186 static_cast<int>(text.size())); | |
187 int res = RestoreDC(context, saved_state); | 81 int res = RestoreDC(context, saved_state); |
188 DCHECK_NE(res, 0); | 82 DCHECK_NE(res, 0); |
189 } | 83 } |
190 | 84 |
191 } // namespace printing | 85 } // namespace printing |
OLD | NEW |