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

Side by Side Diff: chrome/renderer/print_web_view_helper_win.cc

Issue 6826027: Connect the right metafiles for print preview on Linux and Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix compile issues and rename MetafileInterface to Metafile Created 9 years, 8 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 | Annotate | Revision Log
OLDNEW
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 "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/process_util.h" 8 #include "base/process_util.h"
9 #include "base/scoped_ptr.h"
9 #include "chrome/common/print_messages.h" 10 #include "chrome/common/print_messages.h"
10 #include "printing/native_metafile_factory.h" 11 #include "printing/metafile.h"
11 #include "printing/native_metafile.h" 12 #include "printing/metafile_impl.h"
12 #include "printing/units.h" 13 #include "printing/units.h"
13 #include "skia/ext/vector_canvas.h" 14 #include "skia/ext/vector_canvas.h"
14 #include "skia/ext/vector_platform_device_emf_win.h" 15 #include "skia/ext/vector_platform_device_emf_win.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
16 #include "ui/gfx/gdi_util.h" 17 #include "ui/gfx/gdi_util.h"
17 #include "ui/gfx/point.h" 18 #include "ui/gfx/point.h"
18 #include "ui/gfx/rect.h" 19 #include "ui/gfx/rect.h"
19 #include "ui/gfx/size.h" 20 #include "ui/gfx/size.h"
20 21
21 using printing::ConvertUnitDouble; 22 using printing::ConvertUnitDouble;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 } 66 }
66 67
67 } // namespace 68 } // namespace
68 69
69 void PrintWebViewHelper::PrintPageInternal( 70 void PrintWebViewHelper::PrintPageInternal(
70 const PrintMsg_PrintPage_Params& params, 71 const PrintMsg_PrintPage_Params& params,
71 const gfx::Size& canvas_size, 72 const gfx::Size& canvas_size,
72 WebFrame* frame) { 73 WebFrame* frame) {
73 // Generate a memory-based metafile. It will use the current screen's DPI. 74 // Generate a memory-based metafile. It will use the current screen's DPI.
74 // Each metafile contains a single page. 75 // Each metafile contains a single page.
75 scoped_ptr<printing::NativeMetafile> metafile( 76 scoped_ptr<printing::Metafile> metafile(new printing::NativeMetafile);
76 printing::NativeMetafileFactory::Create()); 77 metafile->Init();
77 DCHECK(metafile->context()); 78 DCHECK(metafile->context());
78 skia::PlatformDevice::InitializeDC(metafile->context()); 79 skia::PlatformDevice::InitializeDC(metafile->context());
79 80
80 int page_number = params.page_number; 81 int page_number = params.page_number;
81 82
82 // Calculate the dpi adjustment. 83 // Calculate the dpi adjustment.
83 float scale_factor = static_cast<float>(params.params.desired_dpi / 84 float scale_factor = static_cast<float>(params.params.desired_dpi /
84 params.params.dpi); 85 params.params.dpi);
85 86
86 // Render page for printing. 87 // Render page for printing.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 WebKit::WebNode* node) { 125 WebKit::WebNode* node) {
125 int page_count = 0; 126 int page_count = 0;
126 PrintMsg_Print_Params print_params = params.params; 127 PrintMsg_Print_Params print_params = params.params;
127 UpdatePrintableSizeInPrintParameters(frame, node, &print_params); 128 UpdatePrintableSizeInPrintParameters(frame, node, &print_params);
128 PrepareFrameAndViewForPrint prep_frame_view(print_params, frame, node, 129 PrepareFrameAndViewForPrint prep_frame_view(print_params, frame, node,
129 frame->view()); 130 frame->view());
130 page_count = prep_frame_view.GetExpectedPageCount(); 131 page_count = prep_frame_view.GetExpectedPageCount();
131 if (!page_count) 132 if (!page_count)
132 return; 133 return;
133 134
134 // NOTE: This is an enhanced-format metafile(EMF) which has an appearance of 135 scoped_ptr<printing::Metafile> metafile(new printing::PreviewMetafile);
135 // single page metafile. For print preview, we need a metafile with multiple 136 metafile->Init();
136 // pages.
137 // TODO(kmadhusu): Use a PDF metafile to support multiple pages. After "Skia
138 // PDF backend" work is completed for windows, make changes to replace this
139 // EMF with PDF metafile.
140 // http://code.google.com/p/chromium/issues/detail?id=62889
141 scoped_ptr<printing::NativeMetafile> metafile(
142 printing::NativeMetafileFactory::Create());
143 DCHECK(metafile->context());
144 skia::PlatformDevice::InitializeDC(metafile->context());
145 137
146 // Calculate the dpi adjustment. 138 // Calculate the dpi adjustment.
147 float shrink = static_cast<float>(params.params.desired_dpi / 139 float shrink = static_cast<float>(print_params.desired_dpi /
148 params.params.dpi); 140 print_params.dpi);
149 141
150 if (params.pages.empty()) { 142 if (params.pages.empty()) {
151 for (int i = 0; i < page_count; ++i) { 143 for (int i = 0; i < page_count; ++i) {
152 float scale_factor = shrink; 144 float scale_factor = shrink;
153 RenderPage(params.params, &scale_factor, i, frame, &metafile); 145 RenderPage(print_params, &scale_factor, i, frame, &metafile);
154 } 146 }
155 } else { 147 } else {
156 for (size_t i = 0; i < params.pages.size(); ++i) { 148 for (size_t i = 0; i < params.pages.size(); ++i) {
157 if (params.pages[i] >= page_count) 149 if (params.pages[i] >= page_count)
158 break; 150 break;
159 float scale_factor = shrink; 151 float scale_factor = shrink;
160 RenderPage(params.params, &scale_factor, 152 RenderPage(print_params, &scale_factor,
161 static_cast<int>(params.pages[i]), frame, &metafile); 153 static_cast<int>(params.pages[i]), frame, &metafile);
162 } 154 }
163 } 155 }
164 156
165 // Close the device context to retrieve the compiled metafile.
166 if (!metafile->FinishDocument()) 157 if (!metafile->FinishDocument())
167 NOTREACHED(); 158 NOTREACHED();
168 159
169 // Get the size of the compiled metafile. 160 // Get the size of the compiled metafile.
170 uint32 buf_size = metafile->GetDataSize(); 161 uint32 buf_size = metafile->GetDataSize();
171 DCHECK_GT(buf_size, 128u); 162 DCHECK_GT(buf_size, 128u);
172 163
173 PrintHostMsg_DidPreviewDocument_Params preview_params; 164 PrintHostMsg_DidPreviewDocument_Params preview_params;
174 preview_params.document_cookie = params.params.document_cookie; 165 preview_params.document_cookie = params.params.document_cookie;
175 preview_params.data_size = buf_size; 166 preview_params.data_size = buf_size;
176 preview_params.metafile_data_handle = NULL; 167 preview_params.metafile_data_handle = NULL;
177 preview_params.expected_pages_count = page_count; 168 preview_params.expected_pages_count = page_count;
178 169
179 if (!CopyMetafileDataToSharedMem(metafile.get(), 170 if (!CopyMetafileDataToSharedMem(metafile.get(),
180 &(preview_params.metafile_data_handle))) { 171 &(preview_params.metafile_data_handle))) {
181 preview_params.data_size = 0; 172 preview_params.data_size = 0;
182 preview_params.expected_pages_count = 0; 173 preview_params.expected_pages_count = 0;
183 } 174 }
184 if (!Send(new PrintHostMsg_DuplicateSection( 175 if (!Send(new PrintHostMsg_DuplicateSection(
185 routing_id(), 176 routing_id(),
186 preview_params.metafile_data_handle, 177 preview_params.metafile_data_handle,
187 &preview_params.metafile_data_handle))) { 178 &preview_params.metafile_data_handle))) {
188 NOTREACHED() << "Send message failed."; 179 NOTREACHED() << "Send message failed.";
189 } 180 }
190 Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params)); 181 Send(new PrintHostMsg_PagesReadyForPreview(routing_id(), preview_params));
191 } 182 }
192 183
193 void PrintWebViewHelper::RenderPage( 184 void PrintWebViewHelper::RenderPage(
194 const PrintMsg_Print_Params& params, float* scale_factor, int page_number, 185 const PrintMsg_Print_Params& params, float* scale_factor, int page_number,
195 WebFrame* frame, scoped_ptr<printing::NativeMetafile>* metafile) { 186 WebFrame* frame, scoped_ptr<printing::Metafile>* metafile) {
196 DCHECK(metafile->get()->context());
197
198 double content_width_in_points; 187 double content_width_in_points;
199 double content_height_in_points; 188 double content_height_in_points;
200 double margin_top_in_points; 189 double margin_top_in_points;
201 double margin_left_in_points; 190 double margin_left_in_points;
202 GetPageSizeAndMarginsInPoints(frame, page_number, params, 191 GetPageSizeAndMarginsInPoints(frame, page_number, params,
203 &content_width_in_points, 192 &content_width_in_points,
204 &content_height_in_points, 193 &content_height_in_points,
205 &margin_top_in_points, NULL, NULL, 194 &margin_top_in_points, NULL, NULL,
206 &margin_left_in_points); 195 &margin_left_in_points);
207 196
(...skipping 16 matching lines...) Expand all
224 NOTREACHED() << "Printing page " << page_number << " failed."; 213 NOTREACHED() << "Printing page " << page_number << " failed.";
225 } else { 214 } else {
226 // Update the dpi adjustment with the "page |scale_factor|" calculated in 215 // Update the dpi adjustment with the "page |scale_factor|" calculated in
227 // webkit. 216 // webkit.
228 *scale_factor /= webkit_scale_factor; 217 *scale_factor /= webkit_scale_factor;
229 } 218 }
230 219
231 bool result = (*metafile)->FinishPage(); 220 bool result = (*metafile)->FinishPage();
232 DCHECK(result); 221 DCHECK(result);
233 222
234 skia::VectorPlatformDeviceEmf* platform_device = 223 if (!params.supports_alpha_blend) {
235 static_cast<skia::VectorPlatformDeviceEmf*>(device); 224 // PreviewMetafile (PDF) supports alpha blend.
Lei Zhang 2011/04/11 02:51:10 Err, PrintWebViewHelper::PrintPageInternal() also
vandebo (ex-Chrome) 2011/04/11 06:16:08 Comment clarified.
236 if (platform_device->alpha_blend_used() && !params.supports_alpha_blend) { 225 skia::VectorPlatformDeviceEmf* platform_device =
237 // Currently, we handle alpha blend transparency for a single page. 226 static_cast<skia::VectorPlatformDeviceEmf*>(device);
238 // Therefore, expecting a metafile with page count 1. 227 if (platform_device->alpha_blend_used()) {
239 DCHECK((*metafile)->GetPageCount() == 1); 228 // Currently, we handle alpha blend transparency for a single page.
229 // Therefore, expecting a metafile with page count 1.
230 DCHECK((*metafile)->GetPageCount() == 1);
240 231
241 // Close the device context to retrieve the compiled metafile. 232 // Close the device context to retrieve the compiled metafile.
242 if (!(*metafile)->FinishDocument()) 233 if (!(*metafile)->FinishDocument())
243 NOTREACHED(); 234 NOTREACHED();
244 235
245 scoped_ptr<printing::NativeMetafile> metafile2( 236 // Page used alpha blend, but printer doesn't support it. Rewrite the
246 printing::NativeMetafileFactory::Create()); 237 // metafile and flatten out the transparency.
247 // Page used alpha blend, but printer doesn't support it. Rewrite the 238 HDC bitmap_dc = CreateCompatibleDC(GetDC(NULL));
248 // metafile and flatten out the transparency. 239 if (!bitmap_dc)
249 HDC bitmap_dc = CreateCompatibleDC(GetDC(NULL)); 240 NOTREACHED() << "Bitmap DC creation failed";
250 if (!bitmap_dc) 241 SetGraphicsMode(bitmap_dc, GM_ADVANCED);
251 NOTREACHED() << "Bitmap DC creation failed"; 242 void* bits = NULL;
252 SetGraphicsMode(bitmap_dc, GM_ADVANCED); 243 BITMAPINFO hdr;
253 void* bits = NULL; 244 gfx::CreateBitmapHeader(width, height, &hdr.bmiHeader);
254 BITMAPINFO hdr; 245 HBITMAP hbitmap = CreateDIBSection(
255 gfx::CreateBitmapHeader(width, height, &hdr.bmiHeader); 246 bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0);
256 HBITMAP hbitmap = CreateDIBSection( 247 if (!hbitmap)
257 bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0); 248 NOTREACHED() << "Raster bitmap creation for printing failed";
258 if (!hbitmap)
259 NOTREACHED() << "Raster bitmap creation for printing failed";
260 249
261 HGDIOBJ old_bitmap = SelectObject(bitmap_dc, hbitmap); 250 HGDIOBJ old_bitmap = SelectObject(bitmap_dc, hbitmap);
262 RECT rect = {0, 0, width, height }; 251 RECT rect = {0, 0, width, height };
263 HBRUSH whiteBrush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); 252 HBRUSH whiteBrush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
264 FillRect(bitmap_dc, &rect, whiteBrush); 253 FillRect(bitmap_dc, &rect, whiteBrush);
265 254
266 HDC hdc = metafile2->context(); 255 scoped_ptr<printing::Metafile> metafile2(new printing::NativeMetafile);
267 DCHECK(hdc); 256 metafile2->Init();
268 skia::PlatformDevice::InitializeDC(hdc); 257 HDC hdc = metafile2->context();
258 DCHECK(hdc);
259 skia::PlatformDevice::InitializeDC(hdc);
269 260
270 RECT metafile_bounds = (*metafile)->GetPageBounds(1).ToRECT(); 261 RECT metafile_bounds = (*metafile)->GetPageBounds(1).ToRECT();
271 // Process the old metafile, placing all non-AlphaBlend calls into the 262 // Process the old metafile, placing all non-AlphaBlend calls into the
272 // new metafile, and copying the results of all the AlphaBlend calls 263 // new metafile, and copying the results of all the AlphaBlend calls
273 // from the bitmap DC. 264 // from the bitmap DC.
274 EnumEnhMetaFile(hdc, 265 EnumEnhMetaFile(hdc,
275 (*metafile)->emf(), 266 (*metafile)->emf(),
276 EnhMetaFileProc, 267 EnhMetaFileProc,
277 &bitmap_dc, 268 &bitmap_dc,
278 &metafile_bounds); 269 &metafile_bounds);
279 270
280 SelectObject(bitmap_dc, old_bitmap); 271 SelectObject(bitmap_dc, old_bitmap);
281 metafile->reset(metafile2.release()); 272 metafile->reset(metafile2.release());
273 }
282 } 274 }
283 } 275 }
284 276
285 bool PrintWebViewHelper::CopyMetafileDataToSharedMem( 277 bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
286 printing::NativeMetafile* metafile, 278 printing::Metafile* metafile,
287 base::SharedMemoryHandle* shared_mem_handle) { 279 base::SharedMemoryHandle* shared_mem_handle) {
288 uint32 buf_size = metafile->GetDataSize(); 280 uint32 buf_size = metafile->GetDataSize();
289 base::SharedMemory shared_buf; 281 base::SharedMemory shared_buf;
290 282
291 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx 283 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx
292 // Windows 2000/XP: When a page in a spooled file exceeds approximately 350 284 // Windows 2000/XP: When a page in a spooled file exceeds approximately 350
293 // MB, it can fail to print and not send an error message. 285 // MB, it can fail to print and not send an error message.
294 if (buf_size >= 350*1024*1024) { 286 if (buf_size >= 350*1024*1024) {
295 NOTREACHED() << "Buffer too large: " << buf_size; 287 NOTREACHED() << "Buffer too large: " << buf_size;
296 return false; 288 return false;
297 } 289 }
298 290
299 // Allocate a shared memory buffer to hold the generated metafile data. 291 // Allocate a shared memory buffer to hold the generated metafile data.
300 if (!shared_buf.CreateAndMapAnonymous(buf_size)) { 292 if (!shared_buf.CreateAndMapAnonymous(buf_size)) {
301 NOTREACHED() << "Buffer allocation failed"; 293 NOTREACHED() << "Buffer allocation failed";
302 return false; 294 return false;
303 } 295 }
304 296
305 // Copy the bits into shared memory. 297 // Copy the bits into shared memory.
306 if (!metafile->GetData(shared_buf.memory(), buf_size)) { 298 if (!metafile->GetData(shared_buf.memory(), buf_size)) {
307 NOTREACHED() << "GetData() failed"; 299 NOTREACHED() << "GetData() failed";
308 shared_buf.Unmap(); 300 shared_buf.Unmap();
309 return false; 301 return false;
310 } 302 }
311 shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle); 303 shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle);
312 shared_buf.Unmap(); 304 shared_buf.Unmap();
313 return true; 305 return true;
314 } 306 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698