Serialize LayoutOptions to DocumentDimensions
Add ToVar() and FromVar() methods to DocumentLayout::Options, allowing
serialization to and from a pp::Var. This serialization is then used to
pass layout options (such as default page orientation) to and from
JavaScript (via the "documentDimensions" message).
pp::Var is non-trivial to unit test, due to dependencies on the
browser's PPAPI interfaces. Instead, this change adds 2 browser_tests,
PDFExtensionTest.Layout3 and PDFExtensionTest.Layout4. Each runs the
same layout_test.js suite over two slightly different test PDF files,
test-layout3.pdf (with 3 pages) and test-layout4.pdf (with 4 pages).
There's currently no coverage of deserialization, as we're not doing
anything with the layout options sent back from JavaScript yet. We'll
start using FromVar() in an upcoming CL (such as crrev.com/c/1747170).
Bug: 885110
Change-Id: I8c93b74062576ee07445070e0b4a82f0f861a82e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1830398
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: K Moon <kmoon@chromium.org>
Auto-Submit: K Moon <kmoon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#702324}
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc
index 807f8c48..ff6304da 100644
--- a/chrome/browser/pdf/pdf_extension_test.cc
+++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -626,6 +626,14 @@
RunTestsInFile("viewport_test.js", "test.pdf");
}
+IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Layout3) {
+ RunTestsInFile("layout_test.js", "test-layout3.pdf");
+}
+
+IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Layout4) {
+ RunTestsInFile("layout_test.js", "test-layout4.pdf");
+}
+
IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Bookmark) {
RunTestsInFile("bookmarks_test.js", "test-bookmarks.pdf");
}
diff --git a/chrome/test/data/pdf/layout_test.js b/chrome/test/data/pdf/layout_test.js
new file mode 100644
index 0000000..ddbc0e7
--- /dev/null
+++ b/chrome/test/data/pdf/layout_test.js
@@ -0,0 +1,51 @@
+// 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.
+
+// Tests common to all PDFs.
+const tests = [
+ function testLayoutOptions() {
+ chrome.test.assertEq(
+ {
+ defaultPageOrientation: 0,
+ },
+ viewer.viewport.getLayoutOptions());
+ chrome.test.succeed();
+ },
+];
+
+// Tests specific to each PDF's layout.
+const perLayoutTests = {
+ 'test-layout3.pdf': [
+ function testDimensions3() {
+ chrome.test.assertEq(
+ {
+ width: 103,
+ height: 437,
+ },
+ viewer.viewport.getDocumentDimensions());
+ chrome.test.succeed();
+ },
+ ],
+
+ 'test-layout4.pdf': [
+ function testDimensions4() {
+ chrome.test.assertEq(
+ {
+ width: 143,
+ height: 504,
+ },
+ viewer.viewport.getDocumentDimensions());
+ chrome.test.succeed();
+ },
+ ],
+};
+
+const scriptingAPI = new PDFScriptingAPI(window, window);
+scriptingAPI.setLoadCallback((success) => {
+ if (success && document.title in perLayoutTests) {
+ chrome.test.runTests(tests.concat(perLayoutTests[document.title]));
+ } else {
+ chrome.test.fail(document.title);
+ }
+});
diff --git a/chrome/test/data/pdf/test-layout3.in b/chrome/test/data/pdf/test-layout3.in
new file mode 100644
index 0000000..47932f42
--- /dev/null
+++ b/chrome/test/data/pdf/test-layout3.in
@@ -0,0 +1,49 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /MediaBox [ 0 0 70 100 ]
+ /Count 3
+ /Kids [ 3 0 R 4 0 R 5 0 R ]
+>>
+endobj
+{{object 3 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 6 0 R
+>>
+endobj
+{{object 4 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 6 0 R
+>>
+endobj
+{{object 5 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 6 0 R
+>>
+endobj
+% An asymmetrical "F" figure.
+{{object 6 0}} <<
+ {{streamlen}}
+>>
+stream
+2 0 0 2 10 25 cm
+0.0 G 0.5 g
+5 0 m
+5 25 l 20 25 l 20 20 l 10 20 l
+10 15 l 15 15 l 15 10 l 10 10 l
+10 0 l
+b
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/chrome/test/data/pdf/test-layout3.pdf b/chrome/test/data/pdf/test-layout3.pdf
new file mode 100644
index 0000000..2aa0086
--- /dev/null
+++ b/chrome/test/data/pdf/test-layout3.pdf
@@ -0,0 +1,62 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+ /Type /Pages
+ /MediaBox [ 0 0 70 100 ]
+ /Count 3
+ /Kids [ 3 0 R 4 0 R 5 0 R ]
+>>
+endobj
+3 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 6 0 R
+>>
+endobj
+4 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 6 0 R
+>>
+endobj
+5 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Contents 6 0 R
+>>
+endobj
+% An asymmetrical "F" figure.
+6 0 obj <<
+ /Length 107
+>>
+stream
+2 0 0 2 10 25 cm
+0.0 G 0.5 g
+5 0 m
+5 25 l 20 25 l 20 20 l 10 20 l
+10 15 l 15 15 l 15 10 l 10 10 l
+10 0 l
+b
+endstream
+endobj
+xref
+0 7
+0000000000 65535 f
+0000000015 00000 n
+0000000068 00000 n
+0000000172 00000 n
+0000000241 00000 n
+0000000310 00000 n
+0000000409 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 7
+>>
+startxref
+568
+%%EOF
diff --git a/chrome/test/data/pdf/test-layout4.in b/chrome/test/data/pdf/test-layout4.in
new file mode 100644
index 0000000..62dc71a
--- /dev/null
+++ b/chrome/test/data/pdf/test-layout4.in
@@ -0,0 +1,59 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /MediaBox [ 0 0 70 100 ]
+ /Count 4
+ /Kids [ 3 0 R 4 0 R 5 0 R 6 0 R ]
+>>
+endobj
+{{object 3 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /Rotate 0
+ /Contents 7 0 R
+>>
+endobj
+{{object 4 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /Rotate 90
+ /Contents 7 0 R
+>>
+endobj
+{{object 5 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /Rotate 180
+ /Contents 7 0 R
+>>
+endobj
+{{object 6 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /Rotate 270
+ /Contents 7 0 R
+>>
+endobj
+% An asymmetrical "F" figure.
+{{object 7 0}} <<
+ {{streamlen}}
+>>
+stream
+2 0 0 2 10 25 cm
+0.0 G 0.5 g
+5 0 m
+5 25 l 20 25 l 20 20 l 10 20 l
+10 15 l 15 15 l 15 10 l 10 10 l
+10 0 l
+b
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/chrome/test/data/pdf/test-layout4.pdf b/chrome/test/data/pdf/test-layout4.pdf
new file mode 100644
index 0000000..240038ec2
--- /dev/null
+++ b/chrome/test/data/pdf/test-layout4.pdf
@@ -0,0 +1,73 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+ /Type /Catalog
+ /Pages 2 0 R
+>>
+endobj
+2 0 obj <<
+ /Type /Pages
+ /MediaBox [ 0 0 70 100 ]
+ /Count 4
+ /Kids [ 3 0 R 4 0 R 5 0 R 6 0 R ]
+>>
+endobj
+3 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Rotate 0
+ /Contents 7 0 R
+>>
+endobj
+4 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Rotate 90
+ /Contents 7 0 R
+>>
+endobj
+5 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Rotate 180
+ /Contents 7 0 R
+>>
+endobj
+6 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /Rotate 270
+ /Contents 7 0 R
+>>
+endobj
+% An asymmetrical "F" figure.
+7 0 obj <<
+ /Length 107
+>>
+stream
+2 0 0 2 10 25 cm
+0.0 G 0.5 g
+5 0 m
+5 25 l 20 25 l 20 20 l 10 20 l
+10 15 l 15 15 l 15 10 l 10 10 l
+10 0 l
+b
+endstream
+endobj
+xref
+0 8
+0000000000 65535 f
+0000000015 00000 n
+0000000068 00000 n
+0000000178 00000 n
+0000000259 00000 n
+0000000341 00000 n
+0000000424 00000 n
+0000000537 00000 n
+trailer <<
+ /Root 1 0 R
+ /Size 8
+>>
+startxref
+696
+%%EOF
diff --git a/pdf/document_layout.cc b/pdf/document_layout.cc
index fc4c133..51064a3 100644
--- a/pdf/document_layout.cc
+++ b/pdf/document_layout.cc
@@ -7,11 +7,15 @@
#include "base/logging.h"
#include "ppapi/cpp/rect.h"
#include "ppapi/cpp/size.h"
+#include "ppapi/cpp/var.h"
+#include "ppapi/cpp/var_dictionary.h"
namespace chrome_pdf {
namespace {
+constexpr char kDefaultPageOrientation[] = "defaultPageOrientation";
+
int GetWidestPageWidth(const std::vector<pp::Size>& page_sizes) {
int widest_page_width = 0;
for (const auto& page_size : page_sizes) {
@@ -41,6 +45,26 @@
DocumentLayout::Options::~Options() = default;
+pp::Var DocumentLayout::Options::ToVar() const {
+ pp::VarDictionary dictionary;
+ dictionary.Set(kDefaultPageOrientation,
+ static_cast<int32_t>(default_page_orientation_));
+ return dictionary;
+}
+
+void DocumentLayout::Options::FromVar(const pp::Var& var) {
+ pp::VarDictionary dictionary(var);
+
+ int32_t default_page_orientation =
+ dictionary.Get(kDefaultPageOrientation).AsInt();
+ DCHECK_GE(default_page_orientation,
+ static_cast<int32_t>(PageOrientation::kOriginal));
+ DCHECK_LE(default_page_orientation,
+ static_cast<int32_t>(PageOrientation::kLast));
+ default_page_orientation_ =
+ static_cast<PageOrientation>(default_page_orientation);
+}
+
void DocumentLayout::Options::RotatePagesClockwise() {
default_page_orientation_ = RotateClockwise(default_page_orientation_);
}
diff --git a/pdf/document_layout.h b/pdf/document_layout.h
index 13cc51b..f67ae58 100644
--- a/pdf/document_layout.h
+++ b/pdf/document_layout.h
@@ -14,6 +14,10 @@
#include "ppapi/cpp/rect.h"
#include "ppapi/cpp/size.h"
+namespace pp {
+class Var;
+} // namespace pp
+
namespace chrome_pdf {
// Layout of pages within a PDF document. Pages are placed as rectangles
@@ -35,6 +39,12 @@
~Options();
+ // Serializes layout options to a pp::Var.
+ pp::Var ToVar() const;
+
+ // Deserializes layout options from a pp::Var.
+ void FromVar(const pp::Var& var);
+
PageOrientation default_page_orientation() const {
return default_page_orientation_;
}
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc
index a3786a8..d4fc7bcb 100644
--- a/pdf/out_of_process_instance.cc
+++ b/pdf/out_of_process_instance.cc
@@ -80,6 +80,7 @@
constexpr char kJSDocumentDimensionsType[] = "documentDimensions";
constexpr char kJSDocumentWidth[] = "width";
constexpr char kJSDocumentHeight[] = "height";
+constexpr char kJSLayoutOptions[] = "layoutOptions";
constexpr char kJSPageDimensions[] = "pageDimensions";
constexpr char kJSPageX[] = "x";
constexpr char kJSPageY[] = "y";
@@ -1292,6 +1293,7 @@
dimensions.Set(kType, kJSDocumentDimensionsType);
dimensions.Set(kJSDocumentWidth, pp::Var(document_size_.width()));
dimensions.Set(kJSDocumentHeight, pp::Var(document_size_.height()));
+ dimensions.Set(kJSLayoutOptions, layout.options().ToVar());
pp::VarArray page_dimensions_array;
size_t num_pages = layout.page_count();
if (page_is_processed_.size() < num_pages)