diff options
author | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-24 04:55:26 +0000 |
---|---|---|
committer | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-24 04:55:26 +0000 |
commit | 4ee0c53f86c1b2e0da904018c6bc0c8fdcda28a4 (patch) | |
tree | d158969797da469d8b231a472a0e085be0fbcf8c /chrome/renderer | |
parent | 28d25f732e0b024c491cd5c76e8a7a63e7c494b3 (diff) | |
download | chromium_src-4ee0c53f86c1b2e0da904018c6bc0c8fdcda28a4.zip chromium_src-4ee0c53f86c1b2e0da904018c6bc0c8fdcda28a4.tar.gz chromium_src-4ee0c53f86c1b2e0da904018c6bc0c8fdcda28a4.tar.bz2 |
Added support for vector printing for Pepper v1 plugins for Windows. Mac and Linux to follow.
BUG=None.
TEST=Test printing from Chrome PDF plugin on Windows.
Review URL: http://codereview.chromium.org/2863019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50699 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/webplugin_delegate_pepper.cc | 85 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_pepper.h | 3 |
2 files changed, 88 insertions, 0 deletions
diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc index 69b1b0e..9c6cf2f 100644 --- a/chrome/renderer/webplugin_delegate_pepper.cc +++ b/chrome/renderer/webplugin_delegate_pepper.cc @@ -20,6 +20,7 @@ #endif #include "base/md5.h" #include "base/message_loop.h" +#include "base/path_service.h" #include "base/process_util.h" #if defined(OS_MACOSX) #include "base/scoped_cftyperef.h" @@ -28,6 +29,7 @@ #include "base/stats_counters.h" #include "base/string_util.h" #include "base/time.h" +#include "chrome/common/chrome_paths.h" #include "chrome/common/render_messages.h" #include "chrome/renderer/pepper_widget.h" #include "chrome/renderer/render_thread.h" @@ -39,6 +41,7 @@ #if defined(OS_WIN) #include "gfx/codec/jpeg_codec.h" #include "gfx/gdi_util.h" +#include "printing/units.h" #include "skia/ext/vector_platform_device.h" #endif #include "third_party/npapi/bindings/npapi_extensions.h" @@ -49,6 +52,7 @@ #include "webkit/glue/plugins/plugin_instance.h" #include "webkit/glue/plugins/plugin_lib.h" #include "webkit/glue/plugins/plugin_list.h" +#include "webkit/glue/plugins/plugin_host.h" #include "webkit/glue/plugins/plugin_stream_url.h" #include "webkit/glue/webkit_glue.h" @@ -82,6 +86,17 @@ const int32 kDefaultCommandBufferSize = 1024 * 1024; } // namespace +static const float kPointsPerInch = 72.0; + +#if defined(OS_WIN) +// Exported by pdf.dll +typedef bool (__stdcall *RenderPDFPageToDCProc)( + const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc, + int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, + int bounds_width, int bounds_height, bool fit_to_bounds, + bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds); +#endif // defined(OS_WIN) + WebPluginDelegatePepper* WebPluginDelegatePepper::Create( const FilePath& filename, const std::string& mime_type, @@ -1113,17 +1128,85 @@ int WebPluginDelegatePepper::PrintBegin(const gfx::Rect& printable_area, printer_dpi, &num_pages)) { current_printable_area_ = printable_area; + current_printer_dpi_ = printer_dpi; } } return num_pages; } +bool WebPluginDelegatePepper::VectorPrintPage(int page_number, + WebKit::WebCanvas* canvas) { +#if !defined(OS_WIN) + // TODO(sanjeevr): Add vector print support for Mac and Linux. + return false; +#endif // !defined(OS_WIN) + NPPPrintExtensions* print_extensions = GetPrintExtensions(); + if (!print_extensions) + return false; +#if defined(OS_WIN) + // For Windows, we need the PDF DLL to render the output PDF to a DC. + FilePath pdf_path; + PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_path); + HMODULE pdf_module = GetModuleHandle(pdf_path.value().c_str()); + if (!pdf_module) + return false; + RenderPDFPageToDCProc render_proc = + reinterpret_cast<RenderPDFPageToDCProc>( + GetProcAddress(pdf_module, "RenderPDFPageToDC")); + if (!render_proc) + return false; +#endif // defined(OS_WIN) + + unsigned char* pdf_output = NULL; + int32 output_size = 0; + NPError err = print_extensions->printPageAsPDF(instance()->npp(), page_number, + &pdf_output, &output_size); + if (err != NPERR_NO_ERROR) + return false; + + bool ret = false; +#if defined(OS_WIN) + // On Windows, we now need to render the PDF to the DC that backs the + // supplied canvas. + skia::VectorPlatformDevice& device = + static_cast<skia::VectorPlatformDevice&>( + canvas->getTopPlatformDevice()); + HDC dc = device.getBitmapDC(); + gfx::Size size_in_pixels; + size_in_pixels.set_width( + printing::ConvertUnit(current_printable_area_.width(), + static_cast<int>(kPointsPerInch), + current_printer_dpi_)); + size_in_pixels.set_height( + printing::ConvertUnit(current_printable_area_.height(), + static_cast<int>(kPointsPerInch), + current_printer_dpi_)); + // We need to render using the actual printer DPI (rendering to a smaller + // set of pixels leads to a blurry output). However, we need to counter the + // scaling up that will happen in the browser. + XFORM xform = {0}; + xform.eM11 = xform.eM22 = kPointsPerInch / current_printer_dpi_; + ModifyWorldTransform(dc, &xform, MWT_LEFTMULTIPLY); + + ret = render_proc(pdf_output, output_size, 0, dc, current_printer_dpi_, + current_printer_dpi_, 0, 0, size_in_pixels.width(), + size_in_pixels.height(), true, false, true, true); +#endif // defined(OS_WIN) + + NPAPI::PluginHost::Singleton()->host_functions()->memfree(pdf_output); + return ret; +} + bool WebPluginDelegatePepper::PrintPage(int page_number, WebKit::WebCanvas* canvas) { NPPPrintExtensions* print_extensions = GetPrintExtensions(); if (!print_extensions) return false; + // First try and use vector print. + if (VectorPrintPage(page_number, canvas)) + return true; + DCHECK(!current_printable_area_.IsEmpty()); // Calculate the width and height needed for the raster image. @@ -1207,6 +1290,7 @@ void WebPluginDelegatePepper::PrintEnd() { if (print_extensions) print_extensions->printEnd(instance()->npp()); current_printable_area_ = gfx::Rect(); + current_printer_dpi_ = -1; #if defined(OS_MACOSX) last_printed_page_ = SkBitmap(); #endif // defined(OS_MACOSX) @@ -1224,6 +1308,7 @@ WebPluginDelegatePepper::WebPluginDelegatePepper( plugin_(NULL), instance_(instance), nested_delegate_(NULL), + current_printer_dpi_(-1), #if defined(ENABLE_GPU) command_buffer_(NULL), #endif diff --git a/chrome/renderer/webplugin_delegate_pepper.h b/chrome/renderer/webplugin_delegate_pepper.h index 1d7ca2a..efc60ff 100644 --- a/chrome/renderer/webplugin_delegate_pepper.h +++ b/chrome/renderer/webplugin_delegate_pepper.h @@ -224,6 +224,8 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate, bool CalculatePrintedPageDimensions(int page_number, NPPPrintExtensions* print_extensions, gfx::Size* page_dimensions); + bool VectorPrintPage(int page_number, WebKit::WebCanvas* canvas); + NPPPrintExtensions* GetPrintExtensions(); NPPFindExtensions* GetFindExtensions(); @@ -292,6 +294,7 @@ class WebPluginDelegatePepper : public webkit_glue::WebPluginDelegate, // we need to stretch the printed raster bitmap to these dimensions. It is // cleared in PrintEnd. gfx::Rect current_printable_area_; + int current_printer_dpi_; #if defined(OS_MACOSX) // On the Mac, when we draw the bitmap to the PDFContext, it seems necessary // to keep the pixels valis until CGContextEndPage is called. We use this |