| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 5 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/linked_ptr.h" | 10 #include "base/memory/linked_ptr.h" |
| (...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1098 PP_PrintOutputFormat_Dev* format) { | 1098 PP_PrintOutputFormat_Dev* format) { |
| 1099 // Keep a reference on the stack. See NOTE above. | 1099 // Keep a reference on the stack. See NOTE above. |
| 1100 scoped_refptr<PluginInstance> ref(this); | 1100 scoped_refptr<PluginInstance> ref(this); |
| 1101 if (!LoadPrintInterface()) | 1101 if (!LoadPrintInterface()) |
| 1102 return false; | 1102 return false; |
| 1103 uint32_t supported_formats = | 1103 uint32_t supported_formats = |
| 1104 plugin_print_interface_->QuerySupportedFormats(pp_instance()); | 1104 plugin_print_interface_->QuerySupportedFormats(pp_instance()); |
| 1105 if (supported_formats & PP_PRINTOUTPUTFORMAT_PDF) { | 1105 if (supported_formats & PP_PRINTOUTPUTFORMAT_PDF) { |
| 1106 *format = PP_PRINTOUTPUTFORMAT_PDF; | 1106 *format = PP_PRINTOUTPUTFORMAT_PDF; |
| 1107 return true; | 1107 return true; |
| 1108 } else if (supported_formats & PP_PRINTOUTPUTFORMAT_RASTER) { | |
| 1109 *format = PP_PRINTOUTPUTFORMAT_RASTER; | |
| 1110 return true; | |
| 1111 } | 1108 } |
| 1112 return false; | 1109 return false; |
| 1113 } | 1110 } |
| 1114 | 1111 |
| 1115 bool PluginInstance::SupportsPrintInterface() { | 1112 bool PluginInstance::SupportsPrintInterface() { |
| 1116 PP_PrintOutputFormat_Dev format; | 1113 PP_PrintOutputFormat_Dev format; |
| 1117 return GetPreferredPrintOutputFormat(&format); | 1114 return GetPreferredPrintOutputFormat(&format); |
| 1118 } | 1115 } |
| 1119 | 1116 |
| 1120 bool PluginInstance::IsPrintScalingDisabled() { | 1117 bool PluginInstance::IsPrintScalingDisabled() { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 return false; | 1184 return false; |
| 1188 PP_Resource print_output = plugin_print_interface_->PrintPages( | 1185 PP_Resource print_output = plugin_print_interface_->PrintPages( |
| 1189 pp_instance(), page_ranges, num_ranges); | 1186 pp_instance(), page_ranges, num_ranges); |
| 1190 if (!print_output) | 1187 if (!print_output) |
| 1191 return false; | 1188 return false; |
| 1192 | 1189 |
| 1193 bool ret = false; | 1190 bool ret = false; |
| 1194 | 1191 |
| 1195 if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF) | 1192 if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_PDF) |
| 1196 ret = PrintPDFOutput(print_output, canvas); | 1193 ret = PrintPDFOutput(print_output, canvas); |
| 1197 else if (current_print_settings_.format == PP_PRINTOUTPUTFORMAT_RASTER) | |
| 1198 ret = PrintRasterOutput(print_output, canvas); | |
| 1199 | 1194 |
| 1200 // Now we need to release the print output resource. | 1195 // Now we need to release the print output resource. |
| 1201 PluginModule::GetCore()->ReleaseResource(print_output); | 1196 PluginModule::GetCore()->ReleaseResource(print_output); |
| 1202 | 1197 |
| 1203 return ret; | 1198 return ret; |
| 1204 } | 1199 } |
| 1205 | 1200 |
| 1206 void PluginInstance::PrintEnd() { | 1201 void PluginInstance::PrintEnd() { |
| 1207 // Keep a reference on the stack. See NOTE above. | 1202 // Keep a reference on the stack. See NOTE above. |
| 1208 scoped_refptr<PluginInstance> ref(this); | 1203 scoped_refptr<PluginInstance> ref(this); |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1489 0, dc, current_print_settings_.dpi, | 1484 0, dc, current_print_settings_.dpi, |
| 1490 current_print_settings_.dpi, 0, 0, size_in_pixels.width(), | 1485 current_print_settings_.dpi, 0, 0, size_in_pixels.width(), |
| 1491 size_in_pixels.height(), true, false, true, true, true); | 1486 size_in_pixels.height(), true, false, true, true, true); |
| 1492 skia::EndPlatformPaint(canvas); | 1487 skia::EndPlatformPaint(canvas); |
| 1493 } | 1488 } |
| 1494 #endif // defined(OS_WIN) | 1489 #endif // defined(OS_WIN) |
| 1495 | 1490 |
| 1496 return ret; | 1491 return ret; |
| 1497 } | 1492 } |
| 1498 | 1493 |
| 1499 bool PluginInstance::PrintRasterOutput(PP_Resource print_output, | |
| 1500 WebKit::WebCanvas* canvas) { | |
| 1501 EnterResourceNoLock<PPB_ImageData_API> enter(print_output, true); | |
| 1502 if (enter.failed()) | |
| 1503 return false; | |
| 1504 PPB_ImageData_Impl* image = | |
| 1505 static_cast<PPB_ImageData_Impl*>(enter.object()); | |
| 1506 | |
| 1507 if (!image->Map()) | |
| 1508 return false; | |
| 1509 | |
| 1510 const SkBitmap* bitmap = image->GetMappedBitmap(); | |
| 1511 if (!bitmap) | |
| 1512 return false; | |
| 1513 | |
| 1514 // Draw the printed image into the supplied canvas. | |
| 1515 SkIRect src_rect; | |
| 1516 src_rect.set(0, 0, bitmap->width(), bitmap->height()); | |
| 1517 SkRect dest_rect; | |
| 1518 dest_rect.set( | |
| 1519 SkIntToScalar(current_print_settings_.printable_area.point.x), | |
| 1520 SkIntToScalar(current_print_settings_.printable_area.point.y), | |
| 1521 SkIntToScalar(current_print_settings_.printable_area.point.x + | |
| 1522 current_print_settings_.printable_area.size.width), | |
| 1523 SkIntToScalar(current_print_settings_.printable_area.point.y + | |
| 1524 current_print_settings_.printable_area.size.height)); | |
| 1525 bool draw_to_canvas = true; | |
| 1526 gfx::Rect dest_rect_gfx; | |
| 1527 dest_rect_gfx.set_x(current_print_settings_.printable_area.point.x); | |
| 1528 dest_rect_gfx.set_y(current_print_settings_.printable_area.point.y); | |
| 1529 dest_rect_gfx.set_width(current_print_settings_.printable_area.size.width); | |
| 1530 dest_rect_gfx.set_height(current_print_settings_.printable_area.size.height); | |
| 1531 | |
| 1532 #if defined(OS_WIN) | |
| 1533 // Since this is a raster output, the size of the bitmap can be | |
| 1534 // huge (especially at high printer DPIs). On Windows, this can | |
| 1535 // result in a HUGE EMF (on Mac and Linux the output goes to PDF | |
| 1536 // which appears to Flate compress the bitmap). So, if this bitmap | |
| 1537 // is larger than 20 MB, we save the bitmap as a JPEG into the EMF | |
| 1538 // DC. Note: We chose JPEG over PNG because JPEG compression seems | |
| 1539 // way faster (about 4 times faster). | |
| 1540 static const int kCompressionThreshold = 20 * 1024 * 1024; | |
| 1541 if (bitmap->getSize() > kCompressionThreshold) { | |
| 1542 DrawJPEGToPlatformDC(*bitmap, dest_rect_gfx, canvas); | |
| 1543 draw_to_canvas = false; | |
| 1544 } | |
| 1545 #endif // defined(OS_WIN) | |
| 1546 #if defined(OS_MACOSX) && !defined(USE_SKIA) | |
| 1547 draw_to_canvas = false; | |
| 1548 DrawSkBitmapToCanvas(*bitmap, canvas, dest_rect_gfx, | |
| 1549 current_print_settings_.printable_area.size.height); | |
| 1550 // See comments in the header file. | |
| 1551 last_printed_page_ = image; | |
| 1552 #else // defined(OS_MACOSX) && !defined(USE_SKIA) | |
| 1553 if (draw_to_canvas) | |
| 1554 canvas->drawBitmapRect(*bitmap, &src_rect, dest_rect); | |
| 1555 #endif // defined(OS_MACOSX) && !defined(USE_SKIA) | |
| 1556 return true; | |
| 1557 } | |
| 1558 | |
| 1559 #if defined(OS_WIN) | |
| 1560 bool PluginInstance::DrawJPEGToPlatformDC( | |
| 1561 const SkBitmap& bitmap, | |
| 1562 const gfx::Rect& printable_area, | |
| 1563 WebKit::WebCanvas* canvas) { | |
| 1564 // Ideally we should add JPEG compression to the VectorPlatformDevice class | |
| 1565 // However, Skia currently has no JPEG compression code and we cannot | |
| 1566 // depend on gfx/jpeg_codec.h in Skia. So we do the compression here. | |
| 1567 SkAutoLockPixels lock(bitmap); | |
| 1568 DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config); | |
| 1569 const uint32_t* pixels = | |
| 1570 static_cast<const uint32_t*>(bitmap.getPixels()); | |
| 1571 std::vector<unsigned char> compressed_image; | |
| 1572 base::TimeTicks start_time = base::TimeTicks::Now(); | |
| 1573 bool encoded = gfx::JPEGCodec::Encode( | |
| 1574 reinterpret_cast<const unsigned char*>(pixels), | |
| 1575 gfx::JPEGCodec::FORMAT_BGRA, bitmap.width(), bitmap.height(), | |
| 1576 static_cast<int>(bitmap.rowBytes()), 100, &compressed_image); | |
| 1577 UMA_HISTOGRAM_TIMES("PepperPluginPrint.RasterBitmapCompressTime", | |
| 1578 base::TimeTicks::Now() - start_time); | |
| 1579 if (!encoded) { | |
| 1580 NOTREACHED(); | |
| 1581 return false; | |
| 1582 } | |
| 1583 | |
| 1584 skia::ScopedPlatformPaint scoped_platform_paint(canvas); | |
| 1585 HDC dc = scoped_platform_paint.GetPlatformSurface(); | |
| 1586 DrawEmptyRectangle(dc); | |
| 1587 BITMAPINFOHEADER bmi = {0}; | |
| 1588 gfx::CreateBitmapHeader(bitmap.width(), bitmap.height(), &bmi); | |
| 1589 bmi.biCompression = BI_JPEG; | |
| 1590 bmi.biSizeImage = compressed_image.size(); | |
| 1591 bmi.biHeight = -bmi.biHeight; | |
| 1592 StretchDIBits(dc, printable_area.x(), printable_area.y(), | |
| 1593 printable_area.width(), printable_area.height(), | |
| 1594 0, 0, bitmap.width(), bitmap.height(), | |
| 1595 &compressed_image.front(), | |
| 1596 reinterpret_cast<const BITMAPINFO*>(&bmi), | |
| 1597 DIB_RGB_COLORS, SRCCOPY); | |
| 1598 return true; | |
| 1599 } | |
| 1600 #endif // OS_WIN | |
| 1601 | |
| 1602 #if defined(OS_MACOSX) && !defined(USE_SKIA) | |
| 1603 void PluginInstance::DrawSkBitmapToCanvas( | |
| 1604 const SkBitmap& bitmap, WebKit::WebCanvas* canvas, | |
| 1605 const gfx::Rect& dest_rect, | |
| 1606 int canvas_height) { | |
| 1607 SkAutoLockPixels lock(bitmap); | |
| 1608 DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config); | |
| 1609 base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( | |
| 1610 CGDataProviderCreateWithData( | |
| 1611 NULL, bitmap.getAddr32(0, 0), | |
| 1612 bitmap.rowBytes() * bitmap.height(), NULL)); | |
| 1613 base::mac::ScopedCFTypeRef<CGImageRef> image( | |
| 1614 CGImageCreate( | |
| 1615 bitmap.width(), bitmap.height(), | |
| 1616 8, 32, bitmap.rowBytes(), | |
| 1617 base::mac::GetSystemColorSpace(), | |
| 1618 kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, | |
| 1619 data_provider, NULL, false, kCGRenderingIntentDefault)); | |
| 1620 | |
| 1621 // Flip the transform | |
| 1622 CGContextSaveGState(canvas); | |
| 1623 CGContextTranslateCTM(canvas, 0, canvas_height); | |
| 1624 CGContextScaleCTM(canvas, 1.0, -1.0); | |
| 1625 | |
| 1626 CGRect bounds; | |
| 1627 bounds.origin.x = dest_rect.x(); | |
| 1628 bounds.origin.y = canvas_height - dest_rect.y() - dest_rect.height(); | |
| 1629 bounds.size.width = dest_rect.width(); | |
| 1630 bounds.size.height = dest_rect.height(); | |
| 1631 | |
| 1632 CGContextDrawImage(canvas, bounds, image); | |
| 1633 CGContextRestoreGState(canvas); | |
| 1634 } | |
| 1635 #endif // defined(OS_MACOSX) && !defined(USE_SKIA) | |
| 1636 | |
| 1637 PPB_Graphics2D_Impl* PluginInstance::GetBoundGraphics2D() const { | 1494 PPB_Graphics2D_Impl* PluginInstance::GetBoundGraphics2D() const { |
| 1638 if (bound_graphics_.get() == NULL) | 1495 if (bound_graphics_.get() == NULL) |
| 1639 return NULL; | 1496 return NULL; |
| 1640 | 1497 |
| 1641 if (bound_graphics_->AsPPB_Graphics2D_API()) | 1498 if (bound_graphics_->AsPPB_Graphics2D_API()) |
| 1642 return static_cast<PPB_Graphics2D_Impl*>(bound_graphics_.get()); | 1499 return static_cast<PPB_Graphics2D_Impl*>(bound_graphics_.get()); |
| 1643 return NULL; | 1500 return NULL; |
| 1644 } | 1501 } |
| 1645 | 1502 |
| 1646 PPB_Graphics3D_Impl* PluginInstance::GetBoundGraphics3D() const { | 1503 PPB_Graphics3D_Impl* PluginInstance::GetBoundGraphics3D() const { |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2172 screen_size_for_fullscreen_ = gfx::Size(); | 2029 screen_size_for_fullscreen_ = gfx::Size(); |
| 2173 WebElement element = container_->element(); | 2030 WebElement element = container_->element(); |
| 2174 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); | 2031 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); |
| 2175 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); | 2032 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); |
| 2176 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); | 2033 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); |
| 2177 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); | 2034 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); |
| 2178 } | 2035 } |
| 2179 | 2036 |
| 2180 } // namespace ppapi | 2037 } // namespace ppapi |
| 2181 } // namespace webkit | 2038 } // namespace webkit |
| OLD | NEW |