blob: e998c74fe4a087c4594653144b287fcc2562c914 [file] [log] [blame]
K Moonbd80ce72019-07-26 19:27:501// Copyright 2019 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#ifndef PDF_DOCUMENT_LAYOUT_H_
6#define PDF_DOCUMENT_LAYOUT_H_
7
K Moonff7ec672019-08-14 19:19:568#include <cstddef>
Jeremy Chinsend6fd27ce2019-08-06 00:40:179#include <vector>
10
Hans Wennborg29adea92020-06-22 16:13:5311#include "base/check_op.h"
Lei Zhang4906c102019-08-06 00:28:0312#include "pdf/draw_utils/coordinates.h"
K Moon9a62bf42019-08-07 20:05:3613#include "pdf/page_orientation.h"
Ankit Kumar 🌪️00798692020-08-26 22:57:1414#include "ui/gfx/geometry/rect.h"
Ankit Kumar 🌪️e35101152020-07-30 09:57:5915#include "ui/gfx/geometry/size.h"
K Moonbd80ce72019-07-26 19:27:5016
Gouarb Kunduc4338a62020-07-30 21:30:4817namespace base {
18class Value;
19}
20
K Moon23d56442019-10-03 05:06:2321namespace pp {
22class Var;
23} // namespace pp
24
K Moonbd80ce72019-07-26 19:27:5025namespace chrome_pdf {
26
27// Layout of pages within a PDF document. Pages are placed as rectangles
28// (possibly rotated) in a non-overlapping vertical sequence.
29//
30// All layout units are pixels.
K Mooneb9e0002019-08-06 19:25:3231//
32// The |Options| class controls the behavior of the layout, such as the default
33// orientation of pages.
K Moonbd80ce72019-07-26 19:27:5034class DocumentLayout final {
35 public:
K Mooneb9e0002019-08-06 19:25:3236 // Options controlling layout behavior.
37 class Options final {
38 public:
39 Options();
40
41 Options(const Options& other);
42 Options& operator=(const Options& other);
43
44 ~Options();
45
Hui Yingst28f9f5c2020-01-16 19:52:5646 friend bool operator==(const Options& lhs, const Options& rhs) {
47 return lhs.two_up_view_enabled() == rhs.two_up_view_enabled() &&
48 lhs.default_page_orientation() == rhs.default_page_orientation();
49 }
50
51 friend bool operator!=(const Options& lhs, const Options& rhs) {
52 return !(lhs == rhs);
53 }
54
Gouarb Kunduc4338a62020-07-30 21:30:4855 // Serializes layout options to a base::Value.
56 base::Value ToValue() const;
K Moon23d56442019-10-03 05:06:2357
58 // Deserializes layout options from a pp::Var.
59 void FromVar(const pp::Var& var);
60
K Moon9a62bf42019-08-07 20:05:3661 PageOrientation default_page_orientation() const {
62 return default_page_orientation_;
63 }
K Mooneb9e0002019-08-06 19:25:3264
65 // Rotates default page orientation 90 degrees clockwise.
66 void RotatePagesClockwise();
67
68 // Rotates default page orientation 90 degrees counterclockwise.
69 void RotatePagesCounterclockwise();
70
Hui Yingst28f9f5c2020-01-16 19:52:5671 bool two_up_view_enabled() const { return two_up_view_enabled_; }
72
73 // Changes two-up view status.
74 void set_two_up_view_enabled(bool enable) { two_up_view_enabled_ = enable; }
75
K Mooneb9e0002019-08-06 19:25:3276 private:
K Moon9a62bf42019-08-07 20:05:3677 PageOrientation default_page_orientation_ = PageOrientation::kOriginal;
Hui Yingst28f9f5c2020-01-16 19:52:5678 bool two_up_view_enabled_ = false;
K Mooneb9e0002019-08-06 19:25:3279 };
80
Lei Zhang4906c102019-08-06 00:28:0381 static const draw_utils::PageInsetSizes kSingleViewInsets;
82 static constexpr int32_t kBottomSeparator = 4;
83 static constexpr int32_t kHorizontalSeparator = 1;
84
K Moonbd80ce72019-07-26 19:27:5085 DocumentLayout();
86
K Mooneb9e0002019-08-06 19:25:3287 DocumentLayout(const DocumentLayout& other) = delete;
88 DocumentLayout& operator=(const DocumentLayout& other) = delete;
K Moonbd80ce72019-07-26 19:27:5089
90 ~DocumentLayout();
91
K Mooneb9e0002019-08-06 19:25:3292 // Returns the layout options.
93 const Options& options() const { return options_; }
K Moonbd80ce72019-07-26 19:27:5094
K Moon6d326b92019-09-19 22:42:0795 // Sets the layout options. If certain options with immediate effect change
96 // (such as the default page orientation), the layout will be marked dirty.
97 //
98 // TODO(kmoon): We shouldn't have layout options that take effect immediately.
99 void SetOptions(const Options& options);
100
101 // Returns true if the layout has been modified since the last call to
102 // clear_dirty(). The initial state is false (clean), which assumes
103 // appropriate default behavior for an initially empty layout.
104 bool dirty() const { return dirty_; }
105
106 // Clears the dirty() state of the layout. This should be called after any
107 // layout changes have been applied.
108 void clear_dirty() { dirty_ = false; }
K Moonbd80ce72019-07-26 19:27:50109
110 // Returns the layout's total size.
Ankit Kumar 🌪️e35101152020-07-30 09:57:59111 const gfx::Size& size() const { return size_; }
K Moonbd80ce72019-07-26 19:27:50112
K Moone4bd7522019-08-23 00:12:56113 size_t page_count() const { return page_layouts_.size(); }
Jeremy Chinsen08beb482019-08-07 01:58:54114
K Moonff7ec672019-08-14 19:19:56115 // Gets the layout rectangle for a page. Only valid after computing a layout.
Ankit Kumar 🌪️00798692020-08-26 22:57:14116 const gfx::Rect& page_rect(size_t page_index) const {
K Moonff7ec672019-08-14 19:19:56117 DCHECK_LT(page_index, page_count());
K Moone4bd7522019-08-23 00:12:56118 return page_layouts_[page_index].outer_rect;
119 }
120
121 // Gets the layout rectangle for a page's bounds (which excludes additional
122 // regions like page shadows). Only valid after computing a layout.
Ankit Kumar 🌪️00798692020-08-26 22:57:14123 const gfx::Rect& page_bounds_rect(size_t page_index) const {
K Moone4bd7522019-08-23 00:12:56124 DCHECK_LT(page_index, page_count());
125 return page_layouts_[page_index].inner_rect;
K Moonff7ec672019-08-14 19:19:56126 }
127
128 // Computes layout that represent |page_sizes| formatted for single view.
129 //
130 // TODO(kmoon): Control layout type using an option.
Ankit Kumar 🌪️e35101152020-07-30 09:57:59131 void ComputeSingleViewLayout(const std::vector<gfx::Size>& page_sizes);
K Moonff7ec672019-08-14 19:19:56132
133 // Computes layout that represent |page_sizes| formatted for two-up view.
134 //
135 // TODO(kmoon): Control layout type using an option.
Ankit Kumar 🌪️e35101152020-07-30 09:57:59136 void ComputeTwoUpViewLayout(const std::vector<gfx::Size>& page_sizes);
Jeremy Chinsend6fd27ce2019-08-06 00:40:17137
K Moonbd80ce72019-07-26 19:27:50138 private:
K Moone4bd7522019-08-23 00:12:56139 // Layout of a single page.
140 struct PageLayout {
141 // Bounding rectangle for the page with decorations.
Ankit Kumar 🌪️00798692020-08-26 22:57:14142 gfx::Rect outer_rect;
K Moone4bd7522019-08-23 00:12:56143
144 // Bounding rectangle for the page without decorations.
Ankit Kumar 🌪️00798692020-08-26 22:57:14145 gfx::Rect inner_rect;
K Moone4bd7522019-08-23 00:12:56146 };
147
K Moon6d326b92019-09-19 22:42:07148 // Copies |source_rect| to |destination_rect|, setting |dirty_| to true if
149 // |destination_rect| is modified as a result.
Ankit Kumar 🌪️00798692020-08-26 22:57:14150 void CopyRectIfModified(const gfx::Rect& source_rect,
151 gfx::Rect& destination_rect);
K Moon6d326b92019-09-19 22:42:07152
K Mooneb9e0002019-08-06 19:25:32153 Options options_;
K Moonbd80ce72019-07-26 19:27:50154
K Moon6d326b92019-09-19 22:42:07155 // Indicates if the layout has changed in an externally-observable way,
156 // usually as a result of calling |ComputeLayout()| with different inputs.
157 //
158 // Some operations that may trigger layout changes:
159 // * Changing page sizes
160 // * Adding or removing pages
161 // * Changing page orientations
162 bool dirty_ = false;
163
K Moonbd80ce72019-07-26 19:27:50164 // Layout's total size.
Ankit Kumar 🌪️e35101152020-07-30 09:57:59165 gfx::Size size_;
K Moonff7ec672019-08-14 19:19:56166
K Moone4bd7522019-08-23 00:12:56167 std::vector<PageLayout> page_layouts_;
K Moonbd80ce72019-07-26 19:27:50168};
169
170} // namespace chrome_pdf
171
172#endif // PDF_DOCUMENT_LAYOUT_H_