summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralekseys@chromium.org <alekseys@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-13 22:00:57 +0000
committeralekseys@chromium.org <alekseys@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-13 22:00:57 +0000
commit117eb82d7a3b62cb363fb8e64dc9aa3a7ef7e028 (patch)
tree996988f3b9d32f0c8db3453dfcb9a62c1d8d6fc6
parent3a8b058d8c2eb1a6345196fdf8158593a3bcfeef (diff)
downloadchromium_src-117eb82d7a3b62cb363fb8e64dc9aa3a7ef7e028.zip
chromium_src-117eb82d7a3b62cb363fb8e64dc9aa3a7ef7e028.tar.gz
chromium_src-117eb82d7a3b62cb363fb8e64dc9aa3a7ef7e028.tar.bz2
Add paper size reporting for CUPS printers (to let user to select one in the Print Preview).
BUG=239879 Review URL: https://codereview.chromium.org/334763002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277098 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/libgtk2ui/print_dialog_gtk2.cc83
-rw-r--r--chrome/common/chrome_utility_messages.h3
-rw-r--r--chrome/common/cloud_print/cloud_print_cdd_conversion.cc8
-rw-r--r--printing/backend/cups_helper.cc39
-rw-r--r--printing/backend/cups_helper_unittest.cc33
-rw-r--r--printing/backend/print_backend.h3
-rw-r--r--printing/backend/print_backend_win.cc4
7 files changed, 164 insertions, 9 deletions
diff --git a/chrome/browser/ui/libgtk2ui/print_dialog_gtk2.cc b/chrome/browser/ui/libgtk2ui/print_dialog_gtk2.cc
index 971eecc..b8b0141 100644
--- a/chrome/browser/ui/libgtk2ui/print_dialog_gtk2.cc
+++ b/chrome/browser/ui/libgtk2ui/print_dialog_gtk2.cc
@@ -6,6 +6,8 @@
#include <gtk/gtkunixprint.h>
+#include <algorithm>
+#include <cmath>
#include <string>
#include <vector>
@@ -36,6 +38,53 @@ const char kDuplexNone[] = "None";
const char kDuplexTumble[] = "DuplexTumble";
const char kDuplexNoTumble[] = "DuplexNoTumble";
+int kPaperSizeTresholdMicrons = 100;
+int kMicronsInMm = 1000;
+
+// Checks whether gtk_paper_size can be used to represent user selected media.
+// In fuzzy match mode checks that paper sizes are "close enough" (less than
+// 1mm difference). In the exact mode, looks for the paper with the same PPD
+// name and "close enough" size.
+bool PaperSizeMatch(GtkPaperSize* gtk_paper_size,
+ const PrintSettings::RequestedMedia& media,
+ bool fuzzy_match) {
+ if (!gtk_paper_size) {
+ return false;
+ }
+ gfx::Size paper_size_microns(
+ static_cast<int>(gtk_paper_size_get_width(gtk_paper_size, GTK_UNIT_MM) *
+ kMicronsInMm + 0.5),
+ static_cast<int>(gtk_paper_size_get_height(gtk_paper_size, GTK_UNIT_MM) *
+ kMicronsInMm + 0.5));
+ int diff = std::max(
+ std::abs(paper_size_microns.width() - media.size_microns.width()),
+ std::abs(paper_size_microns.height() - media.size_microns.height()));
+ if (fuzzy_match) {
+ return diff <= kPaperSizeTresholdMicrons;
+ }
+ return !media.vendor_id.empty() &&
+ media.vendor_id == gtk_paper_size_get_ppd_name(gtk_paper_size) &&
+ diff <= kPaperSizeTresholdMicrons;
+}
+
+// Looks up a paper size matching (in terms of PaperSizeMatch) the user selected
+// media in the paper size list reported by GTK. Returns NULL if there's no
+// match found.
+GtkPaperSize* FindPaperSizeMatch(GList* gtk_paper_sizes,
+ const PrintSettings::RequestedMedia& media) {
+ GtkPaperSize* first_fuzzy_match = NULL;
+ for (GList* p = gtk_paper_sizes; p && p->data; p = g_list_next(p)) {
+ GtkPaperSize* gtk_paper_size = static_cast<GtkPaperSize*>(p->data);
+ if (PaperSizeMatch(gtk_paper_size, media, false)) {
+ return gtk_paper_size;
+ }
+ if (!first_fuzzy_match && PaperSizeMatch(gtk_paper_size, media, true)) {
+ first_fuzzy_match = gtk_paper_size;
+ }
+ }
+ return first_fuzzy_match;
+}
+
class StickyPrintSettingGtk {
public:
StickyPrintSettingGtk() : last_used_settings_(gtk_print_settings_new()) {
@@ -224,6 +273,40 @@ bool PrintDialogGtk2::UpdateSettings(printing::PrintSettings* settings) {
if (!page_setup_)
page_setup_ = gtk_page_setup_new();
+ if (page_setup_ && !settings->requested_media().IsDefault()) {
+ const PrintSettings::RequestedMedia& requested_media =
+ settings->requested_media();
+ GtkPaperSize* gtk_current_paper_size =
+ gtk_page_setup_get_paper_size(page_setup_);
+ if (!PaperSizeMatch(gtk_current_paper_size, requested_media,
+ true /*fuzzy_match*/)) {
+ GList* gtk_paper_sizes =
+ gtk_paper_size_get_paper_sizes(false /*include_custom*/);
+ if (gtk_paper_sizes) {
+ GtkPaperSize* matching_gtk_paper_size =
+ FindPaperSizeMatch(gtk_paper_sizes, requested_media);
+ if (matching_gtk_paper_size) {
+ VLOG(1) << "Using listed paper size";
+ gtk_page_setup_set_paper_size(page_setup_, matching_gtk_paper_size);
+ } else {
+ VLOG(1) << "Using custom paper size";
+ GtkPaperSize* custom_size = gtk_paper_size_new_custom(
+ requested_media.vendor_id.c_str(),
+ requested_media.vendor_id.c_str(),
+ requested_media.size_microns.width() / kMicronsInMm,
+ requested_media.size_microns.height() / kMicronsInMm,
+ GTK_UNIT_MM);
+ gtk_page_setup_set_paper_size(page_setup_, custom_size);
+ gtk_paper_size_free(custom_size);
+ }
+ g_list_free_full(gtk_paper_sizes,
+ reinterpret_cast<GDestroyNotify>(gtk_paper_size_free));
+ }
+ } else {
+ VLOG(1) << "Using default paper size";
+ }
+ }
+
gtk_print_settings_set_orientation(
gtk_settings_,
settings->landscape() ? GTK_PAGE_ORIENTATION_LANDSCAPE :
diff --git a/chrome/common/chrome_utility_messages.h b/chrome/common/chrome_utility_messages.h
index b706ee54..b916536 100644
--- a/chrome/common/chrome_utility_messages.h
+++ b/chrome/common/chrome_utility_messages.h
@@ -52,7 +52,8 @@ IPC_ENUM_TRAITS_MAX_VALUE(printing::ColorModel, printing::PROCESSCOLORMODEL_RGB)
IPC_ENUM_TRAITS_MAX_VALUE(printing::DuplexMode, printing::SHORT_EDGE)
IPC_STRUCT_TRAITS_BEGIN(printing::PrinterSemanticCapsAndDefaults::Paper)
- IPC_STRUCT_TRAITS_MEMBER(name)
+ IPC_STRUCT_TRAITS_MEMBER(display_name)
+ IPC_STRUCT_TRAITS_MEMBER(vendor_id)
IPC_STRUCT_TRAITS_MEMBER(size_um)
IPC_STRUCT_TRAITS_END()
diff --git a/chrome/common/cloud_print/cloud_print_cdd_conversion.cc b/chrome/common/cloud_print/cloud_print_cdd_conversion.cc
index b485cff..70c774d 100644
--- a/chrome/common/cloud_print/cloud_print_cdd_conversion.cc
+++ b/chrome/common/cloud_print/cloud_print_cdd_conversion.cc
@@ -55,8 +55,8 @@ scoped_ptr<base::DictionaryValue> PrinterSemanticCapsAndDefaultsToCdd(
color.SaveTo(&description);
if (!semantic_info.papers.empty()) {
- Media default_media(semantic_info.default_paper.name,
- "",
+ Media default_media(semantic_info.default_paper.display_name,
+ semantic_info.default_paper.vendor_id,
semantic_info.default_paper.size_um.width(),
semantic_info.default_paper.size_um.height());
default_media.MatchBySize();
@@ -67,8 +67,8 @@ scoped_ptr<base::DictionaryValue> PrinterSemanticCapsAndDefaultsToCdd(
gfx::Size paper_size = semantic_info.papers[i].size_um;
if (paper_size.width() > paper_size.height())
paper_size.SetSize(paper_size.height(), paper_size.width());
- Media new_media(semantic_info.papers[i].name,
- "",
+ Media new_media(semantic_info.papers[i].display_name,
+ semantic_info.papers[i].vendor_id,
paper_size.width(),
paper_size.height());
new_media.MatchBySize();
diff --git a/printing/backend/cups_helper.cc b/printing/backend/cups_helper.cc
index 981a539..b36722d 100644
--- a/printing/backend/cups_helper.cc
+++ b/printing/backend/cups_helper.cc
@@ -16,6 +16,7 @@
#include "base/values.h"
#include "printing/backend/print_backend.h"
#include "printing/backend/print_backend_consts.h"
+#include "printing/units.h"
#include "url/gurl.h"
namespace printing {
@@ -33,6 +34,9 @@ const char kHighGray[] = "High.Gray";
const char kDuplex[] = "Duplex";
const char kDuplexNone[] = "None";
+const char kPageSize[] = "PageSize";
+
+const double kMicronsPerPoint = kHundrethsMMPerInch / kPointsPerInch * 10;
#if !defined(OS_MACOSX)
void ParseLpOptions(const base::FilePath& filepath,
@@ -358,8 +362,13 @@ bool ParsePpdCapabilities(
}
ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str());
- if (!ppd)
+ if (!ppd) {
+ int line = 0;
+ ppd_status_t ppd_status = ppdLastError(&line);
+ LOG(ERROR) << "Failed to open PDD file: error " << ppd_status << " at line "
+ << line << ", " << ppdErrorString(ppd_status);
return false;
+ }
printing::PrinterSemanticCapsAndDefaults caps;
#if !defined(OS_MACOSX)
@@ -397,6 +406,34 @@ bool ParsePpdCapabilities(
caps.color_model = cm_color;
caps.bw_model = cm_black;
+ if (ppd->num_sizes > 0 && ppd->sizes) {
+ VLOG(1) << "Paper list size - " << ppd->num_sizes;
+ ppd_option_t* paper_option = ppdFindOption(ppd, kPageSize);
+ for (int i = 0; i < ppd->num_sizes; ++i) {
+ gfx::Size paper_size_microns(
+ static_cast<int>(ppd->sizes[i].width * kMicronsPerPoint + 0.5),
+ static_cast<int>(ppd->sizes[i].length * kMicronsPerPoint + 0.5));
+ if (paper_size_microns.width() > 0 && paper_size_microns.height() > 0) {
+ PrinterSemanticCapsAndDefaults::Paper paper;
+ paper.size_um = paper_size_microns;
+ paper.vendor_id = ppd->sizes[i].name;
+ if (paper_option) {
+ ppd_choice_t* paper_choice =
+ ppdFindChoice(paper_option, ppd->sizes[i].name);
+ // Human readable paper name should be UTF-8 encoded, but some PPDs
+ // do not follow this standard.
+ if (paper_choice && base::IsStringUTF8(paper_choice->text)) {
+ paper.display_name = paper_choice->text;
+ }
+ }
+ caps.papers.push_back(paper);
+ if (i == 0 || ppd->sizes[i].marked) {
+ caps.default_paper = paper;
+ }
+ }
+ }
+ }
+
ppdClose(ppd);
base::DeleteFile(ppd_file_path, false);
diff --git a/printing/backend/cups_helper_unittest.cc b/printing/backend/cups_helper_unittest.cc
index 83dc0a1..2a0e72b 100644
--- a/printing/backend/cups_helper_unittest.cc
+++ b/printing/backend/cups_helper_unittest.cc
@@ -172,3 +172,36 @@ TEST(PrintBackendCupsHelperTest, TestPpdParsingColorFalseDuplexLongEdge) {
EXPECT_TRUE(caps.color_changeable);
EXPECT_FALSE(caps.color_default);
}
+
+TEST(PrintBackendCupsHelperTest, TestPpdParsingPageSize) {
+ std::string test_ppd_data;
+ test_ppd_data.append(
+ "*PPD-Adobe: \"4.3\"\n\n"
+ "*OpenUI *PageSize: PickOne\n"
+ "*OrderDependency: 30 AnySetup *PageSize\n"
+ "*DefaultPageSize: Letter\n"
+ "*PageSize Letter/US Letter: \""
+ " <</DeferredMediaSelection true /PageSize [612 792] "
+ " /ImagingBBox null /MediaClass null >> setpagedevice\"\n"
+ "*End\n"
+ "*PageSize Legal/US Legal: \""
+ " <</DeferredMediaSelection true /PageSize [612 1008] "
+ " /ImagingBBox null /MediaClass null >> setpagedevice\"\n"
+ "*End\n"
+ "*DefaultPaperDimension: Letter\n"
+ "*PaperDimension Letter/US Letter: \"612 792\"\n"
+ "*PaperDimension Legal/US Legal: \"612 1008\"\n\n"
+ "*CloseUI: *PageSize\n\n");
+
+ printing::PrinterSemanticCapsAndDefaults caps;
+ EXPECT_TRUE(printing::ParsePpdCapabilities("test", test_ppd_data, &caps));
+ ASSERT_EQ(2UL, caps.papers.size());
+ EXPECT_EQ("Letter", caps.papers[0].vendor_id);
+ EXPECT_EQ("US Letter", caps.papers[0].display_name);
+ EXPECT_EQ(214200, caps.papers[0].size_um.width());
+ EXPECT_EQ(277200, caps.papers[0].size_um.height());
+ EXPECT_EQ("Legal", caps.papers[1].vendor_id);
+ EXPECT_EQ("US Legal", caps.papers[1].display_name);
+ EXPECT_EQ(214200, caps.papers[1].size_um.width());
+ EXPECT_EQ(352800, caps.papers[1].size_um.height());
+}
diff --git a/printing/backend/print_backend.h b/printing/backend/print_backend.h
index 3b307f1..e03ef42 100644
--- a/printing/backend/print_backend.h
+++ b/printing/backend/print_backend.h
@@ -52,7 +52,8 @@ struct PRINTING_EXPORT PrinterSemanticCapsAndDefaults {
ColorModel bw_model;
struct Paper {
- std::string name;
+ std::string display_name;
+ std::string vendor_id;
gfx::Size size_um;
};
std::vector<Paper> papers;
diff --git a/printing/backend/print_backend_win.cc b/printing/backend/print_backend_win.cc
index 87c69ee..287a1f0 100644
--- a/printing/backend/print_backend_win.cc
+++ b/printing/backend/print_backend_win.cc
@@ -93,7 +93,7 @@ void LoadPaper(const wchar_t* printer,
base::string16 tmp_name(name_start, kMaxPaperName);
// Trim trailing zeros.
tmp_name = tmp_name.c_str();
- paper.name = base::WideToUTF8(tmp_name);
+ paper.display_name = base::WideToUTF8(tmp_name);
}
caps->papers.push_back(paper);
}
@@ -119,7 +119,7 @@ void LoadPaper(const wchar_t* printer,
base::string16 tmp_name(name_start, kMaxPaperName);
// Trim trailing zeros.
tmp_name = tmp_name.c_str();
- paper.name = base::WideToUTF8(tmp_name);
+ paper.display_name = base::WideToUTF8(tmp_name);
}
caps->default_paper = paper;
break;