diff options
author | dpapad@chromium.org <dpapad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-02 19:25:17 +0000 |
---|---|---|
committer | dpapad@chromium.org <dpapad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-02 19:25:17 +0000 |
commit | 5ad7617cd93b48a67395f532b8483b8ace445ca2 (patch) | |
tree | ef6ec65870ccdea737de7e0fdcf1d89e2d887511 | |
parent | f83773f72845ed180a23dcbbfa9afbc3c295f758 (diff) | |
download | chromium_src-5ad7617cd93b48a67395f532b8483b8ace445ca2.zip chromium_src-5ad7617cd93b48a67395f532b8483b8ace445ca2.tar.gz chromium_src-5ad7617cd93b48a67395f532b8483b8ace445ca2.tar.bz2 |
Applying factory pattern (through NativeMetafileFactory class). It is used to retrieve different printing contexts (based on the platform and user preferences).
BUG=NONE
TEST=NONE
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=76553
Reverted: http://src.chromium.org/viewvc/chrome?view=rev&revision=76555
Review URL: http://codereview.chromium.org/6544028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76581 0039d316-1c4b-4281-b951-d872f2087c98
30 files changed, 621 insertions, 214 deletions
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc index 8a8de31..42b0500 100644 --- a/chrome/browser/printing/print_view_manager.cc +++ b/chrome/browser/printing/print_view_manager.cc @@ -18,6 +18,7 @@ #include "content/browser/tab_contents/navigation_entry.h" #include "content/browser/tab_contents/tab_contents.h" #include "grit/generated_resources.h" +#include "printing/native_metafile_factory.h" #include "printing/native_metafile.h" #include "printing/printed_document.h" #include "ui/base/l10n/l10n_util.h" @@ -130,7 +131,7 @@ void PrintViewManager::OnDidPrintPage( } } - scoped_ptr<NativeMetafile> metafile(new NativeMetafile()); + scoped_ptr<NativeMetafile> metafile(NativeMetafileFactory::CreateMetafile()); if (metafile_must_be_valid) { if (!metafile->Init(shared_buf.memory(), params.data_size)) { NOTREACHED() << "Invalid metafile header"; diff --git a/chrome/common/common_param_traits_unittest.cc b/chrome/common/common_param_traits_unittest.cc index 9a95c0f0..1dd62f6 100644 --- a/chrome/common/common_param_traits_unittest.cc +++ b/chrome/common/common_param_traits_unittest.cc @@ -14,12 +14,16 @@ #include "ipc/ipc_message_utils.h" #include "net/base/host_port_pair.h" #include "printing/backend/print_backend.h" -#include "printing/native_metafile.h" #include "printing/page_range.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/rect.h" +#if defined(OS_WIN) +#include "printing/native_metafile_factory.h" +#include "printing/native_metafile.h" +#endif + // Tests that serialize/deserialize correctly understand each other TEST(IPCMessageTest, Serialize) { const char* serialize_cases[] = { @@ -227,42 +231,45 @@ TEST(IPCMessageTest, PageRange) { EXPECT_TRUE(input == output); } -// Tests printing::NativeMetafile serialization. +// Tests printing::Emf serialization. // TODO(sanjeevr): Make this test meaningful for non-Windows platforms. We // need to initialize the metafile using alternate means on the other OSes. #if defined(OS_WIN) TEST(IPCMessageTest, Metafile) { - printing::NativeMetafile metafile; + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); RECT test_rect = {0, 0, 100, 100}; - // Create a metsfile using the screen DC as a reference. - metafile.CreateDc(NULL, NULL); - metafile.CloseDc(); + // Create a metafile using the screen DC as a reference. + metafile->CreateDc(NULL, NULL); + metafile->CloseDc(); IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); - IPC::ParamTraits<printing::NativeMetafile>::Write(&msg, metafile); + IPC::ParamTraits<printing::NativeMetafile>::Write(&msg, *metafile); - printing::NativeMetafile output; + scoped_ptr<printing::NativeMetafile> output( + printing::NativeMetafileFactory::CreateMetafile()); void* iter = NULL; EXPECT_TRUE(IPC::ParamTraits<printing::NativeMetafile>::Read( - &msg, &iter, &output)); + &msg, &iter, output.get())); - EXPECT_EQ(metafile.GetDataSize(), output.GetDataSize()); - EXPECT_EQ(metafile.GetBounds(), output.GetBounds()); - EXPECT_EQ(::GetDeviceCaps(metafile.hdc(), LOGPIXELSX), - ::GetDeviceCaps(output.hdc(), LOGPIXELSX)); + EXPECT_EQ(metafile->GetDataSize(), output->GetDataSize()); + EXPECT_EQ(metafile->GetBounds(), output->GetBounds()); + EXPECT_EQ(::GetDeviceCaps(metafile->hdc(), LOGPIXELSX), + ::GetDeviceCaps(output->hdc(), LOGPIXELSX)); // Also test the corrupt case. IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL); // Write some bogus metafile data. - const size_t bogus_data_size = metafile.GetDataSize() * 2; + const size_t bogus_data_size = metafile->GetDataSize() * 2; scoped_array<char> bogus_data(new char[bogus_data_size]); memset(bogus_data.get(), 'B', bogus_data_size); bad_msg.WriteData(bogus_data.get(), bogus_data_size); // Make sure we don't read out the metafile! - printing::NativeMetafile bad_output; + scoped_ptr<printing::NativeMetafile> bad_output( + printing::NativeMetafileFactory::CreateMetafile()); iter = NULL; EXPECT_FALSE(IPC::ParamTraits<printing::NativeMetafile>::Read( - &bad_msg, &iter, &bad_output)); + &bad_msg, &iter, bad_output.get())); } #endif // defined(OS_WIN) diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc index 6b0f39a..75a3dc8 100644 --- a/chrome/plugin/webplugin_delegate_stub.cc +++ b/chrome/plugin/webplugin_delegate_stub.cc @@ -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. @@ -14,7 +14,6 @@ #include "chrome/plugin/plugin_channel.h" #include "chrome/plugin/plugin_thread.h" #include "chrome/plugin/webplugin_proxy.h" -#include "printing/native_metafile.h" #include "third_party/npapi/bindings/npapi.h" #include "third_party/npapi/bindings/npruntime.h" #include "skia/ext/platform_device.h" @@ -23,6 +22,12 @@ #include "webkit/plugins/npapi/webplugin_delegate_impl.h" #include "webkit/glue/webcursor.h" +#if defined(OS_WIN) +#include "base/scoped_ptr.h" +#include "printing/native_metafile_factory.h" +#include "printing/native_metafile.h" +#endif // defined(OS_WIN) + #if defined(ENABLE_GPU) #include "app/gfx/gl/gl_context.h" #endif @@ -281,26 +286,27 @@ void WebPluginDelegateStub::OnDidPaint() { void WebPluginDelegateStub::OnPrint(base::SharedMemoryHandle* shared_memory, uint32* size) { #if defined(OS_WIN) - printing::NativeMetafile metafile; - if (!metafile.CreateDc(NULL, NULL)) { + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); + if (!metafile->CreateDc(NULL, NULL)) { NOTREACHED(); return; } - HDC hdc = metafile.hdc(); + HDC hdc = metafile->hdc(); skia::PlatformDevice::InitializeDC(hdc); delegate_->Print(hdc); - if (!metafile.CloseDc()) { + if (!metafile->CloseDc()) { NOTREACHED(); return; } - *size = metafile.GetDataSize(); + *size = metafile->GetDataSize(); DCHECK(*size); base::SharedMemory shared_buf; CreateSharedBuffer(*size, &shared_buf, shared_memory); // Retrieve a copy of the data. - bool success = metafile.GetData(shared_buf.memory(), *size); + bool success = metafile->GetData(shared_buf.memory(), *size); DCHECK(success); #else // TODO(port): plugin printing. diff --git a/chrome/renderer/mock_printer.cc b/chrome/renderer/mock_printer.cc index b579f88..4510bfc 100644 --- a/chrome/renderer/mock_printer.cc +++ b/chrome/renderer/mock_printer.cc @@ -9,6 +9,8 @@ #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" #include "ipc/ipc_message_utils.h" +#include "printing/native_metafile_factory.h" +#include "printing/native_metafile.h" #include "printing/units.h" #include "testing/gtest/include/gtest/gtest.h" @@ -131,9 +133,10 @@ void MockPrinter::PrintPage(const ViewHostMsg_DidPrintPage_Params& params) { base::SharedMemory metafile_data(params.metafile_data_handle, true); #endif metafile_data.Map(params.data_size); - printing::NativeMetafile metafile; - metafile.Init(metafile_data.memory(), params.data_size); - printing::Image image(metafile); + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); + metafile->Init(metafile_data.memory(), params.data_size); + printing::Image image(*metafile); MockPrinterPage* page_data = new MockPrinterPage(metafile_data.memory(), params.data_size, image); diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc index c4446d3..8fec47f 100644 --- a/chrome/renderer/print_web_view_helper_linux.cc +++ b/chrome/renderer/print_web_view_helper_linux.cc @@ -6,8 +6,10 @@ #include "base/file_descriptor_posix.h" #include "base/logging.h" +#include "base/scoped_ptr.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" +#include "printing/native_metafile_factory.h" #include "printing/native_metafile.h" #include "skia/ext/vector_canvas.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" @@ -23,14 +25,15 @@ void PrintWebViewHelper::CreatePreviewDocument( const ViewMsg_PrintPages_Params& params, WebFrame* frame) { // We only can use PDF in the renderer because Cairo needs to create a // temporary file for a PostScript surface. - printing::NativeMetafile metafile; + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); int page_count = 0; - if (!RenderPages(params, frame, false, &page_count, &metafile)) + if (!RenderPages(params, frame, false, &page_count, metafile.get())) return; // Get the size of the resulting metafile. - uint32 buf_size = metafile.GetDataSize(); + uint32 buf_size = metafile->GetDataSize(); DCHECK_GT(buf_size, 0u); ViewHostMsg_DidPreviewDocument_Params preview_params; @@ -38,7 +41,7 @@ void PrintWebViewHelper::CreatePreviewDocument( preview_params.expected_pages_count = page_count; preview_params.data_size = buf_size; - if (!CopyMetafileDataToSharedMem(&metafile, + if (!CopyMetafileDataToSharedMem(metafile.get(), &(preview_params.metafile_data_handle))) { preview_params.expected_pages_count = 0; preview_params.data_size = 0; @@ -51,7 +54,8 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, WebNode* node) { // We only can use PDF in the renderer because Cairo needs to create a // temporary file for a PostScript surface. - printing::NativeMetafile metafile; + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); int page_count = 0; bool send_expected_page_count = #if defined(OS_CHROMEOS) @@ -61,12 +65,12 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, #endif // defined(OS_CHROMEOS) if (!RenderPages(params, frame, send_expected_page_count, &page_count, - &metafile)) { + metafile.get())) { return; } // Get the size of the resulting metafile. - uint32 buf_size = metafile.GetDataSize(); + uint32 buf_size = metafile->GetDataSize(); DCHECK_GT(buf_size, 0u); #if defined(OS_CHROMEOS) @@ -78,7 +82,7 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, &sequence_number))) { return; } - if (!metafile.SaveTo(fd)) + if (!metafile->SaveTo(fd)) return; // Tell the browser we've finished writing the file. @@ -105,7 +109,7 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params, NOTREACHED() << "Map failed"; return; } - metafile.GetData(shared_buf.memory(), buf_size); + metafile->GetData(shared_buf.memory(), buf_size); printed_page_params.data_size = buf_size; shared_buf.GiveToProcess(base::GetCurrentProcessHandle(), &(printed_page_params.metafile_data_handle)); diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm index 4abae95..4dc218c 100644 --- a/chrome/renderer/print_web_view_helper_mac.mm +++ b/chrome/renderer/print_web_view_helper_mac.mm @@ -7,8 +7,11 @@ #import <AppKit/AppKit.h> #include "base/logging.h" +#include "base/scoped_ptr.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" +#include "printing/native_metafile_factory.h" +#include "printing/native_metafile.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" using WebKit::WebFrame; @@ -16,8 +19,9 @@ using WebKit::WebFrame; void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, const gfx::Size& canvas_size, WebFrame* frame) { - printing::NativeMetafile metafile; - if (!metafile.Init()) + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); + if (!metafile->Init()) return; float scale_factor = frame->getPrintPageShrink(params.page_number); @@ -26,11 +30,11 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, // Render page for printing. gfx::Point origin(0.0f, 0.0f); RenderPage(params.params.printable_size, origin, scale_factor, page_number, - frame, &metafile); - metafile.Close(); + frame, metafile.get()); + metafile->Close(); ViewHostMsg_DidPrintPage_Params page_params; - page_params.data_size = metafile.GetDataSize(); + page_params.data_size = metafile->GetDataSize(); page_params.page_number = page_number; page_params.document_cookie = params.params.document_cookie; page_params.actual_shrink = scale_factor; @@ -41,7 +45,7 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, params.params.printable_size.height()); // Ask the browser to create the shared memory for us. - if (!CopyMetafileDataToSharedMem(&metafile, + if (!CopyMetafileDataToSharedMem(metafile.get(), &(page_params.metafile_data_handle))) { page_params.data_size = 0; } @@ -61,8 +65,9 @@ void PrintWebViewHelper::CreatePreviewDocument( if (!page_count) return; - printing::NativeMetafile metafile; - if (!metafile.Init()) + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); + if (!metafile->Init()) return; float scale_factor = frame->getPrintPageShrink(0); @@ -70,25 +75,25 @@ void PrintWebViewHelper::CreatePreviewDocument( if (params.pages.empty()) { for (int i = 0; i < page_count; ++i) { RenderPage(printParams.page_size, origin, scale_factor, i, frame, - &metafile); + metafile.get()); } } else { for (size_t i = 0; i < params.pages.size(); ++i) { if (params.pages[i] >= page_count) break; RenderPage(printParams.page_size, origin, scale_factor, - static_cast<int>(params.pages[i]), frame, &metafile); + static_cast<int>(params.pages[i]), frame, metafile.get()); } } - metafile.Close(); + metafile->Close(); ViewHostMsg_DidPreviewDocument_Params preview_params; - preview_params.data_size = metafile.GetDataSize(); + preview_params.data_size = metafile->GetDataSize(); preview_params.document_cookie = params.params.document_cookie; preview_params.expected_pages_count = page_count; // Ask the browser to create the shared memory for us. - if (!CopyMetafileDataToSharedMem(&metafile, + if (!CopyMetafileDataToSharedMem(metafile.get(), &(preview_params.metafile_data_handle))) { preview_params.data_size = 0; preview_params.expected_pages_count = 0; diff --git a/chrome/renderer/print_web_view_helper_win.cc b/chrome/renderer/print_web_view_helper_win.cc index ccce2e9..e0332c8 100644 --- a/chrome/renderer/print_web_view_helper_win.cc +++ b/chrome/renderer/print_web_view_helper_win.cc @@ -8,6 +8,8 @@ #include "base/process_util.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_messages_params.h" +#include "printing/native_metafile_factory.h" +#include "printing/native_metafile.h" #include "printing/units.h" #include "skia/ext/vector_canvas.h" #include "skia/ext/vector_platform_device.h" @@ -67,7 +69,8 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params, WebFrame* frame) { // Generate a memory-based metafile. It will use the current screen's DPI. // Each metafile contains a single page. - scoped_ptr<printing::NativeMetafile> metafile(new printing::NativeMetafile); + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); metafile->CreateDc(NULL, NULL); DCHECK(metafile->hdc()); skia::PlatformDevice::InitializeDC(metafile->hdc()); @@ -133,7 +136,8 @@ void PrintWebViewHelper::CreatePreviewDocument( // PDF backend" work is completed for windows, make changes to replace this // EMF with PDF metafile. // http://code.google.com/p/chromium/issues/detail?id=62889 - scoped_ptr<printing::NativeMetafile> metafile(new printing::NativeMetafile); + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); metafile->CreateDc(NULL, NULL); DCHECK(metafile->hdc()); skia::PlatformDevice::InitializeDC(metafile->hdc()); @@ -258,7 +262,7 @@ void PrintWebViewHelper::RenderPage( NOTREACHED(); scoped_ptr<printing::NativeMetafile> metafile2( - new printing::NativeMetafile); + printing::NativeMetafileFactory::CreateMetafile()); // Page used alpha blend, but printer doesn't support it. Rewrite the // metafile and flatten out the transparency. HDC bitmap_dc = CreateCompatibleDC(GetDC(NULL)); diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc index 921138f..43709f8 100644 --- a/chrome/renderer/webplugin_delegate_pepper.cc +++ b/chrome/renderer/webplugin_delegate_pepper.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 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,18 +15,12 @@ #include "base/file_path.h" #include "base/file_util.h" -#if defined(OS_MACOSX) -#include "base/mac/mac_util.h" -#endif #include "base/md5.h" #include "base/message_loop.h" #include "base/metrics/histogram.h" #include "base/metrics/stats_counters.h" #include "base/path_service.h" #include "base/process_util.h" -#if defined(OS_MACOSX) -#include "base/mac/scoped_cftyperef.h" -#endif #include "base/scoped_ptr.h" #include "base/string_number_conversions.h" #include "base/string_util.h" @@ -39,17 +33,9 @@ #include "chrome/renderer/pepper_widget.h" #include "chrome/renderer/render_thread.h" #include "chrome/renderer/render_view.h" -#if defined(OS_LINUX) -#include "chrome/renderer/renderer_sandbox_support_linux.h" -#endif #include "chrome/renderer/webplugin_delegate_proxy.h" #include "ui/gfx/blit.h" -#if defined(OS_WIN) -#include "printing/units.h" -#include "skia/ext/vector_platform_device.h" -#include "ui/gfx/codec/jpeg_codec.h" -#include "ui/gfx/gdi_util.h" -#endif +#include "printing/native_metafile_factory.h" #include "printing/native_metafile.h" #include "third_party/npapi/bindings/npapi_extensions.h" #include "third_party/npapi/bindings/npapi_extensions_private.h" @@ -64,6 +50,19 @@ #include "webkit/plugins/npapi/plugin_host.h" #include "webkit/plugins/npapi/plugin_stream_url.h" +#if defined(OS_MACOSX) +#include "base/mac/mac_util.h" +#include "base/mac/scoped_cftyperef.h" +#elif defined(OS_LINUX) +#include "chrome/renderer/renderer_sandbox_support_linux.h" +#include "printing/pdf_ps_metafile_cairo.h" +#elif defined(OS_WIN) +#include "printing/units.h" +#include "skia/ext/vector_platform_device.h" +#include "ui/gfx/codec/jpeg_codec.h" +#include "ui/gfx/gdi_util.h" +#endif + #if defined(ENABLE_GPU) #include "webkit/plugins/npapi/plugin_constants_win.h" #endif @@ -1222,7 +1221,7 @@ bool WebPluginDelegatePepper::VectorPrintPage(int page_number, // directly. cairo_t* context = canvas->beginPlatformPaint(); printing::NativeMetafile* metafile = - printing::NativeMetafile::FromCairoContext(context); + printing::PdfPsMetafile::FromCairoContext(context); DCHECK(metafile); if (metafile) { ret = metafile->SetRawData(pdf_output, output_size); @@ -1231,14 +1230,15 @@ bool WebPluginDelegatePepper::VectorPrintPage(int page_number, } canvas->endPlatformPaint(); #elif defined(OS_MACOSX) - printing::NativeMetafile metafile; + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); // Create a PDF metafile and render from there into the passed in context. - if (metafile.Init(pdf_output, output_size)) { + if (metafile->Init(pdf_output, output_size)) { // Flip the transform. CGContextSaveGState(canvas); CGContextTranslateCTM(canvas, 0, current_printable_area_.height()); CGContextScaleCTM(canvas, 1.0, -1.0); - ret = metafile.RenderPage(1, canvas, current_printable_area_.ToCGRect(), + ret = metafile->RenderPage(1, canvas, current_printable_area_.ToCGRect(), true, false, true, true); CGContextRestoreGState(canvas); } diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc index 0c98871..bc65843 100644 --- a/chrome/renderer/webplugin_delegate_proxy.cc +++ b/chrome/renderer/webplugin_delegate_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 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,6 +15,7 @@ #include "base/file_util.h" #include "base/logging.h" #include "base/ref_counted.h" +#include "base/scoped_ptr.h" #include "base/string_split.h" #include "base/string_util.h" #include "base/sys_info.h" @@ -33,7 +34,6 @@ #include "grit/renderer_resources.h" #include "ipc/ipc_channel_handle.h" #include "net/base/mime_util.h" -#include "printing/native_metafile.h" #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" @@ -54,6 +54,11 @@ #include "ipc/ipc_channel_posix.h" #endif +#if defined(OS_WIN) +#include "printing/native_metafile_factory.h" +#include "printing/native_metafile.h" +#endif + using WebKit::WebBindings; using WebKit::WebCursorInfo; using WebKit::WebDragData; @@ -926,13 +931,14 @@ void WebPluginDelegateProxy::Print(gfx::NativeDrawingContext context) { } #if defined(OS_WIN) - printing::NativeMetafile metafile; - if (!metafile.Init(memory.memory(), size)) { + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); + if (!metafile->Init(memory.memory(), size)) { NOTREACHED(); return; } // Playback the buffer. - metafile.Playback(context, NULL); + metafile->Playback(context, NULL); #else // TODO(port): plugin printing. NOTIMPLEMENTED(); diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc index b63e27f..a340d8d 100644 --- a/chrome/service/service_utility_process_host.cc +++ b/chrome/service/service_utility_process_host.cc @@ -13,13 +13,15 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/utility_messages.h" #include "ipc/ipc_switches.h" -#include "printing/native_metafile.h" #include "printing/page_range.h" #include "ui/base/ui_base_switches.h" #include "ui/gfx/rect.h" #if defined(OS_WIN) +#include "base/scoped_ptr.h" #include "base/win/scoped_handle.h" +#include "printing/native_metafile_factory.h" +#include "printing/native_metafile.h" #endif ServiceUtilityProcessHost::ServiceUtilityProcessHost( @@ -202,13 +204,15 @@ void ServiceUtilityProcessHost::Client::MetafileAvailable( if (!scratch_metafile_dir.Set(metafile_path.DirName())) LOG(WARNING) << "Unable to set scratch metafile directory"; #if defined(OS_WIN) - printing::NativeMetafile metafile; - if (!metafile.CreateFromFile(metafile_path)) { + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); + if (!metafile->CreateFromFile(metafile_path)) { OnRenderPDFPagesToMetafileFailed(); } else { - OnRenderPDFPagesToMetafileSucceeded(metafile, highest_rendered_page_number); + OnRenderPDFPagesToMetafileSucceeded(*metafile, + highest_rendered_page_number); // Close it so that ScopedTempDir can delete the folder. - metafile.CloseEmf(); + metafile->CloseEmf(); } #endif // defined(OS_WIN) } diff --git a/chrome/utility/utility_thread.cc b/chrome/utility/utility_thread.cc index 6d078e3..0556cbb 100644 --- a/chrome/utility/utility_thread.cc +++ b/chrome/utility/utility_thread.cc @@ -18,7 +18,6 @@ #include "chrome/common/serialized_script_value.h" #include "chrome/common/utility_messages.h" #include "chrome/common/web_resource/web_resource_unpacker.h" -#include "printing/native_metafile.h" #include "printing/page_range.h" #include "printing/units.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -29,7 +28,10 @@ #if defined(OS_WIN) #include "app/win/iat_patch_function.h" +#include "base/scoped_ptr.h" #include "base/win/scoped_handle.h" +#include "printing/native_metafile_factory.h" +#include "printing/native_metafile.h" #endif namespace { @@ -135,10 +137,15 @@ void UtilityThread::OnRenderPDFPagesToMetafile( const std::vector<printing::PageRange>& page_ranges) { bool succeeded = false; #if defined(OS_WIN) - printing::NativeMetafile metafile; + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); int highest_rendered_page_number = 0; - succeeded = RenderPDFToWinMetafile(pdf_file, metafile_path, render_area, - render_dpi, page_ranges, &metafile, + succeeded = RenderPDFToWinMetafile(pdf_file, + metafile_path, + render_area, + render_dpi, + page_ranges, + metafile.get(), &highest_rendered_page_number); if (succeeded) { Send(new UtilityHostMsg_RenderPDFPagesToMetafile_Succeeded( diff --git a/content/browser/renderer_host/render_view_host.cc b/content/browser/renderer_host/render_view_host.cc index 505416e..0e2d5de 100644 --- a/content/browser/renderer_host/render_view_host.cc +++ b/content/browser/renderer_host/render_view_host.cc @@ -45,7 +45,6 @@ #include "content/browser/renderer_host/render_widget_host_view.h" #include "content/browser/site_instance.h" #include "net/base/net_util.h" -#include "printing/native_metafile.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFindOptions.h" #include "ui/gfx/native_widget_types.h" diff --git a/printing/emf_win.h b/printing/emf_win.h index f8a0558..ba139d8 100644 --- a/printing/emf_win.h +++ b/printing/emf_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 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. @@ -9,6 +9,8 @@ #include <vector> #include "base/basictypes.h" +#include "base/gtest_prod_util.h" +#include "printing/native_metafile_win.h" class FilePath; @@ -19,30 +21,31 @@ class Rect; namespace printing { // Simple wrapper class that manage an EMF data stream and its virtual HDC. -class Emf { +class Emf : public NativeMetafile { public: class Record; class Enumerator; struct EnumerationContext; - Emf(); - ~Emf(); + virtual ~Emf(); // Initializes the Emf with the data in |src_buffer|. Returns true on success. - bool Init(const void* src_buffer, uint32 src_buffer_size); + virtual bool Init(const void* src_buffer, uint32 src_buffer_size); // Generates a virtual HDC that will record every GDI commands and compile it // in a EMF data stream. // hdc is used to setup the default DPI and color settings. hdc is optional. // rect specifies the dimensions (in .01-millimeter units) of the EMF. rect is // optional. - bool CreateDc(HDC sibling, const RECT* rect); + virtual bool CreateDc(HDC sibling, const RECT* rect); // Similar to the above method but the metafile is backed by a file. - bool CreateFileBackedDc(HDC sibling, const RECT* rect, const FilePath& path); + virtual bool CreateFileBackedDc(HDC sibling, + const RECT* rect, + const FilePath& path); // Load an EMF file. - bool CreateFromFile(const FilePath& metafile_path); + virtual bool CreateFromFile(const FilePath& metafile_path); // TODO(maruel): CreateFromFile(). If ever used. Maybe users would like to // have the ability to save web pages to an EMF file? Afterward, it is easy to @@ -50,10 +53,10 @@ class Emf { // Closes the HDC created by CreateDc() and generates the compiled EMF // data. - bool CloseDc(); + virtual bool CloseDc(); // Closes the EMF data handle when it is not needed anymore. - void CloseEmf(); + virtual void CloseEmf(); // "Plays" the EMF buffer in a HDC. It is the same effect as calling the // original GDI function that were called when recording the EMF. |rect| is in @@ -63,47 +66,56 @@ class Emf { // functions, whether used directly or indirectly through precompiled EMF // data. We have to accept the risk here. Since it is used only for printing, // it requires user intervention. - bool Playback(HDC hdc, const RECT* rect) const; + virtual bool Playback(HDC hdc, const RECT* rect) const; // The slow version of Playback(). It enumerates all the records and play them // back in the HDC. The trick is that it skip over the records known to have // issue with some printers. See Emf::Record::SafePlayback implementation for // details. - bool SafePlayback(HDC hdc) const; + virtual bool SafePlayback(HDC hdc) const; // Retrieves the bounds of the painted area by this EMF buffer. This value // should be passed to Playback to keep the exact same size. - gfx::Rect GetBounds() const; + virtual gfx::Rect GetBounds() const; // Retrieves the EMF stream size. - uint32 GetDataSize() const; + virtual uint32 GetDataSize() const; // Retrieves the EMF stream. - bool GetData(void* buffer, uint32 size) const; + virtual bool GetData(void* buffer, uint32 size) const; // Retrieves the EMF stream. It is an helper function. - bool GetData(std::vector<uint8>* buffer) const; + virtual bool GetData(std::vector<uint8>* buffer) const; - HENHMETAFILE emf() const { + virtual HENHMETAFILE emf() const { return emf_; } - HDC hdc() const { + virtual HDC hdc() const { return hdc_; } // Inserts a custom GDICOMMENT records indicating StartPage/EndPage calls // (since StartPage and EndPage do not work in a metafile DC). Only valid // when hdc_ is non-NULL. - bool StartPage(); - bool EndPage(); + virtual bool StartPage(); + virtual bool EndPage(); // Saves the EMF data to a file as-is. It is recommended to use the .emf file // extension but it is not enforced. This function synchronously writes to the // file. For testing only. - bool SaveTo(const std::wstring& filename) const; + virtual bool SaveTo(const std::wstring& filename) const; + + protected: + Emf(); private: + friend class NativeMetafileFactory; + FRIEND_TEST_ALL_PREFIXES(EmfTest, DC); + FRIEND_TEST_ALL_PREFIXES(EmfTest, FileBackedDC); + FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, Enumerate); + FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, PageBreak); + // Playbacks safely one EMF record. static int CALLBACK SafePlaybackProc(HDC hdc, HANDLETABLE* handle_table, diff --git a/printing/emf_win_unittest.cc b/printing/emf_win_unittest.cc index 4312b2c..9d3aa00 100644 --- a/printing/emf_win_unittest.cc +++ b/printing/emf_win_unittest.cc @@ -39,6 +39,8 @@ const uint32 EMF_HEADER_SIZE = 128; } // namespace +namespace printing { + TEST(EmfTest, DC) { // Simplest use case. printing::Emf emf; @@ -195,3 +197,4 @@ TEST(EmfTest, FileBackedDC) { emf.CloseEmf(); } +} // namespace printing diff --git a/printing/image.cc b/printing/image.cc index 1116f32..a99e307 100644 --- a/printing/image.cc +++ b/printing/image.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 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. @@ -6,7 +6,9 @@ #include "base/file_util.h" #include "base/md5.h" +#include "base/scoped_ptr.h" #include "base/string_number_conversions.h" +#include "printing/native_metafile_factory.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/codec/png_codec.h" @@ -144,9 +146,10 @@ bool Image::LoadPng(const std::string& compressed) { bool Image::LoadMetafile(const std::string& data) { DCHECK(!data.empty()); - NativeMetafile metafile; - metafile.Init(data.data(), data.size()); - return LoadMetafile(metafile); + scoped_ptr<NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); + metafile->Init(data.data(), data.size()); + return LoadMetafile(*metafile); } } // namespace printing diff --git a/printing/native_metafile.h b/printing/native_metafile.h index b0f957a..7e1d25b 100644 --- a/printing/native_metafile.h +++ b/printing/native_metafile.h @@ -1,50 +1,19 @@ -// 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. #ifndef PRINTING_NATIVE_METAFILE_H_ #define PRINTING_NATIVE_METAFILE_H_ +#include "base/basictypes.h" #include "build/build_config.h" -// Define a metafile format for the current platform. We use this platform -// independent define so we can define interfaces in platform agnostic manner. -// It is still an outstanding design issue whether we create classes on all -// platforms that have the same interface as Emf or if we change Emf to support -// multiple platforms (and rename to NativeMetafile). - - #if defined(OS_WIN) - -#include "printing/emf_win.h" - -namespace printing { - -typedef Emf NativeMetafile; - -} // namespace printing - +#include "printing/native_metafile_win.h" #elif defined(OS_MACOSX) - -#include "printing/pdf_metafile_mac.h" - -namespace printing { - -typedef PdfMetafile NativeMetafile; - -} // namespace printing - +#include "printing/native_metafile_mac.h" #elif defined(OS_POSIX) - -#include "printing/pdf_ps_metafile_cairo.h" - -namespace printing { - -typedef PdfPsMetafile NativeMetafile; - -} // namespace printing - +#include "printing/native_metafile_linux.h" #endif - #endif // PRINTING_NATIVE_METAFILE_H_ diff --git a/printing/native_metafile_factory.cc b/printing/native_metafile_factory.cc new file mode 100644 index 0000000..a41428f --- /dev/null +++ b/printing/native_metafile_factory.cc @@ -0,0 +1,28 @@ +// 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 "printing/native_metafile_factory.h" + +#if defined(OS_WIN) +#include "printing/emf_win.h" +#elif defined(OS_MACOSX) +#include "printing/pdf_metafile_mac.h" +#elif defined(OS_POSIX) +#include "printing/pdf_ps_metafile_cairo.h" +#endif + +namespace printing { + +// static +printing::NativeMetafile* NativeMetafileFactory::CreateMetafile() { +#if defined(OS_WIN) + return new printing::Emf; +#elif defined(OS_MACOSX) + return new printing::PdfMetafile; +#elif defined(OS_POSIX) + return new printing::PdfPsMetafile; +#endif +} + +} // namespace printing diff --git a/printing/native_metafile_factory.h b/printing/native_metafile_factory.h new file mode 100644 index 0000000..d1543c7 --- /dev/null +++ b/printing/native_metafile_factory.h @@ -0,0 +1,30 @@ +// 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. + +#ifndef PRINTING_NATIVE_METAFILE_FACTORY_H_ +#define PRINTING_NATIVE_METAFILE_FACTORY_H_ + +#include "base/basictypes.h" +#include "printing/native_metafile.h" + +namespace printing { + +// Various printing contexts will be supported in the future (cairo, skia, emf). +// So this class returns the appropriate context depending on the platform and +// user preferences. +// (Note: For the moment there is only one option per platform.) +class NativeMetafileFactory { + public: + // This method returns a pointer to the appropriate NativeMetafile object + // according to the platform. + static printing::NativeMetafile* CreateMetafile(); + + private: + NativeMetafileFactory(); + DISALLOW_COPY_AND_ASSIGN(NativeMetafileFactory); +}; + +} // namespace printing + +#endif // PRINTING_NATIVE_METAFILE_FACTORY_H_ diff --git a/printing/native_metafile_linux.h b/printing/native_metafile_linux.h new file mode 100644 index 0000000..9fe622b --- /dev/null +++ b/printing/native_metafile_linux.h @@ -0,0 +1,81 @@ +// 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. + +#ifndef PRINTING_NATIVE_METAFILE_LINUX_H_ +#define PRINTING_NATIVE_METAFILE_LINUX_H_ + +#include "base/basictypes.h" + +typedef struct _cairo_surface cairo_surface_t; +typedef struct _cairo cairo_t; + +namespace base { +struct FileDescriptor; +} + +class FilePath; + +namespace printing { + +// This class is used to generate a PDF stream and to store rendering results +// in a string buffer. +class NativeMetafile { + public: + virtual ~NativeMetafile() {} + + // Initializes to a fresh new metafile. Returns true on success. + // Note: It should only be called from the renderer process to allocate + // rendering resources. + virtual bool Init() = 0; + + // Initializes a copy of metafile from PDF stream data. + // Returns true on success. + // |src_buffer| should point to the shared memory which stores PDF + // contents generated in the renderer. + // Note: It should only be called from the browser process to initialize + // |data_|. + virtual bool Init(const void* src_buffer, uint32 src_buffer_size) = 0; + + // Sets raw PDF data for the document. This is used when a cairo drawing + // surface has already been created. This method will cause all subsequent + // drawing on the surface to be discarded (in Close()). If Init() has not yet + // been called this method simply calls the second version of Init. + virtual bool SetRawData(const void* src_buffer, uint32 src_buffer_size) = 0; + + // Prepares a new cairo surface/context for rendering a new page. + // The unit is in point (=1/72 in). + // Returns NULL when failed. + virtual cairo_t* StartPage(double width_in_points, + double height_in_points, + double margin_top_in_points, + double margin_right_in_points, + double margin_bottom_in_points, + double margin_left_in_points) = 0; + + // Destroys the surface and the context used in rendering current page. + // The results of current page will be appended into buffer |data_|. + // Returns true on success. + virtual bool FinishPage() = 0; + + // Closes resulting PDF file. No further rendering is allowed. + virtual void Close() = 0; + + // Returns size of PDF contents stored in buffer |data_|. + // This function should ONLY be called after PDF file is closed. + virtual uint32 GetDataSize() const = 0; + + // Copies PDF contents stored in buffer |data_| into |dst_buffer|. + // This function should ONLY be called after PDF file is closed. + // Returns true only when success. + virtual bool GetData(void* dst_buffer, uint32 dst_buffer_size) const = 0; + + // Saves PDF contents stored in buffer |data_| into the file + // associated with |fd|. + // This function should ONLY be called after PDF file is closed. + virtual bool SaveTo(const base::FileDescriptor& fd) const = 0; +}; + +} // namespace printing + +#endif // PRINTING_NATIVE_METAFILE_LINUX_H_ diff --git a/printing/native_metafile_mac.h b/printing/native_metafile_mac.h new file mode 100644 index 0000000..940da50 --- /dev/null +++ b/printing/native_metafile_mac.h @@ -0,0 +1,90 @@ +// 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. + +#ifndef PRINTING_NATIVE_METAFILE_MAC_H_ +#define PRINTING_NATIVE_METAFILE_MAC_H_ + +#include <ApplicationServices/ApplicationServices.h> +#include <CoreFoundation/CoreFoundation.h> + +#include "base/basictypes.h" +#include "base/mac/scoped_cftyperef.h" + +namespace gfx { +class Rect; +class Size; +class Point; +} +class FilePath; + +namespace printing { + +// This class creates a graphics context that renders into a PDF data stream. +class NativeMetafile { + public: + + virtual ~NativeMetafile() {} + + // Initializes a new metafile, and returns a drawing context for rendering + // into the PDF. Returns NULL on failure. + // Note: The returned context *must not be retained* past Close(). If it is, + // the data returned from GetData will not be valid PDF data. + virtual CGContextRef Init() = 0; + + // Initializes a copy of metafile from PDF data. Returns true on success. + virtual bool Init(const void* src_buffer, uint32 src_buffer_size) = 0; + + // Prepares a new pdf page at specified |content_origin| with the given + // |page_size| and a |scale_factor| to use for the drawing. + virtual CGContextRef StartPage(const gfx::Size& page_size, + const gfx::Point& content_origin, + const float& scale_factor) = 0; + + // Closes the current page. + virtual void FinishPage() = 0; + + // Closes the PDF file; no further rendering is allowed. + virtual void Close() = 0; + + // Renders the given page into |rect| in the given context. + // Pages use a 1-based index. The rendering uses the following arguments + // to determine scaling and translation factors. + // |shrink_to_fit| specifies whether the output should be shrunk to fit the + // supplied |rect| if the page size is larger than |rect| in any dimension. + // If this is false, parts of the PDF page that lie outside the bounds will be + // clipped. + // |stretch_to_fit| specifies whether the output should be stretched to fit + // the supplied bounds if the page size is smaller than |rect| in all + // dimensions. + // |center_horizontally| specifies whether the final image (after any scaling + // is done) should be centered horizontally within the given |rect|. + // |center_vertically| specifies whether the final image (after any scaling + // is done) should be centered vertically within the given |rect|. + // Note that all scaling preserves the original aspect ratio of the page. + virtual bool RenderPage(unsigned int page_number, CGContextRef context, + const CGRect rect, bool shrink_to_fit, bool stretch_to_fit, + bool center_horizontally, bool center_vertically) const = 0; + virtual unsigned int GetPageCount() const = 0; + + // Returns the bounds of the given page. + // Pages use a 1-based index. + virtual gfx::Rect GetPageBounds(unsigned int page_number) const = 0; + + // Returns the size of the underlying PDF data. Only valid after Close() has + // been called. + virtual uint32 GetDataSize() const = 0; + + // Copies the first |dst_buffer_size| bytes of the PDF data into |dst_buffer|. + // Only valid after Close() has been called. + // Returns true if the copy succeeds. + virtual bool GetData(void* dst_buffer, uint32 dst_buffer_size) const = 0; + + // Saves the raw PDF data to the given file. For testing only. + // Returns true if writing succeeded. + virtual bool SaveTo(const FilePath& file_path) const = 0; +}; + +} // namespace printing + +#endif // PRINTING_NATIVE_METAFILE_MAC_H_ diff --git a/printing/native_metafile_win.h b/printing/native_metafile_win.h new file mode 100644 index 0000000..fa00121 --- /dev/null +++ b/printing/native_metafile_win.h @@ -0,0 +1,103 @@ +// 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. + +#ifndef PRINTING_NATIVE_METAFILE_WIN_H_ +#define PRINTING_NATIVE_METAFILE_WIN_H_ + +#include <windows.h> +#include <vector> + +#include "base/basictypes.h" + +class FilePath; + +namespace gfx { +class Rect; +} + +namespace printing { + +// Simple wrapper class that manages a data stream and its virtual HDC. +class NativeMetafile { + public: + virtual ~NativeMetafile() {} + + // Initializes the data stream with the data in |src_buffer|. Returns + // true on success. + virtual bool Init(const void* src_buffer, uint32 src_buffer_size) = 0; + + // Generates a virtual HDC that will record every GDI commands and compile it + // in a EMF data stream. + // hdc is used to setup the default DPI and color settings. hdc is optional. + // rect specifies the dimensions (in .01-millimeter units) of the EMF. rect is + // optional. + virtual bool CreateDc(HDC sibling, const RECT* rect) = 0; + + // Similar to the above method but the metafile is backed by a file. + virtual bool CreateFileBackedDc(HDC sibling, + const RECT* rect, + const FilePath& path) = 0; + + // Load a data stream from file. + virtual bool CreateFromFile(const FilePath& metafile_path) = 0; + + // TODO(maruel): CreateFromFile(). If ever used. Maybe users would like to + // have the ability to save web pages to an EMF file? Afterward, it is easy to + // convert to PDF. + + // Closes the HDC created by CreateDc() and generates the compiled EMF + // data. + virtual bool CloseDc() = 0; + + // Closes the EMF data handle when it is not needed anymore. + virtual void CloseEmf() = 0; + + // "Plays" the EMF buffer in a HDC. It is the same effect as calling the + // original GDI function that were called when recording the EMF. |rect| is in + // "logical units" and is optional. If |rect| is NULL, the natural EMF bounds + // are used. + // Note: Windows has been known to have stack buffer overflow in its GDI + // functions, whether used directly or indirectly through precompiled EMF + // data. We have to accept the risk here. Since it is used only for printing, + // it requires user intervention. + virtual bool Playback(HDC hdc, const RECT* rect) const = 0; + + // The slow version of Playback(). It enumerates all the records and play them + // back in the HDC. The trick is that it skip over the records known to have + // issue with some printers. See Emf::Record::SafePlayback implementation for + // details. + virtual bool SafePlayback(HDC hdc) const = 0; + + // Retrieves the bounds of the painted area by this EMF buffer. This value + // should be passed to Playback to keep the exact same size. + virtual gfx::Rect GetBounds() const = 0; + + // Retrieves the data stream size. + virtual uint32 GetDataSize() const = 0; + + // Retrieves the data stream. + virtual bool GetData(void* buffer, uint32 size) const = 0; + + // Retrieves the data stream. It is an helper function. + virtual bool GetData(std::vector<uint8>* buffer) const = 0; + + virtual HENHMETAFILE emf() const = 0; + + virtual HDC hdc() const = 0; + + // Inserts a custom GDICOMMENT records indicating StartPage/EndPage calls + // (since StartPage and EndPage do not work in a metafile DC). Only valid + // when hdc_ is non-NULL. + virtual bool StartPage() = 0; + virtual bool EndPage() = 0; + + // Saves the EMF data to a file as-is. It is recommended to use the .emf file + // extension but it is not enforced. This function synchronously writes to the + // file. For testing only. + virtual bool SaveTo(const std::wstring& filename) const = 0; +}; + +} // namespace printing + +#endif // PRINTING_NATIVE_METAFILE_WIN_H_ diff --git a/printing/pdf_metafile_mac.h b/printing/pdf_metafile_mac.h index 557b008..c5669a8 100644 --- a/printing/pdf_metafile_mac.h +++ b/printing/pdf_metafile_mac.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. @@ -9,7 +9,9 @@ #include <CoreFoundation/CoreFoundation.h> #include "base/basictypes.h" +#include "base/gtest_prod_util.h" #include "base/mac/scoped_cftyperef.h" +#include "printing/native_metafile_mac.h" namespace gfx { class Rect; @@ -21,36 +23,31 @@ class FilePath; namespace printing { // This class creates a graphics context that renders into a PDF data stream. -class PdfMetafile { +class PdfMetafile : public NativeMetafile { public: - // To create PDF data, callers should also call Init() to set up the - // rendering context. - // To create a metafile from existing Data, callers should also call - // Init(const void*, uint32). - PdfMetafile(); - ~PdfMetafile(); + virtual ~PdfMetafile(); // Initializes a new metafile, and returns a drawing context for rendering // into the PDF. Returns NULL on failure. // Note: The returned context *must not be retained* past Close(). If it is, // the data returned from GetData will not be valid PDF data. - CGContextRef Init(); + virtual CGContextRef Init(); // Initializes a copy of metafile from PDF data. Returns true on success. - bool Init(const void* src_buffer, uint32 src_buffer_size); + virtual bool Init(const void* src_buffer, uint32 src_buffer_size); // Prepares a new pdf page at specified |content_origin| with the given // |page_size| and a |scale_factor| to use for the drawing. - CGContextRef StartPage(const gfx::Size& page_size, + virtual CGContextRef StartPage(const gfx::Size& page_size, const gfx::Point& content_origin, const float& scale_factor); // Closes the current page. - void FinishPage(); + virtual void FinishPage(); // Closes the PDF file; no further rendering is allowed. - void Close(); + virtual void Close(); // Renders the given page into |rect| in the given context. // Pages use a 1-based index. The rendering uses the following arguments @@ -67,29 +64,39 @@ class PdfMetafile { // |center_vertically| specifies whether the final image (after any scaling // is done) should be centered vertically within the given |rect|. // Note that all scaling preserves the original aspect ratio of the page. - bool RenderPage(unsigned int page_number, CGContextRef context, + virtual bool RenderPage(unsigned int page_number, CGContextRef context, const CGRect rect, bool shrink_to_fit, bool stretch_to_fit, bool center_horizontally, bool center_vertically) const; - unsigned int GetPageCount() const; + virtual unsigned int GetPageCount() const; // Returns the bounds of the given page. // Pages use a 1-based index. - gfx::Rect GetPageBounds(unsigned int page_number) const; + virtual gfx::Rect GetPageBounds(unsigned int page_number) const; // Returns the size of the underlying PDF data. Only valid after Close() has // been called. - uint32 GetDataSize() const; + virtual uint32 GetDataSize() const; // Copies the first |dst_buffer_size| bytes of the PDF data into |dst_buffer|. // Only valid after Close() has been called. // Returns true if the copy succeeds. - bool GetData(void* dst_buffer, uint32 dst_buffer_size) const; + virtual bool GetData(void* dst_buffer, uint32 dst_buffer_size) const; // Saves the raw PDF data to the given file. For testing only. // Returns true if writing succeeded. - bool SaveTo(const FilePath& file_path) const; + virtual bool SaveTo(const FilePath& file_path) const; + + protected: + // To create PDF data, callers should call Init() to set up the rendering + // context. + // To create a metafile from existing data, callers should call + // Init(const void*, uint32). + PdfMetafile(); private: + friend class NativeMetafileFactory; + FRIEND_TEST_ALL_PREFIXES(PdfMetafileTest, Pdf); + // Returns a CGPDFDocumentRef version of pdf_data_. CGPDFDocumentRef GetPDFDocument() const; diff --git a/printing/pdf_metafile_mac_unittest.cc b/printing/pdf_metafile_mac_unittest.cc index ec8cd3a..8b52b06 100644 --- a/printing/pdf_metafile_mac_unittest.cc +++ b/printing/pdf_metafile_mac_unittest.cc @@ -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. @@ -12,6 +12,8 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/rect.h" +namespace printing { + TEST(PdfMetafileTest, Pdf) { // Test in-renderer constructor. printing::PdfMetafile pdf; @@ -60,3 +62,5 @@ TEST(PdfMetafileTest, Pdf) { EXPECT_EQ(720, page_size.width()); EXPECT_EQ(540, page_size.height()); } + +} // namespace printing diff --git a/printing/pdf_ps_metafile_cairo.h b/printing/pdf_ps_metafile_cairo.h index 7274dd8..645a462 100644 --- a/printing/pdf_ps_metafile_cairo.h +++ b/printing/pdf_ps_metafile_cairo.h @@ -8,6 +8,8 @@ #include <string> #include "base/basictypes.h" +#include "base/gtest_prod_util.h" +#include "printing/native_metafile_linux.h" typedef struct _cairo_surface cairo_surface_t; typedef struct _cairo cairo_t; @@ -22,59 +24,58 @@ namespace printing { // This class uses Cairo graphics library to generate PostScript/PDF stream // and stores rendering results in a string buffer. -class PdfPsMetafile { +class PdfPsMetafile : public NativeMetafile { public: - PdfPsMetafile(); - ~PdfPsMetafile(); + virtual ~PdfPsMetafile(); // Initializes to a fresh new metafile. Returns true on success. // Note: Only call in the renderer to allocate rendering resources. - bool Init(); + virtual bool Init(); // Initializes a copy of metafile from PDF stream data. // Returns true on success. // |src_buffer| should point to the shared memory which stores PDF // contents generated in the renderer. // Note: Only call in the browser to initialize |data_|. - bool Init(const void* src_buffer, uint32 src_buffer_size); + virtual bool Init(const void* src_buffer, uint32 src_buffer_size); // Sets raw PDF data for the document. This is used when a cairo drawing // surface has already been created. This method will cause all subsequent // drawing on the surface to be discarded (in Close()). If Init() has not yet // been called this method simply calls the second version of Init. - bool SetRawData(const void* src_buffer, uint32 src_buffer_size); + virtual bool SetRawData(const void* src_buffer, uint32 src_buffer_size); // Prepares a new cairo surface/context for rendering a new page. // The unit is in point (=1/72 in). // Returns NULL when failed. - cairo_t* StartPage(double width_in_points, - double height_in_points, - double margin_top_in_points, - double margin_right_in_points, - double margin_bottom_in_points, - double margin_left_in_points); + virtual cairo_t* StartPage(double width_in_points, + double height_in_points, + double margin_top_in_points, + double margin_right_in_points, + double margin_bottom_in_points, + double margin_left_in_points); // Destroys the surface and the context used in rendering current page. // The results of current page will be appended into buffer |data_|. // Returns true on success. - bool FinishPage(); + virtual bool FinishPage(); // Closes resulting PDF file. No further rendering is allowed. - void Close(); + virtual void Close(); // Returns size of PDF contents stored in buffer |data_|. // This function should ONLY be called after PDF file is closed. - uint32 GetDataSize() const; + virtual uint32 GetDataSize() const; // Copies PDF contents stored in buffer |data_| into |dst_buffer|. // This function should ONLY be called after PDF file is closed. // Returns true only when success. - bool GetData(void* dst_buffer, uint32 dst_buffer_size) const; + virtual bool GetData(void* dst_buffer, uint32 dst_buffer_size) const; // Saves PDF contents stored in buffer |data_| into the file // associated with |fd|. // This function should ONLY be called after PDF file is closed. - bool SaveTo(const base::FileDescriptor& fd) const; + virtual bool SaveTo(const base::FileDescriptor& fd) const; // The hardcoded margins, in points. These values are based on 72 dpi, // with 0.25 margins on top, left, and right, and 0.56 on bottom. @@ -87,7 +88,13 @@ class PdfPsMetafile { // if the context was not created by a PdfPsMetafile object. static PdfPsMetafile* FromCairoContext(cairo_t* context); + protected: + PdfPsMetafile(); + private: + friend class NativeMetafileFactory; + FRIEND_TEST_ALL_PREFIXES(PdfPsTest, Pdf); + // Cleans up all resources. void CleanUpAll(); diff --git a/printing/pdf_ps_metafile_cairo_unittest.cc b/printing/pdf_ps_metafile_cairo_unittest.cc index b7ed449..a3442c8 100644 --- a/printing/pdf_ps_metafile_cairo_unittest.cc +++ b/printing/pdf_ps_metafile_cairo_unittest.cc @@ -15,6 +15,8 @@ typedef struct _cairo cairo_t; +namespace { + class PdfPsTest : public testing::Test { protected: base::FileDescriptor DevNullFD() { @@ -22,6 +24,10 @@ class PdfPsTest : public testing::Test { } }; +} // namespace + +namespace printing { + TEST_F(PdfPsTest, Pdf) { // Tests in-renderer constructor. printing::PdfPsMetafile pdf; @@ -81,3 +87,5 @@ TEST_F(PdfPsTest, Pdf) { pdf3.GetData(WriteInto(&output, size + 1), size); EXPECT_EQ(test_raw_data, output); } + +} // namespace printing diff --git a/printing/print_settings_initializer_gtk.cc b/printing/print_settings_initializer_gtk.cc index 60ab530..8a62929 100644 --- a/printing/print_settings_initializer_gtk.cc +++ b/printing/print_settings_initializer_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 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. @@ -9,7 +9,7 @@ #include "base/string_piece.h" #include "base/utf_string_conversions.h" -#include "printing/native_metafile.h" +#include "printing/pdf_ps_metafile_cairo.h" #include "printing/print_settings.h" #include "printing/units.h" @@ -58,19 +58,19 @@ void PrintSettingsInitializerGtk::InitPrintSettings( double page_width_in_pixel = 8.5 * dpi; double page_height_in_pixel = 11.0 * dpi; physical_size_device_units.SetSize( - static_cast<int>(page_width_in_pixel), - static_cast<int>(page_height_in_pixel)); + static_cast<int>(page_width_in_pixel), + static_cast<int>(page_height_in_pixel)); printable_area_device_units.SetRect( - static_cast<int>( - NativeMetafile::kLeftMarginInInch * dpi), - static_cast<int>( - NativeMetafile::kTopMarginInInch * dpi), - page_width_in_pixel - - (NativeMetafile::kLeftMarginInInch + - NativeMetafile::kRightMarginInInch) * dpi, - page_height_in_pixel - - (NativeMetafile::kTopMarginInInch + - NativeMetafile::kBottomMarginInInch) * dpi); + static_cast<int>( + PdfPsMetafile::kLeftMarginInInch * dpi), + static_cast<int>( + PdfPsMetafile::kTopMarginInInch * dpi), + page_width_in_pixel - + (PdfPsMetafile::kLeftMarginInInch + + PdfPsMetafile::kRightMarginInInch) * dpi, + page_height_in_pixel - + (PdfPsMetafile::kTopMarginInInch + + PdfPsMetafile::kBottomMarginInInch) * dpi); } print_settings->set_dpi(dpi); diff --git a/printing/printed_document.h b/printing/printed_document.h index f95ddcf..14e5e8c 100644 --- a/printing/printed_document.h +++ b/printing/printed_document.h @@ -13,7 +13,6 @@ #include "base/synchronization/lock.h" #include "googleurl/src/gurl.h" #include "printing/print_settings.h" -#include "printing/native_metafile.h" #include "ui/gfx/native_widget_types.h" class FilePath; @@ -25,6 +24,7 @@ class Font; namespace printing { +class NativeMetafile; class PrintedPage; class PrintedPagesSource; class PrintingContext; diff --git a/printing/printing.gyp b/printing/printing.gyp index 270306f..9201e69 100644 --- a/printing/printing.gyp +++ b/printing/printing.gyp @@ -1,4 +1,4 @@ -# Copyright (c) 2010 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. @@ -36,6 +36,11 @@ 'image_mac.cc', 'image_win.cc', 'image.h', + 'native_metafile_factory.cc', + 'native_metafile_factory.h', + 'native_metafile_linux.h', + 'native_metafile_mac.h', + 'native_metafile_win.h', 'native_metafile.h', 'page_number.cc', 'page_number.h', diff --git a/printing/printing_context_cairo.cc b/printing/printing_context_cairo.cc index d0110b1..84aaa64 100644 --- a/printing/printing_context_cairo.cc +++ b/printing/printing_context_cairo.cc @@ -9,7 +9,9 @@ #if defined(OS_CHROMEOS) #include <unicode/ulocdata.h> -#include <printing/native_metafile.h> + +#include "printing/native_metafile.h" +#include "printing/pdf_ps_metafile_cairo.h" #else #include <gtk/gtk.h> #include <gtk/gtkprintunixdialog.h> @@ -119,12 +121,12 @@ PrintingContext::Result PrintingContextCairo::UseDefaultSettings() { physical_size_device_units.SetSize(width, height); printable_area_device_units.SetRect( - static_cast<int>(NativeMetafile::kLeftMarginInInch * dpi), - static_cast<int>(NativeMetafile::kTopMarginInInch * dpi), - width - (NativeMetafile::kLeftMarginInInch + - NativeMetafile::kRightMarginInInch) * dpi, - height - (NativeMetafile::kTopMarginInInch + - NativeMetafile::kBottomMarginInInch) * dpi); + static_cast<int>(PdfPsMetafile::kLeftMarginInInch * dpi), + static_cast<int>(PdfPsMetafile::kTopMarginInInch * dpi), + width - (PdfPsMetafile::kLeftMarginInInch + + PdfPsMetafile::kRightMarginInInch) * dpi, + height - (PdfPsMetafile::kTopMarginInInch + + PdfPsMetafile::kBottomMarginInInch) * dpi); settings_.set_dpi(dpi); settings_.SetPrinterPrintableArea(physical_size_device_units, diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc index bd4264c..3c24dfb 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc @@ -22,7 +22,6 @@ #include "ppapi/c/ppb_core.h" #include "ppapi/c/ppb_instance.h" #include "ppapi/c/ppp_instance.h" -#include "printing/native_metafile.h" #include "printing/units.h" #include "skia/ext/vector_platform_device.h" #include "skia/ext/platform_canvas.h" @@ -54,9 +53,18 @@ #include "webkit/plugins/ppapi/string.h" #include "webkit/plugins/ppapi/var.h" +#if defined(OS_POSIX) +#include "printing/native_metafile.h" +#endif + #if defined(OS_MACOSX) #include "base/mac/mac_util.h" #include "base/mac/scoped_cftyperef.h" +#include "printing/native_metafile_factory.h" +#endif + +#if defined(OS_LINUX) +#include "printing/pdf_ps_metafile_cairo.h" #endif #if defined(OS_WIN) @@ -1035,15 +1043,16 @@ bool PluginInstance::PrintPDFOutput(PP_Resource print_output, // directly. cairo_t* context = canvas->beginPlatformPaint(); printing::NativeMetafile* metafile = - printing::NativeMetafile::FromCairoContext(context); + printing::PdfPsMetafile::FromCairoContext(context); DCHECK(metafile); if (metafile) ret = metafile->SetRawData(buffer->mapped_buffer(), buffer->size()); canvas->endPlatformPaint(); #elif defined(OS_MACOSX) - printing::NativeMetafile metafile; + scoped_ptr<printing::NativeMetafile> metafile( + printing::NativeMetafileFactory::CreateMetafile()); // Create a PDF metafile and render from there into the passed in context. - if (metafile.Init(buffer->mapped_buffer(), buffer->size())) { + if (metafile->Init(buffer->mapped_buffer(), buffer->size())) { // Flip the transform. CGContextSaveGState(canvas); CGContextTranslateCTM(canvas, 0, @@ -1055,7 +1064,7 @@ bool PluginInstance::PrintPDFOutput(PP_Resource print_output, page_rect.size.width = current_print_settings_.printable_area.size.width; page_rect.size.height = current_print_settings_.printable_area.size.height; - ret = metafile.RenderPage(1, canvas, page_rect, true, false, true, true); + ret = metafile->RenderPage(1, canvas, page_rect, true, false, true, true); CGContextRestoreGState(canvas); } #elif defined(OS_WIN) |