0
Files
src/pdf/document_layout_unittest.cc
K Moon 6d326b9edb Increase precision of PDF layout dirty tracking
DocumentLayout now sets a "dirty" bit if (and only if) the layout
changed. The current behavior only looks at changes to the overall
document size, which is inaccurate in cases such as orientation changes
that may change the layout of individual pages, but not the overall
document size (for certain combinations of page sizes).

This doesn't matter in the current code (the DocumentSizeUpdated event
might not fire, which is mostly harmless), but the fix for bug 885110
requires accurately detecting and reporting layout changes to the
viewer's JavaScript code, so DocumentLayout has been instrumented to
detect all current triggers for layout changes:

* Default page orientation changes
* Overall page count changes
* Overall document size changes (possibly redundant)
* Individual page layout rectangle changes

Bug: 885110
Change-Id: I0edfe2ad7af73abd1f176477826901b767c28b2e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1810032
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: K Moon <kmoon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#698235}
2019-09-19 22:42:07 +00:00

268 lines
10 KiB
C++

// 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 "testing/gtest/include/gtest/gtest.h"
namespace chrome_pdf {
namespace {
class DocumentLayoutOptionsTest : public testing::Test {
protected:
DocumentLayout::Options options_;
};
class DocumentLayoutTest : public testing::Test {
protected:
DocumentLayout layout_;
};
// 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;
}
inline bool PpRectEq(const pp::Rect& lhs, const pp::Rect& rhs) {
return lhs == rhs;
}
TEST_F(DocumentLayoutOptionsTest, DefaultConstructor) {
EXPECT_EQ(options_.default_page_orientation(), PageOrientation::kOriginal);
}
TEST_F(DocumentLayoutOptionsTest, CopyConstructor) {
options_.RotatePagesClockwise();
DocumentLayout::Options copy(options_);
EXPECT_EQ(copy.default_page_orientation(), PageOrientation::kClockwise90);
options_.RotatePagesClockwise();
EXPECT_EQ(copy.default_page_orientation(), PageOrientation::kClockwise90);
}
TEST_F(DocumentLayoutOptionsTest, CopyAssignment) {
options_.RotatePagesClockwise();
DocumentLayout::Options copy;
EXPECT_EQ(copy.default_page_orientation(), PageOrientation::kOriginal);
copy = options_;
EXPECT_EQ(copy.default_page_orientation(), PageOrientation::kClockwise90);
options_.RotatePagesClockwise();
EXPECT_EQ(copy.default_page_orientation(), PageOrientation::kClockwise90);
}
TEST_F(DocumentLayoutOptionsTest, RotatePagesClockwise) {
options_.RotatePagesClockwise();
EXPECT_EQ(options_.default_page_orientation(), PageOrientation::kClockwise90);
options_.RotatePagesClockwise();
EXPECT_EQ(options_.default_page_orientation(),
PageOrientation::kClockwise180);
options_.RotatePagesClockwise();
EXPECT_EQ(options_.default_page_orientation(),
PageOrientation::kClockwise270);
options_.RotatePagesClockwise();
EXPECT_EQ(options_.default_page_orientation(), PageOrientation::kOriginal);
}
TEST_F(DocumentLayoutOptionsTest, RotatePagesCounterclockwise) {
options_.RotatePagesCounterclockwise();
EXPECT_EQ(options_.default_page_orientation(),
PageOrientation::kClockwise270);
options_.RotatePagesCounterclockwise();
EXPECT_EQ(options_.default_page_orientation(),
PageOrientation::kClockwise180);
options_.RotatePagesCounterclockwise();
EXPECT_EQ(options_.default_page_orientation(), PageOrientation::kClockwise90);
options_.RotatePagesCounterclockwise();
EXPECT_EQ(options_.default_page_orientation(), PageOrientation::kOriginal);
}
TEST_F(DocumentLayoutTest, DefaultConstructor) {
EXPECT_EQ(layout_.options().default_page_orientation(),
PageOrientation::kOriginal);
EXPECT_FALSE(layout_.dirty());
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 0));
EXPECT_EQ(layout_.page_count(), 0u);
}
TEST_F(DocumentLayoutTest, SetOptionsDoesNotRecomputeLayout) {
layout_.ComputeSingleViewLayout({pp::Size(100, 200)});
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(100, 200));
DocumentLayout::Options options;
options.RotatePagesClockwise();
layout_.SetOptions(options);
EXPECT_EQ(layout_.options().default_page_orientation(),
PageOrientation::kClockwise90);
EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(100, 200));
}
TEST_F(DocumentLayoutTest, DirtySetOnOrientationChange) {
DocumentLayout::Options options;
layout_.SetOptions(options);
EXPECT_FALSE(layout_.dirty());
options.RotatePagesClockwise();
layout_.SetOptions(options);
EXPECT_TRUE(layout_.dirty());
}
TEST_F(DocumentLayoutTest, ComputeSingleViewLayout) {
std::vector<pp::Size> page_sizes{
{300, 400}, {400, 500}, {300, 400}, {200, 300}};
layout_.ComputeSingleViewLayout(page_sizes);
ASSERT_EQ(4u, layout_.page_count());
EXPECT_PRED2(PpRectEq, pp::Rect(50, 0, 300, 400), layout_.page_rect(0));
EXPECT_PRED2(PpRectEq, pp::Rect(0, 404, 400, 500), layout_.page_rect(1));
EXPECT_PRED2(PpRectEq, pp::Rect(50, 908, 300, 400), layout_.page_rect(2));
EXPECT_PRED2(PpRectEq, pp::Rect(100, 1312, 200, 300), layout_.page_rect(3));
EXPECT_PRED2(PpRectEq, pp::Rect(55, 3, 290, 390),
layout_.page_bounds_rect(0));
EXPECT_PRED2(PpRectEq, pp::Rect(5, 407, 390, 490),
layout_.page_bounds_rect(1));
EXPECT_PRED2(PpRectEq, pp::Rect(55, 911, 290, 390),
layout_.page_bounds_rect(2));
EXPECT_PRED2(PpRectEq, pp::Rect(105, 1315, 190, 290),
layout_.page_bounds_rect(3));
EXPECT_PRED2(PpSizeEq, pp::Size(400, 1612), layout_.size());
page_sizes = {{240, 300}, {320, 400}, {250, 360}, {300, 600}, {270, 555}};
layout_.ComputeSingleViewLayout(page_sizes);
ASSERT_EQ(5u, layout_.page_count());
EXPECT_PRED2(PpRectEq, pp::Rect(40, 0, 240, 300), layout_.page_rect(0));
EXPECT_PRED2(PpRectEq, pp::Rect(0, 304, 320, 400), layout_.page_rect(1));
EXPECT_PRED2(PpRectEq, pp::Rect(35, 708, 250, 360), layout_.page_rect(2));
EXPECT_PRED2(PpRectEq, pp::Rect(10, 1072, 300, 600), layout_.page_rect(3));
EXPECT_PRED2(PpRectEq, pp::Rect(25, 1676, 270, 555), layout_.page_rect(4));
EXPECT_PRED2(PpRectEq, pp::Rect(45, 3, 230, 290),
layout_.page_bounds_rect(0));
EXPECT_PRED2(PpRectEq, pp::Rect(5, 307, 310, 390),
layout_.page_bounds_rect(1));
EXPECT_PRED2(PpRectEq, pp::Rect(40, 711, 240, 350),
layout_.page_bounds_rect(2));
EXPECT_PRED2(PpRectEq, pp::Rect(15, 1075, 290, 590),
layout_.page_bounds_rect(3));
EXPECT_PRED2(PpRectEq, pp::Rect(30, 1679, 260, 545),
layout_.page_bounds_rect(4));
EXPECT_PRED2(PpSizeEq, pp::Size(320, 2231), layout_.size());
}
TEST_F(DocumentLayoutTest, ComputeTwoUpViewLayout) {
// Test case where the widest page is on the right.
std::vector<pp::Size> page_sizes{
{826, 1066}, {1066, 826}, {826, 1066}, {826, 900}};
layout_.ComputeTwoUpViewLayout(page_sizes);
ASSERT_EQ(4u, layout_.page_count());
EXPECT_PRED2(PpRectEq, pp::Rect(240, 0, 826, 1066), layout_.page_rect(0));
EXPECT_PRED2(PpRectEq, pp::Rect(1066, 0, 1066, 826), layout_.page_rect(1));
EXPECT_PRED2(PpRectEq, pp::Rect(240, 1066, 826, 1066), layout_.page_rect(2));
EXPECT_PRED2(PpRectEq, pp::Rect(1066, 1066, 826, 900), layout_.page_rect(3));
EXPECT_PRED2(PpRectEq, pp::Rect(245, 3, 820, 1056),
layout_.page_bounds_rect(0));
EXPECT_PRED2(PpRectEq, pp::Rect(1067, 3, 1060, 816),
layout_.page_bounds_rect(1));
EXPECT_PRED2(PpRectEq, pp::Rect(245, 1069, 820, 1056),
layout_.page_bounds_rect(2));
EXPECT_PRED2(PpRectEq, pp::Rect(1067, 1069, 820, 890),
layout_.page_bounds_rect(3));
EXPECT_PRED2(PpSizeEq, pp::Size(2132, 2132), layout_.size());
// Test case where the widest page is on the left.
page_sizes = {{1066, 826}, {820, 1056}, {820, 890}, {826, 1066}};
layout_.ComputeTwoUpViewLayout(page_sizes);
ASSERT_EQ(4u, layout_.page_count());
EXPECT_PRED2(PpRectEq, pp::Rect(0, 0, 1066, 826), layout_.page_rect(0));
EXPECT_PRED2(PpRectEq, pp::Rect(1066, 0, 820, 1056), layout_.page_rect(1));
EXPECT_PRED2(PpRectEq, pp::Rect(246, 1056, 820, 890), layout_.page_rect(2));
EXPECT_PRED2(PpRectEq, pp::Rect(1066, 1056, 826, 1066), layout_.page_rect(3));
EXPECT_PRED2(PpRectEq, pp::Rect(5, 3, 1060, 816),
layout_.page_bounds_rect(0));
EXPECT_PRED2(PpRectEq, pp::Rect(1067, 3, 814, 1046),
layout_.page_bounds_rect(1));
EXPECT_PRED2(PpRectEq, pp::Rect(251, 1059, 814, 880),
layout_.page_bounds_rect(2));
EXPECT_PRED2(PpRectEq, pp::Rect(1067, 1059, 820, 1056),
layout_.page_bounds_rect(3));
EXPECT_PRED2(PpSizeEq, pp::Size(2132, 2122), layout_.size());
// Test case where there's an odd # of pages.
page_sizes = {{200, 300}, {400, 200}, {300, 600}, {250, 500}, {300, 400}};
layout_.ComputeTwoUpViewLayout(page_sizes);
ASSERT_EQ(5u, layout_.page_count());
EXPECT_PRED2(PpRectEq, pp::Rect(200, 0, 200, 300), layout_.page_rect(0));
EXPECT_PRED2(PpRectEq, pp::Rect(400, 0, 400, 200), layout_.page_rect(1));
EXPECT_PRED2(PpRectEq, pp::Rect(100, 300, 300, 600), layout_.page_rect(2));
EXPECT_PRED2(PpRectEq, pp::Rect(400, 300, 250, 500), layout_.page_rect(3));
EXPECT_PRED2(PpRectEq, pp::Rect(100, 900, 300, 400), layout_.page_rect(4));
EXPECT_PRED2(PpRectEq, pp::Rect(205, 3, 194, 290),
layout_.page_bounds_rect(0));
EXPECT_PRED2(PpRectEq, pp::Rect(401, 3, 394, 190),
layout_.page_bounds_rect(1));
EXPECT_PRED2(PpRectEq, pp::Rect(105, 303, 294, 590),
layout_.page_bounds_rect(2));
EXPECT_PRED2(PpRectEq, pp::Rect(401, 303, 244, 490),
layout_.page_bounds_rect(3));
EXPECT_PRED2(PpRectEq, pp::Rect(105, 903, 290, 390),
layout_.page_bounds_rect(4));
EXPECT_PRED2(PpSizeEq, pp::Size(800, 1300), layout_.size());
}
TEST_F(DocumentLayoutTest, DirtySetOnSingleViewLayoutInputChange) {
layout_.ComputeSingleViewLayout({pp::Size(100, 200)});
EXPECT_TRUE(layout_.dirty());
layout_.clear_dirty();
EXPECT_FALSE(layout_.dirty());
layout_.ComputeSingleViewLayout({pp::Size(100, 200)});
EXPECT_FALSE(layout_.dirty());
layout_.ComputeSingleViewLayout({pp::Size(200, 100)});
EXPECT_TRUE(layout_.dirty());
layout_.clear_dirty();
layout_.ComputeSingleViewLayout({pp::Size(200, 100), pp::Size(300, 300)});
EXPECT_TRUE(layout_.dirty());
layout_.clear_dirty();
layout_.ComputeSingleViewLayout({pp::Size(200, 100)});
EXPECT_TRUE(layout_.dirty());
}
TEST_F(DocumentLayoutTest, DirtySetOnTwoUpViewLayoutInputChange) {
layout_.ComputeTwoUpViewLayout({pp::Size(100, 200), pp::Size(200, 100)});
EXPECT_TRUE(layout_.dirty());
layout_.clear_dirty();
EXPECT_FALSE(layout_.dirty());
layout_.ComputeTwoUpViewLayout({pp::Size(100, 200), pp::Size(200, 100)});
EXPECT_FALSE(layout_.dirty());
layout_.ComputeTwoUpViewLayout({pp::Size(200, 100), pp::Size(100, 200)});
EXPECT_TRUE(layout_.dirty());
layout_.clear_dirty();
layout_.ComputeTwoUpViewLayout(
{pp::Size(200, 100), pp::Size(100, 200), pp::Size(300, 300)});
EXPECT_TRUE(layout_.dirty());
layout_.clear_dirty();
layout_.ComputeTwoUpViewLayout({pp::Size(200, 100), pp::Size(100, 200)});
EXPECT_TRUE(layout_.dirty());
}
} // namespace
} // namespace chrome_pdf