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