OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/renderer/print_web_view_helper.h" | 5 #include "chrome/renderer/print_web_view_helper.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/process_util.h" | 10 #include "base/process_util.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 break; | 86 break; |
87 | 87 |
88 default: | 88 default: |
89 // Play this command to the metafile DC. | 89 // Play this command to the metafile DC. |
90 PlayEnhMetaFileRecord(dc, handle_table, record, num_objects); | 90 PlayEnhMetaFileRecord(dc, handle_table, record, num_objects); |
91 break; | 91 break; |
92 } | 92 } |
93 return 1; // Continue enumeration | 93 return 1; // Continue enumeration |
94 } | 94 } |
95 | 95 |
| 96 Metafile* FlattenTransparency(Metafile* metafile, const gfx::Size& page_size) { |
| 97 // Currently, we handle alpha blend transparency for a single page. |
| 98 // Therefore, expecting a metafile with page count 1. |
| 99 DCHECK_EQ(1U, metafile->GetPageCount()); |
| 100 |
| 101 // Close the device context to retrieve the compiled metafile. |
| 102 if (!metafile->FinishDocument()) |
| 103 NOTREACHED(); |
| 104 |
| 105 // Page used alpha blend, but printer doesn't support it. Rewrite the |
| 106 // metafile and flatten out the transparency. |
| 107 base::win::ScopedGetDC screen_dc(NULL); |
| 108 base::win::ScopedCreateDC bitmap_dc(CreateCompatibleDC(screen_dc)); |
| 109 if (!bitmap_dc) |
| 110 NOTREACHED() << "Bitmap DC creation failed"; |
| 111 SetGraphicsMode(bitmap_dc, GM_ADVANCED); |
| 112 void* bits = NULL; |
| 113 BITMAPINFO hdr; |
| 114 gfx::CreateBitmapHeader(page_size.width(), page_size.height(), |
| 115 &hdr.bmiHeader); |
| 116 base::win::ScopedBitmap hbitmap(CreateDIBSection( |
| 117 bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0)); |
| 118 if (!hbitmap) |
| 119 NOTREACHED() << "Raster bitmap creation for printing failed"; |
| 120 |
| 121 base::win::ScopedSelectObject selectBitmap(bitmap_dc, hbitmap); |
| 122 RECT rect = { 0, 0, page_size.width(), page_size.height() }; |
| 123 HBRUSH whiteBrush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); |
| 124 FillRect(bitmap_dc, &rect, whiteBrush); |
| 125 |
| 126 Metafile* metafile2(new printing::NativeMetafile); |
| 127 metafile2->Init(); |
| 128 HDC hdc = metafile2->context(); |
| 129 DCHECK(hdc); |
| 130 skia::InitializeDC(hdc); |
| 131 |
| 132 RECT metafile_bounds = metafile->GetPageBounds(1).ToRECT(); |
| 133 // Process the old metafile, placing all non-AlphaBlend calls into the |
| 134 // new metafile, and copying the results of all the AlphaBlend calls |
| 135 // from the bitmap DC. |
| 136 EnumEnhMetaFile(hdc, |
| 137 metafile->emf(), |
| 138 EnhMetaFileProc, |
| 139 &bitmap_dc, |
| 140 &metafile_bounds); |
| 141 return metafile2; |
| 142 } |
| 143 |
96 } // namespace | 144 } // namespace |
97 | 145 |
98 void PrintWebViewHelper::PrintPageInternal( | 146 void PrintWebViewHelper::PrintPageInternal( |
99 const PrintMsg_PrintPage_Params& params, | 147 const PrintMsg_PrintPage_Params& params, |
100 const gfx::Size& canvas_size, | 148 const gfx::Size& canvas_size, |
101 WebFrame* frame) { | 149 WebFrame* frame) { |
102 // Generate a memory-based metafile. It will use the current screen's DPI. | 150 // Generate a memory-based metafile. It will use the current screen's DPI. |
103 // Each metafile contains a single page. | 151 // Each metafile contains a single page. |
104 scoped_ptr<Metafile> metafile(new printing::NativeMetafile); | 152 scoped_ptr<Metafile> metafile(new printing::NativeMetafile); |
105 metafile->Init(); | 153 metafile->Init(); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 | 319 |
272 bool result = metafile->FinishPage(); | 320 bool result = metafile->FinishPage(); |
273 DCHECK(result); | 321 DCHECK(result); |
274 | 322 |
275 if (!params.supports_alpha_blend) { | 323 if (!params.supports_alpha_blend) { |
276 // PreviewMetafile (PDF) supports alpha blend, so we only hit this case | 324 // PreviewMetafile (PDF) supports alpha blend, so we only hit this case |
277 // for NativeMetafile. | 325 // for NativeMetafile. |
278 DCHECK(!is_preview); | 326 DCHECK(!is_preview); |
279 skia::PlatformDevice* platform_device = skia::GetPlatformDevice(device); | 327 skia::PlatformDevice* platform_device = skia::GetPlatformDevice(device); |
280 if (platform_device && platform_device->AlphaBlendUsed()) { | 328 if (platform_device && platform_device->AlphaBlendUsed()) { |
281 // Currently, we handle alpha blend transparency for a single page. | 329 return FlattenTransparency(metafile, page_size); |
282 // Therefore, expecting a metafile with page count 1. | |
283 DCHECK_EQ(1U, metafile->GetPageCount()); | |
284 | |
285 // Close the device context to retrieve the compiled metafile. | |
286 if (!metafile->FinishDocument()) | |
287 NOTREACHED(); | |
288 | |
289 // Page used alpha blend, but printer doesn't support it. Rewrite the | |
290 // metafile and flatten out the transparency. | |
291 base::win::ScopedGetDC screen_dc(NULL); | |
292 base::win::ScopedCreateDC bitmap_dc(CreateCompatibleDC(screen_dc)); | |
293 if (!bitmap_dc) | |
294 NOTREACHED() << "Bitmap DC creation failed"; | |
295 SetGraphicsMode(bitmap_dc, GM_ADVANCED); | |
296 void* bits = NULL; | |
297 BITMAPINFO hdr; | |
298 gfx::CreateBitmapHeader(page_size.width(), page_size.height(), | |
299 &hdr.bmiHeader); | |
300 base::win::ScopedBitmap hbitmap(CreateDIBSection( | |
301 bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0)); | |
302 if (!hbitmap) | |
303 NOTREACHED() << "Raster bitmap creation for printing failed"; | |
304 | |
305 base::win::ScopedSelectObject selectBitmap(bitmap_dc, hbitmap); | |
306 RECT rect = { 0, 0, page_size.width(), page_size.height() }; | |
307 HBRUSH whiteBrush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); | |
308 FillRect(bitmap_dc, &rect, whiteBrush); | |
309 | |
310 Metafile* metafile2(new printing::NativeMetafile); | |
311 metafile2->Init(); | |
312 HDC hdc = metafile2->context(); | |
313 DCHECK(hdc); | |
314 skia::InitializeDC(hdc); | |
315 | |
316 RECT metafile_bounds = metafile->GetPageBounds(1).ToRECT(); | |
317 // Process the old metafile, placing all non-AlphaBlend calls into the | |
318 // new metafile, and copying the results of all the AlphaBlend calls | |
319 // from the bitmap DC. | |
320 EnumEnhMetaFile(hdc, | |
321 metafile->emf(), | |
322 EnhMetaFileProc, | |
323 &bitmap_dc, | |
324 &metafile_bounds); | |
325 return metafile2; | |
326 } | 330 } |
327 } | 331 } |
328 return metafile; | 332 return metafile; |
329 } | 333 } |
330 | 334 |
331 bool PrintWebViewHelper::CopyMetafileDataToSharedMem( | 335 bool PrintWebViewHelper::CopyMetafileDataToSharedMem( |
332 Metafile* metafile, base::SharedMemoryHandle* shared_mem_handle) { | 336 Metafile* metafile, base::SharedMemoryHandle* shared_mem_handle) { |
333 uint32 buf_size = metafile->GetDataSize(); | 337 uint32 buf_size = metafile->GetDataSize(); |
334 base::SharedMemory shared_buf; | 338 base::SharedMemory shared_buf; |
335 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx | 339 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx |
(...skipping 16 matching lines...) Expand all Loading... |
352 shared_buf.Unmap(); | 356 shared_buf.Unmap(); |
353 return false; | 357 return false; |
354 } | 358 } |
355 shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle); | 359 shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle); |
356 shared_buf.Unmap(); | 360 shared_buf.Unmap(); |
357 | 361 |
358 Send(new PrintHostMsg_DuplicateSection(routing_id(), *shared_mem_handle, | 362 Send(new PrintHostMsg_DuplicateSection(routing_id(), *shared_mem_handle, |
359 shared_mem_handle)); | 363 shared_mem_handle)); |
360 return true; | 364 return true; |
361 } | 365 } |
OLD | NEW |