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 11namespace printing { 12 13PageMargins::PageMargins() 14 : header(0), 15 footer(0), 16 left(0), 17 right(0), 18 top(0), 19 bottom(0) { 20} 21 22void PageMargins::Clear() { 23 header = 0; 24 footer = 0; 25 left = 0; 26 right = 0; 27 top = 0; 28 bottom = 0; 29} 30 31bool 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 40PageSetup::PageSetup() { 41 Clear(); 42} 43 44PageSetup::~PageSetup() {} 45 46void 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 56bool 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 66void 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 83void PageSetup::SetRequestedMargins(const PageMargins& requested_margins) { 84 forced_margins_ = false; 85 SetRequestedMarginsAndCalculateSizes(requested_margins); 86} 87 88void PageSetup::ForceRequestedMargins(const PageMargins& requested_margins) { 89 forced_margins_ = true; 90 SetRequestedMarginsAndCalculateSizes(requested_margins); 91} 92 93void 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 106void 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 117void 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