diff options
author | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-25 21:02:13 +0000 |
---|---|---|
committer | kmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-25 21:02:13 +0000 |
commit | 8360d3ee40d5defb8b0e0c64fdb136d7eb9c7356 (patch) | |
tree | d7993a771b38da1ca345ba61dafbfdb1ba6b268f | |
parent | 90816dcb6d4110189abd114879f9e7d827d91088 (diff) | |
download | chromium_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.h | 14 | ||||
-rw-r--r-- | chrome/renderer/print_web_view_helper_win.cc | 175 |
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; } |