Upload upstream chromium 73.0.3683.0
[platform/framework/web/chromium-efl.git] / printing / page_setup.cc
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
13 namespace {
14
15 // Checks whether |printable_area| can be used to form a valid symmetrical
16 // printable area, so that margin_left equals margin_right, and margin_top
17 // equals margin_bottom.  For example if
18 // printable_area.x() * 2 >= page_size.width(), then the
19 // content_width = page_size.width() - 2 * printable_area.x() would be zero or
20 // negative, which is invalid.
21 // |page_size| is the physical page size that includes margins.
22 bool IsValidPrintableArea(const gfx::Size& page_size,
23                           const gfx::Rect& printable_area) {
24   return !printable_area.IsEmpty() && printable_area.x() >= 0 &&
25          printable_area.y() >= 0 &&
26          printable_area.right() <= page_size.width() &&
27          printable_area.bottom() <= page_size.height() &&
28          printable_area.x() * 2 < page_size.width() &&
29          printable_area.y() * 2 < page_size.height() &&
30          printable_area.right() * 2 > page_size.width() &&
31          printable_area.bottom() * 2 > page_size.height();
32 }
33
34 }  // namespace
35
36 PageMargins::PageMargins()
37     : header(0),
38       footer(0),
39       left(0),
40       right(0),
41       top(0),
42       bottom(0) {
43 }
44
45 void PageMargins::Clear() {
46   header = 0;
47   footer = 0;
48   left = 0;
49   right = 0;
50   top = 0;
51   bottom = 0;
52 }
53
54 bool PageMargins::Equals(const PageMargins& rhs) const {
55   return header == rhs.header &&
56       footer == rhs.footer &&
57       left == rhs.left &&
58       top == rhs.top &&
59       right == rhs.right &&
60       bottom == rhs.bottom;
61 }
62
63 PageSetup::PageSetup() {
64   Clear();
65 }
66
67 PageSetup::PageSetup(const PageSetup& other) = default;
68
69 PageSetup::~PageSetup() = default;
70
71 // static
72 gfx::Rect PageSetup::GetSymmetricalPrintableArea(
73     const gfx::Size& page_size,
74     const gfx::Rect& printable_area) {
75   if (!IsValidPrintableArea(page_size, printable_area))
76     return gfx::Rect();
77
78   int left_right_margin =
79       std::max(printable_area.x(), page_size.width() - printable_area.right());
80   int top_bottom_margin = std::max(
81       printable_area.y(), page_size.height() - printable_area.bottom());
82   int width = page_size.width() - 2 * left_right_margin;
83   int height = page_size.height() - 2 * top_bottom_margin;
84
85   gfx::Rect symmetrical_printable_area = gfx::Rect(page_size);
86   symmetrical_printable_area.ClampToCenteredSize(gfx::Size(width, height));
87
88   return symmetrical_printable_area;
89 }
90
91 void PageSetup::Clear() {
92   physical_size_.SetSize(0, 0);
93   printable_area_.SetRect(0, 0, 0, 0);
94   overlay_area_.SetRect(0, 0, 0, 0);
95   content_area_.SetRect(0, 0, 0, 0);
96   effective_margins_.Clear();
97   text_height_ = 0;
98   forced_margins_ = false;
99 }
100
101 bool PageSetup::Equals(const PageSetup& rhs) const {
102   return physical_size_ == rhs.physical_size_ &&
103       printable_area_ == rhs.printable_area_ &&
104       overlay_area_ == rhs.overlay_area_ &&
105       content_area_ == rhs.content_area_ &&
106       effective_margins_.Equals(rhs.effective_margins_) &&
107       requested_margins_.Equals(rhs.requested_margins_) &&
108       text_height_ == rhs.text_height_;
109 }
110
111 void PageSetup::Init(const gfx::Size& physical_size,
112                      const gfx::Rect& printable_area,
113                      int text_height) {
114   DCHECK_LE(printable_area.right(), physical_size.width());
115   // I've seen this assert triggers on Canon GP160PF PCL 5e and HP LaserJet 5.
116   // Since we don't know the dpi here, just disable the check.
117   // DCHECK_LE(printable_area.bottom(), physical_size.height());
118   DCHECK_GE(printable_area.x(), 0);
119   DCHECK_GE(printable_area.y(), 0);
120   DCHECK_GE(text_height, 0);
121   physical_size_ = physical_size;
122   printable_area_ = printable_area;
123   text_height_ = text_height;
124
125   SetRequestedMarginsAndCalculateSizes(requested_margins_);
126 }
127
128 void PageSetup::SetRequestedMargins(const PageMargins& requested_margins) {
129   forced_margins_ = false;
130   SetRequestedMarginsAndCalculateSizes(requested_margins);
131 }
132
133 void PageSetup::ForceRequestedMargins(const PageMargins& requested_margins) {
134   forced_margins_ = true;
135   SetRequestedMarginsAndCalculateSizes(requested_margins);
136 }
137
138 void PageSetup::FlipOrientation() {
139   if (physical_size_.width() && physical_size_.height()) {
140     gfx::Size new_size(physical_size_.height(), physical_size_.width());
141     int new_y = physical_size_.width() -
142                 (printable_area_.width() + printable_area_.x());
143     gfx::Rect new_printable_area(printable_area_.y(),
144                                  new_y,
145                                  printable_area_.height(),
146                                  printable_area_.width());
147     Init(new_size, new_printable_area, text_height_);
148   }
149 }
150
151 void PageSetup::SetRequestedMarginsAndCalculateSizes(
152     const PageMargins& requested_margins) {
153   requested_margins_ = requested_margins;
154   if (physical_size_.width() && physical_size_.height()) {
155     if (forced_margins_)
156       CalculateSizesWithinRect(gfx::Rect(physical_size_), 0);
157     else
158       CalculateSizesWithinRect(printable_area_, text_height_);
159   }
160 }
161
162 void PageSetup::CalculateSizesWithinRect(const gfx::Rect& bounds,
163                                          int text_height) {
164   // Calculate the effective margins. The tricky part.
165   effective_margins_.header = std::max(requested_margins_.header,
166                                        bounds.y());
167   effective_margins_.footer = std::max(requested_margins_.footer,
168                                        physical_size_.height() -
169                                            bounds.bottom());
170   effective_margins_.left = std::max(requested_margins_.left,
171                                      bounds.x());
172   effective_margins_.top = std::max(std::max(requested_margins_.top,
173                                              bounds.y()),
174                                     effective_margins_.header + text_height);
175   effective_margins_.right = std::max(requested_margins_.right,
176                                       physical_size_.width() -
177                                           bounds.right());
178   effective_margins_.bottom =
179       std::max(std::max(requested_margins_.bottom,
180                         physical_size_.height() - bounds.bottom()),
181                effective_margins_.footer + text_height);
182
183   // Calculate the overlay area. If the margins are excessive, the overlay_area
184   // size will be (0, 0).
185   overlay_area_.set_x(effective_margins_.left);
186   overlay_area_.set_y(effective_margins_.header);
187   overlay_area_.set_width(std::max(0,
188                                    physical_size_.width() -
189                                        effective_margins_.right -
190                                        overlay_area_.x()));
191   overlay_area_.set_height(std::max(0,
192                                     physical_size_.height() -
193                                         effective_margins_.footer -
194                                         overlay_area_.y()));
195
196   // Calculate the content area. If the margins are excessive, the content_area
197   // size will be (0, 0).
198   content_area_.set_x(effective_margins_.left);
199   content_area_.set_y(effective_margins_.top);
200   content_area_.set_width(std::max(0,
201                                    physical_size_.width() -
202                                        effective_margins_.right -
203                                        content_area_.x()));
204   content_area_.set_height(std::max(0,
205                                     physical_size_.height() -
206                                         effective_margins_.bottom -
207                                         content_area_.y()));
208 }
209
210 }  // namespace printing