[go: nahoru, domu]

Add Document::GetSingleViewLayout() and draw_utils::GetRectForSingleView().

Currently the generation of the single-view layout in PDFiumEngine is
untested. To make the generation of these layouts testable the following
helper functions are being added:

  draw_utils::GetRectForSingleView(), given the current document size
  and a page's size, returns a page rect formatted for single-view.

  Document::GetSingleViewLayout(), given a vector of page sizes,
  returns a vector of page rects formatted for single-view and updates
  the size of the document.

Bug: 51472
Change-Id: Ie9e746cc4fedda551ccfb22aab4b3b64822c6b89
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1739666
Commit-Queue: Jeremy Chinsen <chinsenj@google.com>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#684616}
diff --git a/pdf/document_layout.cc b/pdf/document_layout.cc
index a7ab84a..813f1bae 100644
--- a/pdf/document_layout.cc
+++ b/pdf/document_layout.cc
@@ -33,6 +33,27 @@
 DocumentLayout::~DocumentLayout() = default;
 
 // TODO(chinsenj): refactor to not rely on prior DocumentLayout state.
+std::vector<pp::Rect> DocumentLayout::GetSingleViewLayout(
+    const std::vector<pp::Size>& page_sizes) {
+  std::vector<pp::Rect> formatted_rects(page_sizes.size());
+  DCHECK_EQ(0, size_.height());
+
+  for (size_t i = 0; i < page_sizes.size(); ++i) {
+    if (i != 0) {
+      // Add space for bottom separator.
+      EnlargeHeight(kBottomSeparator);
+    }
+
+    const pp::Size& page_size = page_sizes[i];
+    formatted_rects[i] =
+        draw_utils::GetRectForSingleView(page_size, size_, kSingleViewInsets);
+    AppendPageRect(page_size);
+  }
+
+  return formatted_rects;
+}
+
+// TODO(chinsenj): refactor to not rely on prior DocumentLayout state.
 std::vector<pp::Rect> DocumentLayout::GetTwoUpViewLayout(
     const std::vector<pp::Size>& page_sizes) {
   DCHECK_EQ(0, size_.height());
diff --git a/pdf/document_layout.h b/pdf/document_layout.h
index b9155dda..a558fbb7 100644
--- a/pdf/document_layout.h
+++ b/pdf/document_layout.h
@@ -75,6 +75,13 @@
   // Sets the layout's total size.
   void set_size(const pp::Size& size) { size_ = size; }
 
+  // Given |page_sizes| and the layout's width set to the max width of the
+  // document's pages, return pp::Rects that represent |page_sizes|
+  // formatted for single view and update the layout's size to the size of the
+  // new single view layout.
+  std::vector<pp::Rect> GetSingleViewLayout(
+      const std::vector<pp::Size>& page_sizes);
+
   // Given |page_sizes| and the layout's width is set to the max page width of
   // the document's pages, return pp::Rects that represent |page_sizes|
   // formatted for two-up view and update the layout's size to the size of the
diff --git a/pdf/document_layout_unittest.cc b/pdf/document_layout_unittest.cc
index 18cb0f5..02998b8 100644
--- a/pdf/document_layout_unittest.cc
+++ b/pdf/document_layout_unittest.cc
@@ -111,6 +111,32 @@
   EXPECT_PRED2(PpSizeEq, layout_.size(), pp::Size(0, 16));
 }
 
+TEST_F(DocumentLayoutTest, GetSingleViewLayout) {
+  std::vector<pp::Rect> single_view_layout;
+
+  std::vector<pp::Size> page_sizes{
+      {300, 400}, {400, 500}, {300, 400}, {200, 300}};
+  layout_.set_size({400, 0});
+  single_view_layout = layout_.GetSingleViewLayout(page_sizes);
+  ASSERT_EQ(4u, single_view_layout.size());
+  EXPECT_PRED2(PpRectEq, pp::Rect(55, 3, 290, 390), single_view_layout[0]);
+  EXPECT_PRED2(PpRectEq, pp::Rect(5, 407, 390, 490), single_view_layout[1]);
+  EXPECT_PRED2(PpRectEq, pp::Rect(55, 911, 290, 390), single_view_layout[2]);
+  EXPECT_PRED2(PpRectEq, pp::Rect(105, 1315, 190, 290), single_view_layout[3]);
+  EXPECT_PRED2(PpSizeEq, pp::Size(400, 1612), layout_.size());
+
+  page_sizes = {{240, 300}, {320, 400}, {250, 360}, {300, 600}, {270, 555}};
+  layout_.set_size({320, 0});
+  single_view_layout = layout_.GetSingleViewLayout(page_sizes);
+  ASSERT_EQ(5u, single_view_layout.size());
+  EXPECT_PRED2(PpRectEq, pp::Rect(45, 3, 230, 290), single_view_layout[0]);
+  EXPECT_PRED2(PpRectEq, pp::Rect(5, 307, 310, 390), single_view_layout[1]);
+  EXPECT_PRED2(PpRectEq, pp::Rect(40, 711, 240, 350), single_view_layout[2]);
+  EXPECT_PRED2(PpRectEq, pp::Rect(15, 1075, 290, 590), single_view_layout[3]);
+  EXPECT_PRED2(PpRectEq, pp::Rect(30, 1679, 260, 545), single_view_layout[4]);
+  EXPECT_PRED2(PpSizeEq, pp::Size(320, 2231), layout_.size());
+}
+
 TEST_F(DocumentLayoutTest, GetTwoUpViewLayout) {
   std::vector<pp::Rect> two_up_view_layout;
 
diff --git a/pdf/draw_utils/coordinates.cc b/pdf/draw_utils/coordinates.cc
index cd3171e9..4a62020 100644
--- a/pdf/draw_utils/coordinates.cc
+++ b/pdf/draw_utils/coordinates.cc
@@ -88,6 +88,17 @@
                   bottom_separator);
 }
 
+pp::Rect GetRectForSingleView(const pp::Size& rect_size,
+                              const pp::Size& document_size,
+                              const PageInsetSizes& page_insets) {
+  pp::Rect page_rect({0, document_size.height()}, rect_size);
+  CenterRectHorizontally(document_size.width(), &page_rect);
+  page_rect.Inset(page_insets.left, page_insets.top, page_insets.right,
+                  page_insets.bottom);
+
+  return page_rect;
+}
+
 pp::Rect GetScreenRect(const pp::Rect& rect,
                        const pp::Point& position,
                        double zoom) {
diff --git a/pdf/draw_utils/coordinates.h b/pdf/draw_utils/coordinates.h
index 5873197..1a77b49 100644
--- a/pdf/draw_utils/coordinates.h
+++ b/pdf/draw_utils/coordinates.h
@@ -82,6 +82,13 @@
                            const PageInsetSizes& inset_sizes,
                            int bottom_separator);
 
+// Given |rect_size| and |document_size| create a horizontally centered
+// pp::Rect placed at the bottom of the current document, and then inset it with
+// |page_insets|.
+pp::Rect GetRectForSingleView(const pp::Size& rect_size,
+                              const pp::Size& document_size,
+                              const PageInsetSizes& page_insets);
+
 // Given |rect| in document coordinates, a |position| in screen coordinates,
 // and a |zoom| factor, returns the rectangle in screen coordinates (i.e.
 // 0,0 is top left corner of plugin area). An empty |rect| will always
diff --git a/pdf/draw_utils/coordinates_unittest.cc b/pdf/draw_utils/coordinates_unittest.cc
index abb6747..ed221b8 100644
--- a/pdf/draw_utils/coordinates_unittest.cc
+++ b/pdf/draw_utils/coordinates_unittest.cc
@@ -194,6 +194,20 @@
                                                    kBottomSeparator));
 }
 
+TEST(CoordinateTest, GetRectForSingleView) {
+  // Test portrait pages.
+  CompareRect({55, 503, 190, 390},
+              GetRectForSingleView({200, 400}, {300, 500}, kSingleViewInsets));
+  CompareRect({55, 603, 90, 330},
+              GetRectForSingleView({100, 340}, {200, 600}, kSingleViewInsets));
+
+  // Test landscape pages.
+  CompareRect({5, 1003, 490, 440},
+              GetRectForSingleView({500, 450}, {500, 1000}, kSingleViewInsets));
+  CompareRect({30, 1503, 640, 190},
+              GetRectForSingleView({650, 200}, {700, 1500}, kSingleViewInsets));
+}
+
 TEST(CoordinateTest, GetScreenRect) {
   const pp::Rect rect(10, 20, 200, 300);
 
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc
index c461cd4..f9cf6db 100644
--- a/pdf/pdfium/pdfium_engine.cc
+++ b/pdf/pdfium/pdfium_engine.cc
@@ -2392,19 +2392,14 @@
   }
 }
 
+// TODO(chinsenj): Merge with LoadPagesInTwoUpView().
 void PDFiumEngine::LoadPagesInSingleView(std::vector<pp::Size> page_sizes,
                                          bool reload) {
-  for (size_t i = 0; i < page_sizes.size(); ++i) {
-    if (i != 0) {
-      // Add space for bottom separator.
-      layout_.EnlargeHeight(DocumentLayout::kBottomSeparator);
-    }
+  std::vector<pp::Rect> single_view_layout =
+      layout_.GetSingleViewLayout(page_sizes);
 
-    pp::Rect page_rect({0, layout_.size().height()}, page_sizes[i]);
-    layout_.AppendPageRect(page_sizes[i]);
-    draw_utils::CenterRectHorizontally(layout_.size().width(), &page_rect);
-    InsetPage(i, page_sizes.size(), /*multiplier=*/1, &page_rect);
-    AppendPageRectToPages(page_rect, i, reload);
+  for (size_t i = 0; i < single_view_layout.size(); ++i) {
+    AppendPageRectToPages(single_view_layout[i], i, reload);
   }
 }