Commit bd80ce77 authored by K Moon's avatar K Moon Committed by Commit Bot

Split layout state from PDFiumEngine

Refactors layout-specific state (document size, rotation) from
PDFiumEngine into a separate DocumentLayout class. This will allow new
layouts to be computed without disturbing the current layout.

As a side benefit, this should be another step towards simplifying
PDFiumEngine to be less of a grab bag of concerns.

Bug: 885110
Change-Id: Ieabde78d8acdcb2f83aac980d03f6fd8f28295a4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1716158
Commit-Queue: K Moon <kmoon@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#681422}
parent 9f10ab05
......@@ -50,6 +50,8 @@ if (enable_pdf) {
"accessibility.cc",
"accessibility.h",
"chunk_stream.h",
"document_layout.cc",
"document_layout.h",
"document_loader.h",
"document_loader_impl.cc",
"document_loader_impl.h",
......@@ -151,6 +153,7 @@ if (enable_pdf) {
configs += [ ":pdf_common_config" ]
sources = [
"chunk_stream_unittest.cc",
"document_layout_unittest.cc",
"document_loader_impl_unittest.cc",
"draw_utils/coordinates_unittest.cc",
"out_of_process_instance_unittest.cc",
......
// 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.
#include "pdf/document_layout.h"
#include "base/logging.h"
#include "pdf/draw_utils/coordinates.h"
namespace chrome_pdf {
DocumentLayout::DocumentLayout() = default;
DocumentLayout::DocumentLayout(const DocumentLayout& other) = default;
DocumentLayout& DocumentLayout::operator=(const DocumentLayout& other) =
default;
DocumentLayout::~DocumentLayout() = default;
void DocumentLayout::RotatePagesClockwise() {
default_page_orientation_ = (default_page_orientation_ + 1) % 4;
}
void DocumentLayout::RotatePagesCounterclockwise() {
default_page_orientation_ = (default_page_orientation_ - 1) % 4;
}
void DocumentLayout::EnlargeHeight(int height) {
DCHECK_GE(height, 0);
size_.Enlarge(0, height);
}
void DocumentLayout::AppendPageRect(const pp::Size& page_rect) {
// TODO(kmoon): Inline draw_utils::ExpandDocumentSize().
draw_utils::ExpandDocumentSize(page_rect, &size_);
}
} // namespace chrome_pdf
// 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 "ppapi/cpp/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.
//
// TODO(crbug.com/51472): Support multiple columns.
class DocumentLayout final {
public:
DocumentLayout();
DocumentLayout(const DocumentLayout& other);
DocumentLayout& operator=(const DocumentLayout& other);
~DocumentLayout();
// Returns an integer from 0 to 3 (inclusive), encoding the default
// orientation of the document's pages.
//
// A return value of 0 indicates the original page orientation, with each
// increment indicating clockwise rotation by an additional 90 degrees.
//
// TODO(kmoon): Return an enum (class) instead of an integer.
int default_page_orientation() const { return default_page_orientation_; }
// Rotates all pages 90 degrees clockwise. Does not recompute layout.
void RotatePagesClockwise();
// Rotates all pages 90 degrees counterclockwise. Does not recompute layout.
void RotatePagesCounterclockwise();
// Returns the layout's total size.
const pp::Size& size() const { return size_; }
// Sets the layout's total size.
void set_size(const pp::Size& size) { size_ = size; }
// Increases the layout's total height by |height|.
void EnlargeHeight(int height);
// Appends a rectangle of size |page_rect| to the layout. This will increase
// the layout's height by the page's height, and increase the layout's width
// to at least the page's width.
void AppendPageRect(const pp::Size& page_rect);
private:
// Orientations are non-negative integers modulo 4.
//
// TODO(kmoon): Doesn't match return type of default_page_orientation().
// Callers expect int, but internally, we want unsigned semantics. This will
// be cleaned up when we switch to an enum.
unsigned int default_page_orientation_ = 0;
// Layout's total size.
pp::Size size_;
};
} // namespace chrome_pdf
#endif // PDF_DOCUMENT_LAYOUT_H_
// 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.
#include "pdf/document_layout.h"
#include "base/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chrome_pdf {
namespace {
class DocumentLayoutTest : public testing::Test {
protected:
DocumentLayout layout_;
};
using DocumentLayoutDeathTest = DocumentLayoutTest;
// TODO(kmoon): Need to use this with EXPECT_PRED2 instead of just using
// EXPECT_EQ, due to ADL issues with pp::Size's operator== (defined in global
// namespace, instead of in "pp").
inline bool PpSizeEq(const pp::Size& lhs, const pp::Size& rhs) {
return lhs == rhs;
}
TEST_F(DocumentLayoutTest, DefaultConstructor) {
EXPECT_EQ(layout_.default_page_orientation(), 0);
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 0));
}
TEST_F(DocumentLayoutTest, CopyConstructor) {
layout_.RotatePagesClockwise();
layout_.EnlargeHeight(2);
DocumentLayout copy(layout_);
EXPECT_EQ(copy.default_page_orientation(), 1);
EXPECT_PRED2(PpSizeEq, copy.size(), pp::Size(0, 2));
layout_.RotatePagesClockwise();
layout_.EnlargeHeight(5);
EXPECT_EQ(copy.default_page_orientation(), 1);
EXPECT_PRED2(PpSizeEq, copy.size(), pp::Size(0, 2));
}
TEST_F(DocumentLayoutTest, CopyAssignment) {
layout_.RotatePagesClockwise();
layout_.EnlargeHeight(2);
DocumentLayout copy;
EXPECT_EQ(copy.default_page_orientation(), 0);
EXPECT_PRED2(PpSizeEq, copy.size(), pp::Size(0, 0));
copy = layout_;
EXPECT_EQ(copy.default_page_orientation(), 1);
EXPECT_PRED2(PpSizeEq, copy.size(), pp::Size(0, 2));
layout_.RotatePagesClockwise();
layout_.EnlargeHeight(5);
EXPECT_EQ(copy.default_page_orientation(), 1);
EXPECT_PRED2(PpSizeEq, copy.size(), pp::Size(0, 2));
}
TEST_F(DocumentLayoutTest, RotatePagesClockwise) {
layout_.RotatePagesClockwise();
EXPECT_EQ(layout_.default_page_orientation(), 1);
layout_.RotatePagesClockwise();
EXPECT_EQ(layout_.default_page_orientation(), 2);
layout_.RotatePagesClockwise();
EXPECT_EQ(layout_.default_page_orientation(), 3);
layout_.RotatePagesClockwise();
EXPECT_EQ(layout_.default_page_orientation(), 0);
}
TEST_F(DocumentLayoutTest, RotatePagesCounterclockwise) {
layout_.RotatePagesCounterclockwise();
EXPECT_EQ(layout_.default_page_orientation(), 3);
layout_.RotatePagesCounterclockwise();
EXPECT_EQ(layout_.default_page_orientation(), 2);
layout_.RotatePagesCounterclockwise();
EXPECT_EQ(layout_.default_page_orientation(), 1);
layout_.RotatePagesCounterclockwise();
EXPECT_EQ(layout_.default_page_orientation(), 0);
}
TEST_F(DocumentLayoutTest, RotatePagesDoesNotRecomputeLayout) {
layout_.EnlargeHeight(2);
layout_.RotatePagesClockwise();
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 2));
layout_.RotatePagesCounterclockwise();
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 2));
}
TEST_F(DocumentLayoutTest, EnlargeHeight) {
layout_.EnlargeHeight(5);
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 5));
layout_.EnlargeHeight(11);
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 16));
}
TEST_F(DocumentLayoutDeathTest, EnlargeHeightNegativeIncrement) {
EXPECT_DCHECK_DEATH(layout_.EnlargeHeight(-5));
}
TEST_F(DocumentLayoutTest, AppendPageRect) {
layout_.AppendPageRect(pp::Size(3, 5));
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(3, 5));
layout_.AppendPageRect(pp::Size(7, 11));
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(7, 16));
layout_.AppendPageRect(pp::Size(5, 11));
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(7, 27));
}
} // namespace
} // namespace chrome_pdf
This diff is collapsed.
......@@ -17,6 +17,7 @@
#include "base/optional.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "pdf/document_layout.h"
#include "pdf/document_loader.h"
#include "pdf/pdf_engine.h"
#include "pdf/pdfium/pdfium_form_filler.h"
......@@ -515,7 +516,9 @@ class PDFiumEngine : public PDFEngine,
static FPDF_BOOL Pause_NeedToPauseNow(IFSDK_PAUSE* param);
PDFEngine::Client* const client_;
pp::Size document_size_; // Size of document in pixels.
// The current document layout.
DocumentLayout layout_;
// The scroll position in screen coordinates.
pp::Point position_;
......@@ -524,7 +527,6 @@ class PDFiumEngine : public PDFEngine,
// The plugin size in screen coordinates.
pp::Size plugin_size_;
double current_zoom_ = 1.0;
unsigned int current_rotation_ = 0;
std::unique_ptr<DocumentLoader> doc_loader_; // Main document's loader.
std::string url_;
......
......@@ -100,7 +100,7 @@ void PDFiumFormFiller::Form_Invalidate(FPDF_FORMFILLINFO* param,
pp::Rect rect = engine->pages_[page_index]->PageToScreen(
engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right,
bottom, engine->current_rotation_);
bottom, engine->layout_.default_page_orientation());
engine->client_->Invalidate(rect);
}
......@@ -119,7 +119,7 @@ void PDFiumFormFiller::Form_OutputSelectedRect(FPDF_FORMFILLINFO* param,
}
pp::Rect rect = engine->pages_[page_index]->PageToScreen(
engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right,
bottom, engine->current_rotation_);
bottom, engine->layout_.default_page_orientation());
if (rect.IsEmpty())
return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment