android_webview
apps
ash
base
build
build_overrides
buildtools
cc
chrome
chromecast
chromeos
clank
codelabs
components
content
courgette
crypto
dbus
device
docs
extensions
fuchsia_web
gin
google_apis
google_update
gpu
headless
infra
internal
ios
ios_internal
ipc
media
mojo
native_client
native_client_sdk
net
pdf
draw_utils
loader
mojom
pdf_utils
pdfium
test
ui
BUILD.gn
COMMON_METADATA
DEPS
DIR_METADATA
OWNERS
README.md
accessibility.cc
accessibility.h
accessibility_helper.cc
accessibility_helper.h
accessibility_structs.cc
accessibility_structs.h
content_restriction.h
document_attachment_info.cc
document_attachment_info.h
document_layout.cc
document_layout.h
document_layout_unittest.cc
document_metadata.cc
document_metadata.h
features.gni
flatten_pdf_result.cc
flatten_pdf_result.h
metrics_handler.cc
metrics_handler.h
page_orientation.cc
page_orientation.h
page_orientation_unittest.cc
paint_aggregator.cc
paint_aggregator.h
paint_manager.cc
paint_manager.h
paint_manager_unittest.cc
paint_ready_rect.cc
paint_ready_rect.h
parsed_params.cc
parsed_params.h
parsed_params_unittest.cc
pdf.cc
pdf.h
pdf_accessibility_action_handler.h
pdf_accessibility_data_handler.h
pdf_accessibility_image_fetcher.h
pdf_engine.h
pdf_features.cc
pdf_features.h
pdf_init.cc
pdf_init.h
pdf_transform.cc
pdf_transform.h
pdf_transform_unittest.cc
pdf_view_web_plugin.cc
pdf_view_web_plugin.h
pdf_view_web_plugin_unittest.cc
post_message_receiver.cc
post_message_receiver.h
preview_mode_client.cc
preview_mode_client.h
v8_value_converter.h
ppapi
printing
remoting
rlz
sandbox
services
signing_keys
skia
sql
storage
styleguide
testing
third_party
tools
ui
url
v8
webkit
.clang-format
.clang-tidy
.clangd
.eslintrc.js
.git-blame-ignore-revs
.gitallowed
.gitattributes
.gitignore
.gitmodules
.gn
.mailmap
.rustfmt.toml
.vpython3
.yapfignore
ATL_OWNERS
AUTHORS
BUILD.gn
CODE_OF_CONDUCT.md
CPPLINT.cfg
DEPS
DIR_METADATA
LICENSE
LICENSE.chromium_os
OWNERS
PRESUBMIT.py
PRESUBMIT_test.py
PRESUBMIT_test_mocks.py
README.md
WATCHLISTS
codereview.settings

The methodology used to generate this CL is documented in https://crbug.com/1098010#c95. No-Try: true Bug: 1098010 Change-Id: I6ae92e5d7ccbf73b176588124b2f8b4067f805b3 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3900575 Reviewed-by: Mark Mentovai <mark@chromium.org> Owners-Override: Avi Drissman <avi@chromium.org> Commit-Queue: Avi Drissman <avi@chromium.org> Auto-Submit: Avi Drissman <avi@chromium.org> Cr-Commit-Position: refs/heads/main@{#1047628}
180 lines
5.8 KiB
C++
180 lines
5.8 KiB
C++
// Copyright 2019 The Chromium Authors
|
|
// 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 "base/values.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 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::Dict.
|
|
base::Value::Dict ToValue() const;
|
|
|
|
// Deserializes layout options from a base::Value::Dict.
|
|
void FromValue(const base::Value::Dict& 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_
|