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 |