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
3// found in the LICENSE file.
4
5#include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h"
6
7#include "content/public/browser/browser_thread.h"
8#include "content/public/browser/content_browser_client.h"
9#include "content/public/common/content_client.h"
10#include "ppapi/c/pp_errors.h"
11#include "printing/printing_context.h"
12#include "printing/units.h"
13
14namespace content {
15
16namespace {
17
18#if defined(ENABLE_FULL_PRINTING)
19// Print units conversion functions.
20int32_t DeviceUnitsInPoints(int32_t device_units,
21                            int32_t device_units_per_inch) {
22  return printing::ConvertUnit(
23      device_units, device_units_per_inch, printing::kPointsPerInch);
24}
25
26PP_Size PrintSizeToPPPrintSize(const gfx::Size& print_size,
27                               int32_t device_units_per_inch) {
28  PP_Size result;
29  result.width = DeviceUnitsInPoints(print_size.width(), device_units_per_inch);
30  result.height =
31      DeviceUnitsInPoints(print_size.height(), device_units_per_inch);
32  return result;
33}
34
35PP_Rect PrintAreaToPPPrintArea(const gfx::Rect& print_area,
36                               int32_t device_units_per_inch) {
37  PP_Rect result;
38  result.point.x =
39      DeviceUnitsInPoints(print_area.origin().x(), device_units_per_inch);
40  result.point.y =
41      DeviceUnitsInPoints(print_area.origin().y(), device_units_per_inch);
42  result.size =
43      PrintSizeToPPPrintSize(print_area.size(), device_units_per_inch);
44  return result;
45}
46
47class PrintingContextDelegate : public printing::PrintingContext::Delegate {
48 public:
49  // PrintingContext::Delegate methods.
50  virtual gfx::NativeView GetParentView() OVERRIDE { return NULL; }
51  virtual std::string GetAppLocale() OVERRIDE {
52    return GetContentClient()->browser()->GetApplicationLocale();
53  }
54};
55
56PepperPrintSettingsManager::Result ComputeDefaultPrintSettings() {
57  // This function should run on the UI thread because |PrintingContext| methods
58  // call into platform APIs.
59  DCHECK_CURRENTLY_ON(BrowserThread::UI);
60
61  PrintingContextDelegate delegate;
62  scoped_ptr<printing::PrintingContext> context(
63      printing::PrintingContext::Create(&delegate));
64  if (!context.get() ||
65      context->UseDefaultSettings() != printing::PrintingContext::OK) {
66    return PepperPrintSettingsManager::Result(PP_PrintSettings_Dev(),
67                                              PP_ERROR_FAILED);
68  }
69  const printing::PrintSettings& print_settings = context->settings();
70  const printing::PageSetup& page_setup =
71      print_settings.page_setup_device_units();
72  int device_units_per_inch = print_settings.device_units_per_inch();
73  if (device_units_per_inch <= 0) {
74    return PepperPrintSettingsManager::Result(PP_PrintSettings_Dev(),
75                                              PP_ERROR_FAILED);
76  }
77  PP_PrintSettings_Dev settings;
78  settings.printable_area = PrintAreaToPPPrintArea(page_setup.printable_area(),
79                                                   device_units_per_inch);
80  settings.content_area =
81      PrintAreaToPPPrintArea(page_setup.content_area(), device_units_per_inch);
82  settings.paper_size =
83      PrintSizeToPPPrintSize(page_setup.physical_size(), device_units_per_inch);
84  settings.dpi = print_settings.dpi();
85
86  // The remainder of the attributes are hard-coded to the defaults as set
87  // elsewhere.
88  settings.orientation = PP_PRINTORIENTATION_NORMAL;
89  settings.grayscale = PP_FALSE;
90  settings.print_scaling_option = PP_PRINTSCALINGOPTION_SOURCE_SIZE;
91
92  // TODO(raymes): Should be computed in the same way as
93  // |PluginInstance::GetPreferredPrintOutputFormat|.
94  // |PP_PRINTOUTPUTFORMAT_PDF| is currently the only supported format though,
95  // so just make it the default.
96  settings.format = PP_PRINTOUTPUTFORMAT_PDF;
97  return PepperPrintSettingsManager::Result(settings, PP_OK);
98}
99#else
100PepperPrintSettingsManager::Result ComputeDefaultPrintSettings() {
101  return PepperPrintSettingsManager::Result(PP_PrintSettings_Dev(),
102                                            PP_ERROR_NOTSUPPORTED);
103}
104#endif
105
106}  // namespace
107
108void PepperPrintSettingsManagerImpl::GetDefaultPrintSettings(
109    PepperPrintSettingsManager::Callback callback) {
110  BrowserThread::PostTaskAndReplyWithResult(
111      BrowserThread::UI,
112      FROM_HERE,
113      base::Bind(ComputeDefaultPrintSettings),
114      callback);
115}
116
117}  // namespace content
118