blob: bdb10bf2fafb6a5dfed2255ca6f1428f60f17df0 [file] [log] [blame]
initial.commit09911bf2008-07-26 23:55:291// Copyright 2008, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#include "chrome/browser/printing/print_settings.h"
31
[email protected]d30e8e642008-08-06 12:05:2432#include "base/atomic_sequence_num.h"
initial.commit09911bf2008-07-26 23:55:2933#include "base/logging.h"
34#include "chrome/browser/printing/units.h"
35#include "chrome/common/render_messages.h"
36
37namespace printing {
38
[email protected]d30e8e642008-08-06 12:05:2439// Global SequenceNumber used for generating unique cookie values.
40static base::AtomicSequenceNumber cookie_seq;
initial.commit09911bf2008-07-26 23:55:2941
42PrintSettings::PrintSettings()
43 : min_shrink(1.25),
44 max_shrink(2.0),
45 desired_dpi(72),
46 dpi_(0),
47 landscape_(false) {
48}
49
50void PrintSettings::Clear() {
51 ranges.clear();
52 min_shrink = 1.25;
53 max_shrink = 2.;
54 desired_dpi = 72;
55 printer_name_.clear();
56 device_name_.clear();
57 page_setup_cmm_.Clear();
58 page_setup_pixels_.Clear();
59 dpi_ = 0;
60 landscape_ = false;
61}
62
63#ifdef WIN32
64void PrintSettings::Init(HDC hdc,
65 const DEVMODE& dev_mode,
66 const PageRanges& new_ranges,
67 const std::wstring& new_device_name) {
68 DCHECK(hdc);
69 printer_name_ = dev_mode.dmDeviceName;
70 device_name_ = new_device_name;
71 ranges = new_ranges;
72 landscape_ = dev_mode.dmOrientation == DMORIENT_LANDSCAPE;
73
74 int old_dpi = dpi_;
75 dpi_ = GetDeviceCaps(hdc, LOGPIXELSX);
76 // No printer device is known to advertise different dpi in X and Y axis; even
77 // the fax device using the 200x100 dpi setting. It's ought to break so many
78 // applications that it's not even needed to care about. WebKit doesn't
79 // support different dpi settings in X and Y axis.
80 DCHECK_EQ(dpi_, GetDeviceCaps(hdc, LOGPIXELSY));
81
82 DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORX), 0);
83 DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORY), 0);
84
85 // Initialize page_setup_pixels_.
86 gfx::Size physical_size_pixels(GetDeviceCaps(hdc, PHYSICALWIDTH),
87 GetDeviceCaps(hdc, PHYSICALHEIGHT));
88 gfx::Rect printable_area_pixels(GetDeviceCaps(hdc, PHYSICALOFFSETX),
89 GetDeviceCaps(hdc, PHYSICALOFFSETY),
90 GetDeviceCaps(hdc, HORZRES),
91 GetDeviceCaps(hdc, VERTRES));
92 // Hard-code text_height = 0.5cm = ~1/5 of inch
93 page_setup_pixels_.Init(physical_size_pixels, printable_area_pixels,
94 ConvertUnit(500, kHundrethsMMPerInch, dpi_));
95
96 // Initialize page_setup_cmm_.
97 // In theory, we should be using HORZSIZE and VERTSIZE but their value is
98 // so wrong it's useless. So read the values in dpi unit and convert them back
99 // in 0.01 mm.
100 gfx::Size physical_size_cmm(
101 ConvertUnit(physical_size_pixels.width(), dpi_, kHundrethsMMPerInch),
102 ConvertUnit(physical_size_pixels.height(), dpi_, kHundrethsMMPerInch));
103 gfx::Rect printable_area_cmm(
104 ConvertUnit(printable_area_pixels.x(), dpi_, kHundrethsMMPerInch),
105 ConvertUnit(printable_area_pixels.y(), dpi_, kHundrethsMMPerInch),
106 ConvertUnit(printable_area_pixels.width(), dpi_, kHundrethsMMPerInch),
107 ConvertUnit(printable_area_pixels.bottom(), dpi_, kHundrethsMMPerInch));
108
109 static const int kRoundingTolerance = 5;
110 // Some printers may advertise a slightly larger printable area than the
111 // physical area. This is mostly due to integer calculation and rounding.
112 if (physical_size_cmm.height() > printable_area_cmm.bottom() &&
113 physical_size_cmm.height() <= (printable_area_cmm.bottom() +
114 kRoundingTolerance)) {
115 physical_size_cmm.set_height(printable_area_cmm.bottom());
116 }
117 if (physical_size_cmm.width() > printable_area_cmm.right() &&
118 physical_size_cmm.width() <= (printable_area_cmm.right() +
119 kRoundingTolerance)) {
120 physical_size_cmm.set_width(printable_area_cmm.right());
121 }
122 page_setup_cmm_.Init(physical_size_cmm, printable_area_cmm, 500);
123}
124#endif
125
126void PrintSettings::UpdateMarginsMetric(const PageMargins& new_margins) {
127 // Apply the new margins in 0.01 mm unit.
128 page_setup_cmm_.SetRequestedMargins(new_margins);
129
130 // Converts the margins in dpi unit and apply those too.
131 PageMargins pixels_margins;
132 pixels_margins.header = ConvertUnit(new_margins.header, kHundrethsMMPerInch,
133 dpi_);
134 pixels_margins.footer = ConvertUnit(new_margins.footer, kHundrethsMMPerInch,
135 dpi_);
136 pixels_margins.left = ConvertUnit(new_margins.left, kHundrethsMMPerInch,
137 dpi_);
138 pixels_margins.top = ConvertUnit(new_margins.top, kHundrethsMMPerInch, dpi_);
139 pixels_margins.right = ConvertUnit(new_margins.right, kHundrethsMMPerInch,
140 dpi_);
141 pixels_margins.bottom = ConvertUnit(new_margins.bottom, kHundrethsMMPerInch,
142 dpi_);
143 page_setup_pixels_.SetRequestedMargins(pixels_margins);
144}
145
146void PrintSettings::UpdateMarginsMilliInch(const PageMargins& new_margins) {
147 // Convert margins from thousandth inches to cmm (0.01mm).
148 PageMargins cmm_margins;
149 cmm_margins.header =
150 ConvertMilliInchToHundredThousanthMeter(new_margins.header);
151 cmm_margins.footer =
152 ConvertMilliInchToHundredThousanthMeter(new_margins.footer);
153 cmm_margins.left = ConvertMilliInchToHundredThousanthMeter(new_margins.left);
154 cmm_margins.top = ConvertMilliInchToHundredThousanthMeter(new_margins.top);
155 cmm_margins.right =
156 ConvertMilliInchToHundredThousanthMeter(new_margins.right);
157 cmm_margins.bottom =
158 ConvertMilliInchToHundredThousanthMeter(new_margins.bottom);
159 UpdateMarginsMetric(cmm_margins);
160}
161
162void PrintSettings::RenderParams(ViewMsg_Print_Params* params) const {
163 DCHECK(params);
164 params->printable_size.SetSize(page_setup_pixels_.content_area().width(),
165 page_setup_pixels_.content_area().height());
166 params->dpi = dpi_;
167 // Currently hardcoded at 1.25. See PrintSettings' constructor.
168 params->min_shrink = min_shrink;
169 // Currently hardcoded at 2.0. See PrintSettings' constructor.
170 params->max_shrink = max_shrink;
171 // Currently hardcoded at 72dpi. See PrintSettings' constructor.
172 params->desired_dpi = desired_dpi;
173 // Always use an invalid cookie.
174 params->document_cookie = 0;
175}
176
177bool PrintSettings::Equals(const PrintSettings& rhs) const {
178 // Do not test the display device name (printer_name_) for equality since it
179 // may sometimes be chopped off at 30 chars. As long as device_name is the
180 // same, that's fine.
181 return ranges == rhs.ranges &&
182 min_shrink == rhs.min_shrink &&
183 max_shrink == rhs.max_shrink &&
184 desired_dpi == rhs.desired_dpi &&
185 overlays.Equals(rhs.overlays) &&
186 device_name_ == rhs.device_name_ &&
187 page_setup_pixels_.Equals(rhs.page_setup_pixels_) &&
188 page_setup_cmm_.Equals(rhs.page_setup_cmm_) &&
189 dpi_ == rhs.dpi_ &&
190 landscape_ == rhs.landscape_;
191}
192
193int PrintSettings::NewCookie() {
[email protected]d30e8e642008-08-06 12:05:24194 return cookie_seq.GetNext();
initial.commit09911bf2008-07-26 23:55:29195}
196
197} // namespace printing