blob: 98a9ebf986b093912cf0a5535234127974a14982 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 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.
initial.commit09911bf2008-07-26 23:55:294
[email protected]8ff1d422009-07-07 21:31:395#include "printing/print_settings.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]b7191422010-09-21 19:18:057// TODO(jhawkins): Move platform-specific implementations to their own files.
8#if defined(USE_X11)
9#include <gtk/gtk.h>
10#endif // defined(USE_X11)
11
[email protected]d30e8e642008-08-06 12:05:2412#include "base/atomic_sequence_num.h"
initial.commit09911bf2008-07-26 23:55:2913#include "base/logging.h"
[email protected]b7191422010-09-21 19:18:0514#include "base/string_piece.h"
[email protected]b75dca82009-10-13 18:46:2115#include "base/sys_string_conversions.h"
[email protected]b7191422010-09-21 19:18:0516#include "base/utf_string_conversions.h"
[email protected]4ae30d082009-02-20 17:55:5517#include "printing/units.h"
initial.commit09911bf2008-07-26 23:55:2918
19namespace printing {
20
[email protected]d30e8e642008-08-06 12:05:2421// Global SequenceNumber used for generating unique cookie values.
[email protected]a10a16b2008-09-02 13:11:4622static base::AtomicSequenceNumber cookie_seq(base::LINKER_INITIALIZED);
initial.commit09911bf2008-07-26 23:55:2923
24PrintSettings::PrintSettings()
25 : min_shrink(1.25),
26 max_shrink(2.0),
27 desired_dpi(72),
[email protected]c8ad40c2009-06-08 17:05:2128 selection_only(false),
[email protected]38bba4f2010-03-12 05:29:0729 use_overlays(true),
initial.commit09911bf2008-07-26 23:55:2930 dpi_(0),
31 landscape_(false) {
32}
33
34void PrintSettings::Clear() {
35 ranges.clear();
36 min_shrink = 1.25;
37 max_shrink = 2.;
38 desired_dpi = 72;
[email protected]c8ad40c2009-06-08 17:05:2139 selection_only = false;
initial.commit09911bf2008-07-26 23:55:2940 printer_name_.clear();
41 device_name_.clear();
[email protected]6ab86ac2010-05-29 07:18:2942 page_setup_device_units_.Clear();
initial.commit09911bf2008-07-26 23:55:2943 dpi_ = 0;
44 landscape_ = false;
45}
46
[email protected]b7191422010-09-21 19:18:0547#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:2948void PrintSettings::Init(HDC hdc,
49 const DEVMODE& dev_mode,
50 const PageRanges& new_ranges,
[email protected]c8ad40c2009-06-08 17:05:2151 const std::wstring& new_device_name,
52 bool print_selection_only) {
initial.commit09911bf2008-07-26 23:55:2953 DCHECK(hdc);
54 printer_name_ = dev_mode.dmDeviceName;
55 device_name_ = new_device_name;
56 ranges = new_ranges;
57 landscape_ = dev_mode.dmOrientation == DMORIENT_LANDSCAPE;
[email protected]c8ad40c2009-06-08 17:05:2158 selection_only = print_selection_only;
initial.commit09911bf2008-07-26 23:55:2959
initial.commit09911bf2008-07-26 23:55:2960 dpi_ = GetDeviceCaps(hdc, LOGPIXELSX);
61 // No printer device is known to advertise different dpi in X and Y axis; even
62 // the fax device using the 200x100 dpi setting. It's ought to break so many
63 // applications that it's not even needed to care about. WebKit doesn't
64 // support different dpi settings in X and Y axis.
65 DCHECK_EQ(dpi_, GetDeviceCaps(hdc, LOGPIXELSY));
66
67 DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORX), 0);
68 DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORY), 0);
69
[email protected]6ab86ac2010-05-29 07:18:2970 // Initialize page_setup_device_units_.
71 gfx::Size physical_size_device_units(GetDeviceCaps(hdc, PHYSICALWIDTH),
72 GetDeviceCaps(hdc, PHYSICALHEIGHT));
73 gfx::Rect printable_area_device_units(GetDeviceCaps(hdc, PHYSICALOFFSETX),
74 GetDeviceCaps(hdc, PHYSICALOFFSETY),
75 GetDeviceCaps(hdc, HORZRES),
76 GetDeviceCaps(hdc, VERTRES));
[email protected]4ecd07452009-03-31 14:34:4377
[email protected]6ab86ac2010-05-29 07:18:2978 SetPrinterPrintableArea(physical_size_device_units,
79 printable_area_device_units,
80 dpi_);
[email protected]4ecd07452009-03-31 14:34:4381}
[email protected]b75dca82009-10-13 18:46:2182#elif defined(OS_MACOSX)
83void PrintSettings::Init(PMPrinter printer, PMPageFormat page_format,
84 const PageRanges& new_ranges,
85 bool print_selection_only) {
86 printer_name_ = base::SysCFStringRefToWide(PMPrinterGetName(printer));
87 device_name_ = base::SysCFStringRefToWide(PMPrinterGetID(printer));
88 ranges = new_ranges;
89 PMOrientation orientation = kPMPortrait;
90 PMGetOrientation(page_format, &orientation);
91 landscape_ = orientation == kPMLandscape;
92 selection_only = print_selection_only;
93
94 UInt32 resolution_count = 0;
95 PMResolution best_resolution = { 72.0, 72.0 };
96 OSStatus status = PMPrinterGetPrinterResolutionCount(printer,
97 &resolution_count);
98 if (status == noErr) {
99 // Resolution indexes are 1-based.
100 for (uint32 i = 1; i <= resolution_count; ++i) {
101 PMResolution resolution;
102 PMPrinterGetIndexedPrinterResolution(printer, i, &resolution);
[email protected]6ab86ac2010-05-29 07:18:29103 if (resolution.hRes > best_resolution.hRes)
[email protected]b75dca82009-10-13 18:46:21104 best_resolution = resolution;
105 }
106 }
107 dpi_ = best_resolution.hRes;
108 // See comment in the Windows code above.
109 DCHECK_EQ(dpi_, best_resolution.vRes);
110
111 // Get printable area and paper rects (in points)
112 PMRect page_rect, paper_rect;
113 PMGetAdjustedPageRect(page_format, &page_rect);
114 PMGetAdjustedPaperRect(page_format, &paper_rect);
[email protected]6ab86ac2010-05-29 07:18:29115 // Device units are in points. Units per inch is 72.
116 gfx::Size physical_size_device_units(
117 (paper_rect.right - paper_rect.left),
118 (paper_rect.bottom - paper_rect.top));
119 gfx::Rect printable_area_device_units(
120 (page_rect.left - paper_rect.left),
121 (page_rect.top - paper_rect.top),
122 (page_rect.right - page_rect.left),
123 (page_rect.bottom - page_rect.top));
[email protected]b75dca82009-10-13 18:46:21124
[email protected]6ab86ac2010-05-29 07:18:29125 SetPrinterPrintableArea(physical_size_device_units,
126 printable_area_device_units,
127 72);
[email protected]b75dca82009-10-13 18:46:21128}
[email protected]b7191422010-09-21 19:18:05129#elif defined(OS_LINUX)
130void PrintSettings::Init(GtkPrintSettings* settings,
131 GtkPageSetup* page_setup,
132 const PageRanges& new_ranges,
133 bool print_selection_only) {
134 // TODO(jhawkins): |printer_name_| and |device_name_| should be string16.
135 base::StringPiece name(
136 reinterpret_cast<const char*>(gtk_print_settings_get_printer(settings)));
137 printer_name_ = UTF8ToWide(name);
138 device_name_ = printer_name_;
139 ranges = new_ranges;
140
141 GtkPageOrientation orientation = gtk_print_settings_get_orientation(settings);
142 landscape_ = orientation == GTK_PAGE_ORIENTATION_LANDSCAPE;
143 selection_only = print_selection_only;
144
145 dpi_ = gtk_print_settings_get_resolution(settings);
146
147 // Initialize page_setup_device_units_.
148 gfx::Size physical_size_device_units(
149 gtk_page_setup_get_paper_width(page_setup, GTK_UNIT_INCH) * dpi_,
150 gtk_page_setup_get_paper_height(page_setup, GTK_UNIT_INCH) * dpi_);
151 gfx::Rect printable_area_device_units(
152 gtk_page_setup_get_left_margin(page_setup, GTK_UNIT_INCH) * dpi_,
153 gtk_page_setup_get_top_margin(page_setup, GTK_UNIT_INCH) * dpi_,
154 gtk_page_setup_get_page_width(page_setup, GTK_UNIT_INCH) * dpi_,
155 gtk_page_setup_get_page_height(page_setup, GTK_UNIT_INCH) * dpi_);
156
157 SetPrinterPrintableArea(physical_size_device_units,
158 printable_area_device_units,
159 dpi_);
160}
[email protected]4ecd07452009-03-31 14:34:43161#endif
162
163void PrintSettings::SetPrinterPrintableArea(
[email protected]6ab86ac2010-05-29 07:18:29164 gfx::Size const& physical_size_device_units,
165 gfx::Rect const& printable_area_device_units,
166 int units_per_inch) {
[email protected]4ecd07452009-03-31 14:34:43167
[email protected]38bba4f2010-03-12 05:29:07168 int header_footer_text_height = 0;
169 int margin_printer_units = 0;
170 if (use_overlays) {
171 // Hard-code text_height = 0.5cm = ~1/5 of inch.
[email protected]6ab86ac2010-05-29 07:18:29172 header_footer_text_height = ConvertUnit(500, kHundrethsMMPerInch,
173 units_per_inch);
[email protected]38bba4f2010-03-12 05:29:07174 // Default margins 1.0cm = ~2/5 of an inch.
[email protected]6ab86ac2010-05-29 07:18:29175 margin_printer_units = ConvertUnit(1000, kHundrethsMMPerInch,
176 units_per_inch);
[email protected]38bba4f2010-03-12 05:29:07177 }
[email protected]4ecd07452009-03-31 14:34:43178 // Start by setting the user configuration
[email protected]6ab86ac2010-05-29 07:18:29179 page_setup_device_units_.Init(physical_size_device_units,
180 printable_area_device_units,
181 header_footer_text_height);
initial.commit09911bf2008-07-26 23:55:29182
[email protected]be3b19a2009-07-13 14:58:18183
184 // Apply default margins (not user configurable just yet).
185 // Since the font height is half the margin we put the header and footers at
186 // the font height from the margins.
[email protected]4ecd07452009-03-31 14:34:43187 PageMargins margins;
[email protected]be3b19a2009-07-13 14:58:18188 margins.header = header_footer_text_height;
189 margins.footer = header_footer_text_height;
[email protected]c86d4722009-06-23 17:59:55190 margins.left = margin_printer_units;
191 margins.top = margin_printer_units;
192 margins.right = margin_printer_units;
193 margins.bottom = margin_printer_units;
[email protected]6ab86ac2010-05-29 07:18:29194 page_setup_device_units_.SetRequestedMargins(margins);
initial.commit09911bf2008-07-26 23:55:29195}
196
initial.commit09911bf2008-07-26 23:55:29197bool PrintSettings::Equals(const PrintSettings& rhs) const {
198 // Do not test the display device name (printer_name_) for equality since it
199 // may sometimes be chopped off at 30 chars. As long as device_name is the
200 // same, that's fine.
201 return ranges == rhs.ranges &&
202 min_shrink == rhs.min_shrink &&
203 max_shrink == rhs.max_shrink &&
204 desired_dpi == rhs.desired_dpi &&
205 overlays.Equals(rhs.overlays) &&
206 device_name_ == rhs.device_name_ &&
[email protected]6ab86ac2010-05-29 07:18:29207 page_setup_device_units_.Equals(rhs.page_setup_device_units_) &&
initial.commit09911bf2008-07-26 23:55:29208 dpi_ == rhs.dpi_ &&
209 landscape_ == rhs.landscape_;
210}
211
212int PrintSettings::NewCookie() {
[email protected]13c9eec2008-08-06 13:42:44213 // A cookie of 0 is used to mark a document as unassigned, count from 1.
214 return cookie_seq.GetNext() + 1;
initial.commit09911bf2008-07-26 23:55:29215}
216
217} // namespace printing