0

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}
This commit is contained in:
K Moon
2019-10-03 05:06:23 +00:00
committed by Commit Bot
parent ee489fb626
commit 23d5644630
9 changed files with 338 additions and 0 deletions

@ -626,6 +626,14 @@ IN_PROC_BROWSER_TEST_F(PDFExtensionTest, Viewport) {
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");
}

@ -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);
}
});

@ -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

@ -0,0 +1,62 @@
%PDF-1.7
%<25><><EFBFBD><EFBFBD>
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

@ -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

@ -0,0 +1,73 @@
%PDF-1.7
%<25><><EFBFBD><EFBFBD>
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

@ -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& DocumentLayout::Options::operator=(
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_);
}

@ -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 @@ class DocumentLayout final {
~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_;
}

@ -80,6 +80,7 @@ constexpr char kJSStopScrollingType[] = "stopScrolling";
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 @@ void OutOfProcessInstance::ProposeDocumentLayout(const DocumentLayout& layout) {
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)