Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: printing/backend/cups_ipp_util.cc

Issue 2105463002: Create a new print backend for the updated CUPS APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix printing gyp file. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "printing/backend/cups_ipp_util.h"
6
7 #include <cups/cups.h>
8
9 #include <algorithm>
10 #include <string>
11 #include <vector>
12
13 #include "base/logging.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_piece.h"
16 #include "base/strings/string_split.h"
17 #include "base/strings/string_util.h"
18 #include "printing/backend/cups_printer.h"
19 #include "printing/backend/print_backend_consts.h"
20 #include "printing/units.h"
21
22 namespace printing {
23
24 namespace {
25
26 const char kIppCollate[] = "sheet-collate"; // RFC 3381
27 const char kIppCopies[] = CUPS_COPIES;
28 const char kIppColor[] = CUPS_PRINT_COLOR_MODE;
29 const char kIppMedia[] = CUPS_MEDIA;
30 const char kIppDuplex[] = CUPS_SIDES;
31
32 const int kMicronsPerMM = 1000;
33 const double kMMPerInch = 25.4;
34 const double kMicronsPerInch = kMMPerInch * kMicronsPerMM;
35
36 enum Unit {
37 INCHES,
38 MILLIMETERS,
39 };
40
41 bool PrinterSupportsValue(const CupsPrinter& printer,
42 base::StringPiece name,
43 base::StringPiece value) {
44 std::vector<base::StringPiece> values =
45 printer.GetSupportedOptionValueStrings(name);
46 auto iter = std::find(values.begin(), values.end(), value);
47 return iter != values.end();
48 }
49
50 DuplexMode PrinterDefaultDuplex(const CupsPrinter& printer) {
51 ipp_attribute_t* attr = printer.GetDefaultOptionValue(kIppDuplex);
52 if (attr == nullptr) {
53 return UNKNOWN_DUPLEX_MODE;
54 }
55
56 const char* value = ippGetString(attr, 0, NULL);
57 if (base::EqualsCaseInsensitiveASCII(value, CUPS_SIDES_ONE_SIDED))
58 return SIMPLEX;
59 if (base::EqualsCaseInsensitiveASCII(value, CUPS_SIDES_TWO_SIDED_PORTRAIT))
60 return LONG_EDGE;
61 if (base::EqualsCaseInsensitiveASCII(value, CUPS_SIDES_TWO_SIDED_LANDSCAPE))
62 return SHORT_EDGE;
63
64 return UNKNOWN_DUPLEX_MODE;
65 }
66
67 gfx::Size DimensionsToMicrons(base::StringPiece value) {
68 Unit unit;
69 base::StringPiece dims;
70 size_t unit_position;
71 if ((unit_position = value.find("mm")) != base::StringPiece::npos) {
72 unit = MILLIMETERS;
73 dims = value.substr(0, unit_position);
74 } else if ((unit_position = value.find("in")) != base::StringPiece::npos) {
75 unit = INCHES;
76 dims = value.substr(0, unit_position);
77 } else {
78 LOG(WARNING) << "Could not parse paper dimensions";
79 return {0, 0};
80 }
81
82 std::vector<std::string> pieces = base::SplitString(
83 dims, "x", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
84 double width;
85 double height;
86
87 if (pieces.size() != 2 || !base::StringToDouble(pieces[0], &width) ||
88 !base::StringToDouble(pieces[1], &height)) {
89 return {0, 0};
90 }
91
92 int width_microns;
93 int height_microns;
94
95 switch (unit) {
96 case MILLIMETERS:
97 width_microns = width * kMicronsPerMM;
98 height_microns = height * kMicronsPerMM;
99 break;
100 case INCHES:
101 width_microns = width * kMicronsPerInch;
102 height_microns = height * kMicronsPerInch;
103 break;
104 default:
105 NOTREACHED();
106 break;
107 }
108
109 return gfx::Size{width_microns, height_microns};
110 }
111
112 PrinterSemanticCapsAndDefaults::Paper ParsePaper(base::StringPiece value) {
113 // <name>_<width>x<height>{in,mm}
114 // e.g. na_letter_8.5x11in, iso_a4_210x297mm
115
116 std::vector<base::StringPiece> pieces = base::SplitStringPiece(
117 value, "_", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
118 if (pieces.size() < 2) {
119 // we expect at least a display string and a dimension string
120 return PrinterSemanticCapsAndDefaults::Paper();
121 }
122
123 base::StringPiece dimensions = pieces.back();
124
125 std::string display = pieces[0].as_string();
126 for (size_t i = 1; i <= pieces.size() - 2; ++i) {
127 display.append(" ");
128 pieces[i].AppendToString(&display);
129 }
130
131 PrinterSemanticCapsAndDefaults::Paper paper;
132 paper.display_name = display;
133 paper.vendor_id = value.as_string();
134 paper.size_um = DimensionsToMicrons(dimensions);
135
136 return paper;
137 }
138
139 } // namespace
140
141 void ExtractColor(const CupsPrinter& printer,
142 PrinterSemanticCapsAndDefaults* printer_info) {
143 std::vector<base::StringPiece> color_modes =
144 printer.GetSupportedOptionValueStrings(kIppColor);
145 auto iter = std::find(color_modes.begin(), color_modes.end(),
146 CUPS_PRINT_COLOR_MODE_COLOR);
147 if (iter != color_modes.end()) {
148 printer_info->color_model = COLORMODE_COLOR;
149 } else {
150 printer_info->color_model = UNKNOWN_COLOR_MODEL;
151 }
152
153 iter = std::find(color_modes.begin(), color_modes.end(),
154 CUPS_PRINT_COLOR_MODE_MONOCHROME);
155 if (iter != color_modes.end()) {
156 printer_info->bw_model = COLORMODE_MONOCHROME;
157 } else {
158 printer_info->bw_model = UNKNOWN_COLOR_MODEL;
159 }
160
161 printer_info->color_changeable =
162 (printer_info->color_model != UNKNOWN_COLOR_MODEL &&
163 printer_info->bw_model != UNKNOWN_COLOR_MODEL);
164
165 // default color
166 ipp_attribute_t* attr = printer.GetDefaultOptionValue(kIppColor);
167 if (attr != nullptr) {
168 const char* value = ippGetString(attr, 0, NULL);
169 printer_info->color_default = !base::EqualsCaseInsensitiveASCII(
170 value, CUPS_PRINT_COLOR_MODE_MONOCHROME);
171 }
172 }
173
174 PrinterSemanticCapsAndDefaults::Paper DefaultPaper(const CupsPrinter& printer) {
175 ipp_attribute_t* attr = printer.GetDefaultOptionValue(kIppMedia);
176 if (attr == nullptr) {
177 return PrinterSemanticCapsAndDefaults::Paper();
178 }
179
180 const char* value = ippGetString(attr, 0, NULL);
181 return ParsePaper(value);
182 }
183
184 void ExtractPaper(const CupsPrinter& printer,
185 PrinterSemanticCapsAndDefaults* printer_info) {
186 // paper
187 std::vector<base::StringPiece> papers =
188 printer.GetSupportedOptionValueStrings(kIppMedia);
189 for (base::StringPiece paper : papers) {
190 PrinterSemanticCapsAndDefaults::Paper p = ParsePaper(paper);
191 printer_info->papers.push_back(p);
192 }
193
194 // default paper
195 printer_info->default_paper = DefaultPaper(printer);
196 }
197
198 void ExtractCopies(const CupsPrinter& printer,
199 PrinterSemanticCapsAndDefaults* printer_info) {
200 // copies
201 ipp_attribute_t* attr = printer.GetSupportedOptionValues(kIppCopies);
202 if (attr != nullptr) {
203 int upper_bound;
204 int lower_bound = ippGetRange(attr, 0, &upper_bound);
205 printer_info->copies_capable = (lower_bound != -1) && (upper_bound >= 2);
206 } else {
207 printer_info->copies_capable = false;
208 }
209 }
210
211 void ExtractCollate(const CupsPrinter& printer,
212 PrinterSemanticCapsAndDefaults* printer_info) {
213 ipp_attribute_t* attr;
214
215 // collate
216 std::vector<base::StringPiece> values =
217 printer.GetSupportedOptionValueStrings(kIppCollate);
218 auto iter = std::find(values.begin(), values.end(), "collated");
219 printer_info->collate_capable = iter != values.end();
220
221 // collate default
222 attr = printer.GetDefaultOptionValue(kIppCollate);
223 if (attr != nullptr) {
224 base::StringPiece name = ippGetString(attr, 0, NULL);
225 printer_info->collate_default = name.compare("collated") == 0;
226 } else {
227 printer_info->collate_default = false;
228 }
229 }
230
231 void ExtractDuplex(const CupsPrinter& printer,
232 PrinterSemanticCapsAndDefaults* printer_info) {
233 printer_info->duplex_capable =
234 PrinterSupportsValue(printer, kIppDuplex, CUPS_SIDES_TWO_SIDED_PORTRAIT);
235 printer_info->duplex_default = PrinterDefaultDuplex(printer);
236 }
237
238 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698