aw_pdf_exporter.cc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "android_webview/browser/aw_pdf_exporter.h"
  5. #include <memory>
  6. #include <utility>
  7. #include <vector>
  8. #include "android_webview/browser/aw_print_manager.h"
  9. #include "android_webview/browser_jni_headers/AwPdfExporter_jni.h"
  10. #include "base/android/jni_android.h"
  11. #include "base/android/jni_array.h"
  12. #include "base/bind.h"
  13. #include "content/public/browser/browser_thread.h"
  14. #include "printing/print_settings.h"
  15. #include "printing/units.h"
  16. using base::android::JavaParamRef;
  17. using base::android::JavaRef;
  18. using base::android::ScopedJavaLocalRef;
  19. namespace android_webview {
  20. namespace {
  21. void JNI_AwPdfExporter_GetPageRanges(JNIEnv* env,
  22. const JavaRef<jintArray>& int_arr,
  23. printing::PageRanges* range_vector) {
  24. std::vector<int> pages;
  25. base::android::JavaIntArrayToIntVector(env, int_arr, &pages);
  26. for (int page : pages) {
  27. printing::PageRange range;
  28. range.from = page;
  29. range.to = page;
  30. range_vector->push_back(range);
  31. }
  32. }
  33. } // namespace
  34. AwPdfExporter::AwPdfExporter(JNIEnv* env,
  35. const JavaRef<jobject>& obj,
  36. content::WebContents* web_contents)
  37. : java_ref_(env, obj), web_contents_(web_contents) {
  38. DCHECK(obj);
  39. Java_AwPdfExporter_setNativeAwPdfExporter(env, obj,
  40. reinterpret_cast<intptr_t>(this));
  41. }
  42. AwPdfExporter::~AwPdfExporter() {
  43. JNIEnv* env = base::android::AttachCurrentThread();
  44. ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
  45. if (!obj)
  46. return;
  47. // Clear the Java peer's weak pointer to |this| object.
  48. Java_AwPdfExporter_setNativeAwPdfExporter(env, obj, 0);
  49. }
  50. void AwPdfExporter::ExportToPdf(JNIEnv* env,
  51. const JavaParamRef<jobject>& obj,
  52. int fd,
  53. const JavaParamRef<jintArray>& pages,
  54. const JavaParamRef<jobject>& cancel_signal) {
  55. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  56. printing::PageRanges page_ranges;
  57. JNI_AwPdfExporter_GetPageRanges(env, pages, &page_ranges);
  58. // Create an AwPrintManager for the provided WebContents if the
  59. // AwPrintManager doesn't exist.
  60. if (!AwPrintManager::FromWebContents(web_contents_))
  61. AwPrintManager::CreateForWebContents(web_contents_);
  62. // Update the parameters of the current print manager.
  63. AwPrintManager* print_manager =
  64. AwPrintManager::FromWebContents(web_contents_);
  65. print_manager->UpdateParam(CreatePdfSettings(env, obj, page_ranges), fd,
  66. base::BindRepeating(&AwPdfExporter::DidExportPdf,
  67. base::Unretained(this)));
  68. if (!print_manager->PrintNow())
  69. DidExportPdf(0);
  70. }
  71. namespace {
  72. // Converts from 1/1000 of inches to device units using DPI.
  73. int MilsToDots(int val, int dpi) {
  74. return static_cast<int>(printing::ConvertUnitFloat(val, 1000, dpi));
  75. }
  76. } // namespace
  77. std::unique_ptr<printing::PrintSettings> AwPdfExporter::CreatePdfSettings(
  78. JNIEnv* env,
  79. const JavaRef<jobject>& obj,
  80. const printing::PageRanges& page_ranges) {
  81. auto settings = std::make_unique<printing::PrintSettings>();
  82. int dpi = Java_AwPdfExporter_getDpi(env, obj);
  83. int width = Java_AwPdfExporter_getPageWidth(env, obj);
  84. int height = Java_AwPdfExporter_getPageHeight(env, obj);
  85. gfx::Size physical_size_device_units;
  86. int width_in_dots = MilsToDots(width, dpi);
  87. int height_in_dots = MilsToDots(height, dpi);
  88. physical_size_device_units.SetSize(width_in_dots, height_in_dots);
  89. gfx::Rect printable_area_device_units;
  90. // Assume full page is printable for now.
  91. printable_area_device_units.SetRect(0, 0, width_in_dots, height_in_dots);
  92. if (!page_ranges.empty())
  93. settings->set_ranges(page_ranges);
  94. settings->set_dpi(dpi);
  95. // TODO(sgurun) verify that the value for newly added parameter for
  96. // (i.e. landscape_needs_flip) is correct.
  97. settings->SetPrinterPrintableArea(physical_size_device_units,
  98. printable_area_device_units, true);
  99. printing::PageMargins margins;
  100. margins.left = MilsToDots(Java_AwPdfExporter_getLeftMargin(env, obj), dpi);
  101. margins.right = MilsToDots(Java_AwPdfExporter_getRightMargin(env, obj), dpi);
  102. margins.top = MilsToDots(Java_AwPdfExporter_getTopMargin(env, obj), dpi);
  103. margins.bottom =
  104. MilsToDots(Java_AwPdfExporter_getBottomMargin(env, obj), dpi);
  105. settings->SetCustomMargins(margins);
  106. settings->set_should_print_backgrounds(true);
  107. return settings;
  108. }
  109. void AwPdfExporter::DidExportPdf(int page_count) {
  110. JNIEnv* env = base::android::AttachCurrentThread();
  111. ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
  112. if (!obj)
  113. return;
  114. Java_AwPdfExporter_didExportPdf(env, obj, page_count);
  115. }
  116. } // namespace android_webview