summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authorsanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-24 04:55:26 +0000
committersanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-24 04:55:26 +0000
commit4ee0c53f86c1b2e0da904018c6bc0c8fdcda28a4 (patch)
treed158969797da469d8b231a472a0e085be0fbcf8c /chrome/renderer
parent28d25f732e0b024c491cd5c76e8a7a63e7c494b3 (diff)
downloadchromium_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.cc85
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.h3
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