forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdocument_layout.h
182 lines (138 loc) · 5.78 KB
/
document_layout.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef PDF_DOCUMENT_LAYOUT_H_
#define PDF_DOCUMENT_LAYOUT_H_
#include <cstddef>
#include <vector>
#include "base/check_op.h"
#include "base/i18n/rtl.h"
#include "pdf/draw_utils/coordinates.h"
#include "pdf/page_orientation.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
namespace base {
class Value;
}
namespace chrome_pdf {
// Layout of pages within a PDF document. Pages are placed as rectangles
// (possibly rotated) in a non-overlapping vertical sequence.
//
// All layout units are pixels.
//
// The `Options` class controls the behavior of the layout, such as the default
// orientation of pages.
class DocumentLayout final {
public:
// TODO(crbug.com/1144505): Add `kTwoUpEven` page spread support.
enum class PageSpread {
kOneUp = 0, // One page per spread.
kTwoUpOdd = 1, // Two pages per spread, with odd pages first.
};
// Options controlling layout behavior.
class Options final {
public:
Options();
Options(const Options& other);
Options& operator=(const Options& other);
~Options();
friend bool operator==(const Options& lhs, const Options& rhs) {
return lhs.direction() == rhs.direction() &&
lhs.default_page_orientation() == rhs.default_page_orientation() &&
lhs.page_spread() == rhs.page_spread();
}
friend bool operator!=(const Options& lhs, const Options& rhs) {
return !(lhs == rhs);
}
// Serializes layout options to a base::Value.
base::Value ToValue() const;
// Deserializes layout options from a base::Value.
void FromValue(const base::Value& value);
// Page layout direction. This is tied to the direction of the user's UI,
// rather than the direction of individual pages.
base::i18n::TextDirection direction() const { return direction_; }
void set_direction(base::i18n::TextDirection direction) {
direction_ = direction;
}
PageOrientation default_page_orientation() const {
return default_page_orientation_;
}
// Rotates default page orientation 90 degrees clockwise.
void RotatePagesClockwise();
// Rotates default page orientation 90 degrees counterclockwise.
void RotatePagesCounterclockwise();
PageSpread page_spread() const { return page_spread_; }
// Changes two-up view status.
void set_page_spread(PageSpread spread) { page_spread_ = spread; }
private:
base::i18n::TextDirection direction_ = base::i18n::UNKNOWN_DIRECTION;
PageOrientation default_page_orientation_ = PageOrientation::kOriginal;
PageSpread page_spread_ = PageSpread::kOneUp;
};
static const draw_utils::PageInsetSizes kSingleViewInsets;
static constexpr int32_t kBottomSeparator = 4;
static constexpr int32_t kHorizontalSeparator = 1;
DocumentLayout();
DocumentLayout(const DocumentLayout& other) = delete;
DocumentLayout& operator=(const DocumentLayout& other) = delete;
~DocumentLayout();
// Returns the layout options.
const Options& options() const { return options_; }
// Sets the layout options. If certain options with immediate effect change
// (such as the default page orientation), the layout will be marked dirty.
//
// TODO(kmoon): We shouldn't have layout options that take effect immediately.
void SetOptions(const Options& options);
// Returns true if the layout has been modified since the last call to
// clear_dirty(). The initial state is false (clean), which assumes
// appropriate default behavior for an initially empty layout.
bool dirty() const { return dirty_; }
// Clears the dirty() state of the layout. This should be called after any
// layout changes have been applied.
void clear_dirty() { dirty_ = false; }
// Returns the layout's total size.
const gfx::Size& size() const { return size_; }
size_t page_count() const { return page_layouts_.size(); }
// Gets the layout rectangle for a page. Only valid after computing a layout.
const gfx::Rect& page_rect(size_t page_index) const {
DCHECK_LT(page_index, page_count());
return page_layouts_[page_index].outer_rect;
}
// Gets the layout rectangle for a page's bounds (which excludes additional
// regions like page shadows). Only valid after computing a layout.
const gfx::Rect& page_bounds_rect(size_t page_index) const {
DCHECK_LT(page_index, page_count());
return page_layouts_[page_index].inner_rect;
}
// Computes the layout for a given list of `page_sizes` based on `options_`.
void ComputeLayout(const std::vector<gfx::Size>& page_sizes);
private:
// Layout of a single page.
struct PageLayout {
// Bounding rectangle for the page with decorations.
gfx::Rect outer_rect;
// Bounding rectangle for the page without decorations.
gfx::Rect inner_rect;
};
// Helpers for ComputeLayout() handling different page spreads.
void ComputeOneUpLayout(const std::vector<gfx::Size>& page_sizes);
void ComputeTwoUpOddLayout(const std::vector<gfx::Size>& page_sizes);
// Copies `source_rect` to `destination_rect`, setting `dirty_` to true if
// `destination_rect` is modified as a result.
void CopyRectIfModified(const gfx::Rect& source_rect,
gfx::Rect& destination_rect);
Options options_;
// Indicates if the layout has changed in an externally-observable way,
// usually as a result of calling `ComputeLayout()` with different inputs.
//
// Some operations that may trigger layout changes:
// * Changing page sizes
// * Adding or removing pages
// * Changing page orientations
bool dirty_ = false;
// Layout's total size.
gfx::Size size_;
std::vector<PageLayout> page_layouts_;
};
} // namespace chrome_pdf
#endif // PDF_DOCUMENT_LAYOUT_H_