• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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