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