summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-25 21:02:13 +0000
committerkmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-25 21:02:13 +0000
commit8360d3ee40d5defb8b0e0c64fdb136d7eb9c7356 (patch)
treed7993a771b38da1ca345ba61dafbfdb1ba6b268f
parent90816dcb6d4110189abd114879f9e7d827d91088 (diff)
downloadchromium_src-8360d3ee40d5defb8b0e0c64fdb136d7eb9c7356.zip
chromium_src-8360d3ee40d5defb8b0e0c64fdb136d7eb9c7356.tar.gz
chromium_src-8360d3ee40d5defb8b0e0c64fdb136d7eb9c7356.tar.bz2
Refactor win printing workflow.
As a preparation for print preview workflow, refactored PrintPage() function. Created the following functions: 1. RenderPage(): Renders the page for printing. Handles Alpha blend transparency. 2. CopyMetafileDataToSharedMem(): Copy the metafile data to shared memory. BUG=none TEST=printing works after code changes. Review URL: http://codereview.chromium.org/6321017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72542 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/renderer/print_web_view_helper.h14
-rw-r--r--chrome/renderer/print_web_view_helper_win.cc175
2 files changed, 111 insertions, 78 deletions
diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h
index 9b89dc3..075db13 100644
--- a/chrome/renderer/print_web_view_helper.h
+++ b/chrome/renderer/print_web_view_helper.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,9 +15,9 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebViewClient.h"
-#if defined(OS_MACOSX)
+#if defined(OS_MACOSX) || defined(OS_WIN)
#include "base/shared_memory.h"
-#endif // defined(OS_MACOSX)
+#endif // defined(OS_MACOSX) || defined(OS_WIN)
namespace gfx {
class Size;
@@ -181,6 +181,14 @@ class PrintWebViewHelper : public WebKit::WebViewClient,
void RenderPage(const gfx::Size& page_size, const gfx::Point& content_origin,
const float& scale_factor, int page_number,
WebKit::WebFrame* frame, printing::NativeMetafile* metafile);
+#elif defined(OS_WIN)
+ void RenderPage(const gfx::Size& page_size, float* scale_factor,
+ int page_number, WebKit::WebFrame* frame,
+ scoped_ptr<printing::NativeMetafile>* metafile,
+ bool supports_alpha_blend);
+#endif
+
+#if defined(OS_MACOSX) || defined(OS_WIN)
bool CopyMetafileDataToSharedMem(printing::NativeMetafile* metafile,
base::SharedMemoryHandle* shared_mem_handle);
#endif
diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc
index 286e801..94b622f 100644
--- a/chrome/renderer/print_web_view_helper_win.cc
+++ b/chrome/renderer/print_web_view_helper_win.cc
@@ -1,10 +1,11 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/renderer/print_web_view_helper.h"
#include "base/logging.h"
+#include "base/process_util.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
#include "chrome/renderer/render_view.h"
@@ -66,12 +67,11 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,
const gfx::Size& canvas_size,
WebFrame* frame) {
// Generate a memory-based metafile. It will use the current screen's DPI.
- printing::NativeMetafile metafile;
-
- metafile.CreateDc(NULL, NULL);
- HDC hdc = metafile.hdc();
- DCHECK(hdc);
- skia::PlatformDevice::InitializeDC(hdc);
+ // Each metafile contains a single page.
+ scoped_ptr<printing::NativeMetafile> metafile(new printing::NativeMetafile);
+ metafile->CreateDc(NULL, NULL);
+ DCHECK(metafile->hdc());
+ skia::PlatformDevice::InitializeDC(metafile->hdc());
int page_number = params.page_number;
@@ -88,10 +88,56 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,
// Since WebKit extends the page width depending on the magical |scale_factor|
// we make sure the canvas covers the worst case scenario (x2.0 currently).
// PrintContext will then set the correct clipping region.
- int width = static_cast<int>(content_width_in_points *
- params.params.max_shrink);
- int height = static_cast<int>(content_height_in_points *
- params.params.max_shrink);
+ gfx::Size page_size(
+ static_cast<int>(content_width_in_points * params.params.max_shrink),
+ static_cast<int>(content_height_in_points * params.params.max_shrink));
+
+ // Render page for printing.
+ RenderPage(page_size, &scale_factor, page_number, frame, &metafile,
+ params.params.supports_alpha_blend);
+
+ // Close the device context to retrieve the compiled metafile.
+ if (!metafile->CloseDc())
+ NOTREACHED();
+
+ // Get the size of the compiled metafile.
+ uint32 buf_size = metafile->GetDataSize();
+ DCHECK_GT(buf_size, 128u);
+
+ ViewHostMsg_DidPrintPage_Params page_params;
+ page_params.data_size = 0;
+ page_params.metafile_data_handle = NULL;
+ page_params.page_number = page_number;
+ page_params.document_cookie = params.params.document_cookie;
+ page_params.actual_shrink = scale_factor;
+ page_params.page_size = params.params.page_size;
+ page_params.content_area = gfx::Rect(params.params.margin_left,
+ params.params.margin_top, params.params.printable_size.width(),
+ params.params.printable_size.height());
+ page_params.has_visible_overlays = frame->isPageBoxVisible(page_number);
+
+ if (CopyMetafileDataToSharedMem(metafile.get(),
+ &(page_params.metafile_data_handle))) {
+ page_params.data_size = buf_size;
+ }
+ metafile->CloseEmf();
+ if (Send(new ViewHostMsg_DuplicateSection(
+ routing_id(),
+ page_params.metafile_data_handle,
+ &page_params.metafile_data_handle))) {
+ Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params));
+ }
+}
+
+void PrintWebViewHelper::RenderPage(
+ const gfx::Size& page_size, float* scale_factor, int page_number,
+ WebFrame* frame, scoped_ptr<printing::NativeMetafile>* metafile,
+ bool supports_alpha_blend) {
+ HDC hdc = (*metafile)->hdc();
+ DCHECK(hdc);
+
+ int width = page_size.width();
+ int height = page_size.height();
#if 0
// TODO(maruel): This code is kept for testing until the 100% GDI drawing
// code is stable. maruels use this code's output as a reference when the
@@ -101,12 +147,12 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,
skia::PlatformCanvas canvas(width, height, true);
canvas.drawARGB(255, 255, 255, 255, SkXfermode::kSrc_Mode);
float webkit_scale_factor = frame->printPage(page_number, &canvas);
- if (scale_factor <= 0 || webkit_scale_factor <= 0) {
+ if (*scale_factor <= 0 || webkit_scale_factor <= 0) {
NOTREACHED() << "Printing page " << page_number << " failed.";
} else {
- // Update the dpi adjustment with the "page |scale_factor|" calculated
- // in webkit.
- scale_factor /= webkit_scale_factor;
+ // Update the dpi adjustment with the "page |scale_factor|" calculated in
+ // webkit.
+ *scale_factor /= webkit_scale_factor;
}
// Create a BMP v4 header that we can serialize.
@@ -129,26 +175,24 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,
// 100% GDI based.
skia::VectorCanvas canvas(hdc, width, height);
float webkit_scale_factor = frame->printPage(page_number, &canvas);
- if (scale_factor <= 0 || webkit_scale_factor <= 0) {
+ if (*scale_factor <= 0 || webkit_scale_factor <= 0) {
NOTREACHED() << "Printing page " << page_number << " failed.";
} else {
- // Update the dpi adjustment with the "page scale_factor" calculated
- // in webkit.
- scale_factor /= webkit_scale_factor;
+ // Update the dpi adjustment with the "page |scale_factor|" calculated in
+ // webkit.
+ *scale_factor /= webkit_scale_factor;
}
#endif
- // Done printing. Close the device context to retrieve the compiled metafile.
- if (!metafile.CloseDc()) {
- NOTREACHED() << "metafile failed";
- }
- printing::NativeMetafile* mf = &metafile;
- printing::NativeMetafile metafile2;
-
skia::VectorPlatformDevice* platform_device =
- static_cast<skia::VectorPlatformDevice*>(canvas.getDevice());
- if (platform_device->alpha_blend_used() &&
- !params.params.supports_alpha_blend) {
+ static_cast<skia::VectorPlatformDevice*>(canvas.getDevice());
+ if (platform_device->alpha_blend_used() && !supports_alpha_blend) {
+ // Close the device context to retrieve the compiled metafile.
+ if (!(*metafile)->CloseDc())
+ NOTREACHED();
+
+ scoped_ptr<printing::NativeMetafile> metafile2(
+ new printing::NativeMetafile);
// Page used alpha blend, but printer doesn't support it. Rewrite the
// metafile and flatten out the transparency.
HDC bitmap_dc = CreateCompatibleDC(GetDC(NULL));
@@ -170,72 +214,53 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,
HBRUSH whiteBrush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
FillRect(bitmap_dc, &rect, whiteBrush);
- metafile2.CreateDc(NULL, NULL);
- HDC hdc = metafile2.hdc();
+ metafile2->CreateDc(NULL, NULL);
+ HDC hdc = metafile2->hdc();
DCHECK(hdc);
skia::PlatformDevice::InitializeDC(hdc);
- RECT metafile_bounds = metafile.GetBounds().ToRECT();
+ RECT metafile_bounds = (*metafile)->GetBounds().ToRECT();
// Process the old metafile, placing all non-AlphaBlend calls into the
// new metafile, and copying the results of all the AlphaBlend calls
// from the bitmap DC.
EnumEnhMetaFile(hdc,
- metafile.emf(),
+ (*metafile)->emf(),
EnhMetaFileProc,
&bitmap_dc,
&metafile_bounds);
SelectObject(bitmap_dc, old_bitmap);
-
- if (!metafile2.CloseDc()) {
- NOTREACHED() << "metafile failed";
- }
- mf = &metafile2;
+ metafile->reset(metafile2.release());
}
+}
- // Get the size of the compiled metafile.
- uint32 buf_size = mf->GetDataSize();
- DCHECK_GT(buf_size, 128u);
- ViewHostMsg_DidPrintPage_Params page_params;
- page_params.data_size = 0;
- page_params.metafile_data_handle = NULL;
- page_params.page_number = page_number;
- page_params.document_cookie = params.params.document_cookie;
- page_params.actual_shrink = scale_factor;
- page_params.page_size = params.params.page_size;
- page_params.content_area = gfx::Rect(params.params.margin_left,
- params.params.margin_top, params.params.printable_size.width(),
- params.params.printable_size.height());
- page_params.has_visible_overlays = frame->isPageBoxVisible(page_number);
+bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
+ printing::NativeMetafile* metafile,
+ base::SharedMemoryHandle* shared_mem_handle) {
+ uint32 buf_size = metafile->GetDataSize();
base::SharedMemory shared_buf;
// http://msdn2.microsoft.com/en-us/library/ms535522.aspx
// Windows 2000/XP: When a page in a spooled file exceeds approximately 350
// MB, it can fail to print and not send an error message.
- if (buf_size < 350*1024*1024) {
- // Allocate a shared memory buffer to hold the generated metafile data.
- if (shared_buf.CreateAndMapAnonymous(buf_size)) {
- // Copy the bits into shared memory.
- if (mf->GetData(shared_buf.memory(), buf_size)) {
- page_params.metafile_data_handle = shared_buf.handle();
- page_params.data_size = buf_size;
- } else {
- NOTREACHED() << "GetData() failed";
- }
- shared_buf.Unmap();
- } else {
- NOTREACHED() << "Buffer allocation failed";
- }
- } else {
+ if (buf_size >= 350*1024*1024) {
NOTREACHED() << "Buffer too large: " << buf_size;
+ return false;
}
- mf->CloseEmf();
- if (Send(new ViewHostMsg_DuplicateSection(
- routing_id(),
- page_params.metafile_data_handle,
- &page_params.metafile_data_handle))) {
- if (!is_preview_) {
- Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params));
- }
+
+ // Allocate a shared memory buffer to hold the generated metafile data.
+ if (!shared_buf.CreateAndMapAnonymous(buf_size)) {
+ NOTREACHED() << "Buffer allocation failed";
+ return false;
+ }
+
+ // Copy the bits into shared memory.
+ if (!metafile->GetData(shared_buf.memory(), buf_size)) {
+ NOTREACHED() << "GetData() failed";
+ shared_buf.Unmap();
+ return false;
}
+ shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), shared_mem_handle);
+ shared_buf.Unmap();
+ return true;
}