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, gfx::Size page_size) { | |
Lei Zhang
2012/08/17 02:30:00
gfx::Size -> const gfx::Size& ?
Vitaly Buka (NO REVIEWS)
2012/08/17 02:40:32
Done. But it's just 64bit. It's below my threshold
| |
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 |