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

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

Issue 6321017: Refactor win printing workflow. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed comments. Created 9 years, 11 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) 2009 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 "chrome/common/render_messages.h" 9 #include "chrome/common/render_messages.h"
9 #include "chrome/common/render_messages_params.h" 10 #include "chrome/common/render_messages_params.h"
10 #include "chrome/renderer/render_view.h" 11 #include "chrome/renderer/render_view.h"
11 #include "gfx/gdi_util.h" 12 #include "gfx/gdi_util.h"
12 #include "gfx/size.h" 13 #include "gfx/size.h"
13 #include "grit/generated_resources.h" 14 #include "grit/generated_resources.h"
14 #include "printing/native_metafile.h" 15 #include "printing/native_metafile.h"
15 #include "printing/units.h" 16 #include "printing/units.h"
16 #include "skia/ext/vector_canvas.h" 17 #include "skia/ext/vector_canvas.h"
17 #include "skia/ext/vector_platform_device.h" 18 #include "skia/ext/vector_platform_device.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 // Play this command to the metafile DC. 60 // Play this command to the metafile DC.
60 PlayEnhMetaFileRecord(dc, handle_table, record, num_objects); 61 PlayEnhMetaFileRecord(dc, handle_table, record, num_objects);
61 } 62 }
62 return 1; // Continue enumeration 63 return 1; // Continue enumeration
63 } 64 }
64 65
65 void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, 66 void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,
66 const gfx::Size& canvas_size, 67 const gfx::Size& canvas_size,
67 WebFrame* frame) { 68 WebFrame* frame) {
68 // Generate a memory-based metafile. It will use the current screen's DPI. 69 // Generate a memory-based metafile. It will use the current screen's DPI.
69 printing::NativeMetafile metafile; 70 // Each metafile contains a single page.
70 71 scoped_ptr<printing::NativeMetafile> metafile(new printing::NativeMetafile());
vandebo (ex-Chrome) 2011/01/25 18:13:15 nit: extra ()
kmadhusu 2011/01/25 18:57:32 Done.
71 metafile.CreateDc(NULL, NULL); 72 metafile->CreateDc(NULL, NULL);
72 HDC hdc = metafile.hdc(); 73 DCHECK(metafile->hdc());
73 DCHECK(hdc); 74 skia::PlatformDevice::InitializeDC(metafile->hdc());
74 skia::PlatformDevice::InitializeDC(hdc);
75 75
76 int page_number = params.page_number; 76 int page_number = params.page_number;
77 77
78 double content_width_in_points; 78 double content_width_in_points;
79 double content_height_in_points; 79 double content_height_in_points;
80 GetPageSizeAndMarginsInPoints(frame, page_number, params.params, 80 GetPageSizeAndMarginsInPoints(frame, page_number, params.params,
81 &content_width_in_points, &content_height_in_points, NULL, NULL, NULL, 81 &content_width_in_points, &content_height_in_points, NULL, NULL, NULL,
82 NULL); 82 NULL);
83 83
84 // Calculate the dpi adjustment. 84 // Calculate the dpi adjustment.
85 float scale_factor = static_cast<float>(params.params.desired_dpi / 85 float scale_factor = static_cast<float>(params.params.desired_dpi /
86 params.params.dpi); 86 params.params.dpi);
87 87
88 // Since WebKit extends the page width depending on the magical |scale_factor| 88 // Since WebKit extends the page width depending on the magical |scale_factor|
89 // we make sure the canvas covers the worst case scenario (x2.0 currently). 89 // we make sure the canvas covers the worst case scenario (x2.0 currently).
90 // PrintContext will then set the correct clipping region. 90 // PrintContext will then set the correct clipping region.
91 int width = static_cast<int>(content_width_in_points * 91 gfx::Size page_size(
92 params.params.max_shrink); 92 static_cast<int>(content_width_in_points * params.params.max_shrink),
93 int height = static_cast<int>(content_height_in_points * 93 static_cast<int>(content_height_in_points * params.params.max_shrink));
94 params.params.max_shrink); 94
95 // Render page for printing.
96 RenderPage(page_size, &scale_factor, page_number, frame, &metafile,
97 params.params.supports_alpha_blend);
98
99 // Close the device context to retrieve the compiled metafile.
100 if (!metafile->CloseDc())
101 NOTREACHED();
102
103 // Get the size of the compiled metafile.
104 uint32 buf_size = metafile->GetDataSize();
105 DCHECK_GT(buf_size, 128u);
106
107 ViewHostMsg_DidPrintPage_Params page_params;
108 page_params.data_size = 0;
109 page_params.metafile_data_handle = NULL;
110 page_params.page_number = page_number;
111 page_params.document_cookie = params.params.document_cookie;
112 page_params.actual_shrink = scale_factor;
113 page_params.page_size = params.params.page_size;
114 page_params.content_area = gfx::Rect(params.params.margin_left,
115 params.params.margin_top, params.params.printable_size.width(),
116 params.params.printable_size.height());
117 page_params.has_visible_overlays = frame->isPageBoxVisible(page_number);
118
119 if (CopyMetafileDataToSharedMem(metafile.get(),
120 &(page_params.metafile_data_handle))) {
121 page_params.data_size = buf_size;
122 }
123 metafile->CloseEmf();
124 if (Send(new ViewHostMsg_DuplicateSection(
125 routing_id(),
126 page_params.metafile_data_handle,
127 &page_params.metafile_data_handle))) {
128 Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params));
129 }
130 }
131
132 void PrintWebViewHelper::RenderPage(
133 const gfx::Size& page_size, float* scale_factor, int page_number,
134 WebFrame* frame, scoped_ptr<printing::NativeMetafile>* metafile,
135 bool supports_alpha_blend) {
136 HDC hdc = (*metafile)->hdc();
137 DCHECK(hdc);
138
139 int width = page_size.width();
140 int height = page_size.height();
95 #if 0 141 #if 0
96 // TODO(maruel): This code is kept for testing until the 100% GDI drawing 142 // TODO(maruel): This code is kept for testing until the 100% GDI drawing
97 // code is stable. maruels use this code's output as a reference when the 143 // code is stable. maruels use this code's output as a reference when the
98 // GDI drawing code fails. 144 // GDI drawing code fails.
99 145
100 // Mix of Skia and GDI based. 146 // Mix of Skia and GDI based.
101 skia::PlatformCanvas canvas(width, height, true); 147 skia::PlatformCanvas canvas(width, height, true);
102 canvas.drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode); 148 canvas.drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode);
103 float webkit_scale_factor = frame->printPage(page_number, &canvas); 149 float webkit_scale_factor = frame->printPage(page_number, &canvas);
104 if (scale_factor <= 0 || webkit_scale_factor <= 0) { 150 if (*scale_factor <= 0 || webkit_scale_factor <= 0) {
105 NOTREACHED() << "Printing page " << page_number << " failed."; 151 NOTREACHED() << "Printing page " << page_number << " failed.";
106 } else { 152 } else {
107 // Update the dpi adjustment with the "page |scale_factor|" calculated 153 // Update the dpi adjustment with the "page |scale_factor|" calculated in
108 // in webkit. 154 // webkit.
109 scale_factor /= webkit_scale_factor; 155 *scale_factor /= webkit_scale_factor;
110 } 156 }
111 157
112 // Create a BMP v4 header that we can serialize. 158 // Create a BMP v4 header that we can serialize.
113 BITMAPV4HEADER bitmap_header; 159 BITMAPV4HEADER bitmap_header;
114 gfx::CreateBitmapV4Header(width, height, &bitmap_header); 160 gfx::CreateBitmapV4Header(width, height, &bitmap_header);
115 const SkBitmap& src_bmp = canvas.getDevice()->accessBitmap(true); 161 const SkBitmap& src_bmp = canvas.getDevice()->accessBitmap(true);
116 SkAutoLockPixels src_lock(src_bmp); 162 SkAutoLockPixels src_lock(src_bmp);
117 int retval = StretchDIBits(hdc, 163 int retval = StretchDIBits(hdc,
118 0, 164 0,
119 0, 165 0,
120 width, height, 166 width, height,
121 0, 0, 167 0, 0,
122 width, height, 168 width, height,
123 src_bmp.getPixels(), 169 src_bmp.getPixels(),
124 reinterpret_cast<BITMAPINFO*>(&bitmap_header), 170 reinterpret_cast<BITMAPINFO*>(&bitmap_header),
125 DIB_RGB_COLORS, 171 DIB_RGB_COLORS,
126 SRCCOPY); 172 SRCCOPY);
127 DCHECK(retval != GDI_ERROR); 173 DCHECK(retval != GDI_ERROR);
128 #else 174 #else
129 // 100% GDI based. 175 // 100% GDI based.
130 skia::VectorCanvas canvas(hdc, width, height); 176 skia::VectorCanvas canvas(hdc, width, height);
131 float webkit_scale_factor = frame->printPage(page_number, &canvas); 177 float webkit_scale_factor = frame->printPage(page_number, &canvas);
132 if (scale_factor <= 0 || webkit_scale_factor <= 0) { 178 if (*scale_factor <= 0 || webkit_scale_factor <= 0) {
133 NOTREACHED() << "Printing page " << page_number << " failed."; 179 NOTREACHED() << "Printing page " << page_number << " failed.";
134 } else { 180 } else {
135 // Update the dpi adjustment with the "page scale_factor" calculated 181 // Update the dpi adjustment with the "page |scale_factor|" calculated in
136 // in webkit. 182 // webkit.
137 scale_factor /= webkit_scale_factor; 183 *scale_factor /= webkit_scale_factor;
138 } 184 }
139 #endif 185 #endif
140 186
141 // Done printing. Close the device context to retrieve the compiled metafile. 187 skia::VectorPlatformDevice* platform_device =
142 if (!metafile.CloseDc()) { 188 static_cast<skia::VectorPlatformDevice*>(canvas.getDevice());
143 NOTREACHED() << "metafile failed"; 189 if (platform_device->alpha_blend_used() && !supports_alpha_blend) {
144 } 190 // Close the device context to retrieve the compiled metafile.
145 printing::NativeMetafile* mf = &metafile; 191 if (!(*metafile)->CloseDc())
146 printing::NativeMetafile metafile2; 192 NOTREACHED();
147 193
148 skia::VectorPlatformDevice* platform_device = 194 scoped_ptr<printing::NativeMetafile> metafile2(
149 static_cast<skia::VectorPlatformDevice*>(canvas.getDevice()); 195 new printing::NativeMetafile());
kmadhusu 2011/01/25 18:57:32 Removed extra "()".
150 if (platform_device->alpha_blend_used() &&
151 !params.params.supports_alpha_blend) {
152 // Page used alpha blend, but printer doesn't support it. Rewrite the 196 // Page used alpha blend, but printer doesn't support it. Rewrite the
153 // metafile and flatten out the transparency. 197 // metafile and flatten out the transparency.
154 HDC bitmap_dc = CreateCompatibleDC(GetDC(NULL)); 198 HDC bitmap_dc = CreateCompatibleDC(GetDC(NULL));
155 if (!bitmap_dc) { 199 if (!bitmap_dc) {
156 NOTREACHED() << "Bitmap DC creation failed"; 200 NOTREACHED() << "Bitmap DC creation failed";
157 } 201 }
158 SetGraphicsMode(bitmap_dc, GM_ADVANCED); 202 SetGraphicsMode(bitmap_dc, GM_ADVANCED);
159 void* bits = NULL; 203 void* bits = NULL;
160 BITMAPINFO hdr; 204 BITMAPINFO hdr;
161 gfx::CreateBitmapHeader(width, height, &hdr.bmiHeader); 205 gfx::CreateBitmapHeader(width, height, &hdr.bmiHeader);
162 HBITMAP hbitmap = CreateDIBSection( 206 HBITMAP hbitmap = CreateDIBSection(
163 bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0); 207 bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0);
164 if (!hbitmap) { 208 if (!hbitmap) {
165 NOTREACHED() << "Raster bitmap creation for printing failed"; 209 NOTREACHED() << "Raster bitmap creation for printing failed";
166 } 210 }
167 211
168 HGDIOBJ old_bitmap = SelectObject(bitmap_dc, hbitmap); 212 HGDIOBJ old_bitmap = SelectObject(bitmap_dc, hbitmap);
169 RECT rect = {0, 0, width, height }; 213 RECT rect = {0, 0, width, height };
170 HBRUSH whiteBrush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); 214 HBRUSH whiteBrush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
171 FillRect(bitmap_dc, &rect, whiteBrush); 215 FillRect(bitmap_dc, &rect, whiteBrush);
172 216
173 metafile2.CreateDc(NULL, NULL); 217 metafile2->CreateDc(NULL, NULL);
174 HDC hdc = metafile2.hdc(); 218 HDC hdc = metafile2->hdc();
175 DCHECK(hdc); 219 DCHECK(hdc);
176 skia::PlatformDevice::InitializeDC(hdc); 220 skia::PlatformDevice::InitializeDC(hdc);
177 221
178 RECT metafile_bounds = metafile.GetBounds().ToRECT(); 222 RECT metafile_bounds = (*metafile)->GetBounds().ToRECT();
179 // Process the old metafile, placing all non-AlphaBlend calls into the 223 // Process the old metafile, placing all non-AlphaBlend calls into the
180 // new metafile, and copying the results of all the AlphaBlend calls 224 // new metafile, and copying the results of all the AlphaBlend calls
181 // from the bitmap DC. 225 // from the bitmap DC.
182 EnumEnhMetaFile(hdc, 226 EnumEnhMetaFile(hdc,
183 metafile.emf(), 227 (*metafile)->emf(),
184 EnhMetaFileProc, 228 EnhMetaFileProc,
185 &bitmap_dc, 229 &bitmap_dc,
186 &metafile_bounds); 230 &metafile_bounds);
187 231
188 SelectObject(bitmap_dc, old_bitmap); 232 SelectObject(bitmap_dc, old_bitmap);
233 metafile->reset(metafile2.release());
234 }
235 }
189 236
190 if (!metafile2.CloseDc()) { 237 bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
191 NOTREACHED() << "metafile failed"; 238 printing::NativeMetafile* metafile,
192 } 239 base::SharedMemoryHandle* shared_mem_handle) {
193 mf = &metafile2; 240 uint32 buf_size = metafile->GetDataSize();
194 }
195
196 // Get the size of the compiled metafile.
197 uint32 buf_size = mf->GetDataSize();
198 DCHECK_GT(buf_size, 128u);
199 ViewHostMsg_DidPrintPage_Params page_params;
200 page_params.data_size = 0;
201 page_params.metafile_data_handle = NULL;
202 page_params.page_number = page_number;
203 page_params.document_cookie = params.params.document_cookie;
204 page_params.actual_shrink = scale_factor;
205 page_params.page_size = params.params.page_size;
206 page_params.content_area = gfx::Rect(params.params.margin_left,
207 params.params.margin_top, params.params.printable_size.width(),
208 params.params.printable_size.height());
209 page_params.has_visible_overlays = frame->isPageBoxVisible(page_number);
210 base::SharedMemory shared_buf; 241 base::SharedMemory shared_buf;
211 242
212 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx 243 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx
213 // Windows 2000/XP: When a page in a spooled file exceeds approximately 350 244 // Windows 2000/XP: When a page in a spooled file exceeds approximately 350
214 // MB, it can fail to print and not send an error message. 245 // MB, it can fail to print and not send an error message.
215 if (buf_size < 350*1024*1024) { 246 if (buf_size >= 350*1024*1024) {
216 // Allocate a shared memory buffer to hold the generated metafile data.
217 if (shared_buf.CreateAndMapAnonymous(buf_size)) {
218 // Copy the bits into shared memory.
219 if (mf->GetData(shared_buf.memory(), buf_size)) {
220 page_params.metafile_data_handle = shared_buf.handle();
221 page_params.data_size = buf_size;
222 } else {
223 NOTREACHED() << "GetData() failed";
224 }
225 shared_buf.Unmap();
226 } else {
227 NOTREACHED() << "Buffer allocation failed";
228 }
229 } else {
230 NOTREACHED() << "Buffer too large: " << buf_size; 247 NOTREACHED() << "Buffer too large: " << buf_size;
248 return false;
231 } 249 }
232 mf->CloseEmf(); 250
233 if (Send(new ViewHostMsg_DuplicateSection( 251 // Allocate a shared memory buffer to hold the generated metafile data.
234 routing_id(), 252 if (!shared_buf.CreateAndMapAnonymous(buf_size)) {
235 page_params.metafile_data_handle, 253 NOTREACHED() << "Buffer allocation failed";
236 &page_params.metafile_data_handle))) { 254 return false;
237 if (!is_preview_) {
238 Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params));
239 }
240 } 255 }
256
257 // Copy the bits into shared memory.
258 if (!metafile->GetData(shared_buf.memory(), buf_size)) {
259 NOTREACHED() << "GetData() failed";
260 shared_buf.Unmap();
261 return false;
262 }
263 shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle);
264 shared_buf.Unmap();
265 return true;
241 } 266 }
OLDNEW
« chrome/renderer/print_web_view_helper.h ('K') | « chrome/renderer/print_web_view_helper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698