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; |
} |