Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: printing/printed_document.cc

Issue 268036: Implement the basic OS-level printing mechanics on Mac (Closed)
Patch Set: Address review comments Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 <set> 7 #include <set>
8 8
9 #include "app/gfx/font.h" 9 #include "app/gfx/font.h"
10 #include "app/gfx/text_elider.h" 10 #include "app/gfx/text_elider.h"
(...skipping 23 matching lines...) Expand all
34 PrintDebugDumpPath() 34 PrintDebugDumpPath()
35 : enabled(false) { 35 : enabled(false) {
36 } 36 }
37 37
38 bool enabled; 38 bool enabled;
39 std::wstring debug_dump_path; 39 std::wstring debug_dump_path;
40 }; 40 };
41 41
42 Singleton<PrintDebugDumpPath> g_debug_dump_info; 42 Singleton<PrintDebugDumpPath> g_debug_dump_info;
43 43
44 #if defined(OS_WIN)
45 void SimpleModifyWorldTransform(HDC context,
46 int offset_x,
47 int offset_y,
48 double shrink_factor) {
49 XFORM xform = { 0 };
50 xform.eDx = static_cast<float>(offset_x);
51 xform.eDy = static_cast<float>(offset_y);
52 xform.eM11 = xform.eM22 = static_cast<float>(1. / shrink_factor);
53 BOOL res = ModifyWorldTransform(context, &xform, MWT_LEFTMULTIPLY);
54 DCHECK_NE(res, 0);
55 }
56
57 void DrawRect(HDC context, gfx::Rect rect) {
58 Rectangle(context, rect.x(), rect.y(), rect.right(), rect.bottom());
59 }
60 #endif // OS_WIN
61
62 } // namespace 44 } // namespace
63 45
64 namespace printing { 46 namespace printing {
65 47
66 PrintedDocument::PrintedDocument(const PrintSettings& settings, 48 PrintedDocument::PrintedDocument(const PrintSettings& settings,
67 PrintedPagesSource* source, 49 PrintedPagesSource* source,
68 int cookie) 50 int cookie)
69 : mutable_(source), 51 : mutable_(source),
70 immutable_(settings, source, cookie) { 52 immutable_(settings, source, cookie) {
71 53
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 PrintedPages::const_iterator itr = mutable_.pages_.find(page_number); 90 PrintedPages::const_iterator itr = mutable_.pages_.find(page_number);
109 if (itr != mutable_.pages_.end()) { 91 if (itr != mutable_.pages_.end()) {
110 if (itr->second.get()) { 92 if (itr->second.get()) {
111 *page = itr->second; 93 *page = itr->second;
112 return true; 94 return true;
113 } 95 }
114 } 96 }
115 return false; 97 return false;
116 } 98 }
117 99
118 void PrintedDocument::RenderPrintedPage(const PrintedPage& page, 100 bool PrintedDocument::RenderPrintedPageNumber(
119 HDC context) const { 101 int page_number, gfx::NativeDrawingContext context) {
120 #ifndef NDEBUG
121 {
122 // Make sure the page is from our list.
123 AutoLock lock(lock_);
124 DCHECK(&page == mutable_.pages_.find(page.page_number() - 1)->second.get());
125 }
126 #endif
127
128 #if defined(OS_WIN)
129 const printing::PageSetup& page_setup(
130 immutable_.settings_.page_setup_pixels());
131
132 // Save the state to make sure the context this function call does not modify
133 // the device context.
134 int saved_state = SaveDC(context);
135 DCHECK_NE(saved_state, 0);
136 skia::PlatformDevice::InitializeDC(context);
137 {
138 // Save the state (again) to apply the necessary world transformation.
139 int saved_state = SaveDC(context);
140 DCHECK_NE(saved_state, 0);
141
142 #if 0
143 // Debug code to visually verify margins (leaks GDI handles).
144 XFORM debug_xform = { 0 };
145 ModifyWorldTransform(context, &debug_xform, MWT_IDENTITY);
146 // Printable area:
147 SelectObject(context, CreatePen(PS_SOLID, 1, RGB(0, 0, 0)));
148 SelectObject(context, CreateSolidBrush(RGB(0x90, 0x90, 0x90)));
149 Rectangle(context,
150 0,
151 0,
152 page_setup.printable_area().width(),
153 page_setup.printable_area().height());
154 // Overlay area:
155 gfx::Rect debug_overlay_area(page_setup.overlay_area());
156 debug_overlay_area.Offset(-page_setup.printable_area().x(),
157 -page_setup.printable_area().y());
158 SelectObject(context, CreateSolidBrush(RGB(0xb0, 0xb0, 0xb0)));
159 DrawRect(context, debug_overlay_area);
160 // Content area:
161 gfx::Rect debug_content_area(page_setup.content_area());
162 debug_content_area.Offset(-page_setup.printable_area().x(),
163 -page_setup.printable_area().y());
164 SelectObject(context, CreateSolidBrush(RGB(0xd0, 0xd0, 0xd0)));
165 DrawRect(context, debug_content_area);
166 #endif
167
168 // Setup the matrix to translate and scale to the right place. Take in
169 // account the actual shrinking factor.
170 // Note that the printing output is relative to printable area of the page.
171 // That is 0,0 is offset by PHYSICALOFFSETX/Y from the page.
172 SimpleModifyWorldTransform(
173 context,
174 page_setup.content_area().x() - page_setup.printable_area().x(),
175 page_setup.content_area().y() - page_setup.printable_area().y(),
176 mutable_.shrink_factor);
177
178 if (!page.native_metafile()->SafePlayback(context)) {
179 NOTREACHED();
180 }
181
182 BOOL res = RestoreDC(context, saved_state);
183 DCHECK_NE(res, 0);
184 }
185
186 // Print the header and footer. Offset by printable area offset (see comment
187 // above).
188 SimpleModifyWorldTransform(
189 context,
190 -page_setup.printable_area().x(),
191 -page_setup.printable_area().y(),
192 1);
193 int base_font_size = gfx::Font().height();
194 int new_font_size = ConvertUnit(10,
195 immutable_.settings_.desired_dpi,
196 immutable_.settings_.dpi());
197 DCHECK_GT(new_font_size, base_font_size);
198 gfx::Font font(gfx::Font().DeriveFont(new_font_size - base_font_size));
199 HGDIOBJ old_font = SelectObject(context, font.hfont());
200 DCHECK(old_font != NULL);
201 // We don't want a white square around the text ever if overflowing.
202 SetBkMode(context, TRANSPARENT);
203 PrintHeaderFooter(context, page, PageOverlays::LEFT, PageOverlays::TOP,
204 font);
205 PrintHeaderFooter(context, page, PageOverlays::CENTER, PageOverlays::TOP,
206 font);
207 PrintHeaderFooter(context, page, PageOverlays::RIGHT, PageOverlays::TOP,
208 font);
209 PrintHeaderFooter(context, page, PageOverlays::LEFT, PageOverlays::BOTTOM,
210 font);
211 PrintHeaderFooter(context, page, PageOverlays::CENTER, PageOverlays::BOTTOM,
212 font);
213 PrintHeaderFooter(context, page, PageOverlays::RIGHT, PageOverlays::BOTTOM,
214 font);
215 int res = RestoreDC(context, saved_state);
216 DCHECK_NE(res, 0);
217 #else // OS_WIN
218 NOTIMPLEMENTED();
219 #endif // OS_WIN
220 }
221
222 bool PrintedDocument::RenderPrintedPageNumber(int page_number, HDC context) {
223 scoped_refptr<PrintedPage> page; 102 scoped_refptr<PrintedPage> page;
224 if (!GetPage(page_number, &page)) 103 if (!GetPage(page_number, &page))
225 return false; 104 return false;
226 RenderPrintedPage(*page.get(), context); 105 RenderPrintedPage(*page.get(), context);
227 return true; 106 return true;
228 } 107 }
229 108
230 bool PrintedDocument::IsComplete() const { 109 bool PrintedDocument::IsComplete() const {
231 AutoLock lock(lock_); 110 AutoLock lock(lock_);
232 if (!mutable_.page_count_) 111 if (!mutable_.page_count_)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 int PrintedDocument::page_count() const { 163 int PrintedDocument::page_count() const {
285 AutoLock lock(lock_); 164 AutoLock lock(lock_);
286 return mutable_.page_count_; 165 return mutable_.page_count_;
287 } 166 }
288 167
289 int PrintedDocument::expected_page_count() const { 168 int PrintedDocument::expected_page_count() const {
290 AutoLock lock(lock_); 169 AutoLock lock(lock_);
291 return mutable_.expected_page_count_; 170 return mutable_.expected_page_count_;
292 } 171 }
293 172
294 void PrintedDocument::PrintHeaderFooter(HDC context, 173 void PrintedDocument::PrintHeaderFooter(gfx::NativeDrawingContext context,
295 const PrintedPage& page, 174 const PrintedPage& page,
296 PageOverlays::HorizontalPosition x, 175 PageOverlays::HorizontalPosition x,
297 PageOverlays::VerticalPosition y, 176 PageOverlays::VerticalPosition y,
298 const gfx::Font& font) const { 177 const gfx::Font& font) const {
299 const PrintSettings& settings = immutable_.settings_; 178 const PrintSettings& settings = immutable_.settings_;
300 const std::wstring& line = settings.overlays.GetOverlay(x, y); 179 const std::wstring& line = settings.overlays.GetOverlay(x, y);
301 if (line.empty()) { 180 if (line.empty()) {
302 return; 181 return;
303 } 182 }
304 std::wstring output(PageOverlays::ReplaceVariables(line, *this, page)); 183 std::wstring output(PageOverlays::ReplaceVariables(line, *this, page));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 } 222 }
344 223
345 if (string_size.width() > bounding.width()) { 224 if (string_size.width() > bounding.width()) {
346 if (line == PageOverlays::kUrl) { 225 if (line == PageOverlays::kUrl) {
347 output = gfx::ElideUrl(url(), font, bounding.width(), std::wstring()); 226 output = gfx::ElideUrl(url(), font, bounding.width(), std::wstring());
348 } else { 227 } else {
349 output = gfx::ElideText(output, font, bounding.width()); 228 output = gfx::ElideText(output, font, bounding.width());
350 } 229 }
351 } 230 }
352 231
232 // TODO(stuartmorgan): Factor out this platform-specific part into another
233 // method that can be moved into the platform files.
353 #if defined(OS_WIN) 234 #if defined(OS_WIN)
354 // Save the state (again) for the clipping region. 235 // Save the state (again) for the clipping region.
355 int saved_state = SaveDC(context); 236 int saved_state = SaveDC(context);
356 DCHECK_NE(saved_state, 0); 237 DCHECK_NE(saved_state, 0);
357 238
358 int result = IntersectClipRect(context, bounding.x(), bounding.y(), 239 int result = IntersectClipRect(context, bounding.x(), bounding.y(),
359 bounding.right() + 1, bounding.bottom() + 1); 240 bounding.right() + 1, bounding.bottom() + 1);
360 DCHECK(result == SIMPLEREGION || result == COMPLEXREGION); 241 DCHECK(result == SIMPLEREGION || result == COMPLEXREGION);
361 TextOut(context, 242 TextOut(context,
362 bounding.x(), bounding.y(), 243 bounding.x(), bounding.y(),
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 date_ = win_util::FormatSystemDate(systemtime, std::wstring()); 305 date_ = win_util::FormatSystemDate(systemtime, std::wstring());
425 time_ = win_util::FormatSystemTime(systemtime, std::wstring()); 306 time_ = win_util::FormatSystemTime(systemtime, std::wstring());
426 #else // OS_WIN 307 #else // OS_WIN
427 Time now = Time::Now(); 308 Time now = Time::Now();
428 date_ = base::TimeFormatShortDateNumeric(now); 309 date_ = base::TimeFormatShortDateNumeric(now);
429 time_ = base::TimeFormatTimeOfDay(now); 310 time_ = base::TimeFormatTimeOfDay(now);
430 #endif // OS_WIN 311 #endif // OS_WIN
431 } 312 }
432 313
433 } // namespace printing 314 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698