OLD | NEW |
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 "chrome/common/render_messages.h" | 9 #include "chrome/common/render_messages.h" |
10 #include "chrome/common/render_messages_params.h" | 10 #include "chrome/common/render_messages_params.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 WebFrame* frame) { | 68 WebFrame* frame) { |
69 // 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. |
70 // Each metafile contains a single page. | 70 // Each metafile contains a single page. |
71 scoped_ptr<printing::NativeMetafile> metafile(new printing::NativeMetafile); | 71 scoped_ptr<printing::NativeMetafile> metafile(new printing::NativeMetafile); |
72 metafile->CreateDc(NULL, NULL); | 72 metafile->CreateDc(NULL, NULL); |
73 DCHECK(metafile->hdc()); | 73 DCHECK(metafile->hdc()); |
74 skia::PlatformDevice::InitializeDC(metafile->hdc()); | 74 skia::PlatformDevice::InitializeDC(metafile->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; | |
79 double content_height_in_points; | |
80 GetPageSizeAndMarginsInPoints(frame, page_number, params.params, | |
81 &content_width_in_points, &content_height_in_points, NULL, NULL, NULL, | |
82 NULL); | |
83 | |
84 // Calculate the dpi adjustment. | 78 // Calculate the dpi adjustment. |
85 float scale_factor = static_cast<float>(params.params.desired_dpi / | 79 float scale_factor = static_cast<float>(params.params.desired_dpi / |
86 params.params.dpi); | 80 params.params.dpi); |
87 | 81 |
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). | |
90 // PrintContext will then set the correct clipping region. | |
91 gfx::Size page_size( | |
92 static_cast<int>(content_width_in_points * params.params.max_shrink), | |
93 static_cast<int>(content_height_in_points * params.params.max_shrink)); | |
94 | |
95 // Render page for printing. | 82 // Render page for printing. |
96 RenderPage(page_size, &scale_factor, page_number, frame, &metafile, | 83 RenderPage(params.params, &scale_factor, page_number, frame, &metafile); |
97 params.params.supports_alpha_blend); | |
98 | 84 |
99 // Close the device context to retrieve the compiled metafile. | 85 // Close the device context to retrieve the compiled metafile. |
100 if (!metafile->CloseDc()) | 86 if (!metafile->CloseDc()) |
101 NOTREACHED(); | 87 NOTREACHED(); |
102 | 88 |
103 // Get the size of the compiled metafile. | 89 // Get the size of the compiled metafile. |
104 uint32 buf_size = metafile->GetDataSize(); | 90 uint32 buf_size = metafile->GetDataSize(); |
105 DCHECK_GT(buf_size, 128u); | 91 DCHECK_GT(buf_size, 128u); |
106 | 92 |
107 ViewHostMsg_DidPrintPage_Params page_params; | 93 ViewHostMsg_DidPrintPage_Params page_params; |
(...skipping 14 matching lines...) Expand all Loading... |
122 } | 108 } |
123 metafile->CloseEmf(); | 109 metafile->CloseEmf(); |
124 if (Send(new ViewHostMsg_DuplicateSection( | 110 if (Send(new ViewHostMsg_DuplicateSection( |
125 routing_id(), | 111 routing_id(), |
126 page_params.metafile_data_handle, | 112 page_params.metafile_data_handle, |
127 &page_params.metafile_data_handle))) { | 113 &page_params.metafile_data_handle))) { |
128 Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params)); | 114 Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params)); |
129 } | 115 } |
130 } | 116 } |
131 | 117 |
| 118 void PrintWebViewHelper::CreatePreviewDocument( |
| 119 const ViewMsg_PrintPages_Params& params, WebFrame* frame, |
| 120 ViewHostMsg_DidPreviewDocument_Params* preview_params) { |
| 121 int page_count = 0; |
| 122 ViewMsg_Print_Params print_params = params.params; |
| 123 UpdatePrintableSizeInPrintParameters(frame, NULL, &print_params); |
| 124 PrepareFrameAndViewForPrint prep_frame_view(print_params, frame, NULL, |
| 125 frame->view()); |
| 126 page_count = prep_frame_view.GetExpectedPageCount(); |
| 127 if (!page_count) |
| 128 return; |
| 129 |
| 130 // NOTE: This is an enhanced-format metafile(EMF) which has an appearance of |
| 131 // single page metafile. For print preview, we need a metafile with multiple |
| 132 // pages. |
| 133 // TODO(kmadhusu): Use a PDF metafile to support multiple pages. After "Skia |
| 134 // PDF backend" work is completed for windows, make changes to replace this |
| 135 // EMF with PDF metafile. |
| 136 // http://code.google.com/p/chromium/issues/detail?id=62889 |
| 137 scoped_ptr<printing::NativeMetafile> metafile(new printing::NativeMetafile); |
| 138 metafile->CreateDc(NULL, NULL); |
| 139 DCHECK(metafile->hdc()); |
| 140 skia::PlatformDevice::InitializeDC(metafile->hdc()); |
| 141 |
| 142 // Calculate the dpi adjustment. |
| 143 float shrink = static_cast<float>(params.params.desired_dpi / |
| 144 params.params.dpi); |
| 145 |
| 146 if (params.pages.empty()) { |
| 147 for (int i = 0; i < page_count; ++i) { |
| 148 float scale_factor = shrink; |
| 149 RenderPage(params.params, &scale_factor, i, frame, &metafile); |
| 150 } |
| 151 } else { |
| 152 for (size_t i = 0; i < params.pages.size(); ++i) { |
| 153 if (params.pages[i] >= page_count) |
| 154 break; |
| 155 float scale_factor = shrink; |
| 156 RenderPage(params.params, &scale_factor, |
| 157 static_cast<int>(params.pages[i]), frame, &metafile); |
| 158 } |
| 159 } |
| 160 |
| 161 // Close the device context to retrieve the compiled metafile. |
| 162 if (!metafile->CloseDc()) |
| 163 NOTREACHED(); |
| 164 |
| 165 // Get the size of the compiled metafile. |
| 166 uint32 buf_size = metafile->GetDataSize(); |
| 167 DCHECK_GT(buf_size, 128u); |
| 168 |
| 169 preview_params->document_cookie = params.params.document_cookie; |
| 170 preview_params->data_size = 0; |
| 171 preview_params->metafile_data_handle = NULL; |
| 172 |
| 173 if (CopyMetafileDataToSharedMem(metafile.get(), |
| 174 &(preview_params->metafile_data_handle))) { |
| 175 preview_params->data_size = buf_size; |
| 176 } |
| 177 metafile->CloseEmf(); |
| 178 if (!Send(new ViewHostMsg_DuplicateSection( |
| 179 routing_id(), |
| 180 preview_params->metafile_data_handle, |
| 181 &preview_params->metafile_data_handle))) { |
| 182 NOTREACHED() << "Send message failed."; |
| 183 } |
| 184 } |
| 185 |
132 void PrintWebViewHelper::RenderPage( | 186 void PrintWebViewHelper::RenderPage( |
133 const gfx::Size& page_size, float* scale_factor, int page_number, | 187 const ViewMsg_Print_Params& params, float* scale_factor, int page_number, |
134 WebFrame* frame, scoped_ptr<printing::NativeMetafile>* metafile, | 188 WebFrame* frame, scoped_ptr<printing::NativeMetafile>* metafile) { |
135 bool supports_alpha_blend) { | |
136 HDC hdc = (*metafile)->hdc(); | 189 HDC hdc = (*metafile)->hdc(); |
137 DCHECK(hdc); | 190 DCHECK(hdc); |
138 | 191 |
139 int width = page_size.width(); | 192 double content_width_in_points; |
140 int height = page_size.height(); | 193 double content_height_in_points; |
| 194 GetPageSizeAndMarginsInPoints(frame, page_number, params, |
| 195 &content_width_in_points, &content_height_in_points, NULL, NULL, NULL, |
| 196 NULL); |
| 197 |
| 198 // Since WebKit extends the page width depending on the magical scale factor |
| 199 // we make sure the canvas covers the worst case scenario (x2.0 currently). |
| 200 // PrintContext will then set the correct clipping region. |
| 201 int width = static_cast<int>(content_width_in_points * params.max_shrink); |
| 202 int height = static_cast<int>(content_height_in_points * params.max_shrink); |
| 203 |
141 #if 0 | 204 #if 0 |
142 // TODO(maruel): This code is kept for testing until the 100% GDI drawing | 205 // TODO(maruel): This code is kept for testing until the 100% GDI drawing |
143 // code is stable. maruels use this code's output as a reference when the | 206 // code is stable. maruels use this code's output as a reference when the |
144 // GDI drawing code fails. | 207 // GDI drawing code fails. |
145 | 208 |
146 // Mix of Skia and GDI based. | 209 // Mix of Skia and GDI based. |
147 skia::PlatformCanvas canvas(width, height, true); | 210 skia::PlatformCanvas canvas(width, height, true); |
148 canvas.drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode); | 211 canvas.drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode); |
149 float webkit_scale_factor = frame->printPage(page_number, &canvas); | 212 float webkit_scale_factor = frame->printPage(page_number, &canvas); |
150 if (*scale_factor <= 0 || webkit_scale_factor <= 0) { | 213 if (*scale_factor <= 0 || webkit_scale_factor <= 0) { |
(...skipping 28 matching lines...) Expand all Loading... |
179 NOTREACHED() << "Printing page " << page_number << " failed."; | 242 NOTREACHED() << "Printing page " << page_number << " failed."; |
180 } else { | 243 } else { |
181 // Update the dpi adjustment with the "page |scale_factor|" calculated in | 244 // Update the dpi adjustment with the "page |scale_factor|" calculated in |
182 // webkit. | 245 // webkit. |
183 *scale_factor /= webkit_scale_factor; | 246 *scale_factor /= webkit_scale_factor; |
184 } | 247 } |
185 #endif | 248 #endif |
186 | 249 |
187 skia::VectorPlatformDevice* platform_device = | 250 skia::VectorPlatformDevice* platform_device = |
188 static_cast<skia::VectorPlatformDevice*>(canvas.getDevice()); | 251 static_cast<skia::VectorPlatformDevice*>(canvas.getDevice()); |
189 if (platform_device->alpha_blend_used() && !supports_alpha_blend) { | 252 if (platform_device->alpha_blend_used() && !params.supports_alpha_blend) { |
190 // Close the device context to retrieve the compiled metafile. | 253 // Close the device context to retrieve the compiled metafile. |
191 if (!(*metafile)->CloseDc()) | 254 if (!(*metafile)->CloseDc()) |
192 NOTREACHED(); | 255 NOTREACHED(); |
193 | 256 |
194 scoped_ptr<printing::NativeMetafile> metafile2( | 257 scoped_ptr<printing::NativeMetafile> metafile2( |
195 new printing::NativeMetafile); | 258 new printing::NativeMetafile); |
196 // Page used alpha blend, but printer doesn't support it. Rewrite the | 259 // Page used alpha blend, but printer doesn't support it. Rewrite the |
197 // metafile and flatten out the transparency. | 260 // metafile and flatten out the transparency. |
198 HDC bitmap_dc = CreateCompatibleDC(GetDC(NULL)); | 261 HDC bitmap_dc = CreateCompatibleDC(GetDC(NULL)); |
199 if (!bitmap_dc) { | 262 if (!bitmap_dc) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 // Copy the bits into shared memory. | 320 // Copy the bits into shared memory. |
258 if (!metafile->GetData(shared_buf.memory(), buf_size)) { | 321 if (!metafile->GetData(shared_buf.memory(), buf_size)) { |
259 NOTREACHED() << "GetData() failed"; | 322 NOTREACHED() << "GetData() failed"; |
260 shared_buf.Unmap(); | 323 shared_buf.Unmap(); |
261 return false; | 324 return false; |
262 } | 325 } |
263 shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle); | 326 shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle); |
264 shared_buf.Unmap(); | 327 shared_buf.Unmap(); |
265 return true; | 328 return true; |
266 } | 329 } |
OLD | NEW |