diff options
-rw-r--r-- | chrome/renderer/print_web_view_helper.cc | 10 | ||||
-rw-r--r-- | ppapi/api/dev/ppp_printing_dev.idl | 15 | ||||
-rw-r--r-- | ppapi/c/dev/ppp_printing_dev.h | 17 | ||||
-rw-r--r-- | ppapi/examples/printing/printing.cc | 50 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppapi_plugin_instance.cc | 143 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppapi_plugin_instance.h | 13 |
6 files changed, 56 insertions, 192 deletions
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc index ae6fc69..b32ee66 100644 --- a/chrome/renderer/print_web_view_helper.cc +++ b/chrome/renderer/print_web_view_helper.cc @@ -31,6 +31,8 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginDocument.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebPlugin.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLResponse.h" @@ -70,6 +72,8 @@ using WebKit::WebDocument; using WebKit::WebElement; using WebKit::WebFrame; using WebKit::WebNode; +using WebKit::WebPlugin; +using WebKit::WebPluginDocument; using WebKit::WebSize; using WebKit::WebString; using WebKit::WebURLRequest; @@ -309,8 +313,10 @@ void CalculatePrintCanvasSize(const PrintMsg_Print_Params& print_params, bool PrintingNodeOrPdfFrame(const WebFrame* frame, const WebNode& node) { if (!node.isNull()) return true; - std::string mime(frame->dataSource()->response().mimeType().utf8()); - return mime == "application/pdf"; + if (!frame->document().isPluginDocument()) + return false; + WebPlugin* plugin = frame->document().to<WebPluginDocument>().plugin(); + return plugin && plugin->supportsPaginatedPrint(); } bool PrintingFrameHasPageSizeStyle(WebFrame* frame, int total_page_count) { diff --git a/ppapi/api/dev/ppp_printing_dev.idl b/ppapi/api/dev/ppp_printing_dev.idl index 62cc23e..74f5f6a 100644 --- a/ppapi/api/dev/ppp_printing_dev.idl +++ b/ppapi/api/dev/ppp_printing_dev.idl @@ -34,6 +34,7 @@ struct PP_PrintSettings_Dev { int32_t dpi; PP_PrintOrientation_Dev orientation; PP_Bool grayscale; + /** Note that Chrome currently only supports PDF printing. */ PP_PrintOutputFormat_Dev format; }; @@ -50,14 +51,14 @@ struct PP_PrintPageNumberRange_Dev { interface PPP_Printing_Dev { /** * Returns a bit field representing the supported print output formats. For - * example, if only Raster and PostScript are supported, + * example, if only PDF and PostScript are supported, * QuerySupportedFormats returns a value equivalent to: - * (PP_PRINTOUTPUTFORMAT_RASTER | PP_PRINTOUTPUTFORMAT_POSTSCRIPT) + * (PP_PRINTOUTPUTFORMAT_PDF | PP_PRINTOUTPUTFORMAT_POSTSCRIPT) */ uint32_t QuerySupportedFormats([in] PP_Instance instance); /** - * Begins a print session with the given print settings. Calls to PrintPage + * Begins a print session with the given print settings. Calls to PrintPages * can only be made after a successful call to Begin. Returns the number of * pages required for the print output at the given page size (0 indicates * a failure). @@ -67,16 +68,14 @@ interface PPP_Printing_Dev { /** * Prints the specified pages using the format specified in Begin. - * Returns a resource that represents the printed output. - * This is a PPB_ImageData resource if the output format is - * PP_PrintOutputFormat_Raster and a PPB_Buffer otherwise. Returns 0 on - * failure. + * Returns a PPB_Buffer resource that represents the printed output. Returns + * 0 on failure. */ PP_Resource PrintPages([in] PP_Instance instance, [in] PP_PrintPageNumberRange_Dev page_ranges, [in] uint32_t page_range_count); - /** Ends the print session. Further calls to PrintPage will fail. */ + /** Ends the print session. Further calls to PrintPages will fail. */ void End([in] PP_Instance instance); /** diff --git a/ppapi/c/dev/ppp_printing_dev.h b/ppapi/c/dev/ppp_printing_dev.h index 2af075e..b600358 100644 --- a/ppapi/c/dev/ppp_printing_dev.h +++ b/ppapi/c/dev/ppp_printing_dev.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From dev/ppp_printing_dev.idl modified Wed Feb 22 12:44:39 2012. */ +/* From dev/ppp_printing_dev.idl modified Tue Apr 17 20:28:30 2012. */ #ifndef PPAPI_C_DEV_PPP_PRINTING_DEV_H_ #define PPAPI_C_DEV_PPP_PRINTING_DEV_H_ @@ -59,6 +59,7 @@ struct PP_PrintSettings_Dev { int32_t dpi; PP_PrintOrientation_Dev orientation; PP_Bool grayscale; + /** Note that Chrome currently only supports PDF printing. */ PP_PrintOutputFormat_Dev format; }; PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_PrintSettings_Dev, 32); @@ -83,13 +84,13 @@ PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_PrintPageNumberRange_Dev, 8); struct PPP_Printing_Dev_0_5 { /** * Returns a bit field representing the supported print output formats. For - * example, if only Raster and PostScript are supported, + * example, if only PDF and PostScript are supported, * QuerySupportedFormats returns a value equivalent to: - * (PP_PRINTOUTPUTFORMAT_RASTER | PP_PRINTOUTPUTFORMAT_POSTSCRIPT) + * (PP_PRINTOUTPUTFORMAT_PDF | PP_PRINTOUTPUTFORMAT_POSTSCRIPT) */ uint32_t (*QuerySupportedFormats)(PP_Instance instance); /** - * Begins a print session with the given print settings. Calls to PrintPage + * Begins a print session with the given print settings. Calls to PrintPages * can only be made after a successful call to Begin. Returns the number of * pages required for the print output at the given page size (0 indicates * a failure). @@ -98,16 +99,14 @@ struct PPP_Printing_Dev_0_5 { const struct PP_PrintSettings_Dev* print_settings); /** * Prints the specified pages using the format specified in Begin. - * Returns a resource that represents the printed output. - * This is a PPB_ImageData resource if the output format is - * PP_PrintOutputFormat_Raster and a PPB_Buffer otherwise. Returns 0 on - * failure. + * Returns a PPB_Buffer resource that represents the printed output. Returns + * 0 on failure. */ PP_Resource (*PrintPages)( PP_Instance instance, const struct PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count); - /** Ends the print session. Further calls to PrintPage will fail. */ + /** Ends the print session. Further calls to PrintPages will fail. */ void (*End)(PP_Instance instance); /** * Returns true if the current content should be printed into the full page diff --git a/ppapi/examples/printing/printing.cc b/ppapi/examples/printing/printing.cc index 657a109..866e51a 100644 --- a/ppapi/examples/printing/printing.cc +++ b/ppapi/examples/printing/printing.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ppapi/cpp/dev/buffer_dev.h" #include "ppapi/cpp/dev/printing_dev.h" #include "ppapi/cpp/image_data.h" #include "ppapi/cpp/instance.h" @@ -11,17 +12,32 @@ namespace { -void FillRect(pp::ImageData* image, int left, int top, int width, int height, - uint32_t color) { - for (int y = std::max(0, top); - y < std::min(image->size().height(), top + height); - y++) { - for (int x = std::max(0, left); - x < std::min(image->size().width(), left + width); - x++) - *image->GetAddr32(pp::Point(x, y)) = color; - } -} +const char pdf_data[] = "%PDF-1.4\r" +"% \r" +"1 0 obj<</Type/FontDescriptor/FontBBox[-50 -207 1447 1000]/FontName/Verdana/Flags 32/StemV 92/CapHeight 734/XHeight 546/Ascent 1005/Descent -209/ItalicAngle 0/FontFamily(Verdana)/FontStretch/Normal/FontWeight 400>>\r" +"2 0 obj<</Type/Font/Subtype/TrueType/Encoding/UniCNS-UTF16-H/BaseFont/Verdana/Name/Verdana/FontDescriptor 1 0 R/FirstChar 72/LastChar 114/Widths[ 750 420 454 692 556 843 748 787 602 787 695 684 616 731 684 989 685 614 685 454 454 454 818 635 635 600 623 521 623 595 351 623 633 274 343 591 274 972 633 607 623 623 426]>>\r" +"4 0 obj<</Type/Page/Parent 3 0 R/MediaBox[0 0 612 792]/Contents 5 0 R/Resources<</ProcSet[/PDF/Text/ColorC]/Font<</N2 2 0 R>> >> >>endobj\r" +"5 0 obj<</Length 70>>stream\r" +"BT/N2 24 Tf 100 692 Td(Hello)Tj ET\r" +"BT/N2 24 Tf 200 692 Td(World)Tj ET\r" +"\r" +"endstream\r" +"endobj\r" +"3 0 obj<</Type/Pages/Kids[ 4 0 R]/Count 1>>endobj\r" +"6 0 obj<</Type/Catalog/Pages 3 0 R>>endobj\r" +"xref\r" +"0 7\r" +"0000000000 65535 f \r" +"0000000015 00000 n \r" +"0000000230 00000 n \r" +"0000000805 00000 n \r" +"0000000551 00000 n \r" +"0000000689 00000 n \r" +"0000000855 00000 n \r" +"trailer<</Size 7/Root 6 0 R>>\r" +"startxref\r" +"898\r" +"%%EOF"; } // namespace @@ -38,7 +54,7 @@ class MyInstance : public pp::Instance, public pp::Printing_Dev { } virtual uint32_t QuerySupportedPrintOutputFormats() { - return PP_PRINTOUTPUTFORMAT_RASTER; + return PP_PRINTOUTPUTFORMAT_PDF; } virtual int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) { @@ -48,13 +64,11 @@ class MyInstance : public pp::Instance, public pp::Printing_Dev { virtual pp::Resource PrintPages( const PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count) { - pp::Size size(100, 100); - pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, true); - FillRect(&image, 0, 0, size.width(), size.height(), 0xFFFFFFFF); + size_t pdf_len = strlen(pdf_data); + pp::Buffer_Dev buffer(this, pdf_len); - FillRect(&image, 0, 0, 10, 10, 0xFF000000); - FillRect(&image, size.width() - 11, size.height() - 11, 10, 10, 0xFF000000); - return image; + memcpy(buffer.data(), pdf_data, pdf_len); + return buffer; } virtual void PrintEnd() { diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc index ffb0c17..2947360 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc @@ -1118,9 +1118,6 @@ bool PluginInstance::GetPreferredPrintOutputFormat( if (supported_formats & PP_PRINTOUTPUTFORMAT_PDF) { *format = PP_PRINTOUTPUTFORMAT_PDF; return true; - } else if (supported_formats & PP_PRINTOUTPUTFORMAT_RASTER) { - *format = PP_PRINTOUTPUTFORMAT_RASTER; - return true; } return false; } @@ -1207,8 +1204,6 @@ bool PluginInstance::PrintPageHelper(PP_PrintPageNumberRange_Dev* page_ranges, if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF) ret = PrintPDFOutput(print_output, canvas); - else if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_RASTER) - ret = PrintRasterOutput(print_output, canvas); // Now we need to release the print output resource. PluginModule::GetCore()->ReleaseResource(print_output); @@ -1509,144 +1504,6 @@ bool PluginInstance::PrintPDFOutput(PP_Resource print_output, return ret; } -bool PluginInstance::PrintRasterOutput(PP_Resource print_output, - WebKit::WebCanvas* canvas) { - EnterResourceNoLock<PPB_ImageData_API> enter(print_output, true); - if (enter.failed()) - return false; - PPB_ImageData_Impl* image = - static_cast<PPB_ImageData_Impl*>(enter.object()); - - if (!image->Map()) - return false; - - const SkBitmap* bitmap = image->GetMappedBitmap(); - if (!bitmap) - return false; - - // Draw the printed image into the supplied canvas. - SkIRect src_rect; - src_rect.set(0, 0, bitmap->width(), bitmap->height()); - SkRect dest_rect; - dest_rect.set( - SkIntToScalar(current_print_settings_.printable_area.point.x), - SkIntToScalar(current_print_settings_.printable_area.point.y), - SkIntToScalar(current_print_settings_.printable_area.point.x + - current_print_settings_.printable_area.size.width), - SkIntToScalar(current_print_settings_.printable_area.point.y + - current_print_settings_.printable_area.size.height)); - bool draw_to_canvas = true; - gfx::Rect dest_rect_gfx; - dest_rect_gfx.set_x(current_print_settings_.printable_area.point.x); - dest_rect_gfx.set_y(current_print_settings_.printable_area.point.y); - dest_rect_gfx.set_width(current_print_settings_.printable_area.size.width); - dest_rect_gfx.set_height(current_print_settings_.printable_area.size.height); - -#if defined(OS_WIN) - // Since this is a raster output, the size of the bitmap can be - // huge (especially at high printer DPIs). On Windows, this can - // result in a HUGE EMF (on Mac and Linux the output goes to PDF - // which appears to Flate compress the bitmap). So, if this bitmap - // is larger than 20 MB, we save the bitmap as a JPEG into the EMF - // DC. Note: We chose JPEG over PNG because JPEG compression seems - // way faster (about 4 times faster). - static const int kCompressionThreshold = 20 * 1024 * 1024; - if (bitmap->getSize() > kCompressionThreshold) { - DrawJPEGToPlatformDC(*bitmap, dest_rect_gfx, canvas); - draw_to_canvas = false; - } -#endif // defined(OS_WIN) -#if defined(OS_MACOSX) && !defined(USE_SKIA) - draw_to_canvas = false; - DrawSkBitmapToCanvas(*bitmap, canvas, dest_rect_gfx, - current_print_settings_.printable_area.size.height); - // See comments in the header file. - last_printed_page_ = image; -#else // defined(OS_MACOSX) && !defined(USE_SKIA) - if (draw_to_canvas) - canvas->drawBitmapRect(*bitmap, &src_rect, dest_rect); -#endif // defined(OS_MACOSX) && !defined(USE_SKIA) - return true; -} - -#if defined(OS_WIN) -bool PluginInstance::DrawJPEGToPlatformDC( - const SkBitmap& bitmap, - const gfx::Rect& printable_area, - WebKit::WebCanvas* canvas) { - // Ideally we should add JPEG compression to the VectorPlatformDevice class - // However, Skia currently has no JPEG compression code and we cannot - // depend on gfx/jpeg_codec.h in Skia. So we do the compression here. - SkAutoLockPixels lock(bitmap); - DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config); - const uint32_t* pixels = - static_cast<const uint32_t*>(bitmap.getPixels()); - std::vector<unsigned char> compressed_image; - base::TimeTicks start_time = base::TimeTicks::Now(); - bool encoded = gfx::JPEGCodec::Encode( - reinterpret_cast<const unsigned char*>(pixels), - gfx::JPEGCodec::FORMAT_BGRA, bitmap.width(), bitmap.height(), - static_cast<int>(bitmap.rowBytes()), 100, &compressed_image); - UMA_HISTOGRAM_TIMES("PepperPluginPrint.RasterBitmapCompressTime", - base::TimeTicks::Now() - start_time); - if (!encoded) { - NOTREACHED(); - return false; - } - - skia::ScopedPlatformPaint scoped_platform_paint(canvas); - HDC dc = scoped_platform_paint.GetPlatformSurface(); - DrawEmptyRectangle(dc); - BITMAPINFOHEADER bmi = {0}; - gfx::CreateBitmapHeader(bitmap.width(), bitmap.height(), &bmi); - bmi.biCompression = BI_JPEG; - bmi.biSizeImage = compressed_image.size(); - bmi.biHeight = -bmi.biHeight; - StretchDIBits(dc, printable_area.x(), printable_area.y(), - printable_area.width(), printable_area.height(), - 0, 0, bitmap.width(), bitmap.height(), - &compressed_image.front(), - reinterpret_cast<const BITMAPINFO*>(&bmi), - DIB_RGB_COLORS, SRCCOPY); - return true; -} -#endif // OS_WIN - -#if defined(OS_MACOSX) && !defined(USE_SKIA) -void PluginInstance::DrawSkBitmapToCanvas( - const SkBitmap& bitmap, WebKit::WebCanvas* canvas, - const gfx::Rect& dest_rect, - int canvas_height) { - SkAutoLockPixels lock(bitmap); - DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config); - base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( - CGDataProviderCreateWithData( - NULL, bitmap.getAddr32(0, 0), - bitmap.rowBytes() * bitmap.height(), NULL)); - base::mac::ScopedCFTypeRef<CGImageRef> image( - CGImageCreate( - bitmap.width(), bitmap.height(), - 8, 32, bitmap.rowBytes(), - base::mac::GetSystemColorSpace(), - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, - data_provider, NULL, false, kCGRenderingIntentDefault)); - - // Flip the transform - CGContextSaveGState(canvas); - CGContextTranslateCTM(canvas, 0, canvas_height); - CGContextScaleCTM(canvas, 1.0, -1.0); - - CGRect bounds; - bounds.origin.x = dest_rect.x(); - bounds.origin.y = canvas_height - dest_rect.y() - dest_rect.height(); - bounds.size.width = dest_rect.width(); - bounds.size.height = dest_rect.height(); - - CGContextDrawImage(canvas, bounds, image); - CGContextRestoreGState(canvas); -} -#endif // defined(OS_MACOSX) && !defined(USE_SKIA) - PPB_Graphics2D_Impl* PluginInstance::GetBoundGraphics2D() const { if (bound_graphics_.get() == NULL) return NULL; diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.h b/webkit/plugins/ppapi/ppapi_plugin_instance.h index dc430e71..932143b 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.h +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.h @@ -430,20 +430,9 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : // Queries the plugin for supported print formats and sets |format| to the // best format to use. Returns false if the plugin does not support any - // print format that we can handle (we can handle raster and PDF). + // print format that we can handle (we can handle only PDF). bool GetPreferredPrintOutputFormat(PP_PrintOutputFormat_Dev* format); bool PrintPDFOutput(PP_Resource print_output, WebKit::WebCanvas* canvas); - bool PrintRasterOutput(PP_Resource print_output, WebKit::WebCanvas* canvas); -#if defined(OS_WIN) - bool DrawJPEGToPlatformDC(const SkBitmap& bitmap, - const gfx::Rect& printable_area, - WebKit::WebCanvas* canvas); -#elif defined(OS_MACOSX) && !defined(USE_SKIA) - // Draws the given kARGB_8888_Config bitmap to the specified canvas starting - // at the specified destination rect. - void DrawSkBitmapToCanvas(const SkBitmap& bitmap, WebKit::WebCanvas* canvas, - const gfx::Rect& dest_rect, int canvas_height); -#endif // OS_MACOSX // Get the bound graphics context as a concrete 2D graphics context or returns // null if the context is not 2D. |