1// Copyright 2014 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 "chrome/service/cloud_print/cdd_conversion_win.h"
6
7#include "base/strings/string_number_conversions.h"
8#include "components/cloud_devices/common/printer_description.h"
9#include "printing/backend/win_helper.h"
10
11namespace cloud_print {
12
13bool IsValidCjt(const std::string& print_ticket_data) {
14  cloud_devices::CloudDeviceDescription description;
15  return description.InitFromString(print_ticket_data);
16}
17
18scoped_ptr<DEVMODE, base::FreeDeleter> CjtToDevMode(
19    const base::string16& printer_name,
20    const std::string& print_ticket) {
21  scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode;
22
23  cloud_devices::CloudDeviceDescription description;
24  if (!description.InitFromString(print_ticket))
25    return dev_mode.Pass();
26
27  using namespace cloud_devices::printer;
28  printing::ScopedPrinterHandle printer;
29  if (!printer.OpenPrinter(printer_name.c_str()))
30    return dev_mode.Pass();
31
32  {
33    ColorTicketItem color;
34    if (color.LoadFrom(description)) {
35      bool is_color = color.value().type == STANDARD_COLOR;
36      dev_mode = printing::CreateDevModeWithColor(printer.Get(), printer_name,
37                                                  is_color);
38    } else {
39      dev_mode = printing::CreateDevMode(printer.Get(), NULL);
40    }
41  }
42
43  if (!dev_mode)
44    return dev_mode.Pass();
45
46  ColorTicketItem color;
47  DuplexTicketItem duplex;
48  OrientationTicketItem orientation;
49  MarginsTicketItem margins;
50  DpiTicketItem dpi;
51  FitToPageTicketItem fit_to_page;
52  MediaTicketItem media;
53  CopiesTicketItem copies;
54  PageRangeTicketItem page_range;
55  CollateTicketItem collate;
56  ReverseTicketItem reverse;
57
58  if (orientation.LoadFrom(description)) {
59    dev_mode->dmFields |= DM_ORIENTATION;
60    if (orientation.value() == LANDSCAPE) {
61      dev_mode->dmOrientation = DMORIENT_LANDSCAPE;
62    } else {
63      dev_mode->dmOrientation = DMORIENT_PORTRAIT;
64    }
65  }
66
67  if (color.LoadFrom(description)) {
68    dev_mode->dmFields |= DM_COLOR;
69    if (color.value().type == STANDARD_MONOCHROME) {
70      dev_mode->dmColor = DMCOLOR_MONOCHROME;
71    } else if (color.value().type == STANDARD_COLOR) {
72      dev_mode->dmColor = DMCOLOR_COLOR;
73    } else {
74      NOTREACHED();
75    }
76  }
77
78  if (duplex.LoadFrom(description)) {
79    dev_mode->dmFields |= DM_DUPLEX;
80    if (duplex.value() == NO_DUPLEX) {
81      dev_mode->dmDuplex = DMDUP_SIMPLEX;
82    } else if (duplex.value() == LONG_EDGE) {
83      dev_mode->dmDuplex = DMDUP_VERTICAL;
84    } else if (duplex.value() == SHORT_EDGE) {
85      dev_mode->dmDuplex = DMDUP_HORIZONTAL;
86    } else {
87      NOTREACHED();
88    }
89  }
90
91  if (copies.LoadFrom(description)) {
92    dev_mode->dmFields |= DM_COPIES;
93    dev_mode->dmCopies = copies.value();
94  }
95
96  if (dpi.LoadFrom(description)) {
97    if (dpi.value().horizontal > 0) {
98      dev_mode->dmFields |= DM_PRINTQUALITY;
99      dev_mode->dmPrintQuality = dpi.value().horizontal;
100    }
101    if (dpi.value().vertical > 0) {
102      dev_mode->dmFields |= DM_YRESOLUTION;
103      dev_mode->dmYResolution = dpi.value().vertical;
104    }
105  }
106
107  if (collate.LoadFrom(description)) {
108    dev_mode->dmFields |= DM_COLLATE;
109    dev_mode->dmCollate = (collate.value() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE);
110  }
111
112  if (media.LoadFrom(description)) {
113    static const size_t kFromUm = 100;  // Windows uses 0.1mm.
114    int width = media.value().width_um / kFromUm;
115    int height = media.value().height_um / kFromUm;
116    unsigned id = 0;
117    if (base::StringToUint(media.value().vendor_id, &id) && id) {
118      dev_mode->dmFields |= DM_PAPERSIZE;
119      dev_mode->dmPaperSize = static_cast<short>(id);
120    } else if (width > 0 && height > 0) {
121      dev_mode->dmFields |= DM_PAPERWIDTH;
122      dev_mode->dmPaperWidth = width;
123      dev_mode->dmFields |= DM_PAPERLENGTH;
124      dev_mode->dmPaperLength = height;
125    }
126  }
127
128  return printing::CreateDevMode(printer.Get(), dev_mode.get());
129}
130
131}  // namespace cloud_print
132