cdd_conversion_win.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 "components/cloud_devices/printer_description.h" 8#include "printing/backend/print_backend.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 = CreateDevModeWithColor(printer, printer_name, is_color); 37 } else { 38 dev_mode = printing::CreateDevMode(printer, NULL); 39 } 40 } 41 42 if (!dev_mode) 43 return dev_mode.Pass(); 44 45 ColorTicketItem color; 46 DuplexTicketItem duplex; 47 OrientationTicketItem orientation; 48 MarginsTicketItem margins; 49 DpiTicketItem dpi; 50 FitToPageTicketItem fit_to_page; 51 MediaTicketItem media; 52 CopiesTicketItem copies; 53 PageRangeTicketItem page_range; 54 CollateTicketItem collate; 55 ReverseTicketItem reverse; 56 57 if (orientation.LoadFrom(description)) { 58 dev_mode->dmFields |= DM_ORIENTATION; 59 if (orientation.value() == LANDSCAPE) { 60 dev_mode->dmOrientation = DMORIENT_LANDSCAPE; 61 } else { 62 dev_mode->dmOrientation = DMORIENT_PORTRAIT; 63 } 64 } 65 66 if (color.LoadFrom(description)) { 67 dev_mode->dmFields |= DM_COLOR; 68 if (color.value().type == STANDARD_MONOCHROME) { 69 dev_mode->dmColor = DMCOLOR_MONOCHROME; 70 } else if (color.value().type == STANDARD_COLOR) { 71 dev_mode->dmColor = DMCOLOR_COLOR; 72 } else { 73 NOTREACHED(); 74 } 75 } 76 77 if (duplex.LoadFrom(description)) { 78 dev_mode->dmFields |= DM_DUPLEX; 79 if (duplex.value() == NO_DUPLEX) { 80 dev_mode->dmDuplex = DMDUP_SIMPLEX; 81 } else if (duplex.value() == LONG_EDGE) { 82 dev_mode->dmDuplex = DMDUP_VERTICAL; 83 } else if (duplex.value() == SHORT_EDGE) { 84 dev_mode->dmDuplex = DMDUP_HORIZONTAL; 85 } else { 86 NOTREACHED(); 87 } 88 } 89 90 if (copies.LoadFrom(description)) { 91 dev_mode->dmFields |= DM_COPIES; 92 dev_mode->dmCopies = copies.value(); 93 } 94 95 if (dpi.LoadFrom(description)) { 96 if (dpi.value().horizontal > 0) { 97 dev_mode->dmFields |= DM_PRINTQUALITY; 98 dev_mode->dmPrintQuality = dpi.value().horizontal; 99 } 100 if (dpi.value().vertical > 0) { 101 dev_mode->dmFields |= DM_YRESOLUTION; 102 dev_mode->dmYResolution = dpi.value().vertical; 103 } 104 } 105 106 if (collate.LoadFrom(description)) { 107 dev_mode->dmFields |= DM_COLLATE; 108 dev_mode->dmCollate = (collate.value() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE); 109 } 110 111 if (media.LoadFrom(description)) { 112 static const size_t kFromUm = 100; // Windows uses 0.1mm. 113 int width = media.value().width_um / kFromUm; 114 int height = media.value().height_um / kFromUm; 115 if (width > 0) { 116 dev_mode->dmFields |= DM_PAPERWIDTH; 117 dev_mode->dmPaperWidth = width; 118 } 119 if (height > 0) { 120 dev_mode->dmFields |= DM_PAPERLENGTH; 121 dev_mode->dmPaperLength = height; 122 } 123 } 124 125 return printing::CreateDevMode(printer, dev_mode.get()); 126} 127 128std::string CapabilitiesToCdd( 129 const printing::PrinterSemanticCapsAndDefaults& semantic_info) { 130 using namespace cloud_devices::printer; 131 cloud_devices::CloudDeviceDescription description; 132 133 ContentTypesCapability content_types; 134 content_types.AddOption("application/pdf"); 135 content_types.SaveTo(&description); 136 137 ColorCapability color; 138 if (semantic_info.color_default || semantic_info.color_changeable) { 139 color.AddDefaultOption(Color(STANDARD_COLOR), semantic_info.color_default); 140 } 141 142 if (!semantic_info.color_default || semantic_info.color_changeable) { 143 color.AddDefaultOption(Color(STANDARD_MONOCHROME), 144 !semantic_info.color_default); 145 } 146 color.SaveTo(&description); 147 148 if (semantic_info.duplex_capable) { 149 DuplexCapability duplex; 150 duplex.AddDefaultOption( 151 NO_DUPLEX, semantic_info.duplex_default == printing::SIMPLEX); 152 duplex.AddDefaultOption( 153 LONG_EDGE, semantic_info.duplex_default == printing::LONG_EDGE); 154 duplex.AddDefaultOption( 155 SHORT_EDGE, semantic_info.duplex_default == printing::SHORT_EDGE); 156 duplex.SaveTo(&description); 157 } 158 159 if (!semantic_info.papers.empty()) { 160 Media default_media(semantic_info.default_paper.name, 161 semantic_info.default_paper.size_um.width(), 162 semantic_info.default_paper.size_um.height()); 163 default_media.MatchBySize(); 164 165 MediaCapability media; 166 bool is_default_set = false; 167 for (size_t i = 0; i < semantic_info.papers.size(); ++i) { 168 gfx::Size paper_size = semantic_info.papers[i].size_um; 169 if (paper_size.width() > paper_size.height()) 170 paper_size.SetSize(paper_size.height(), paper_size.width()); 171 Media new_media(semantic_info.papers[i].name, paper_size.width(), 172 paper_size.height()); 173 new_media.MatchBySize(); 174 if (new_media.IsValid() && !media.Contains(new_media)) { 175 if (!default_media.IsValid()) 176 default_media = new_media; 177 media.AddDefaultOption(new_media, new_media == default_media); 178 is_default_set = is_default_set || (new_media == default_media); 179 } 180 } 181 if (!is_default_set && default_media.IsValid()) 182 media.AddDefaultOption(default_media, true); 183 184 if (media.IsValid()) { 185 media.SaveTo(&description); 186 } else { 187 NOTREACHED(); 188 } 189 } 190 191 if (semantic_info.collate_capable) { 192 CollateCapability collate; 193 collate.set_default_value(semantic_info.collate_default); 194 collate.SaveTo(&description); 195 } 196 197 if (semantic_info.copies_capable) { 198 CopiesCapability copies; 199 copies.SaveTo(&description); 200 } 201 202 if (!semantic_info.dpis.empty()) { 203 DpiCapability dpi; 204 Dpi default_dpi(semantic_info.default_dpi.width(), 205 semantic_info.default_dpi.height()); 206 bool is_default_set = false; 207 for (size_t i = 0; i < semantic_info.dpis.size(); ++i) { 208 Dpi new_dpi(semantic_info.dpis[i].width(), 209 semantic_info.dpis[i].height()); 210 if (new_dpi.IsValid() && !dpi.Contains(new_dpi)) { 211 if (!default_dpi.IsValid()) 212 default_dpi = new_dpi; 213 dpi.AddDefaultOption(new_dpi, new_dpi == default_dpi); 214 is_default_set = is_default_set || (new_dpi == default_dpi); 215 } 216 } 217 if (!is_default_set && default_dpi.IsValid()) 218 dpi.AddDefaultOption(default_dpi, true); 219 if (dpi.IsValid()) { 220 dpi.SaveTo(&description); 221 } else { 222 NOTREACHED(); 223 } 224 } 225 226 OrientationCapability orientation; 227 orientation.AddDefaultOption(PORTRAIT, true); 228 orientation.AddOption(LANDSCAPE); 229 orientation.AddOption(AUTO_ORIENTATION); 230 orientation.SaveTo(&description); 231 232 return description.ToString(); 233} 234 235} // namespace cloud_print 236