OLD | NEW |
---|---|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/common/render_messages.h" | 8 #include "chrome/common/render_messages.h" |
9 #include "chrome/common/render_messages_params.h" | 9 #include "chrome/common/render_messages_params.h" |
10 #include "chrome/renderer/render_view.h" | 10 #include "chrome/renderer/render_view.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 const gfx::Size& canvas_size, | 66 const gfx::Size& canvas_size, |
67 WebFrame* frame) { | 67 WebFrame* frame) { |
68 // Generate a memory-based metafile. It will use the current screen's DPI. | 68 // Generate a memory-based metafile. It will use the current screen's DPI. |
69 printing::NativeMetafile metafile; | 69 printing::NativeMetafile metafile; |
70 | 70 |
71 metafile.CreateDc(NULL, NULL); | 71 metafile.CreateDc(NULL, NULL); |
72 HDC hdc = metafile.hdc(); | 72 HDC hdc = metafile.hdc(); |
73 DCHECK(hdc); | 73 DCHECK(hdc); |
74 skia::PlatformDevice::InitializeDC(hdc); | 74 skia::PlatformDevice::InitializeDC(hdc); |
75 | 75 |
76 double content_width_in_points; | 76 // Calculate the dpi adjustment. |
77 double content_height_in_points; | 77 float scale_factor = static_cast<float>(params.params.desired_dpi / |
78 double margin_top_in_points; | 78 params.params.dpi); |
79 double margin_right_in_points; | 79 int page_number = params.page_number; |
80 double margin_bottom_in_points; | |
81 double margin_left_in_points; | |
82 GetPageSizeAndMarginsInPoints(frame, | |
83 params.page_number, | |
84 params.params, | |
85 &content_width_in_points, | |
86 &content_height_in_points, | |
87 &margin_top_in_points, | |
88 &margin_right_in_points, | |
89 &margin_bottom_in_points, | |
90 &margin_left_in_points); | |
91 | 80 |
92 // Since WebKit extends the page width depending on the magical shrink | 81 int width = static_cast<int>( |
Lei Zhang
2011/01/19 05:10:04
width/height is suppose to be the same as size_x/s
kmadhusu
2011/01/19 17:09:41
In the old code, we calculated |size_x| and |size_
Lei Zhang
2011/01/19 21:44:03
(repeating our in person conversation for senorbla
kmadhusu
2011/01/19 23:25:12
New code caused some random errors while handling
| |
93 // factor we make sure the canvas covers the worst case scenario | 82 params.params.printable_size.width() * params.params.max_shrink); |
94 // (x2.0 currently). PrintContext will then set the correct clipping region. | 83 int height = static_cast<int>( |
95 int size_x = static_cast<int>(content_width_in_points * | 84 params.params.printable_size.height() * params.params.max_shrink); |
96 params.params.max_shrink); | |
97 int size_y = static_cast<int>(content_height_in_points * | |
98 params.params.max_shrink); | |
99 // Calculate the dpi adjustment. | |
100 float shrink = static_cast<float>(params.params.desired_dpi / | |
101 params.params.dpi); | |
102 #if 0 | 85 #if 0 |
103 // TODO(maruel): This code is kept for testing until the 100% GDI drawing | 86 // TODO(maruel): This code is kept for testing until the 100% GDI drawing |
104 // code is stable. maruels use this code's output as a reference when the | 87 // code is stable. maruels use this code's output as a reference when the |
105 // GDI drawing code fails. | 88 // GDI drawing code fails. |
106 | 89 |
107 // Mix of Skia and GDI based. | 90 // Mix of Skia and GDI based. |
108 skia::PlatformCanvas canvas(size_x, size_y, true); | 91 skia::PlatformCanvas canvas(width, height, true); |
109 canvas.drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode); | 92 canvas.drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode); |
110 float webkit_shrink = frame->printPage(params.page_number, &canvas); | 93 float webkit_scale_factor = frame->printPage(page_number, &canvas); |
111 if (shrink <= 0 || webkit_shrink <= 0) { | 94 if (scale_factor <= 0 || webkit_scale_factor <= 0) { |
112 NOTREACHED() << "Printing page " << params.page_number << " failed."; | 95 NOTREACHED() << "Printing page " << page_number << " failed."; |
113 } else { | 96 } else { |
114 // Update the dpi adjustment with the "page shrink" calculated in webkit. | 97 // Update the dpi adjustment with the "page |scale_factor|" calculated |
115 shrink /= webkit_shrink; | 98 // in webkit. |
99 scale_factor /= webkit_scale_factor; | |
116 } | 100 } |
117 | 101 |
118 // Create a BMP v4 header that we can serialize. | 102 // Create a BMP v4 header that we can serialize. |
119 BITMAPV4HEADER bitmap_header; | 103 BITMAPV4HEADER bitmap_header; |
120 gfx::CreateBitmapV4Header(size_x, size_y, &bitmap_header); | 104 gfx::CreateBitmapV4Header(width, height, &bitmap_header); |
121 const SkBitmap& src_bmp = canvas.getDevice()->accessBitmap(true); | 105 const SkBitmap& src_bmp = canvas.getDevice()->accessBitmap(true); |
122 SkAutoLockPixels src_lock(src_bmp); | 106 SkAutoLockPixels src_lock(src_bmp); |
123 int retval = StretchDIBits(hdc, | 107 int retval = StretchDIBits(hdc, |
124 0, | 108 0, |
125 0, | 109 0, |
126 size_x, size_y, | 110 width, height, |
127 0, 0, | 111 0, 0, |
128 size_x, size_y, | 112 width, height, |
129 src_bmp.getPixels(), | 113 src_bmp.getPixels(), |
130 reinterpret_cast<BITMAPINFO*>(&bitmap_header), | 114 reinterpret_cast<BITMAPINFO*>(&bitmap_header), |
131 DIB_RGB_COLORS, | 115 DIB_RGB_COLORS, |
132 SRCCOPY); | 116 SRCCOPY); |
133 DCHECK(retval != GDI_ERROR); | 117 DCHECK(retval != GDI_ERROR); |
134 #else | 118 #else |
135 // 100% GDI based. | 119 // 100% GDI based. |
136 skia::VectorCanvas canvas(hdc, size_x, size_y); | 120 skia::VectorCanvas canvas(hdc, width, height); |
137 float webkit_shrink = frame->printPage(params.page_number, &canvas); | 121 float webkit_scale_factor = frame->printPage(page_number, &canvas); |
138 if (shrink <= 0 || webkit_shrink <= 0) { | 122 if (scale_factor <= 0 || webkit_scale_factor <= 0) { |
139 NOTREACHED() << "Printing page " << params.page_number << " failed."; | 123 NOTREACHED() << "Printing page " << page_number << " failed."; |
140 } else { | 124 } else { |
141 // Update the dpi adjustment with the "page shrink" calculated in webkit. | 125 // Update the dpi adjustment with the "page scale_factor" calculated |
142 shrink /= webkit_shrink; | 126 // in webkit. |
127 scale_factor /= webkit_scale_factor; | |
143 } | 128 } |
144 #endif | 129 #endif |
145 | 130 |
146 // Done printing. Close the device context to retrieve the compiled metafile. | 131 // Done printing. Close the device context to retrieve the compiled metafile. |
147 if (!metafile.CloseDc()) { | 132 if (!metafile.CloseDc()) { |
148 NOTREACHED() << "metafile failed"; | 133 NOTREACHED() << "metafile failed"; |
149 } | 134 } |
150 printing::NativeMetafile* mf = &metafile; | 135 printing::NativeMetafile* mf = &metafile; |
151 printing::NativeMetafile metafile2; | 136 printing::NativeMetafile metafile2; |
152 | 137 |
153 skia::VectorPlatformDevice* platform_device = | 138 skia::VectorPlatformDevice* platform_device = |
154 static_cast<skia::VectorPlatformDevice*>(canvas.getDevice()); | 139 static_cast<skia::VectorPlatformDevice*>(canvas.getDevice()); |
155 if (platform_device->alpha_blend_used() && | 140 if (platform_device->alpha_blend_used() && |
156 !params.params.supports_alpha_blend) { | 141 !params.params.supports_alpha_blend) { |
157 // Page used alpha blend, but printer doesn't support it. Rewrite the | 142 // Page used alpha blend, but printer doesn't support it. Rewrite the |
158 // metafile and flatten out the transparency. | 143 // metafile and flatten out the transparency. |
159 HDC bitmap_dc = CreateCompatibleDC(GetDC(NULL)); | 144 HDC bitmap_dc = CreateCompatibleDC(GetDC(NULL)); |
160 if (!bitmap_dc) { | 145 if (!bitmap_dc) { |
161 NOTREACHED() << "Bitmap DC creation failed"; | 146 NOTREACHED() << "Bitmap DC creation failed"; |
162 } | 147 } |
163 SetGraphicsMode(bitmap_dc, GM_ADVANCED); | 148 SetGraphicsMode(bitmap_dc, GM_ADVANCED); |
164 void* bits = NULL; | 149 void* bits = NULL; |
165 BITMAPINFO hdr; | 150 BITMAPINFO hdr; |
166 gfx::CreateBitmapHeader(size_x, size_y, &hdr.bmiHeader); | 151 gfx::CreateBitmapHeader(width, height, &hdr.bmiHeader); |
167 HBITMAP hbitmap = CreateDIBSection( | 152 HBITMAP hbitmap = CreateDIBSection( |
168 bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0); | 153 bitmap_dc, &hdr, DIB_RGB_COLORS, &bits, NULL, 0); |
169 if (!hbitmap) { | 154 if (!hbitmap) { |
170 NOTREACHED() << "Raster bitmap creation for printing failed"; | 155 NOTREACHED() << "Raster bitmap creation for printing failed"; |
171 } | 156 } |
172 | 157 |
173 HGDIOBJ old_bitmap = SelectObject(bitmap_dc, hbitmap); | 158 HGDIOBJ old_bitmap = SelectObject(bitmap_dc, hbitmap); |
174 RECT rect = {0, 0, size_x, size_y }; | 159 RECT rect = {0, 0, width, height }; |
175 HBRUSH whiteBrush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); | 160 HBRUSH whiteBrush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); |
176 FillRect(bitmap_dc, &rect, whiteBrush); | 161 FillRect(bitmap_dc, &rect, whiteBrush); |
177 | 162 |
178 metafile2.CreateDc(NULL, NULL); | 163 metafile2.CreateDc(NULL, NULL); |
179 HDC hdc = metafile2.hdc(); | 164 HDC hdc = metafile2.hdc(); |
180 DCHECK(hdc); | 165 DCHECK(hdc); |
181 skia::PlatformDevice::InitializeDC(hdc); | 166 skia::PlatformDevice::InitializeDC(hdc); |
182 | 167 |
183 RECT metafile_bounds = metafile.GetBounds().ToRECT(); | 168 RECT metafile_bounds = metafile.GetBounds().ToRECT(); |
184 // Process the old metafile, placing all non-AlphaBlend calls into the | 169 // Process the old metafile, placing all non-AlphaBlend calls into the |
(...skipping 12 matching lines...) Expand all Loading... | |
197 } | 182 } |
198 mf = &metafile2; | 183 mf = &metafile2; |
199 } | 184 } |
200 | 185 |
201 // Get the size of the compiled metafile. | 186 // Get the size of the compiled metafile. |
202 uint32 buf_size = mf->GetDataSize(); | 187 uint32 buf_size = mf->GetDataSize(); |
203 DCHECK_GT(buf_size, 128u); | 188 DCHECK_GT(buf_size, 128u); |
204 ViewHostMsg_DidPrintPage_Params page_params; | 189 ViewHostMsg_DidPrintPage_Params page_params; |
205 page_params.data_size = 0; | 190 page_params.data_size = 0; |
206 page_params.metafile_data_handle = NULL; | 191 page_params.metafile_data_handle = NULL; |
207 page_params.page_number = params.page_number; | 192 page_params.page_number = page_number; |
208 page_params.document_cookie = params.params.document_cookie; | 193 page_params.document_cookie = params.params.document_cookie; |
209 page_params.actual_shrink = shrink; | 194 page_params.actual_shrink = scale_factor; |
210 page_params.page_size = gfx::Size( | 195 page_params.page_size = params.params.page_size; |
211 static_cast<int>(ConvertUnitDouble( | 196 page_params.content_area = gfx::Rect(params.params.margin_left, |
212 content_width_in_points + | 197 params.params.margin_top, params.params.printable_size.width(), |
213 margin_left_in_points + margin_right_in_points, | 198 params.params.printable_size.height()); |
214 kPointsPerInch, params.params.dpi)), | 199 page_params.has_visible_overlays = frame->isPageBoxVisible(page_number); |
215 static_cast<int>(ConvertUnitDouble( | |
216 content_height_in_points + | |
217 margin_top_in_points + margin_bottom_in_points, | |
218 kPointsPerInch, params.params.dpi))); | |
219 page_params.content_area = gfx::Rect( | |
220 static_cast<int>(ConvertUnitDouble( | |
221 margin_left_in_points, kPointsPerInch, params.params.dpi)), | |
222 static_cast<int>(ConvertUnitDouble( | |
223 margin_top_in_points, kPointsPerInch, params.params.dpi)), | |
224 static_cast<int>(ConvertUnitDouble( | |
225 content_width_in_points, kPointsPerInch, params.params.dpi)), | |
226 static_cast<int>(ConvertUnitDouble( | |
227 content_height_in_points, kPointsPerInch, params.params.dpi))); | |
228 page_params.has_visible_overlays = | |
229 frame->isPageBoxVisible(params.page_number); | |
230 base::SharedMemory shared_buf; | 200 base::SharedMemory shared_buf; |
231 | 201 |
232 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx | 202 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx |
233 // Windows 2000/XP: When a page in a spooled file exceeds approximately 350 | 203 // Windows 2000/XP: When a page in a spooled file exceeds approximately 350 |
234 // MB, it can fail to print and not send an error message. | 204 // MB, it can fail to print and not send an error message. |
235 if (buf_size < 350*1024*1024) { | 205 if (buf_size < 350*1024*1024) { |
236 // Allocate a shared memory buffer to hold the generated metafile data. | 206 // Allocate a shared memory buffer to hold the generated metafile data. |
237 if (shared_buf.CreateAndMapAnonymous(buf_size)) { | 207 if (shared_buf.CreateAndMapAnonymous(buf_size)) { |
238 // Copy the bits into shared memory. | 208 // Copy the bits into shared memory. |
239 if (mf->GetData(shared_buf.memory(), buf_size)) { | 209 if (mf->GetData(shared_buf.memory(), buf_size)) { |
(...skipping 12 matching lines...) Expand all Loading... | |
252 mf->CloseEmf(); | 222 mf->CloseEmf(); |
253 if (Send(new ViewHostMsg_DuplicateSection( | 223 if (Send(new ViewHostMsg_DuplicateSection( |
254 routing_id(), | 224 routing_id(), |
255 page_params.metafile_data_handle, | 225 page_params.metafile_data_handle, |
256 &page_params.metafile_data_handle))) { | 226 &page_params.metafile_data_handle))) { |
257 if (!is_preview_) { | 227 if (!is_preview_) { |
258 Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params)); | 228 Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params)); |
259 } | 229 } |
260 } | 230 } |
261 } | 231 } |
OLD | NEW |