blob: 13cc51b8e0414dffc862ff06b7fc8b6238279cc8 [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
K Moonff7ec672019-08-14 19:19:5611#include "base/logging.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"
Jeremy Chinsend6fd27ce2019-08-06 00:40:1714#include "ppapi/cpp/rect.h"
K Moonbd80ce72019-07-26 19:27:5015#include "ppapi/cpp/size.h"
16
17namespace chrome_pdf {
18
19// Layout of pages within a PDF document. Pages are placed as rectangles
20// (possibly rotated) in a non-overlapping vertical sequence.
21//
22// All layout units are pixels.
K Mooneb9e0002019-08-06 19:25:3223//
24// The |Options| class controls the behavior of the layout, such as the default
25// orientation of pages.
K Moonbd80ce72019-07-26 19:27:5026class DocumentLayout final {
27 public:
K Mooneb9e0002019-08-06 19:25:3228 // Options controlling layout behavior.
29 class Options final {
30 public:
31 Options();
32
33 Options(const Options& other);
34 Options& operator=(const Options& other);
35
36 ~Options();
37
K Moon9a62bf42019-08-07 20:05:3638 PageOrientation default_page_orientation() const {
39 return default_page_orientation_;
40 }
K Mooneb9e0002019-08-06 19:25:3241
42 // Rotates default page orientation 90 degrees clockwise.
43 void RotatePagesClockwise();
44
45 // Rotates default page orientation 90 degrees counterclockwise.
46 void RotatePagesCounterclockwise();
47
48 private:
K Moon9a62bf42019-08-07 20:05:3649 PageOrientation default_page_orientation_ = PageOrientation::kOriginal;
K Mooneb9e0002019-08-06 19:25:3250 };
51
Lei Zhang4906c102019-08-06 00:28:0352 static const draw_utils::PageInsetSizes kSingleViewInsets;
53 static constexpr int32_t kBottomSeparator = 4;
54 static constexpr int32_t kHorizontalSeparator = 1;
55
K Moonbd80ce72019-07-26 19:27:5056 DocumentLayout();
57
K Mooneb9e0002019-08-06 19:25:3258 DocumentLayout(const DocumentLayout& other) = delete;
59 DocumentLayout& operator=(const DocumentLayout& other) = delete;
K Moonbd80ce72019-07-26 19:27:5060
61 ~DocumentLayout();
62
K Mooneb9e0002019-08-06 19:25:3263 // Returns the layout options.
64 const Options& options() const { return options_; }
K Moonbd80ce72019-07-26 19:27:5065
K Moon6d326b92019-09-19 22:42:0766 // Sets the layout options. If certain options with immediate effect change
67 // (such as the default page orientation), the layout will be marked dirty.
68 //
69 // TODO(kmoon): We shouldn't have layout options that take effect immediately.
70 void SetOptions(const Options& options);
71
72 // Returns true if the layout has been modified since the last call to
73 // clear_dirty(). The initial state is false (clean), which assumes
74 // appropriate default behavior for an initially empty layout.
75 bool dirty() const { return dirty_; }
76
77 // Clears the dirty() state of the layout. This should be called after any
78 // layout changes have been applied.
79 void clear_dirty() { dirty_ = false; }
K Moonbd80ce72019-07-26 19:27:5080
81 // Returns the layout's total size.
82 const pp::Size& size() const { return size_; }
83
K Moone4bd7522019-08-23 00:12:5684 size_t page_count() const { return page_layouts_.size(); }
Jeremy Chinsen08beb482019-08-07 01:58:5485
K Moonff7ec672019-08-14 19:19:5686 // Gets the layout rectangle for a page. Only valid after computing a layout.
87 const pp::Rect& page_rect(size_t page_index) const {
88 DCHECK_LT(page_index, page_count());
K Moone4bd7522019-08-23 00:12:5689 return page_layouts_[page_index].outer_rect;
90 }
91
92 // Gets the layout rectangle for a page's bounds (which excludes additional
93 // regions like page shadows). Only valid after computing a layout.
94 const pp::Rect& page_bounds_rect(size_t page_index) const {
95 DCHECK_LT(page_index, page_count());
96 return page_layouts_[page_index].inner_rect;
K Moonff7ec672019-08-14 19:19:5697 }
98
99 // Computes layout that represent |page_sizes| formatted for single view.
100 //
101 // TODO(kmoon): Control layout type using an option.
102 void ComputeSingleViewLayout(const std::vector<pp::Size>& page_sizes);
103
104 // Computes layout that represent |page_sizes| formatted for two-up view.
105 //
106 // TODO(kmoon): Control layout type using an option.
107 void ComputeTwoUpViewLayout(const std::vector<pp::Size>& page_sizes);
Jeremy Chinsend6fd27ce2019-08-06 00:40:17108
K Moonbd80ce72019-07-26 19:27:50109 private:
K Moone4bd7522019-08-23 00:12:56110 // Layout of a single page.
111 struct PageLayout {
112 // Bounding rectangle for the page with decorations.
113 pp::Rect outer_rect;
114
115 // Bounding rectangle for the page without decorations.
116 pp::Rect inner_rect;
117 };
118
K Moon6d326b92019-09-19 22:42:07119 // Copies |source_rect| to |destination_rect|, setting |dirty_| to true if
120 // |destination_rect| is modified as a result.
121 void CopyRectIfModified(const pp::Rect& source_rect,
122 pp::Rect* destination_rect);
123
K Mooneb9e0002019-08-06 19:25:32124 Options options_;
K Moonbd80ce72019-07-26 19:27:50125
K Moon6d326b92019-09-19 22:42:07126 // Indicates if the layout has changed in an externally-observable way,
127 // usually as a result of calling |ComputeLayout()| with different inputs.
128 //
129 // Some operations that may trigger layout changes:
130 // * Changing page sizes
131 // * Adding or removing pages
132 // * Changing page orientations
133 bool dirty_ = false;
134
K Moonbd80ce72019-07-26 19:27:50135 // Layout's total size.
136 pp::Size size_;
K Moonff7ec672019-08-14 19:19:56137
K Moone4bd7522019-08-23 00:12:56138 std::vector<PageLayout> page_layouts_;
K Moonbd80ce72019-07-26 19:27:50139};
140
141} // namespace chrome_pdf
142
143#endif // PDF_DOCUMENT_LAYOUT_H_