1 // Copyright (c) 2011 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.
4
5 #include "printing/page_setup.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10
11 namespace printing {
12
PageMargins()13 PageMargins::PageMargins()
14 : header(0),
15 footer(0),
16 left(0),
17 right(0),
18 top(0),
19 bottom(0) {
20 }
21
Clear()22 void PageMargins::Clear() {
23 header = 0;
24 footer = 0;
25 left = 0;
26 right = 0;
27 top = 0;
28 bottom = 0;
29 }
30
Equals(const PageMargins & rhs) const31 bool PageMargins::Equals(const PageMargins& rhs) const {
32 return header == rhs.header &&
33 footer == rhs.footer &&
34 left == rhs.left &&
35 top == rhs.top &&
36 right == rhs.right &&
37 bottom == rhs.bottom;
38 }
39
PageSetup()40 PageSetup::PageSetup() {
41 Clear();
42 }
43
~PageSetup()44 PageSetup::~PageSetup() {}
45
Clear()46 void PageSetup::Clear() {
47 physical_size_.SetSize(0, 0);
48 printable_area_.SetRect(0, 0, 0, 0);
49 overlay_area_.SetRect(0, 0, 0, 0);
50 content_area_.SetRect(0, 0, 0, 0);
51 effective_margins_.Clear();
52 text_height_ = 0;
53 forced_margins_ = false;
54 }
55
Equals(const PageSetup & rhs) const56 bool PageSetup::Equals(const PageSetup& rhs) const {
57 return physical_size_ == rhs.physical_size_ &&
58 printable_area_ == rhs.printable_area_ &&
59 overlay_area_ == rhs.overlay_area_ &&
60 content_area_ == rhs.content_area_ &&
61 effective_margins_.Equals(rhs.effective_margins_) &&
62 requested_margins_.Equals(rhs.requested_margins_) &&
63 text_height_ == rhs.text_height_;
64 }
65
Init(const gfx::Size & physical_size,const gfx::Rect & printable_area,int text_height)66 void PageSetup::Init(const gfx::Size& physical_size,
67 const gfx::Rect& printable_area,
68 int text_height) {
69 DCHECK_LE(printable_area.right(), physical_size.width());
70 // I've seen this assert triggers on Canon GP160PF PCL 5e and HP LaserJet 5.
71 // Since we don't know the dpi here, just disable the check.
72 // DCHECK_LE(printable_area.bottom(), physical_size.height());
73 DCHECK_GE(printable_area.x(), 0);
74 DCHECK_GE(printable_area.y(), 0);
75 DCHECK_GE(text_height, 0);
76 physical_size_ = physical_size;
77 printable_area_ = printable_area;
78 text_height_ = text_height;
79
80 SetRequestedMarginsAndCalculateSizes(requested_margins_);
81 }
82
SetRequestedMargins(const PageMargins & requested_margins)83 void PageSetup::SetRequestedMargins(const PageMargins& requested_margins) {
84 forced_margins_ = false;
85 SetRequestedMarginsAndCalculateSizes(requested_margins);
86 }
87
ForceRequestedMargins(const PageMargins & requested_margins)88 void PageSetup::ForceRequestedMargins(const PageMargins& requested_margins) {
89 forced_margins_ = true;
90 SetRequestedMarginsAndCalculateSizes(requested_margins);
91 }
92
FlipOrientation()93 void PageSetup::FlipOrientation() {
94 if (physical_size_.width() && physical_size_.height()) {
95 gfx::Size new_size(physical_size_.height(), physical_size_.width());
96 int new_y = physical_size_.width() -
97 (printable_area_.width() + printable_area_.x());
98 gfx::Rect new_printable_area(printable_area_.y(),
99 new_y,
100 printable_area_.height(),
101 printable_area_.width());
102 Init(new_size, new_printable_area, text_height_);
103 }
104 }
105
SetRequestedMarginsAndCalculateSizes(const PageMargins & requested_margins)106 void PageSetup::SetRequestedMarginsAndCalculateSizes(
107 const PageMargins& requested_margins) {
108 requested_margins_ = requested_margins;
109 if (physical_size_.width() && physical_size_.height()) {
110 if (forced_margins_)
111 CalculateSizesWithinRect(gfx::Rect(physical_size_), 0);
112 else
113 CalculateSizesWithinRect(printable_area_, text_height_);
114 }
115 }
116
CalculateSizesWithinRect(const gfx::Rect & bounds,int text_height)117 void PageSetup::CalculateSizesWithinRect(const gfx::Rect& bounds,
118 int text_height) {
119 // Calculate the effective margins. The tricky part.
120 effective_margins_.header = std::max(requested_margins_.header,
121 bounds.y());
122 effective_margins_.footer = std::max(requested_margins_.footer,
123 physical_size_.height() -
124 bounds.bottom());
125 effective_margins_.left = std::max(requested_margins_.left,
126 bounds.x());
127 effective_margins_.top = std::max(std::max(requested_margins_.top,
128 bounds.y()),
129 effective_margins_.header + text_height);
130 effective_margins_.right = std::max(requested_margins_.right,
131 physical_size_.width() -
132 bounds.right());
133 effective_margins_.bottom =
134 std::max(std::max(requested_margins_.bottom,
135 physical_size_.height() - bounds.bottom()),
136 effective_margins_.footer + text_height);
137
138 // Calculate the overlay area. If the margins are excessive, the overlay_area
139 // size will be (0, 0).
140 overlay_area_.set_x(effective_margins_.left);
141 overlay_area_.set_y(effective_margins_.header);
142 overlay_area_.set_width(std::max(0,
143 physical_size_.width() -
144 effective_margins_.right -
145 overlay_area_.x()));
146 overlay_area_.set_height(std::max(0,
147 physical_size_.height() -
148 effective_margins_.footer -
149 overlay_area_.y()));
150
151 // Calculate the content area. If the margins are excessive, the content_area
152 // size will be (0, 0).
153 content_area_.set_x(effective_margins_.left);
154 content_area_.set_y(effective_margins_.top);
155 content_area_.set_width(std::max(0,
156 physical_size_.width() -
157 effective_margins_.right -
158 content_area_.x()));
159 content_area_.set_height(std::max(0,
160 physical_size_.height() -
161 effective_margins_.bottom -
162 content_area_.y()));
163 }
164
165 } // namespace printing
166