Chromium Code Reviews| Index: printing/backend/print_backend_win.cc |
| diff --git a/printing/backend/print_backend_win.cc b/printing/backend/print_backend_win.cc |
| index abf8404e404f8da7cbf9cfcf4fefcc98cc7081d2..de42c46725ce55ec2a2051c423e04322c3e23c2e 100644 |
| --- a/printing/backend/print_backend_win.cc |
| +++ b/printing/backend/print_backend_win.cc |
| @@ -17,6 +17,7 @@ |
| #include "printing/backend/printing_info_win.h" |
| #include "printing/backend/win_helper.h" |
| +namespace printing { |
| namespace { |
| @@ -33,9 +34,128 @@ HRESULT StreamOnHGlobalToString(IStream* stream, std::string* out) { |
| return hr; |
| } |
| -} // namespace |
| +template <class T> |
| +void GetDeviceCapabilityArray(const wchar_t* printer, |
| + const wchar_t* port, |
| + WORD id, |
| + std::vector<T>* result) { |
| + int count = DeviceCapabilities(printer, port, id, NULL, NULL); |
| + if (count <= 0) |
| + return; |
| + result->resize(count); |
| + CHECK_EQ(count, |
| + DeviceCapabilities(printer, port, id, |
|
Noam Samuel
2014/02/04 18:33:22
Misaligned.
Vitaly Buka (NO REVIEWS)
2014/02/04 18:48:24
Done.
|
| + reinterpret_cast<LPTSTR>(result->data()), NULL)); |
| +} |
| -namespace printing { |
| +void LoadPaper(const wchar_t* printer, |
| + const wchar_t* port, |
| + const DEVMODE* devmode, |
| + PrinterSemanticCapsAndDefaults* caps) { |
| + static const size_t kToUm = 100; |
| + static const size_t kMaxPaperName = 64; |
| + |
| + short default_id = 0; |
| + gfx::Size default_size; |
| + |
| + if (devmode) { |
| + if ((devmode->dmFields & DM_PAPERSIZE) == DM_PAPERSIZE) |
| + default_id = devmode->dmPaperSize; |
| + if ((devmode->dmFields & DM_PAPERWIDTH) == DM_PAPERWIDTH) |
| + default_size.set_width(devmode->dmPaperWidth * kToUm); |
| + if ((devmode->dmFields & DM_PAPERLENGTH) == DM_PAPERLENGTH) |
| + default_size.set_height(devmode->dmPaperLength * kToUm); |
| + } |
| + |
| + struct PaperName { |
| + wchar_t chars[kMaxPaperName]; |
| + }; |
| + |
| + // Paper |
| + std::vector<PaperName> names; |
| + GetDeviceCapabilityArray(printer, port, DC_PAPERNAMES, &names); |
| + |
| + std::vector<POINT> sizes; |
| + GetDeviceCapabilityArray(printer, port, DC_PAPERSIZE, &sizes); |
| + |
| + std::vector<WORD> ids; |
| + GetDeviceCapabilityArray(printer, port, DC_PAPERS, &ids); |
| + |
| + DCHECK_EQ(ids.size(), sizes.size()); |
| + DCHECK_EQ(names.size(), sizes.size()); |
| + |
| + if (ids.size() != sizes.size()) |
| + ids.clear(); |
| + if (names.size() != sizes.size()) |
| + names.clear(); |
| + |
| + for (size_t i = 0; i < sizes.size(); ++i) { |
| + PrinterSemanticCapsAndDefaults::Paper paper; |
| + paper.size_um.SetSize(sizes[i].x * kToUm, sizes[i].y * kToUm); |
| + if (!names.empty()) { |
| + paper.name.assign(&names[i].chars, &names[i].chars + kMaxPaperName); |
| + // Trim trailing zeros. |
| + paper.name = paper.name.c_str(); |
| + } |
| + if (caps->default_paper < 0) { |
| + if (!default_size.IsEmpty()) { |
| + if (default_size == paper.size_um) |
| + caps->default_paper = i; |
| + } else if (default_id && !ids.empty() && ids[i] == default_id) { |
| + caps->default_paper = i; |
| + } |
| + } |
| + caps->papers.push_back(paper); |
| + } |
| + |
| + if (caps->default_paper < 0) { |
| + // Add default paper because DeviceCapabilities it was not found yet. |
|
Noam Samuel
2014/02/04 18:33:22
"Add default paper because DeviceCapabilities hasn
Vitaly Buka (NO REVIEWS)
2014/02/04 18:48:24
Done.
|
| + if (!default_size.IsEmpty()) { |
| + caps->default_paper = caps->papers.size(); |
| + PrinterSemanticCapsAndDefaults::Paper paper; |
| + paper.size_um = default_size; |
| + paper.name = "CUSTOM"; |
| + caps->papers.push_back(paper); |
| + } |
| + } |
| +} |
| + |
| +void LoadDpi(const wchar_t* printer, |
| + const wchar_t* port, |
| + const DEVMODE* devmode, |
| + PrinterSemanticCapsAndDefaults* caps) { |
| + gfx::Size default_dpi; |
| + |
| + if (devmode) { |
| + if ((devmode->dmFields & DM_PRINTQUALITY) == DM_PRINTQUALITY && |
| + devmode->dmPrintQuality > 0) { |
| + default_dpi.SetSize(devmode->dmPrintQuality, devmode->dmPrintQuality); |
| + if ((devmode->dmFields & DM_YRESOLUTION) == DM_PRINTQUALITY) { |
| + default_dpi.set_height(devmode->dmYResolution); |
| + } |
| + } |
| + } |
| + |
| + std::vector<POINT> dpis; |
| + GetDeviceCapabilityArray(printer, port, DC_ENUMRESOLUTIONS, &dpis); |
| + |
| + for (size_t i = 0; i < dpis.size() ; ++i) { |
| + gfx::Size dpi(dpis[i].x, dpis[i].y); |
| + if (caps->default_dpi < 0 && default_dpi == dpi) |
| + caps->default_dpi = i; |
| + caps->dpis.push_back(dpi); |
| + } |
| + |
| + if (caps->default_dpi < 0) { |
| + // Add default dpi because DeviceCapabilities didn't return it. |
| + if (!default_dpi.IsEmpty()) { |
| + caps->default_dpi = caps->dpis.size(); |
| + caps->dpis.push_back(default_dpi); |
| + } |
| + } |
| +} |
| + |
| +} // namespace |
| class PrintBackendWin : public PrintBackend { |
| public: |
| @@ -108,29 +228,14 @@ bool PrintBackendWin::GetPrinterSemanticCapsAndDefaults( |
| } |
| PrinterInfo5 info_5; |
| - if (!info_5.Init(printer_handle)) { |
| + if (!info_5.Init(printer_handle)) |
| return false; |
| - } |
| - DCHECK_EQ(info_5.get()->pPrinterName, base::UTF8ToUTF16(printer_name)); |
| + const wchar_t* name = info_5.get()->pPrinterName; |
| + const wchar_t* port = info_5.get()->pPortName; |
| + DCHECK_EQ(name, base::UTF8ToUTF16(printer_name)); |
| PrinterSemanticCapsAndDefaults caps; |
| - |
| - // Get printer capabilities. For more info see here: |
| - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183552(v=vs.85).aspx |
| - caps.color_changeable = (::DeviceCapabilities(info_5.get()->pPrinterName, |
| - info_5.get()->pPortName, |
| - DC_COLORDEVICE, |
| - NULL, |
| - NULL) == 1); |
| - |
| - caps.duplex_capable = (::DeviceCapabilities(info_5.get()->pPrinterName, |
| - info_5.get()->pPortName, |
| - DC_DUPLEX, |
| - NULL, |
| - NULL) == 1); |
| - |
| UserDefaultDevMode user_settings; |
| - |
| if (user_settings.Init(printer_handle)) { |
| if ((user_settings.get()->dmFields & DM_COLOR) == DM_COLOR) |
| caps.color_default = (user_settings.get()->dmColor == DMCOLOR_COLOR); |
| @@ -150,12 +255,32 @@ bool PrintBackendWin::GetPrinterSemanticCapsAndDefaults( |
| NOTREACHED(); |
| } |
| } |
| + |
| + if ((user_settings.get()->dmFields & DM_COLLATE) == DM_COLLATE) |
| + caps.collate_default = (user_settings.get()->dmCollate == DMCOLLATE_TRUE); |
| } else { |
| LOG(WARNING) << "Fallback to color/simplex mode."; |
| caps.color_default = caps.color_changeable; |
| caps.duplex_default = SIMPLEX; |
| } |
| + // Get printer capabilities. For more info see here: |
| + // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183552(v=vs.85).aspx |
| + caps.color_changeable = |
| + (DeviceCapabilities(name, port, DC_COLORDEVICE, NULL, NULL) == 1); |
| + |
| + caps.duplex_capable = |
| + (DeviceCapabilities(name, port, DC_DUPLEX, NULL, NULL) == 1); |
| + |
| + caps.collate_capable = |
| + (DeviceCapabilities(name, port, DC_COLLATE, NULL, NULL) == 1); |
| + |
| + caps.copies_capable = |
| + (DeviceCapabilities(name, port, DC_COPIES, NULL, NULL) > 1); |
| + |
| + LoadPaper(name, port, user_settings.get(), &caps); |
| + LoadDpi(name, port, user_settings.get(), &caps); |
| + |
| *printer_info = caps; |
| return true; |
| } |