license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 1 | // 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.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | |
| 5 | #include "chrome/browser/printing/print_settings.h" |
| 6 | |
[email protected] | d30e8e64 | 2008-08-06 12:05:24 | [diff] [blame] | 7 | #include "base/atomic_sequence_num.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 8 | #include "base/logging.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 9 | #include "chrome/common/render_messages.h" |
[email protected] | 4ae30d08 | 2009-02-20 17:55:55 | [diff] [blame^] | 10 | #include "printing/units.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 11 | |
| 12 | namespace printing { |
| 13 | |
[email protected] | d30e8e64 | 2008-08-06 12:05:24 | [diff] [blame] | 14 | // Global SequenceNumber used for generating unique cookie values. |
[email protected] | a10a16b | 2008-09-02 13:11:46 | [diff] [blame] | 15 | static base::AtomicSequenceNumber cookie_seq(base::LINKER_INITIALIZED); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 16 | |
| 17 | PrintSettings::PrintSettings() |
| 18 | : min_shrink(1.25), |
| 19 | max_shrink(2.0), |
| 20 | desired_dpi(72), |
| 21 | dpi_(0), |
| 22 | landscape_(false) { |
| 23 | } |
| 24 | |
| 25 | void PrintSettings::Clear() { |
| 26 | ranges.clear(); |
| 27 | min_shrink = 1.25; |
| 28 | max_shrink = 2.; |
| 29 | desired_dpi = 72; |
| 30 | printer_name_.clear(); |
| 31 | device_name_.clear(); |
| 32 | page_setup_cmm_.Clear(); |
| 33 | page_setup_pixels_.Clear(); |
| 34 | dpi_ = 0; |
| 35 | landscape_ = false; |
| 36 | } |
| 37 | |
| 38 | #ifdef WIN32 |
| 39 | void PrintSettings::Init(HDC hdc, |
| 40 | const DEVMODE& dev_mode, |
| 41 | const PageRanges& new_ranges, |
| 42 | const std::wstring& new_device_name) { |
| 43 | DCHECK(hdc); |
| 44 | printer_name_ = dev_mode.dmDeviceName; |
| 45 | device_name_ = new_device_name; |
| 46 | ranges = new_ranges; |
| 47 | landscape_ = dev_mode.dmOrientation == DMORIENT_LANDSCAPE; |
| 48 | |
| 49 | int old_dpi = dpi_; |
| 50 | dpi_ = GetDeviceCaps(hdc, LOGPIXELSX); |
| 51 | // No printer device is known to advertise different dpi in X and Y axis; even |
| 52 | // the fax device using the 200x100 dpi setting. It's ought to break so many |
| 53 | // applications that it's not even needed to care about. WebKit doesn't |
| 54 | // support different dpi settings in X and Y axis. |
| 55 | DCHECK_EQ(dpi_, GetDeviceCaps(hdc, LOGPIXELSY)); |
| 56 | |
| 57 | DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORX), 0); |
| 58 | DCHECK_EQ(GetDeviceCaps(hdc, SCALINGFACTORY), 0); |
| 59 | |
| 60 | // Initialize page_setup_pixels_. |
| 61 | gfx::Size physical_size_pixels(GetDeviceCaps(hdc, PHYSICALWIDTH), |
| 62 | GetDeviceCaps(hdc, PHYSICALHEIGHT)); |
| 63 | gfx::Rect printable_area_pixels(GetDeviceCaps(hdc, PHYSICALOFFSETX), |
| 64 | GetDeviceCaps(hdc, PHYSICALOFFSETY), |
| 65 | GetDeviceCaps(hdc, HORZRES), |
| 66 | GetDeviceCaps(hdc, VERTRES)); |
| 67 | // Hard-code text_height = 0.5cm = ~1/5 of inch |
[email protected] | 4ae30d08 | 2009-02-20 17:55:55 | [diff] [blame^] | 68 | page_setup_pixels_.Init(physical_size_pixels, |
| 69 | printable_area_pixels, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 70 | ConvertUnit(500, kHundrethsMMPerInch, dpi_)); |
| 71 | |
| 72 | // Initialize page_setup_cmm_. |
| 73 | // In theory, we should be using HORZSIZE and VERTSIZE but their value is |
| 74 | // so wrong it's useless. So read the values in dpi unit and convert them back |
| 75 | // in 0.01 mm. |
| 76 | gfx::Size physical_size_cmm( |
| 77 | ConvertUnit(physical_size_pixels.width(), dpi_, kHundrethsMMPerInch), |
| 78 | ConvertUnit(physical_size_pixels.height(), dpi_, kHundrethsMMPerInch)); |
| 79 | gfx::Rect printable_area_cmm( |
| 80 | ConvertUnit(printable_area_pixels.x(), dpi_, kHundrethsMMPerInch), |
| 81 | ConvertUnit(printable_area_pixels.y(), dpi_, kHundrethsMMPerInch), |
| 82 | ConvertUnit(printable_area_pixels.width(), dpi_, kHundrethsMMPerInch), |
| 83 | ConvertUnit(printable_area_pixels.bottom(), dpi_, kHundrethsMMPerInch)); |
| 84 | |
| 85 | static const int kRoundingTolerance = 5; |
| 86 | // Some printers may advertise a slightly larger printable area than the |
| 87 | // physical area. This is mostly due to integer calculation and rounding. |
| 88 | if (physical_size_cmm.height() > printable_area_cmm.bottom() && |
| 89 | physical_size_cmm.height() <= (printable_area_cmm.bottom() + |
| 90 | kRoundingTolerance)) { |
| 91 | physical_size_cmm.set_height(printable_area_cmm.bottom()); |
| 92 | } |
| 93 | if (physical_size_cmm.width() > printable_area_cmm.right() && |
| 94 | physical_size_cmm.width() <= (printable_area_cmm.right() + |
| 95 | kRoundingTolerance)) { |
| 96 | physical_size_cmm.set_width(printable_area_cmm.right()); |
| 97 | } |
| 98 | page_setup_cmm_.Init(physical_size_cmm, printable_area_cmm, 500); |
| 99 | } |
| 100 | #endif |
| 101 | |
| 102 | void PrintSettings::UpdateMarginsMetric(const PageMargins& new_margins) { |
| 103 | // Apply the new margins in 0.01 mm unit. |
| 104 | page_setup_cmm_.SetRequestedMargins(new_margins); |
| 105 | |
| 106 | // Converts the margins in dpi unit and apply those too. |
| 107 | PageMargins pixels_margins; |
[email protected] | 4ae30d08 | 2009-02-20 17:55:55 | [diff] [blame^] | 108 | pixels_margins.header = ConvertUnit(new_margins.header, |
| 109 | kHundrethsMMPerInch, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 110 | dpi_); |
[email protected] | 4ae30d08 | 2009-02-20 17:55:55 | [diff] [blame^] | 111 | pixels_margins.footer = ConvertUnit(new_margins.footer, |
| 112 | kHundrethsMMPerInch, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 113 | dpi_); |
[email protected] | 4ae30d08 | 2009-02-20 17:55:55 | [diff] [blame^] | 114 | pixels_margins.left = ConvertUnit(new_margins.left, |
| 115 | kHundrethsMMPerInch, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 116 | dpi_); |
| 117 | pixels_margins.top = ConvertUnit(new_margins.top, kHundrethsMMPerInch, dpi_); |
[email protected] | 4ae30d08 | 2009-02-20 17:55:55 | [diff] [blame^] | 118 | pixels_margins.right = ConvertUnit(new_margins.right, |
| 119 | kHundrethsMMPerInch, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 120 | dpi_); |
[email protected] | 4ae30d08 | 2009-02-20 17:55:55 | [diff] [blame^] | 121 | pixels_margins.bottom = ConvertUnit(new_margins.bottom, |
| 122 | kHundrethsMMPerInch, |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 123 | dpi_); |
| 124 | page_setup_pixels_.SetRequestedMargins(pixels_margins); |
| 125 | } |
| 126 | |
| 127 | void PrintSettings::UpdateMarginsMilliInch(const PageMargins& new_margins) { |
| 128 | // Convert margins from thousandth inches to cmm (0.01mm). |
| 129 | PageMargins cmm_margins; |
| 130 | cmm_margins.header = |
| 131 | ConvertMilliInchToHundredThousanthMeter(new_margins.header); |
| 132 | cmm_margins.footer = |
| 133 | ConvertMilliInchToHundredThousanthMeter(new_margins.footer); |
| 134 | cmm_margins.left = ConvertMilliInchToHundredThousanthMeter(new_margins.left); |
| 135 | cmm_margins.top = ConvertMilliInchToHundredThousanthMeter(new_margins.top); |
| 136 | cmm_margins.right = |
| 137 | ConvertMilliInchToHundredThousanthMeter(new_margins.right); |
| 138 | cmm_margins.bottom = |
| 139 | ConvertMilliInchToHundredThousanthMeter(new_margins.bottom); |
| 140 | UpdateMarginsMetric(cmm_margins); |
| 141 | } |
| 142 | |
| 143 | void PrintSettings::RenderParams(ViewMsg_Print_Params* params) const { |
| 144 | DCHECK(params); |
| 145 | params->printable_size.SetSize(page_setup_pixels_.content_area().width(), |
| 146 | page_setup_pixels_.content_area().height()); |
| 147 | params->dpi = dpi_; |
| 148 | // Currently hardcoded at 1.25. See PrintSettings' constructor. |
| 149 | params->min_shrink = min_shrink; |
| 150 | // Currently hardcoded at 2.0. See PrintSettings' constructor. |
| 151 | params->max_shrink = max_shrink; |
| 152 | // Currently hardcoded at 72dpi. See PrintSettings' constructor. |
| 153 | params->desired_dpi = desired_dpi; |
| 154 | // Always use an invalid cookie. |
| 155 | params->document_cookie = 0; |
| 156 | } |
| 157 | |
| 158 | bool PrintSettings::Equals(const PrintSettings& rhs) const { |
| 159 | // Do not test the display device name (printer_name_) for equality since it |
| 160 | // may sometimes be chopped off at 30 chars. As long as device_name is the |
| 161 | // same, that's fine. |
| 162 | return ranges == rhs.ranges && |
| 163 | min_shrink == rhs.min_shrink && |
| 164 | max_shrink == rhs.max_shrink && |
| 165 | desired_dpi == rhs.desired_dpi && |
| 166 | overlays.Equals(rhs.overlays) && |
| 167 | device_name_ == rhs.device_name_ && |
| 168 | page_setup_pixels_.Equals(rhs.page_setup_pixels_) && |
| 169 | page_setup_cmm_.Equals(rhs.page_setup_cmm_) && |
| 170 | dpi_ == rhs.dpi_ && |
| 171 | landscape_ == rhs.landscape_; |
| 172 | } |
| 173 | |
| 174 | int PrintSettings::NewCookie() { |
[email protected] | 13c9eec | 2008-08-06 13:42:44 | [diff] [blame] | 175 | // A cookie of 0 is used to mark a document as unassigned, count from 1. |
| 176 | return cookie_seq.GetNext() + 1; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | } // namespace printing |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 180 | |