summaryrefslogtreecommitdiff
path: root/chromium/pdf
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-05-15 10:20:33 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-05-15 10:28:57 +0000
commitd17ea114e5ef69ad5d5d7413280a13e6428098aa (patch)
tree2c01a75df69f30d27b1432467cfe7c1467a498da /chromium/pdf
parent8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (diff)
downloadqtwebengine-chromium-d17ea114e5ef69ad5d5d7413280a13e6428098aa.tar.gz
BASELINE: Update Chromium to 67.0.3396.47
Change-Id: Idcb1341782e417561a2473eeecc82642dafda5b7 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/pdf')
-rw-r--r--chromium/pdf/BUILD.gn7
-rw-r--r--chromium/pdf/DEPS2
-rw-r--r--chromium/pdf/OWNERS1
-rw-r--r--chromium/pdf/chunk_stream.h32
-rw-r--r--chromium/pdf/document_loader.cc88
-rw-r--r--chromium/pdf/document_loader.h17
-rw-r--r--chromium/pdf/out_of_process_instance.cc60
-rw-r--r--chromium/pdf/out_of_process_instance.h7
-rw-r--r--chromium/pdf/pdf.cc10
-rw-r--r--chromium/pdf/pdf.h8
-rw-r--r--chromium/pdf/pdf_engine.h21
-rw-r--r--chromium/pdf/pdf_transform.cc139
-rw-r--r--chromium/pdf/pdf_transform.h100
-rw-r--r--chromium/pdf/pdf_transform_unittest.cc335
-rw-r--r--chromium/pdf/pdfium/DEPS3
-rw-r--r--chromium/pdf/pdfium/fuzzers/BUILD.gn9
-rw-r--r--chromium/pdf/pdfium/pdfium_engine.cc372
-rw-r--r--chromium/pdf/pdfium/pdfium_engine.h22
-rw-r--r--chromium/pdf/pdfium/pdfium_range.cc47
-rw-r--r--chromium/pdf/pdfium/pdfium_range.h2
-rw-r--r--chromium/pdf/preview_mode_client.cc13
-rw-r--r--chromium/pdf/preview_mode_client.h7
-rw-r--r--chromium/pdf/run_all_unittests.cc2
23 files changed, 1072 insertions, 232 deletions
diff --git a/chromium/pdf/BUILD.gn b/chromium/pdf/BUILD.gn
index 6d46f53b399..c5afc0833b5 100644
--- a/chromium/pdf/BUILD.gn
+++ b/chromium/pdf/BUILD.gn
@@ -10,8 +10,8 @@ import("//testing/test.gni")
import("//third_party/pdfium/pdfium.gni")
# Generate a buildflag header for compile-time checking of PDF support.
-buildflag_header("features") {
- header = "features.h"
+buildflag_header("buildflags") {
+ header = "buildflags.h"
flags = [ "ENABLE_PDF=$enable_pdf" ]
}
@@ -52,6 +52,8 @@ if (enable_pdf) {
"pdf_engine.h",
"pdf_ppapi.cc",
"pdf_ppapi.h",
+ "pdf_transform.cc",
+ "pdf_transform.h",
"preview_mode_client.cc",
"preview_mode_client.h",
"range_set.cc",
@@ -102,6 +104,7 @@ if (enable_pdf) {
sources = [
"chunk_stream_unittest.cc",
"document_loader_unittest.cc",
+ "pdf_transform_unittest.cc",
"range_set_unittest.cc",
"run_all_unittests.cc",
]
diff --git a/chromium/pdf/DEPS b/chromium/pdf/DEPS
index 6e45472268d..36bce0d849a 100644
--- a/chromium/pdf/DEPS
+++ b/chromium/pdf/DEPS
@@ -2,9 +2,11 @@ include_rules = [
"+chrome/common/content_restriction.h",
"+net",
"+ppapi",
+ "+printing/units.h",
"+ui/base/window_open_disposition.h",
"+ui/events/keycodes/keyboard_codes.h",
"+ui/gfx/geometry/point_f.h",
+ "+ui/gfx/geometry/rect.h",
"+ui/gfx/range/range.h",
"+v8/include/v8.h"
]
diff --git a/chromium/pdf/OWNERS b/chromium/pdf/OWNERS
index f9f754215c0..1b70ae55ba7 100644
--- a/chromium/pdf/OWNERS
+++ b/chromium/pdf/OWNERS
@@ -1,4 +1,5 @@
dsinclair@chromium.org
+hnakashima@chromium.org
jochen@chromium.org
thestig@chromium.org
diff --git a/chromium/pdf/chunk_stream.h b/chromium/pdf/chunk_stream.h
index b8b3c831e90..7eb75cf61b8 100644
--- a/chromium/pdf/chunk_stream.h
+++ b/chromium/pdf/chunk_stream.h
@@ -11,6 +11,7 @@
#include <algorithm>
#include <array>
#include <memory>
+#include <utility>
#include <vector>
#include "pdf/range_set.h"
@@ -31,20 +32,21 @@ class ChunkStream {
void SetChunkData(uint32_t chunk_index, std::unique_ptr<ChunkData> data) {
if (!data)
return;
- if (chunk_index >= data_.size()) {
+
+ if (chunk_index >= data_.size())
data_.resize(chunk_index + 1);
- }
- if (!data_[chunk_index]) {
+
+ if (!data_[chunk_index])
++filled_chunks_count_;
- }
+
data_[chunk_index] = std::move(data);
filled_chunks_.Union(gfx::Range(chunk_index, chunk_index + 1));
}
bool ReadData(const gfx::Range& range, void* buffer) const {
- if (!IsRangeAvailable(range)) {
+ if (!IsRangeAvailable(range))
return false;
- }
+
unsigned char* data_buffer = static_cast<unsigned char*>(buffer);
uint32_t start = range.start();
while (start != range.end()) {
@@ -62,18 +64,20 @@ class ChunkStream {
uint32_t GetChunkIndex(uint32_t offset) const { return offset / kChunkSize; }
gfx::Range GetChunksRange(uint32_t offset, uint32_t size) const {
- return gfx::Range(GetChunkIndex(offset),
- GetChunkIndex(offset + size + kChunkSize - 1));
+ return gfx::Range(GetChunkIndex(offset), GetChunkEnd(offset + size));
}
bool IsRangeAvailable(const gfx::Range& range) const {
if (!range.IsValid() || range.is_reversed() ||
- (eof_pos_ > 0 && eof_pos_ < range.end()))
+ (eof_pos_ > 0 && eof_pos_ < range.end())) {
return false;
+ }
+
if (range.is_empty())
return true;
+
const gfx::Range chunks_range(GetChunkIndex(range.start()),
- GetChunkIndex(range.end() + kChunkSize - 1));
+ GetChunkEnd(range.end()));
return filled_chunks_.Contains(chunks_range);
}
@@ -94,11 +98,13 @@ class ChunkStream {
}
uint32_t filled_chunks_count() const { return filled_chunks_count_; }
- uint32_t total_chunks_count() const {
- return GetChunkIndex(eof_pos_ + kChunkSize - 1);
- }
+ uint32_t total_chunks_count() const { return GetChunkEnd(eof_pos_); }
private:
+ uint32_t GetChunkEnd(uint32_t offset) const {
+ return (offset + kChunkSize - 1) / kChunkSize;
+ }
+
std::vector<std::unique_ptr<ChunkData>> data_;
uint32_t eof_pos_ = 0;
RangeSet filled_chunks_;
diff --git a/chromium/pdf/document_loader.cc b/chromium/pdf/document_loader.cc
index f8f89f55d36..23ed4ac83ac 100644
--- a/chromium/pdf/document_loader.cc
+++ b/chromium/pdf/document_loader.cc
@@ -98,16 +98,15 @@ bool DocumentLoader::Init(std::unique_ptr<URLLoaderWrapper> loader,
url_ = url;
loader_ = std::move(loader);
- if (!loader_->IsContentEncoded()) {
- chunk_stream_.set_eof_pos(std::max(0, loader_->GetContentLength()));
- }
+ if (!loader_->IsContentEncoded())
+ SetDocumentSize(std::max(0, loader_->GetContentLength()));
+
int64_t bytes_received = 0;
int64_t total_bytes_to_be_received = 0;
- if (!chunk_stream_.eof_pos() &&
+ if (GetDocumentSize() == 0 &&
loader_->GetDownloadProgress(&bytes_received,
&total_bytes_to_be_received)) {
- chunk_stream_.set_eof_pos(
- std::max(0, static_cast<int>(total_bytes_to_be_received)));
+ SetDocumentSize(std::max(0, static_cast<int>(total_bytes_to_be_received)));
}
SetPartialLoadingEnabled(
@@ -124,6 +123,10 @@ bool DocumentLoader::IsDocumentComplete() const {
return chunk_stream_.IsComplete();
}
+void DocumentLoader::SetDocumentSize(uint32_t size) {
+ chunk_stream_.set_eof_pos(size);
+}
+
uint32_t DocumentLoader::GetDocumentSize() const {
return chunk_stream_.eof_pos();
}
@@ -153,22 +156,22 @@ bool DocumentLoader::IsDataAvailable(uint32_t position, uint32_t size) const {
}
void DocumentLoader::RequestData(uint32_t position, uint32_t size) {
- if (!size || IsDataAvailable(position, size)) {
+ if (size == 0 || IsDataAvailable(position, size))
return;
- }
- {
- // Check integer overflow.
+
+ const uint32_t document_size = GetDocumentSize();
+ if (document_size != 0) {
+ // Check for integer overflow.
base::CheckedNumeric<uint32_t> addition_result = position;
addition_result += size;
if (!addition_result.IsValid())
return;
- }
- if (GetDocumentSize() && (position + size > GetDocumentSize())) {
- return;
+ if (addition_result.ValueOrDie() > document_size)
+ return;
}
- // We have some artefact request from
+ // We have some artifact request from
// PDFiumEngine::OnDocumentComplete() -> FPDFAvail_IsPageAvail after
// document is complete.
// We need this fix in PDFIum. Adding this as a work around.
@@ -207,9 +210,10 @@ bool DocumentLoader::ShouldCancelLoading() const {
void DocumentLoader::ContinueDownload() {
if (!ShouldCancelLoading())
return ReadMore();
+
DCHECK(partial_loading_enabled_);
DCHECK(!IsDocumentComplete());
- DCHECK(GetDocumentSize());
+ DCHECK_GT(GetDocumentSize(), 0U);
const uint32_t range_start =
pending_requests_.IsEmpty() ? 0 : pending_requests_.First().start();
@@ -241,7 +245,7 @@ void DocumentLoader::ContinueDownload() {
const uint32_t start = next_request.start() * DataStream::kChunkSize;
const uint32_t length =
- std::min(chunk_stream_.eof_pos() - start,
+ std::min(GetDocumentSize() - start,
next_request.length() * DataStream::kChunkSize);
loader_ = client_->CreateURLLoader();
@@ -311,35 +315,37 @@ void DocumentLoader::DidRead(int32_t result) {
DCHECK(!chunk_.chunk_data);
chunk_.chunk_index = chunk_stream_.GetChunkIndex(start_pos);
}
- if (!SaveChunkData(buffer_, result))
+ if (!SaveBuffer(buffer_, result))
return ReadMore();
if (IsDocumentComplete())
return ReadComplete();
return ContinueDownload();
}
-bool DocumentLoader::SaveChunkData(char* input, uint32_t input_size) {
- count_of_bytes_received_ += input_size;
+bool DocumentLoader::SaveBuffer(char* input, uint32_t input_size) {
+ const uint32_t document_size = GetDocumentSize();
+ if (document_size != 0) {
+ // If the HTTP server sends more data than expected, then truncate
+ // |input_size| to the expected size.
+ input_size = std::min(document_size - bytes_received_, input_size);
+ }
+ bytes_received_ += input_size;
bool chunk_saved = false;
bool loading_pending_request = pending_requests_.Contains(chunk_.chunk_index);
while (input_size > 0) {
- if (chunk_.data_size == 0) {
+ if (chunk_.data_size == 0)
chunk_.chunk_data = std::make_unique<DataStream::ChunkData>();
- }
+
const uint32_t new_chunk_data_len =
std::min(DataStream::kChunkSize - chunk_.data_size, input_size);
memcpy(chunk_.chunk_data->data() + chunk_.data_size, input,
new_chunk_data_len);
chunk_.data_size += new_chunk_data_len;
if (chunk_.data_size == DataStream::kChunkSize ||
- chunk_stream_.eof_pos() ==
- chunk_.chunk_index * DataStream::kChunkSize + chunk_.data_size) {
- chunk_stream_.SetChunkData(chunk_.chunk_index,
- std::move(chunk_.chunk_data));
+ document_size == EndOfCurrentChunk()) {
pending_requests_.Subtract(
gfx::Range(chunk_.chunk_index, chunk_.chunk_index + 1));
- chunk_.data_size = 0;
- ++(chunk_.chunk_index);
+ SaveChunkData();
chunk_saved = true;
}
@@ -362,20 +368,32 @@ bool DocumentLoader::SaveChunkData(char* input, uint32_t input_size) {
return true;
}
+void DocumentLoader::SaveChunkData() {
+ chunk_stream_.SetChunkData(chunk_.chunk_index, std::move(chunk_.chunk_data));
+ chunk_.data_size = 0;
+ ++chunk_.chunk_index;
+}
+
+uint32_t DocumentLoader::EndOfCurrentChunk() const {
+ return chunk_.chunk_index * DataStream::kChunkSize + chunk_.data_size;
+}
+
void DocumentLoader::ReadComplete() {
- if (!GetDocumentSize()) {
- uint32_t eof =
- chunk_.chunk_index * DataStream::kChunkSize + chunk_.data_size;
+ if (GetDocumentSize() != 0) {
+ // If there is remaining data in |chunk_|, then save whatever can be saved.
+ // e.g. In the underrun case.
+ if (chunk_.data_size != 0)
+ SaveChunkData();
+ } else {
+ uint32_t eof = EndOfCurrentChunk();
if (!chunk_stream_.filled_chunks().IsEmpty()) {
eof = std::max(
chunk_stream_.filled_chunks().Last().end() * DataStream::kChunkSize,
eof);
}
- chunk_stream_.set_eof_pos(eof);
- if (eof == chunk_.chunk_index * DataStream::kChunkSize + chunk_.data_size) {
- chunk_stream_.SetChunkData(chunk_.chunk_index,
- std::move(chunk_.chunk_data));
- }
+ SetDocumentSize(eof);
+ if (eof == EndOfCurrentChunk())
+ SaveChunkData();
}
loader_.reset();
if (IsDocumentComplete()) {
diff --git a/chromium/pdf/document_loader.h b/chromium/pdf/document_loader.h
index b8af158c06e..3df4f8ccf33 100644
--- a/chromium/pdf/document_loader.h
+++ b/chromium/pdf/document_loader.h
@@ -11,6 +11,7 @@
#include <memory>
#include <string>
+#include "base/macros.h"
#include "pdf/chunk_stream.h"
#include "ppapi/utility/completion_callback_factory.h"
@@ -62,8 +63,9 @@ class DocumentLoader {
void RequestData(uint32_t position, uint32_t size);
bool IsDocumentComplete() const;
+ void SetDocumentSize(uint32_t size);
uint32_t GetDocumentSize() const;
- uint32_t count_of_bytes_received() const { return count_of_bytes_received_; }
+ uint32_t bytes_received() const { return bytes_received_; }
// Clear pending requests from the queue.
void ClearPendingRequests();
@@ -97,7 +99,10 @@ class DocumentLoader {
// Called when we complete server request.
void ReadComplete();
- bool SaveChunkData(char* input, uint32_t input_size);
+ bool SaveBuffer(char* input, uint32_t input_size);
+ void SaveChunkData();
+
+ uint32_t EndOfCurrentChunk() const;
Client* const client_;
std::string url_;
@@ -112,9 +117,15 @@ class DocumentLoader {
static constexpr uint32_t kReadBufferSize = 256 * 1024;
char buffer_[kReadBufferSize];
+ // The current chunk DocumentLoader is working with.
Chunk chunk_;
+
+ // In units of Chunks.
RangeSet pending_requests_;
- uint32_t count_of_bytes_received_ = 0;
+
+ uint32_t bytes_received_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(DocumentLoader);
};
} // namespace chrome_pdf
diff --git a/chromium/pdf/out_of_process_instance.cc b/chromium/pdf/out_of_process_instance.cc
index a8d19d236d2..804971bc44d 100644
--- a/chromium/pdf/out_of_process_instance.cc
+++ b/chromium/pdf/out_of_process_instance.cc
@@ -112,6 +112,8 @@ const char kJSPreviewPageIndex[] = "index";
const char kJSSetScrollPositionType[] = "setScrollPosition";
const char kJSPositionX[] = "x";
const char kJSPositionY[] = "y";
+// Scroll by (Plugin -> Page)
+const char kJSScrollByType[] = "scrollBy";
// Cancel the stream URL request (Plugin -> Page)
const char kJSCancelStreamUrlType[] = "cancelStreamUrl";
// Navigate to the given URL (Plugin -> Page)
@@ -323,24 +325,6 @@ void ScaleRect(float scale, pp::Rect* rect) {
rect->SetRect(left, top, right - left, bottom - top);
}
-// TODO(raymes): Remove this dependency on VarPrivate/InstancePrivate. It's
-// needed right now to do a synchronous call to JavaScript, but we could easily
-// replace this with a custom PPB_PDF function.
-pp::Var ModalDialog(const pp::Instance* instance,
- const std::string& type,
- const std::string& message,
- const std::string& default_answer) {
- const PPB_Instance_Private* ppb_interface =
- reinterpret_cast<const PPB_Instance_Private*>(
- pp::Module::Get()->GetBrowserInterface(
- PPB_INSTANCE_PRIVATE_INTERFACE));
- pp::VarPrivate window(
- pp::PASS_REF, ppb_interface->GetWindowObject(instance->pp_instance()));
- if (default_answer.empty())
- return window.Call(type, message);
- return window.Call(type, message, default_answer);
-}
-
} // namespace
OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance)
@@ -932,6 +916,12 @@ void OutOfProcessInstance::SendAccessibilityViewportInfo() {
-top_toolbar_height_in_viewport_coords_ * device_scale_;
viewport_info.offset = available_area_.point();
viewport_info.zoom = zoom_ * device_scale_;
+
+ engine_->GetSelection(&viewport_info.selection_start_page_index,
+ &viewport_info.selection_start_char_index,
+ &viewport_info.selection_end_page_index,
+ &viewport_info.selection_end_char_index);
+
pp::PDF::SetAccessibilityViewportInfo(GetPluginInstance(), &viewport_info);
}
@@ -947,6 +937,8 @@ void OutOfProcessInstance::SelectionChanged(const pp::Rect& left,
pp::PDF::SelectionChanged(GetPluginInstance(),
PP_MakeFloatPoint(l.x(), l.y()), left.height(),
PP_MakeFloatPoint(r.x(), r.y()), right.height());
+ if (accessibility_state_ == ACCESSIBILITY_STATE_LOADED)
+ SendAccessibilityViewportInfo();
}
void OutOfProcessInstance::SetCaretPosition(const pp::FloatPoint& position) {
@@ -1226,11 +1218,9 @@ void OutOfProcessInstance::Invalidate(const pp::Rect& rect) {
paint_manager_.InvalidateRect(offset_rect);
}
-void OutOfProcessInstance::Scroll(const pp::Point& point) {
- if (!image_data_.is_null()) {
+void OutOfProcessInstance::DidScroll(const pp::Point& point) {
+ if (!image_data_.is_null())
paint_manager_.ScrollRect(available_area_, point);
- pp::PDF::DidScroll(GetPluginInstance());
- }
}
void OutOfProcessInstance::ScrollToX(int x_in_screen_coords) {
@@ -1252,6 +1242,14 @@ void OutOfProcessInstance::ScrollToY(int y_in_screen_coords,
PostMessage(position);
}
+void OutOfProcessInstance::ScrollBy(const pp::Point& point) {
+ pp::VarDictionary position;
+ position.Set(kType, kJSScrollByType);
+ position.Set(kJSPositionX, pp::Var(point.x() / device_scale_));
+ position.Set(kJSPositionY, pp::Var(point.y() / device_scale_));
+ PostMessage(position);
+}
+
void OutOfProcessInstance::ScrollToPage(int page) {
if (engine_->GetNumberOfPages() == 0)
return;
@@ -1367,17 +1365,17 @@ void OutOfProcessInstance::GetDocumentPassword(
}
void OutOfProcessInstance::Alert(const std::string& message) {
- ModalDialog(this, "alert", message, std::string());
+ pp::PDF::ShowAlertDialog(this, message.c_str());
}
bool OutOfProcessInstance::Confirm(const std::string& message) {
- pp::Var result = ModalDialog(this, "confirm", message, std::string());
- return result.is_bool() ? result.AsBool() : false;
+ return pp::PDF::ShowConfirmDialog(this, message.c_str());
}
std::string OutOfProcessInstance::Prompt(const std::string& question,
const std::string& default_answer) {
- pp::Var result = ModalDialog(this, "prompt", question, default_answer);
+ pp::Var result =
+ pp::PDF::ShowPromptDialog(this, question.c_str(), default_answer.c_str());
return result.is_string() ? result.AsString() : std::string();
}
@@ -1500,7 +1498,8 @@ OutOfProcessInstance::SearchString(const base::char16* string,
void OutOfProcessInstance::DocumentPaintOccurred() {}
void OutOfProcessInstance::DocumentLoadComplete(
- const PDFEngine::DocumentFeatures& document_features) {
+ const PDFEngine::DocumentFeatures& document_features,
+ uint32_t file_size) {
// Clear focus state for OSK.
FormTextFieldFocusChange(false);
@@ -1565,6 +1564,9 @@ void OutOfProcessInstance::DocumentLoadComplete(
}
pp::PDF::SetContentRestriction(this, content_restrictions);
+ static const int32_t kMaxFileSizeInKB = 12 * 1024 * 1024;
+ HistogramCustomCounts("PDF.FileSizeInKB", file_size / 1024, 0,
+ kMaxFileSizeInKB, 50);
HistogramCustomCounts("PDF.PageCount", document_features.page_count, 1,
1000000, 50);
HistogramEnumeration("PDF.HasAttachment",
@@ -1813,6 +1815,10 @@ void OutOfProcessInstance::IsEditModeChanged(bool is_edit_mode) {
PostMessage(message);
}
+float OutOfProcessInstance::GetToolbarHeightInScreenCoords() {
+ return top_toolbar_height_in_viewport_coords_ * device_scale_;
+}
+
void OutOfProcessInstance::ProcessPreviewPageInfo(const std::string& url,
int dest_page_index) {
DCHECK(IsPrintPreview());
diff --git a/chromium/pdf/out_of_process_instance.h b/chromium/pdf/out_of_process_instance.h
index 99b58b2a46b..654623f941b 100644
--- a/chromium/pdf/out_of_process_instance.h
+++ b/chromium/pdf/out_of_process_instance.h
@@ -98,9 +98,10 @@ class OutOfProcessInstance : public pp::Instance,
// PDFEngine::Client implementation.
void DocumentSizeUpdated(const pp::Size& size) override;
void Invalidate(const pp::Rect& rect) override;
- void Scroll(const pp::Point& point) override;
+ void DidScroll(const pp::Point& point) override;
void ScrollToX(int x_in_screen_coords) override;
void ScrollToY(int y_in_screen_coords, bool compensate_for_toolbar) override;
+ void ScrollBy(const pp::Point& point) override;
void ScrollToPage(int page) override;
void NavigateTo(const std::string& url,
WindowOpenDisposition disposition) override;
@@ -134,7 +135,8 @@ class OutOfProcessInstance : public pp::Instance,
bool case_sensitive) override;
void DocumentPaintOccurred() override;
void DocumentLoadComplete(
- const PDFEngine::DocumentFeatures& document_features) override;
+ const PDFEngine::DocumentFeatures& document_features,
+ uint32_t file_size) override;
void DocumentLoadFailed() override;
void FontSubstituted() override;
pp::Instance* GetPluginInstance() override;
@@ -147,6 +149,7 @@ class OutOfProcessInstance : public pp::Instance,
void IsSelectingChanged(bool is_selecting) override;
void SelectionChanged(const pp::Rect& left, const pp::Rect& right) override;
void IsEditModeChanged(bool is_edit_mode) override;
+ float GetToolbarHeightInScreenCoords() override;
// PreviewModeClient::Client implementation.
void PreviewDocumentLoadComplete() override;
diff --git a/chromium/pdf/pdf.cc b/chromium/pdf/pdf.cc
index ea9df891797..e4583f5250a 100644
--- a/chromium/pdf/pdf.cc
+++ b/chromium/pdf/pdf.cc
@@ -31,7 +31,8 @@ bool RenderPDFPageToDC(const void* pdf_buffer,
bool stretch_to_bounds,
bool keep_aspect_ratio,
bool center_in_bounds,
- bool autorotate) {
+ bool autorotate,
+ bool use_color) {
if (!IsSDKInitializedViaPepper()) {
if (!InitializeSDK()) {
return false;
@@ -42,7 +43,7 @@ bool RenderPDFPageToDC(const void* pdf_buffer,
dpi_x, dpi_y,
pp::Rect(bounds_origin_x, bounds_origin_y, bounds_width, bounds_height),
fit_to_bounds, stretch_to_bounds, keep_aspect_ratio, center_in_bounds,
- autorotate);
+ autorotate, use_color);
bool ret = engine_exports->RenderPDFPageToDC(pdf_buffer, buffer_size,
page_number, settings, dc);
if (!IsSDKInitializedViaPepper())
@@ -108,7 +109,8 @@ bool RenderPDFPageToBitmap(const void* pdf_buffer,
int bitmap_height,
int dpi_x,
int dpi_y,
- bool autorotate) {
+ bool autorotate,
+ bool use_color) {
if (!IsSDKInitializedViaPepper()) {
if (!InitializeSDK())
return false;
@@ -116,7 +118,7 @@ bool RenderPDFPageToBitmap(const void* pdf_buffer,
PDFEngineExports* engine_exports = PDFEngineExports::Get();
PDFEngineExports::RenderingSettings settings(
dpi_x, dpi_y, pp::Rect(bitmap_width, bitmap_height), true, false, true,
- true, autorotate);
+ true, autorotate, use_color);
bool ret = engine_exports->RenderPDFPageToBitmap(
pdf_buffer, pdf_buffer_size, page_number, settings, bitmap_buffer);
if (!IsSDKInitializedViaPepper())
diff --git a/chromium/pdf/pdf.h b/chromium/pdf/pdf.h
index 751e3a5dfa9..ddd286d1998 100644
--- a/chromium/pdf/pdf.h
+++ b/chromium/pdf/pdf.h
@@ -53,6 +53,7 @@ enum PrintingMode {
// done) should be centered within the given bounds.
// |autorotate| specifies whether the final image should be rotated to match
// the output bound.
+// |use_color| specifies color or grayscale.
// Returns false if the document or the page number are not valid.
bool RenderPDFPageToDC(const void* pdf_buffer,
int buffer_size,
@@ -68,7 +69,8 @@ bool RenderPDFPageToDC(const void* pdf_buffer,
bool stretch_to_bounds,
bool keep_aspect_ratio,
bool center_in_bounds,
- bool autorotate);
+ bool autorotate,
+ bool use_color);
void SetPDFEnsureTypefaceCharactersAccessible(
PDFEnsureTypefaceCharactersAccessible func);
@@ -111,6 +113,7 @@ bool GetPDFPageSizeByIndex(const void* pdf_buffer,
// |dpi_x| and |dpi_y| is the resolution.
// |autorotate| specifies whether the final image should be rotated to match
// the output bound.
+// |use_color| specifies color or grayscale.
// Returns false if the document or the page number are not valid.
bool RenderPDFPageToBitmap(const void* pdf_buffer,
int pdf_buffer_size,
@@ -120,7 +123,8 @@ bool RenderPDFPageToBitmap(const void* pdf_buffer,
int bitmap_height,
int dpi_x,
int dpi_y,
- bool autorotate);
+ bool autorotate,
+ bool use_color);
} // namespace chrome_pdf
diff --git a/chromium/pdf/pdf_engine.h b/chromium/pdf/pdf_engine.h
index df7225f524d..e547974bfa7 100644
--- a/chromium/pdf/pdf_engine.h
+++ b/chromium/pdf/pdf_engine.h
@@ -135,7 +135,7 @@ class PDFEngine {
virtual void Invalidate(const pp::Rect& rect) = 0;
// Informs the client to scroll the plugin area by the given offset.
- virtual void Scroll(const pp::Point& point) = 0;
+ virtual void DidScroll(const pp::Point& point) = 0;
// Scroll the horizontal/vertical scrollbars to a given position.
// Values are in screen coordinates, where 0 is the top/left of the document
@@ -146,6 +146,9 @@ class PDFEngine {
virtual void ScrollToY(int y_in_screen_coords,
bool compensate_for_toolbar) = 0;
+ // Scroll by a given delta relative to the current position.
+ virtual void ScrollBy(const pp::Point& point) = 0;
+
// Scroll to zero-based |page|.
virtual void ScrollToPage(int page) = 0;
@@ -232,8 +235,8 @@ class PDFEngine {
virtual void DocumentPaintOccurred() = 0;
// Notifies the client that the document has finished loading.
- virtual void DocumentLoadComplete(
- const DocumentFeatures& document_features) = 0;
+ virtual void DocumentLoadComplete(const DocumentFeatures& document_features,
+ uint32_t file_size) = 0;
// Notifies the client that the document has failed to load.
virtual void DocumentLoadFailed() = 0;
@@ -270,6 +273,10 @@ class PDFEngine {
// Sets edit mode state.
virtual void IsEditModeChanged(bool is_edit_mode) {}
+
+ // Gets the height of the top toolbar in screen coordinates. This is
+ // independent of whether it is hidden or not at the moment.
+ virtual float GetToolbarHeightInScreenCoords() = 0;
};
// Factory method to create an instance of the PDF Engine.
@@ -399,6 +406,10 @@ class PDFEngine {
virtual void MoveRangeSelectionExtent(const pp::Point& extent) = 0;
virtual void SetSelectionBounds(const pp::Point& base,
const pp::Point& extent) = 0;
+ virtual void GetSelection(uint32_t* selection_start_page_index,
+ uint32_t* selection_start_char_index,
+ uint32_t* selection_end_page_index,
+ uint32_t* selection_end_char_index) = 0;
// Remove focus from form widgets, consolidating the user input.
virtual void KillFormFocus() = 0;
@@ -415,7 +426,8 @@ class PDFEngineExports {
bool stretch_to_bounds,
bool keep_aspect_ratio,
bool center_in_bounds,
- bool autorotate);
+ bool autorotate,
+ bool use_color);
RenderingSettings(const RenderingSettings& that);
int dpi_x;
@@ -426,6 +438,7 @@ class PDFEngineExports {
bool keep_aspect_ratio;
bool center_in_bounds;
bool autorotate;
+ bool use_color;
};
PDFEngineExports() {}
diff --git a/chromium/pdf/pdf_transform.cc b/chromium/pdf/pdf_transform.cc
new file mode 100644
index 00000000000..28a69de503f
--- /dev/null
+++ b/chromium/pdf/pdf_transform.cc
@@ -0,0 +1,139 @@
+// Copyright 2015 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/pdf_transform.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/logging.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace chrome_pdf {
+
+namespace {
+
+// When a PdfRectangle has top < bottom, or right < left, the values should be
+// swapped.
+void SwapPdfRectangleValuesIfNeeded(PdfRectangle* rect) {
+ if (rect->top < rect->bottom)
+ std::swap(rect->top, rect->bottom);
+ if (rect->right < rect->left)
+ std::swap(rect->right, rect->left);
+}
+
+} // namespace
+
+double CalculateScaleFactor(const gfx::Rect& content_rect,
+ double src_width,
+ double src_height,
+ bool rotated) {
+ if (src_width == 0 || src_height == 0)
+ return 1.0;
+
+ double actual_source_page_width = rotated ? src_height : src_width;
+ double actual_source_page_height = rotated ? src_width : src_height;
+ double ratio_x =
+ static_cast<double>(content_rect.width()) / actual_source_page_width;
+ double ratio_y =
+ static_cast<double>(content_rect.height()) / actual_source_page_height;
+ return std::min(ratio_x, ratio_y);
+}
+
+void SetDefaultClipBox(bool rotated, PdfRectangle* clip_box) {
+ const int kDpi = 72;
+ const float kPaperWidth = 8.5 * kDpi;
+ const float kPaperHeight = 11 * kDpi;
+ clip_box->left = 0;
+ clip_box->bottom = 0;
+ clip_box->right = rotated ? kPaperHeight : kPaperWidth;
+ clip_box->top = rotated ? kPaperWidth : kPaperHeight;
+}
+
+void CalculateMediaBoxAndCropBox(bool rotated,
+ bool has_media_box,
+ bool has_crop_box,
+ PdfRectangle* media_box,
+ PdfRectangle* crop_box) {
+ if (has_media_box)
+ SwapPdfRectangleValuesIfNeeded(media_box);
+ if (has_crop_box)
+ SwapPdfRectangleValuesIfNeeded(crop_box);
+
+ if (!has_media_box && !has_crop_box) {
+ SetDefaultClipBox(rotated, crop_box);
+ SetDefaultClipBox(rotated, media_box);
+ } else if (has_crop_box && !has_media_box) {
+ *media_box = *crop_box;
+ } else if (has_media_box && !has_crop_box) {
+ *crop_box = *media_box;
+ }
+}
+
+PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
+ const PdfRectangle& crop_box) {
+ PdfRectangle clip_box;
+
+ // Clip |media_box| to the size of |crop_box|, but ignore |crop_box| if it is
+ // bigger than |media_box|.
+ clip_box.left = std::max(crop_box.left, media_box.left);
+ clip_box.bottom = std::max(crop_box.bottom, media_box.bottom);
+ clip_box.right = std::min(crop_box.right, media_box.right);
+ clip_box.top = std::min(crop_box.top, media_box.top);
+ return clip_box;
+}
+
+void ScalePdfRectangle(double scale_factor, PdfRectangle* rect) {
+ rect->left *= scale_factor;
+ rect->bottom *= scale_factor;
+ rect->right *= scale_factor;
+ rect->top *= scale_factor;
+}
+
+void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
+ const PdfRectangle& source_clip_box,
+ double* offset_x,
+ double* offset_y) {
+ const float clip_box_width = source_clip_box.right - source_clip_box.left;
+ const float clip_box_height = source_clip_box.top - source_clip_box.bottom;
+
+ // Center the intended clip region to real clip region.
+ *offset_x = (content_rect.width() - clip_box_width) / 2 + content_rect.x() -
+ source_clip_box.left;
+ *offset_y = (content_rect.height() - clip_box_height) / 2 + content_rect.y() -
+ source_clip_box.bottom;
+}
+
+void CalculateNonScaledClipBoxOffset(const gfx::Rect& content_rect,
+ int rotation,
+ int page_width,
+ int page_height,
+ const PdfRectangle& source_clip_box,
+ double* offset_x,
+ double* offset_y) {
+ // Align the intended clip region to left-top corner of real clip region.
+ switch (rotation) {
+ case 0:
+ *offset_x = -1 * source_clip_box.left;
+ *offset_y = page_height - source_clip_box.top;
+ break;
+ case 1:
+ *offset_x = 0;
+ *offset_y = -1 * source_clip_box.bottom;
+ break;
+ case 2:
+ *offset_x = page_width - source_clip_box.right;
+ *offset_y = 0;
+ break;
+ case 3:
+ *offset_x = page_height - source_clip_box.right;
+ *offset_y = page_width - source_clip_box.top;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+} // namespace chrome_pdf
diff --git a/chromium/pdf/pdf_transform.h b/chromium/pdf/pdf_transform.h
new file mode 100644
index 00000000000..da506f1678d
--- /dev/null
+++ b/chromium/pdf/pdf_transform.h
@@ -0,0 +1,100 @@
+// Copyright 2015 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_PDF_TRANSFORM_H_
+#define PDF_PDF_TRANSFORM_H_
+
+namespace gfx {
+class Rect;
+}
+
+namespace chrome_pdf {
+
+// A rect struct for use with FPDF bounding box functions.
+// With PDFs, origin is bottom-left.
+struct PdfRectangle {
+ float left;
+ float bottom;
+ float right;
+ float top;
+};
+
+// Calculate the scale factor between |content_rect| and a page of size
+// |src_width| x |src_height|.
+//
+// |content_rect| specifies the printable area of the destination page, with
+// origin at left-bottom. Values are in points.
+// |src_width| specifies the source page width in points.
+// |src_height| specifies the source page height in points.
+// |rotated| True if source page is rotated 90 degree or 270 degree.
+double CalculateScaleFactor(const gfx::Rect& content_rect,
+ double src_width,
+ double src_height,
+ bool rotated);
+
+// Make the default size to be letter size (8.5" X 11"). We are just following
+// the PDFium way of handling these corner cases. PDFium always consider
+// US-Letter as the default page size.
+void SetDefaultClipBox(bool rotated, PdfRectangle* clip_box);
+
+// Set the media box and/or crop box as needed. If both boxes are there, then
+// nothing needs to be done. If one box is missing, then fill it with the value
+// from the other box. If both boxes are missing, then they both get the default
+// value from SetDefaultClipBox(), based on |rotated|.
+void CalculateMediaBoxAndCropBox(bool rotated,
+ bool has_media_box,
+ bool has_crop_box,
+ PdfRectangle* media_box,
+ PdfRectangle* crop_box);
+
+// Compute source clip box boundaries based on the crop box / media box of
+// source page and scale factor.
+// Returns the computed source clip box values.
+//
+// |media_box| The PDF's media box.
+// |crop_box| The PDF's crop box.
+PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
+ const PdfRectangle& crop_box);
+
+// Scale |box| by |scale_factor|.
+void ScalePdfRectangle(double scale_factor, PdfRectangle* rect);
+
+// Calculate the clip box translation offset for a page that does need to be
+// scaled. All parameters are in points.
+//
+// |content_rect| specifies the printable area of the destination page, with
+// origin at left-bottom.
+// |source_clip_box| specifies the source clip box positions, relative to
+// origin at left-bottom.
+// |offset_x| and |offset_y| will contain the final translation offsets for the
+// source clip box, relative to origin at left-bottom.
+void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
+ const PdfRectangle& source_clip_box,
+ double* offset_x,
+ double* offset_y);
+
+// Calculate the clip box offset for a page that does not need to be scaled.
+// All parameters are in points.
+//
+// |content_rect| specifies the printable area of the destination page, with
+// origin at left-bottom.
+// |rotation| specifies the source page rotation values which are N / 90
+// degrees.
+// |page_width| specifies the screen destination page width.
+// |page_height| specifies the screen destination page height.
+// |source_clip_box| specifies the source clip box positions, relative to origin
+// at left-bottom.
+// |offset_x| and |offset_y| will contain the final translation offsets for the
+// source clip box, relative to origin at left-bottom.
+void CalculateNonScaledClipBoxOffset(const gfx::Rect& content_rect,
+ int rotation,
+ int page_width,
+ int page_height,
+ const PdfRectangle& source_clip_box,
+ double* offset_x,
+ double* offset_y);
+
+} // namespace chrome_pdf
+
+#endif // PDF_PDF_TRANSFORM_H_
diff --git a/chromium/pdf/pdf_transform_unittest.cc b/chromium/pdf/pdf_transform_unittest.cc
new file mode 100644
index 00000000000..e52b02a8665
--- /dev/null
+++ b/chromium/pdf/pdf_transform_unittest.cc
@@ -0,0 +1,335 @@
+// Copyright 2015 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/pdf_transform.h"
+
+#include "printing/units.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace chrome_pdf {
+
+namespace {
+
+const float kDefaultWidth = 8.5 * printing::kPointsPerInch;
+const float kDefaultHeight = 11.0 * printing::kPointsPerInch;
+const float kDefaultRatio = kDefaultWidth / kDefaultHeight;
+const double kTolerance = 0.0001;
+
+void ExpectDefaultPortraitBox(const PdfRectangle& box) {
+ EXPECT_FLOAT_EQ(0, box.left);
+ EXPECT_FLOAT_EQ(0, box.bottom);
+ EXPECT_FLOAT_EQ(kDefaultWidth, box.right);
+ EXPECT_FLOAT_EQ(kDefaultHeight, box.top);
+}
+
+void ExpectDefaultLandscapeBox(const PdfRectangle& box) {
+ EXPECT_FLOAT_EQ(0, box.left);
+ EXPECT_FLOAT_EQ(0, box.bottom);
+ EXPECT_FLOAT_EQ(kDefaultHeight, box.right);
+ EXPECT_FLOAT_EQ(kDefaultWidth, box.top);
+}
+
+void ExpectBoxesAreEqual(const PdfRectangle& expected,
+ const PdfRectangle& actual) {
+ EXPECT_FLOAT_EQ(expected.left, actual.left);
+ EXPECT_FLOAT_EQ(expected.bottom, actual.bottom);
+ EXPECT_FLOAT_EQ(expected.right, actual.right);
+ EXPECT_FLOAT_EQ(expected.top, actual.top);
+}
+
+void InitializeBoxToInvalidValues(PdfRectangle* box) {
+ box->left = box->bottom = box->right = box->top = -1;
+}
+
+void InitializeBoxToDefaultPortraitValues(PdfRectangle* box) {
+ box->left = 0;
+ box->bottom = 0;
+ box->right = kDefaultWidth;
+ box->top = kDefaultHeight;
+}
+
+void InitializeBoxToDefaultLandscapeValue(PdfRectangle* box) {
+ box->left = 0;
+ box->bottom = 0;
+ box->right = kDefaultHeight;
+ box->top = kDefaultWidth;
+}
+
+} // namespace
+
+TEST(PdfTransformTest, CalculateScaleFactor) {
+ gfx::Rect rect(kDefaultWidth, kDefaultHeight);
+ double scale;
+
+ // 1:1
+ scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, false);
+ EXPECT_NEAR(1, scale, kTolerance);
+ scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, true);
+ EXPECT_NEAR(kDefaultRatio, scale, kTolerance);
+
+ // 1:2
+ rect = gfx::Rect(kDefaultWidth / 2, kDefaultHeight / 2);
+ scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, false);
+ EXPECT_NEAR(0.5, scale, kTolerance);
+ scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, true);
+ EXPECT_NEAR(kDefaultRatio / 2, scale, kTolerance);
+
+ // 3:1
+ rect = gfx::Rect(kDefaultWidth * 3, kDefaultHeight * 3);
+ scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, false);
+ EXPECT_NEAR(3, scale, kTolerance);
+ scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, true);
+ EXPECT_NEAR(kDefaultRatio * 3, scale, kTolerance);
+
+ // 3:1, rotated.
+ rect = gfx::Rect(kDefaultHeight * 3, kDefaultWidth * 3);
+ scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, false);
+ EXPECT_NEAR(kDefaultRatio * 3, scale, kTolerance);
+ scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, true);
+ EXPECT_NEAR(3, scale, kTolerance);
+
+ // Odd size
+ rect = gfx::Rect(10, 1000);
+ scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, false);
+ EXPECT_NEAR(0.01634, scale, kTolerance);
+ scale = CalculateScaleFactor(rect, kDefaultWidth, kDefaultHeight, true);
+ EXPECT_NEAR(0.01263, scale, kTolerance);
+}
+
+TEST(PdfTransformTest, SetDefaultClipBox) {
+ PdfRectangle box;
+
+ SetDefaultClipBox(false, &box);
+ ExpectDefaultPortraitBox(box);
+
+ SetDefaultClipBox(true, &box);
+ ExpectDefaultLandscapeBox(box);
+}
+
+TEST(PdfTransformTest, CalculateMediaBoxAndCropBox) {
+ PdfRectangle media_box;
+ PdfRectangle crop_box;
+
+ // Assume both boxes are there.
+ InitializeBoxToDefaultPortraitValues(&media_box);
+ InitializeBoxToDefaultLandscapeValue(&crop_box);
+ CalculateMediaBoxAndCropBox(true, true, true, &media_box, &crop_box);
+ ExpectDefaultPortraitBox(media_box);
+ ExpectDefaultLandscapeBox(crop_box);
+
+ // Assume both boxes are missing.
+ InitializeBoxToInvalidValues(&media_box);
+ InitializeBoxToInvalidValues(&crop_box);
+ CalculateMediaBoxAndCropBox(false, false, false, &media_box, &crop_box);
+ ExpectDefaultPortraitBox(media_box);
+ ExpectDefaultPortraitBox(crop_box);
+ CalculateMediaBoxAndCropBox(true, false, false, &media_box, &crop_box);
+ ExpectDefaultLandscapeBox(media_box);
+ ExpectDefaultLandscapeBox(crop_box);
+
+ // Assume crop box is missing.
+ const PdfRectangle expected_box = {0, 0, 42, 420};
+ media_box = expected_box;
+ InitializeBoxToInvalidValues(&crop_box);
+ CalculateMediaBoxAndCropBox(false, true, false, &media_box, &crop_box);
+ ExpectBoxesAreEqual(expected_box, media_box);
+ ExpectBoxesAreEqual(expected_box, crop_box);
+
+ // Assume media box is missing.
+ InitializeBoxToInvalidValues(&media_box);
+ CalculateMediaBoxAndCropBox(false, false, true, &media_box, &crop_box);
+ ExpectBoxesAreEqual(expected_box, media_box);
+ ExpectBoxesAreEqual(expected_box, crop_box);
+}
+
+TEST(PdfTransformTest, CalculateClipBoxBoundary) {
+ PdfRectangle media_box;
+ PdfRectangle crop_box;
+ PdfRectangle result;
+
+ // media box and crop box are the same.
+ InitializeBoxToDefaultPortraitValues(&media_box);
+ InitializeBoxToDefaultPortraitValues(&crop_box);
+ result = CalculateClipBoxBoundary(media_box, crop_box);
+ ExpectDefaultPortraitBox(result);
+
+ // media box is portrait and crop box is landscape.
+ InitializeBoxToDefaultLandscapeValue(&crop_box);
+ result = CalculateClipBoxBoundary(media_box, crop_box);
+ EXPECT_FLOAT_EQ(0, result.left);
+ EXPECT_FLOAT_EQ(0, result.bottom);
+ EXPECT_FLOAT_EQ(kDefaultWidth, result.right);
+ EXPECT_FLOAT_EQ(kDefaultWidth, result.top);
+
+ // crop box is smaller than media box.
+ crop_box.left = 0;
+ crop_box.bottom = 0;
+ crop_box.right = 100;
+ crop_box.top = 200;
+ result = CalculateClipBoxBoundary(media_box, crop_box);
+ EXPECT_FLOAT_EQ(0, result.left);
+ EXPECT_FLOAT_EQ(0, result.bottom);
+ EXPECT_FLOAT_EQ(100, result.right);
+ EXPECT_FLOAT_EQ(200, result.top);
+
+ // crop box is smaller than the media box in one dimension and longer in the
+ // other.
+ crop_box.left = 0;
+ crop_box.bottom = 0;
+ crop_box.right = 100;
+ crop_box.top = 2000;
+ result = CalculateClipBoxBoundary(media_box, crop_box);
+ EXPECT_FLOAT_EQ(0, result.left);
+ EXPECT_FLOAT_EQ(0, result.bottom);
+ EXPECT_FLOAT_EQ(100, result.right);
+ EXPECT_FLOAT_EQ(kDefaultHeight, result.top);
+}
+
+TEST(PdfTransformTest, CalculateScaledClipBoxOffset) {
+ const gfx::Rect rect(kDefaultWidth, kDefaultHeight);
+ PdfRectangle clip_box;
+ double offset_x;
+ double offset_y;
+
+ // |rect| and |clip_box| are the same size.
+ InitializeBoxToDefaultPortraitValues(&clip_box);
+ CalculateScaledClipBoxOffset(rect, clip_box, &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+
+ // |rect| is larger than |clip_box|.
+ clip_box.top /= 2;
+ clip_box.right /= 4;
+ CalculateScaledClipBoxOffset(rect, clip_box, &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(229.5, offset_x);
+ EXPECT_DOUBLE_EQ(198, offset_y);
+}
+
+TEST(PdfTransformTest, CalculateNonScaledClipBoxOffset) {
+ int page_width = kDefaultWidth;
+ int page_height = kDefaultHeight;
+ const gfx::Rect rect(kDefaultWidth, kDefaultHeight);
+ PdfRectangle clip_box;
+ double offset_x;
+ double offset_y;
+
+ // |rect|, page size and |clip_box| are the same.
+ InitializeBoxToDefaultPortraitValues(&clip_box);
+ CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+ CalculateNonScaledClipBoxOffset(rect, 1, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+ CalculateNonScaledClipBoxOffset(rect, 2, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+ CalculateNonScaledClipBoxOffset(rect, 3, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(180, offset_x);
+ EXPECT_DOUBLE_EQ(-180, offset_y);
+
+ // Smaller |clip_box|.
+ clip_box.top /= 4;
+ clip_box.right /= 2;
+ CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(594, offset_y);
+ CalculateNonScaledClipBoxOffset(rect, 1, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+ CalculateNonScaledClipBoxOffset(rect, 2, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(306, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+ CalculateNonScaledClipBoxOffset(rect, 3, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(486, offset_x);
+ EXPECT_DOUBLE_EQ(414, offset_y);
+
+ // Larger page size.
+ InitializeBoxToDefaultPortraitValues(&clip_box);
+ page_width += 10;
+ page_height += 20;
+ CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(20, offset_y);
+ CalculateNonScaledClipBoxOffset(rect, 1, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+ CalculateNonScaledClipBoxOffset(rect, 2, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(10, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+ CalculateNonScaledClipBoxOffset(rect, 3, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(200, offset_x);
+ EXPECT_DOUBLE_EQ(-170, offset_y);
+}
+
+// https://crbug.com/491160 and https://crbug.com/588757
+TEST(PdfTransformTest, ReversedMediaBox) {
+ int page_width = kDefaultWidth;
+ int page_height = kDefaultHeight;
+ const gfx::Rect rect(kDefaultWidth, kDefaultHeight);
+ PdfRectangle clip_box;
+ double offset_x;
+ double offset_y;
+
+ const PdfRectangle expected_media_box_b491160 = {0, -792, 612, 0};
+ PdfRectangle media_box_b491160 = {0, 0, 612, -792};
+ CalculateMediaBoxAndCropBox(false, true, false, &media_box_b491160,
+ &clip_box);
+ ExpectBoxesAreEqual(expected_media_box_b491160, media_box_b491160);
+ ExpectBoxesAreEqual(expected_media_box_b491160, clip_box);
+
+ CalculateScaledClipBoxOffset(rect, media_box_b491160, &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(792, offset_y);
+
+ CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height,
+ media_box_b491160, &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(792, offset_y);
+
+ PdfRectangle media_box_b588757 = {0, 792, 612, 0};
+ CalculateMediaBoxAndCropBox(false, true, false, &media_box_b588757,
+ &clip_box);
+ ExpectDefaultPortraitBox(media_box_b588757);
+ ExpectDefaultPortraitBox(clip_box);
+
+ CalculateScaledClipBoxOffset(rect, clip_box, &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+
+ CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+
+ PdfRectangle media_box_left_right_flipped = {612, 792, 0, 0};
+ CalculateMediaBoxAndCropBox(false, true, false, &media_box_left_right_flipped,
+ &clip_box);
+ ExpectDefaultPortraitBox(media_box_left_right_flipped);
+ ExpectDefaultPortraitBox(clip_box);
+
+ CalculateScaledClipBoxOffset(rect, clip_box, &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+
+ CalculateNonScaledClipBoxOffset(rect, 0, page_width, page_height, clip_box,
+ &offset_x, &offset_y);
+ EXPECT_DOUBLE_EQ(0, offset_x);
+ EXPECT_DOUBLE_EQ(0, offset_y);
+}
+
+} // namespace chrome_pdf
diff --git a/chromium/pdf/pdfium/DEPS b/chromium/pdf/pdfium/DEPS
index cf1dc868957..00a544d4693 100644
--- a/chromium/pdf/pdfium/DEPS
+++ b/chromium/pdf/pdfium/DEPS
@@ -1,9 +1,6 @@
include_rules = [
"+gin/array_buffer.h",
"+gin/public",
- "+printing/pdf_transform.h",
- "+printing/units.h",
"+third_party/pdfium/public",
"+ui/gfx/codec/jpeg_codec.h",
- "+ui/gfx/geometry/rect.h",
]
diff --git a/chromium/pdf/pdfium/fuzzers/BUILD.gn b/chromium/pdf/pdfium/fuzzers/BUILD.gn
index cfff56d9296..98062af13e0 100644
--- a/chromium/pdf/pdfium/fuzzers/BUILD.gn
+++ b/chromium/pdf/pdfium/fuzzers/BUILD.gn
@@ -31,7 +31,6 @@ group("pdf_fuzzers") {
if (pdf_enable_xfa) {
deps += [
":pdf_cfx_barcode_fuzzer",
- ":pdf_cfx_saxreader_fuzzer",
":pdf_codec_bmp_fuzzer",
":pdf_codec_gif_fuzzer",
":pdf_codec_jpeg_fuzzer",
@@ -242,14 +241,6 @@ if (pdf_enable_xfa) {
]
}
- fuzzer_test("pdf_cfx_saxreader_fuzzer") {
- sources = []
- deps = [
- "//third_party/pdfium/testing/libfuzzer:pdf_cfx_saxreader_fuzzer",
- ]
- dict = "dicts/pdf_xml.dict"
- }
-
fuzzer_test("pdfium_xfa_fuzzer") {
sources = [
"pdfium_fuzzer_helper.cc",
diff --git a/chromium/pdf/pdfium/pdfium_engine.cc b/chromium/pdf/pdfium/pdfium_engine.cc
index f2062ee90c7..7f5da005d37 100644
--- a/chromium/pdf/pdfium/pdfium_engine.cc
+++ b/chromium/pdf/pdfium/pdfium_engine.cc
@@ -31,6 +31,7 @@
#include "gin/public/gin_embedders.h"
#include "gin/public/isolate_holder.h"
#include "pdf/draw_utils.h"
+#include "pdf/pdf_transform.h"
#include "pdf/pdfium/pdfium_api_string_buffer_adapter.h"
#include "pdf/pdfium/pdfium_mem_buffer_file_read.h"
#include "pdf/pdfium/pdfium_mem_buffer_file_write.h"
@@ -48,7 +49,6 @@
#include "ppapi/cpp/url_response_info.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/var_dictionary.h"
-#include "printing/pdf_transform.h"
#include "printing/units.h"
#include "third_party/pdfium/public/cpp/fpdf_deleters.h"
#include "third_party/pdfium/public/fpdf_annot.h"
@@ -111,6 +111,13 @@ constexpr int kMaxPasswordTries = 3;
constexpr base::TimeDelta kTouchLongPressTimeout =
base::TimeDelta::FromMilliseconds(300);
+// Windows has native panning capabilities. No need to use our own.
+#if defined(OS_WIN)
+constexpr bool kViewerImplementedPanning = false;
+#else
+constexpr bool kViewerImplementedPanning = true;
+#endif
+
// See Table 3.20 in
// http://www.adobe.com/devnet/acrobat/pdfs/pdf_reference_1-7.pdf
const uint32_t kPDFPermissionPrintLowQualityMask = 1 << 2;
@@ -758,6 +765,7 @@ PDFiumEngine::PDFiumEngine(PDFEngine::Client* client)
in_form_text_area_(false),
editable_form_text_area_(false),
mouse_left_button_down_(false),
+ mouse_middle_button_down_(false),
permissions_(0),
permissions_handler_revision_(-1),
fpdf_availability_(nullptr),
@@ -906,13 +914,58 @@ void PDFiumEngine::Form_GetPageViewRect(FPDF_FORMFILLINFO* param,
double* right,
double* bottom) {
PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
- int page_index = engine->GetMostVisiblePage();
+ int page_index = engine->GetVisiblePageIndex(page);
+ if (!engine->PageIndexInBounds(page_index)) {
+ *left = 0;
+ *right = 0;
+ *top = 0;
+ *bottom = 0;
+ return;
+ }
+
pp::Rect page_view_rect = engine->GetPageContentsRect(page_index);
- *left = page_view_rect.x();
- *right = page_view_rect.right();
- *top = page_view_rect.y();
- *bottom = page_view_rect.bottom();
+ float toolbar_height_in_screen_coords =
+ engine->GetToolbarHeightInScreenCoords();
+
+ float page_width = FPDF_GetPageWidth(page);
+ float page_height = FPDF_GetPageHeight(page);
+
+ // To convert from a screen scale to a page scale, we multiply by
+ // (page_height / page_view_rect.height()) and
+ // (page_width / page_view_rect.width()),
+ // The base point of the page in screen coords is (page_view_rect.x(),
+ // page_view_rect.y()).
+ // Therefore, to convert an x position from screen to page
+ // coords, we use (page_width * (x - base_x) / page_view_rect.width()).
+ // For y positions, (page_height * (y - base_y) / page_view_rect.height()).
+
+ // The top-most y position that can be relied to be visible on the screen is
+ // the bottom of the toolbar, which is y = toolbar_height_in_screen_coords.
+ float screen_top_in_page_coords =
+ page_height * (toolbar_height_in_screen_coords - page_view_rect.y()) /
+ page_view_rect.height();
+ // The bottom-most y position that is visible on the screen is the bottom of
+ // the plugin area, which is y = engine->plugin_size_.height().
+ float screen_bottom_in_page_coords =
+ page_height * (engine->plugin_size_.height() - page_view_rect.y()) /
+ page_view_rect.height();
+ // The left-most x position that is visible on the screen is the left of the
+ // plugin area, which is x = 0.
+ float screen_left_in_page_coords =
+ page_width * (0 - page_view_rect.x()) / page_view_rect.width();
+ // The right-most x position that is visible on the screen is the right of the
+ // plugin area, which is x = engine->plugin_size_.width().
+ float screen_right_in_page_coords =
+ page_width * (engine->plugin_size_.width() - page_view_rect.x()) /
+ page_view_rect.width();
+
+ // Return the edge of the screen or of the page, since we're restricted to
+ // both.
+ *left = std::max(screen_left_in_page_coords, 0.0f);
+ *right = std::min(screen_right_in_page_coords, page_width);
+ *top = std::max(screen_top_in_page_coords, 0.0f);
+ *bottom = std::min(screen_bottom_in_page_coords, page_height);
}
int PDFiumEngine::Form_GetPlatform(FPDF_FORMFILLINFO* param,
@@ -1063,7 +1116,8 @@ void PDFiumEngine::ScrolledToXPosition(int position) {
int old_x = position_.x();
position_.set_x(position);
CalculateVisiblePages();
- client_->Scroll(pp::Point(old_x - position, 0));
+ client_->DidScroll(pp::Point(old_x - position, 0));
+ OnSelectionPositionChanged();
}
void PDFiumEngine::ScrolledToYPosition(int position) {
@@ -1072,7 +1126,8 @@ void PDFiumEngine::ScrolledToYPosition(int position) {
int old_y = position_.y();
position_.set_y(position);
CalculateVisiblePages();
- client_->Scroll(pp::Point(0, old_y - position));
+ client_->DidScroll(pp::Point(0, old_y - position));
+ OnSelectionPositionChanged();
}
void PDFiumEngine::PrePaint() {
@@ -1263,14 +1318,14 @@ void PDFiumEngine::OnPendingRequestComplete() {
}
void PDFiumEngine::OnNewDataReceived() {
- client_->DocumentLoadProgress(doc_loader_->count_of_bytes_received(),
+ client_->DocumentLoadProgress(doc_loader_->bytes_received(),
doc_loader_->GetDocumentSize());
}
void PDFiumEngine::OnDocumentComplete() {
- if (doc_) {
+ if (doc_)
return FinishLoadingDocument();
- }
+
file_access_.m_FileLen = doc_loader_->GetDocumentSize();
if (!fpdf_availability_) {
fpdf_availability_ = FPDFAvail_Create(&file_availability_, &file_access_);
@@ -1291,7 +1346,8 @@ void PDFiumEngine::CancelBrowserDownload() {
}
void PDFiumEngine::FinishLoadingDocument() {
- DCHECK(doc_loader_->IsDocumentComplete() && doc_);
+ DCHECK(doc_);
+ DCHECK(doc_loader_->IsDocumentComplete());
LoadBody();
@@ -1331,7 +1387,8 @@ void PDFiumEngine::FinishLoadingDocument() {
(FPDFAvail_IsLinearized(fpdf_availability_) == PDF_LINEARIZED);
document_features.is_tagged = FPDFCatalog_IsTagged(doc_);
document_features.form_type = static_cast<FormType>(FPDF_GetFormType(doc_));
- client_->DocumentLoadComplete(document_features);
+ client_->DocumentLoadComplete(document_features,
+ doc_loader_->bytes_received());
}
}
@@ -1403,6 +1460,9 @@ bool PDFiumEngine::HandleEvent(const pp::InputEvent& event) {
case PP_INPUTEVENT_TYPE_MOUSEMOVE:
rv = OnMouseMove(pp::MouseInputEvent(event));
break;
+ case PP_INPUTEVENT_TYPE_MOUSEENTER:
+ OnMouseEnter(pp::MouseInputEvent(event));
+ break;
case PP_INPUTEVENT_TYPE_KEYDOWN:
rv = OnKeyDown(pp::KeyboardInputEvent(event));
break;
@@ -1499,7 +1559,13 @@ FPDF_DOCUMENT PDFiumEngine::CreateSinglePageRasterPdf(
FPDF_RenderPageBitmap(bitmap, page_to_print->GetPrintPage(), page_rect.x(),
page_rect.y(), page_rect.width(), page_rect.height(),
print_settings.orientation,
- FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
+ FPDF_PRINTING | FPDF_NO_CATCH);
+
+ // Draw the forms.
+ FPDF_FFLDraw(form_, bitmap, page_to_print->GetPrintPage(), page_rect.x(),
+ page_rect.y(), page_rect.width(), page_rect.height(),
+ print_settings.orientation,
+ FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
unsigned char* bitmap_data =
static_cast<unsigned char*>(FPDFBitmap_GetBuffer(bitmap));
@@ -1902,6 +1968,8 @@ bool PDFiumEngine::OnLeftMouseDown(const pp::MouseInputEvent& event) {
bool PDFiumEngine::OnMiddleMouseDown(const pp::MouseInputEvent& event) {
SetMouseLeftButtonDown(false);
+ mouse_middle_button_down_ = true;
+ mouse_middle_button_last_position_ = event.GetPosition();
SelectionChangeInvalidator selection_invalidator(this);
selection_.clear();
@@ -1920,6 +1988,11 @@ bool PDFiumEngine::OnMiddleMouseDown(const pp::MouseInputEvent& event) {
if (IsLinkArea(area))
return true;
+ if (kViewerImplementedPanning) {
+ // Switch to hand cursor when panning.
+ client_->UpdateCursor(PP_CURSORTYPE_HAND);
+ }
+
// Prevent middle mouse button from selecting texts.
return false;
}
@@ -2002,6 +2075,8 @@ bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) {
if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT)
SetMouseLeftButtonDown(false);
+ else if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_MIDDLE)
+ mouse_middle_button_down_ = false;
int page_index = -1;
int char_index = -1;
@@ -2030,6 +2105,9 @@ bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) {
return true;
}
if (area == PDFiumPage::DOCLINK_AREA) {
+ if (!PageIndexInBounds(target.page))
+ return true;
+
pp::Rect page_rect(GetPageScreenRect(target.page));
int y = position_.y() + page_rect.y();
if (target.y_in_pixels)
@@ -2040,9 +2118,15 @@ bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) {
}
}
- // Prevent middle mouse button from selecting texts.
- if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_MIDDLE)
+ if (event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_MIDDLE) {
+ if (kViewerImplementedPanning) {
+ // Update the cursor when panning stops.
+ client_->UpdateCursor(DetermineCursorType(area, form_type));
+ }
+
+ // Prevent middle mouse button from selecting texts.
return false;
+ }
if (page_index != -1) {
double page_x;
@@ -2073,48 +2157,7 @@ bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) {
mouse_down_state_.Reset();
if (!selecting_) {
- PP_CursorType_Dev cursor;
- switch (area) {
- case PDFiumPage::TEXT_AREA:
- cursor = PP_CURSORTYPE_IBEAM;
- break;
- case PDFiumPage::WEBLINK_AREA:
- case PDFiumPage::DOCLINK_AREA:
- cursor = PP_CURSORTYPE_HAND;
- break;
- case PDFiumPage::NONSELECTABLE_AREA:
- case PDFiumPage::FORM_TEXT_AREA:
- default:
- switch (form_type) {
- case FPDF_FORMFIELD_PUSHBUTTON:
- case FPDF_FORMFIELD_CHECKBOX:
- case FPDF_FORMFIELD_RADIOBUTTON:
- case FPDF_FORMFIELD_COMBOBOX:
- case FPDF_FORMFIELD_LISTBOX:
- cursor = PP_CURSORTYPE_HAND;
- break;
- case FPDF_FORMFIELD_TEXTFIELD:
- cursor = PP_CURSORTYPE_IBEAM;
- break;
-#if defined(PDF_ENABLE_XFA)
- case FPDF_FORMFIELD_XFA_CHECKBOX:
- case FPDF_FORMFIELD_XFA_COMBOBOX:
- case FPDF_FORMFIELD_XFA_IMAGEFIELD:
- case FPDF_FORMFIELD_XFA_LISTBOX:
- case FPDF_FORMFIELD_XFA_PUSHBUTTON:
- case FPDF_FORMFIELD_XFA_SIGNATURE:
- cursor = PP_CURSORTYPE_HAND;
- break;
- case FPDF_FORMFIELD_XFA_TEXTFIELD:
- cursor = PP_CURSORTYPE_IBEAM;
- break;
-#endif
- default:
- cursor = PP_CURSORTYPE_POINTER;
- break;
- }
- break;
- }
+ client_->UpdateCursor(DetermineCursorType(area, form_type));
if (page_index != -1) {
double page_x;
@@ -2123,7 +2166,6 @@ bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) {
FORM_OnMouseMove(form_, pages_[page_index]->GetPage(), 0, page_x, page_y);
}
- client_->UpdateCursor(cursor);
std::string url = GetLinkAtPosition(event.GetPosition());
if (url != link_under_cursor_) {
link_under_cursor_ = url;
@@ -2137,6 +2179,19 @@ bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) {
SetFormSelectedText(form_, pages_[last_page_mouse_down_]->GetPage());
}
+ if (kViewerImplementedPanning && mouse_middle_button_down_) {
+ // Subtract (origin - destination) so delta is already the delta for
+ // moving the page, rather than the delta the mouse moved.
+ // GetMovement() does not work here, as small mouse movements are
+ // considered zero.
+ pp::Point page_position_delta =
+ mouse_middle_button_last_position_ - event.GetPosition();
+ if (page_position_delta.x() != 0 || page_position_delta.y() != 0) {
+ client_->ScrollBy(page_position_delta);
+ mouse_middle_button_last_position_ = event.GetPosition();
+ }
+ }
+
// No need to swallow the event, since this might interfere with the
// scrollbars if the user is dragging them.
return false;
@@ -2151,6 +2206,60 @@ bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) {
return ExtendSelection(page_index, char_index);
}
+PP_CursorType_Dev PDFiumEngine::DetermineCursorType(PDFiumPage::Area area,
+ int form_type) const {
+ if (kViewerImplementedPanning && mouse_middle_button_down_) {
+ return PP_CURSORTYPE_HAND;
+ }
+
+ switch (area) {
+ case PDFiumPage::TEXT_AREA:
+ return PP_CURSORTYPE_IBEAM;
+ case PDFiumPage::WEBLINK_AREA:
+ case PDFiumPage::DOCLINK_AREA:
+ return PP_CURSORTYPE_HAND;
+ case PDFiumPage::NONSELECTABLE_AREA:
+ case PDFiumPage::FORM_TEXT_AREA:
+ default:
+ switch (form_type) {
+ case FPDF_FORMFIELD_PUSHBUTTON:
+ case FPDF_FORMFIELD_CHECKBOX:
+ case FPDF_FORMFIELD_RADIOBUTTON:
+ case FPDF_FORMFIELD_COMBOBOX:
+ case FPDF_FORMFIELD_LISTBOX:
+ return PP_CURSORTYPE_HAND;
+ case FPDF_FORMFIELD_TEXTFIELD:
+ return PP_CURSORTYPE_IBEAM;
+#if defined(PDF_ENABLE_XFA)
+ case FPDF_FORMFIELD_XFA_CHECKBOX:
+ case FPDF_FORMFIELD_XFA_COMBOBOX:
+ case FPDF_FORMFIELD_XFA_IMAGEFIELD:
+ case FPDF_FORMFIELD_XFA_LISTBOX:
+ case FPDF_FORMFIELD_XFA_PUSHBUTTON:
+ case FPDF_FORMFIELD_XFA_SIGNATURE:
+ return PP_CURSORTYPE_HAND;
+ case FPDF_FORMFIELD_XFA_TEXTFIELD:
+ return PP_CURSORTYPE_IBEAM;
+#endif
+ default:
+ return PP_CURSORTYPE_POINTER;
+ }
+ }
+}
+
+void PDFiumEngine::OnMouseEnter(const pp::MouseInputEvent& event) {
+ if (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) {
+ if (!mouse_middle_button_down_) {
+ mouse_middle_button_down_ = true;
+ mouse_middle_button_last_position_ = event.GetPosition();
+ }
+ } else {
+ if (mouse_middle_button_down_) {
+ mouse_middle_button_down_ = false;
+ }
+ }
+}
+
bool PDFiumEngine::ExtendSelection(int page_index, int char_index) {
// Check if the user has decreased their selection area and we need to remove
// pages from |selection_|.
@@ -3010,7 +3119,8 @@ bool PDFiumEngine::TryLoadingDoc(const std::string& password,
void PDFiumEngine::GetPasswordAndLoad() {
getting_password_ = true;
- DCHECK(!doc_ && FPDF_GetLastError() == FPDF_ERR_PASSWORD);
+ DCHECK(!doc_);
+ DCHECK_EQ(static_cast<unsigned long>(FPDF_ERR_PASSWORD), FPDF_GetLastError());
client_->GetDocumentPassword(password_factory_.NewCallbackWithOutput(
&PDFiumEngine::OnGetPasswordComplete));
}
@@ -3662,8 +3772,10 @@ PDFiumEngine::SelectionChangeInvalidator::~SelectionChangeInvalidator() {
}
}
- if (selection_changed)
- engine_->OnSelectionChanged();
+ if (selection_changed) {
+ engine_->OnSelectionTextChanged();
+ engine_->OnSelectionPositionChanged();
+ }
}
std::vector<pp::Rect>
@@ -3795,35 +3907,33 @@ void PDFiumEngine::TransformPDFPageForPrinting(
const gfx::Rect gfx_content_rect(content_rect.x(), content_rect.y(),
content_rect.width(), content_rect.height());
const double scale_factor =
- fit_to_page
- ? printing::CalculateScaleFactor(gfx_content_rect, src_page_width,
- src_page_height, rotated)
- : 1.0;
+ fit_to_page ? CalculateScaleFactor(gfx_content_rect, src_page_width,
+ src_page_height, rotated)
+ : 1.0;
// Calculate positions for the clip box.
- printing::PdfRectangle media_box;
- printing::PdfRectangle crop_box;
+ PdfRectangle media_box;
+ PdfRectangle crop_box;
bool has_media_box =
!!FPDFPage_GetMediaBox(page, &media_box.left, &media_box.bottom,
&media_box.right, &media_box.top);
bool has_crop_box = !!FPDFPage_GetCropBox(
page, &crop_box.left, &crop_box.bottom, &crop_box.right, &crop_box.top);
- printing::CalculateMediaBoxAndCropBox(rotated, has_media_box, has_crop_box,
- &media_box, &crop_box);
- printing::PdfRectangle source_clip_box =
- printing::CalculateClipBoxBoundary(media_box, crop_box);
- printing::ScalePdfRectangle(scale_factor, &source_clip_box);
+ CalculateMediaBoxAndCropBox(rotated, has_media_box, has_crop_box, &media_box,
+ &crop_box);
+ PdfRectangle source_clip_box = CalculateClipBoxBoundary(media_box, crop_box);
+ ScalePdfRectangle(scale_factor, &source_clip_box);
// Calculate the translation offset values.
double offset_x = 0;
double offset_y = 0;
if (fit_to_page) {
- printing::CalculateScaledClipBoxOffset(gfx_content_rect, source_clip_box,
- &offset_x, &offset_y);
+ CalculateScaledClipBoxOffset(gfx_content_rect, source_clip_box, &offset_x,
+ &offset_y);
} else {
- printing::CalculateNonScaledClipBoxOffset(
- gfx_content_rect, src_page_rotation, actual_page_width,
- actual_page_height, source_clip_box, &offset_x, &offset_y);
+ CalculateNonScaledClipBoxOffset(gfx_content_rect, src_page_rotation,
+ actual_page_width, actual_page_height,
+ source_clip_box, &offset_x, &offset_y);
}
// Reset the media box and crop box. When the page has crop box and media box,
@@ -3915,10 +4025,12 @@ void PDFiumEngine::GetRegion(const pp::Point& location,
*region = buffer;
}
-void PDFiumEngine::OnSelectionChanged() {
+void PDFiumEngine::OnSelectionTextChanged() {
DCHECK(!in_form_text_area_);
pp::PDF::SetSelectedText(GetPluginInstance(), GetSelectedText().c_str());
+}
+void PDFiumEngine::OnSelectionPositionChanged() {
// We need to determine the top-left and bottom-right points of the selection
// in order to report those to the embedder. This code assumes that the
// selection list is out of order.
@@ -4038,6 +4150,10 @@ bool PDFiumEngine::PageIndexInBounds(int index) const {
return index >= 0 && index < static_cast<int>(pages_.size());
}
+float PDFiumEngine::GetToolbarHeightInScreenCoords() {
+ return client_->GetToolbarHeightInScreenCoords();
+}
+
void PDFiumEngine::Form_Invalidate(FPDF_FORMFILLINFO* param,
FPDF_PAGE page,
double left,
@@ -4378,6 +4494,35 @@ void PDFiumEngine::SetSelectionBounds(const pp::Point& base,
: RangeSelectionDirection::Right;
}
+void PDFiumEngine::GetSelection(uint32_t* selection_start_page_index,
+ uint32_t* selection_start_char_index,
+ uint32_t* selection_end_page_index,
+ uint32_t* selection_end_char_index) {
+ size_t len = selection_.size();
+ if (len == 0) {
+ *selection_start_page_index = 0;
+ *selection_start_char_index = 0;
+ *selection_end_page_index = 0;
+ *selection_end_char_index = 0;
+ return;
+ }
+
+ *selection_start_page_index = selection_[0].page_index();
+ *selection_start_char_index = selection_[0].char_index();
+ *selection_end_page_index = selection_[len - 1].page_index();
+
+ // If the selection is all within one page, the end index is the
+ // start index plus the char count. But if the selection spans
+ // multiple pages, the selection starts at the beginning of the
+ // last page in |selection_| and goes to the char count.
+ if (len == 1) {
+ *selection_end_char_index =
+ selection_[0].char_index() + selection_[0].char_count();
+ } else {
+ *selection_end_char_index = selection_[len - 1].char_count();
+ }
+}
+
PDFiumEngine::FormFillTimerData::FormFillTimerData(base::TimeDelta period,
TimerCallback callback)
: timer_period(period), timer_callback(callback) {}
@@ -4484,7 +4629,8 @@ PDFEngineExports::RenderingSettings::RenderingSettings(int dpi_x,
bool stretch_to_bounds,
bool keep_aspect_ratio,
bool center_in_bounds,
- bool autorotate)
+ bool autorotate,
+ bool use_color)
: dpi_x(dpi_x),
dpi_y(dpi_y),
bounds(bounds),
@@ -4492,7 +4638,8 @@ PDFEngineExports::RenderingSettings::RenderingSettings(int dpi_x,
stretch_to_bounds(stretch_to_bounds),
keep_aspect_ratio(keep_aspect_ratio),
center_in_bounds(center_in_bounds),
- autorotate(autorotate) {}
+ autorotate(autorotate),
+ use_color(use_color) {}
PDFEngineExports::RenderingSettings::RenderingSettings(
const RenderingSettings& that) = default;
@@ -4507,14 +4654,14 @@ bool PDFiumEngineExports::RenderPDFPageToDC(const void* pdf_buffer,
int page_number,
const RenderingSettings& settings,
HDC dc) {
- FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, buffer_size, nullptr);
+ std::unique_ptr<void, FPDFDocumentDeleter> doc(
+ FPDF_LoadMemDocument(pdf_buffer, buffer_size, nullptr));
if (!doc)
return false;
- FPDF_PAGE page = FPDF_LoadPage(doc, page_number);
- if (!page) {
- FPDF_CloseDocument(doc);
+ FPDF_PAGE page = FPDF_LoadPage(doc.get(), page_number);
+ if (!page)
return false;
- }
+
RenderingSettings new_settings = settings;
// calculate the page size
if (new_settings.dpi_x == -1)
@@ -4533,6 +4680,10 @@ bool PDFiumEngineExports::RenderPDFPageToDC(const void* pdf_buffer,
settings.bounds.x() + settings.bounds.width(),
settings.bounds.y() + settings.bounds.height());
+ int flags = FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH;
+ if (!settings.use_color)
+ flags |= FPDF_GRAYSCALE;
+
// A "temporary" hack. Some PDFs seems to render very slowly if
// FPDF_RenderPage() is directly used on a printer DC. I suspect it is
// because of the code to talk Postscript directly to the printer if
@@ -4546,7 +4697,7 @@ bool PDFiumEngineExports::RenderPDFPageToDC(const void* pdf_buffer,
// Clear the bitmap
FPDFBitmap_FillRect(bitmap, 0, 0, dest.width(), dest.height(), 0xFFFFFFFF);
FPDF_RenderPageBitmap(bitmap, page, 0, 0, dest.width(), dest.height(),
- rotate, FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
+ rotate, flags);
int stride = FPDFBitmap_GetStride(bitmap);
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(bmi));
@@ -4563,11 +4714,10 @@ bool PDFiumEngineExports::RenderPDFPageToDC(const void* pdf_buffer,
FPDFBitmap_Destroy(bitmap);
} else {
FPDF_RenderPage(dc, page, dest.x(), dest.y(), dest.width(), dest.height(),
- rotate, FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
+ rotate, flags);
}
RestoreDC(dc, save_state);
FPDF_ClosePage(page);
- FPDF_CloseDocument(doc);
return true;
}
@@ -4592,15 +4742,13 @@ bool PDFiumEngineExports::RenderPDFPageToBitmap(
int page_number,
const RenderingSettings& settings,
void* bitmap_buffer) {
- FPDF_DOCUMENT doc =
- FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, nullptr);
+ std::unique_ptr<void, FPDFDocumentDeleter> doc(
+ FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, nullptr));
if (!doc)
return false;
- FPDF_PAGE page = FPDF_LoadPage(doc, page_number);
- if (!page) {
- FPDF_CloseDocument(doc);
+ FPDF_PAGE page = FPDF_LoadPage(doc.get(), page_number);
+ if (!page)
return false;
- }
pp::Rect dest;
int rotate = CalculatePosition(page, settings, &dest);
@@ -4613,12 +4761,15 @@ bool PDFiumEngineExports::RenderPDFPageToBitmap(
settings.bounds.height(), 0xFFFFFFFF);
// Shift top-left corner of bounds to (0, 0) if it's not there.
dest.set_point(dest.point() - settings.bounds.point());
+
+ int flags = FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH;
+ if (!settings.use_color)
+ flags |= FPDF_GRAYSCALE;
+
FPDF_RenderPageBitmap(bitmap, page, dest.x(), dest.y(), dest.width(),
- dest.height(), rotate,
- FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
+ dest.height(), rotate, flags);
FPDFBitmap_Destroy(bitmap);
FPDF_ClosePage(page);
- FPDF_CloseDocument(doc);
return true;
}
@@ -4626,25 +4777,30 @@ bool PDFiumEngineExports::GetPDFDocInfo(const void* pdf_buffer,
int buffer_size,
int* page_count,
double* max_page_width) {
- FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, buffer_size, nullptr);
+ std::unique_ptr<void, FPDFDocumentDeleter> doc(
+ FPDF_LoadMemDocument(pdf_buffer, buffer_size, nullptr));
if (!doc)
return false;
- int page_count_local = FPDF_GetPageCount(doc);
- if (page_count) {
+
+ if (!page_count && !max_page_width)
+ return true;
+
+ int page_count_local = FPDF_GetPageCount(doc.get());
+ if (page_count)
*page_count = page_count_local;
- }
+
if (max_page_width) {
*max_page_width = 0;
for (int page_number = 0; page_number < page_count_local; page_number++) {
double page_width = 0;
double page_height = 0;
- FPDF_GetPageSizeByIndex(doc, page_number, &page_width, &page_height);
+ FPDF_GetPageSizeByIndex(doc.get(), page_number, &page_width,
+ &page_height);
if (page_width > *max_page_width) {
*max_page_width = page_width;
}
}
}
- FPDF_CloseDocument(doc);
return true;
}
@@ -4653,13 +4809,11 @@ bool PDFiumEngineExports::GetPDFPageSizeByIndex(const void* pdf_buffer,
int page_number,
double* width,
double* height) {
- FPDF_DOCUMENT doc =
- FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, nullptr);
+ std::unique_ptr<void, FPDFDocumentDeleter> doc(
+ FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, nullptr));
if (!doc)
return false;
- bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0;
- FPDF_CloseDocument(doc);
- return success;
+ return FPDF_GetPageSizeByIndex(doc.get(), page_number, width, height) != 0;
}
} // namespace chrome_pdf
diff --git a/chromium/pdf/pdfium/pdfium_engine.h b/chromium/pdf/pdfium/pdfium_engine.h
index fb6990d023d..ce15d90ac9a 100644
--- a/chromium/pdf/pdfium/pdfium_engine.h
+++ b/chromium/pdf/pdfium/pdfium_engine.h
@@ -115,6 +115,10 @@ class PDFiumEngine : public PDFEngine,
void MoveRangeSelectionExtent(const pp::Point& extent) override;
void SetSelectionBounds(const pp::Point& base,
const pp::Point& extent) override;
+ void GetSelection(uint32_t* selection_start_page_index,
+ uint32_t* selection_start_char_index,
+ uint32_t* selection_end_page_index,
+ uint32_t* selection_end_char_index) override;
// DocumentLoader::Client implementation.
pp::Instance* GetPluginInstance() override;
@@ -291,10 +295,15 @@ class PDFiumEngine : public PDFEngine,
bool OnMouseDown(const pp::MouseInputEvent& event);
bool OnMouseUp(const pp::MouseInputEvent& event);
bool OnMouseMove(const pp::MouseInputEvent& event);
+ void OnMouseEnter(const pp::MouseInputEvent& event);
bool OnKeyDown(const pp::KeyboardInputEvent& event);
bool OnKeyUp(const pp::KeyboardInputEvent& event);
bool OnChar(const pp::KeyboardInputEvent& event);
+ // Decide what cursor should be displayed.
+ PP_CursorType_Dev DetermineCursorType(PDFiumPage::Area area,
+ int form_type) const;
+
bool ExtendSelection(int page_index, int char_index);
FPDF_DOCUMENT CreateSinglePageRasterPdf(
@@ -435,7 +444,8 @@ class PDFiumEngine : public PDFEngine,
int* stride) const;
// Called when the selection changes.
- void OnSelectionChanged();
+ void OnSelectionTextChanged();
+ void OnSelectionPositionChanged();
// Common code shared by RotateClockwise() and RotateCounterclockwise().
void RotateInternal();
@@ -460,6 +470,10 @@ class PDFiumEngine : public PDFEngine,
bool PageIndexInBounds(int index) const;
+ // Gets the height of the top toolbar in screen coordinates. This is
+ // independent of whether it is hidden or not at the moment.
+ float GetToolbarHeightInScreenCoords();
+
void ScheduleTouchTimer(const pp::TouchInputEvent& event);
void KillTouchTimer(int timer_id);
void HandleLongPress(const pp::TouchInputEvent& event);
@@ -691,6 +705,12 @@ class PDFiumEngine : public PDFEngine,
// True if left mouse button is currently being held down.
bool mouse_left_button_down_;
+ // True if middle mouse button is currently being held down.
+ bool mouse_middle_button_down_;
+
+ // Last known position while performing middle mouse button pan.
+ pp::Point mouse_middle_button_last_position_;
+
// The current text used for searching.
std::string current_find_text_;
// The results found.
diff --git a/chromium/pdf/pdfium/pdfium_range.cc b/chromium/pdf/pdfium/pdfium_range.cc
index fb1d94b4a31..bec834ff3d9 100644
--- a/chromium/pdf/pdfium/pdfium_range.cc
+++ b/chromium/pdf/pdfium/pdfium_range.cc
@@ -10,11 +10,26 @@
namespace chrome_pdf {
+namespace {
+
+void AdjustForBackwardsRange(int* index, int* count) {
+ int& char_index = *index;
+ int& char_count = *count;
+ if (char_count < 0) {
+ char_count *= -1;
+ char_index -= char_count - 1;
+ }
+}
+
+} // namespace
+
PDFiumRange::PDFiumRange(PDFiumPage* page, int char_index, int char_count)
- : page_(page),
- char_index_(char_index),
- char_count_(char_count),
- cached_screen_rects_zoom_(0) {}
+ : page_(page), char_index_(char_index), char_count_(char_count) {
+#if DCHECK_IS_ON()
+ AdjustForBackwardsRange(&char_index, &char_count);
+ DCHECK_LE(char_count, FPDFText_CountChars(page_->GetTextPage()));
+#endif
+}
PDFiumRange::PDFiumRange(const PDFiumRange& that) = default;
@@ -22,6 +37,11 @@ PDFiumRange::~PDFiumRange() = default;
void PDFiumRange::SetCharCount(int char_count) {
char_count_ = char_count;
+#if DCHECK_IS_ON()
+ int dummy_index = 0;
+ AdjustForBackwardsRange(&dummy_index, &char_count);
+ DCHECK_LE(char_count, FPDFText_CountChars(page_->GetTextPage()));
+#endif
cached_screen_rects_offset_ = pp::Point();
cached_screen_rects_zoom_ = 0;
@@ -42,10 +62,14 @@ const std::vector<pp::Rect>& PDFiumRange::GetScreenRects(
int char_index = char_index_;
int char_count = char_count_;
- if (char_count < 0) {
- char_count *= -1;
- char_index -= char_count - 1;
- }
+ if (char_count == 0)
+ return cached_screen_rects_;
+
+ AdjustForBackwardsRange(&char_index, &char_count);
+ DCHECK_GE(char_index, 0) << " start: " << char_index_
+ << " count: " << char_count_;
+ DCHECK_LT(char_index, FPDFText_CountChars(page_->GetTextPage()))
+ << " start: " << char_index_ << " count: " << char_count_;
int count = FPDFText_CountRects(page_->GetTextPage(), char_index, char_count);
for (int i = 0; i < count; ++i) {
@@ -68,11 +92,10 @@ base::string16 PDFiumRange::GetText() const {
int index = char_index_;
int count = char_count_;
base::string16 rv;
- if (count < 0) {
- count *= -1;
- index -= count - 1;
- }
+ if (count == 0)
+ return rv;
+ AdjustForBackwardsRange(&index, &count);
if (count > 0) {
PDFiumAPIStringBufferAdapter<base::string16> api_string_adapter(&rv, count,
false);
diff --git a/chromium/pdf/pdfium/pdfium_range.h b/chromium/pdf/pdfium/pdfium_range.h
index 6137c4dc7cb..56b0fcadb8e 100644
--- a/chromium/pdf/pdfium/pdfium_range.h
+++ b/chromium/pdf/pdfium/pdfium_range.h
@@ -47,7 +47,7 @@ class PDFiumRange {
// Cache of ScreenRect, and the associated variables used when caching it.
std::vector<pp::Rect> cached_screen_rects_;
pp::Point cached_screen_rects_offset_;
- double cached_screen_rects_zoom_;
+ double cached_screen_rects_zoom_ = 0;
};
} // namespace chrome_pdf
diff --git a/chromium/pdf/preview_mode_client.cc b/chromium/pdf/preview_mode_client.cc
index c824fdafe58..cfe2bfc99d2 100644
--- a/chromium/pdf/preview_mode_client.cc
+++ b/chromium/pdf/preview_mode_client.cc
@@ -18,7 +18,7 @@ void PreviewModeClient::Invalidate(const pp::Rect& rect) {
NOTREACHED();
}
-void PreviewModeClient::Scroll(const pp::Point& point) {
+void PreviewModeClient::DidScroll(const pp::Point& point) {
NOTREACHED();
}
@@ -31,6 +31,10 @@ void PreviewModeClient::ScrollToY(int y_in_screen_coords,
NOTREACHED();
}
+void PreviewModeClient::ScrollBy(const pp::Point& point) {
+ NOTREACHED();
+}
+
void PreviewModeClient::ScrollToPage(int page) {
NOTREACHED();
}
@@ -132,7 +136,8 @@ void PreviewModeClient::DocumentPaintOccurred() {
}
void PreviewModeClient::DocumentLoadComplete(
- const PDFEngine::DocumentFeatures& document_features) {
+ const PDFEngine::DocumentFeatures& document_features,
+ uint32_t file_size) {
client_->PreviewDocumentLoadComplete();
}
@@ -167,6 +172,10 @@ bool PreviewModeClient::IsPrintPreview() {
void PreviewModeClient::CancelBrowserDownload() {}
+float PreviewModeClient::GetToolbarHeightInScreenCoords() {
+ return 0.0f;
+}
+
uint32_t PreviewModeClient::GetBackgroundColor() {
NOTREACHED();
return 0;
diff --git a/chromium/pdf/preview_mode_client.h b/chromium/pdf/preview_mode_client.h
index 807cf800b40..3786478b0a9 100644
--- a/chromium/pdf/preview_mode_client.h
+++ b/chromium/pdf/preview_mode_client.h
@@ -29,9 +29,10 @@ class PreviewModeClient : public PDFEngine::Client {
// PDFEngine::Client implementation.
void DocumentSizeUpdated(const pp::Size& size) override;
void Invalidate(const pp::Rect& rect) override;
- void Scroll(const pp::Point& point) override;
+ void DidScroll(const pp::Point& point) override;
void ScrollToX(int x_in_screen_coords) override;
void ScrollToY(int y_in_screen_coords, bool compensate_for_toolbar) override;
+ void ScrollBy(const pp::Point& point) override;
void ScrollToPage(int page) override;
void NavigateTo(const std::string& url,
WindowOpenDisposition disposition) override;
@@ -65,7 +66,8 @@ class PreviewModeClient : public PDFEngine::Client {
bool case_sensitive) override;
void DocumentPaintOccurred() override;
void DocumentLoadComplete(
- const PDFEngine::DocumentFeatures& document_features) override;
+ const PDFEngine::DocumentFeatures& document_features,
+ uint32_t file_size) override;
void DocumentLoadFailed() override;
void FontSubstituted() override;
pp::Instance* GetPluginInstance() override;
@@ -74,6 +76,7 @@ class PreviewModeClient : public PDFEngine::Client {
void FormTextFieldFocusChange(bool in_focus) override;
bool IsPrintPreview() override;
void CancelBrowserDownload() override;
+ float GetToolbarHeightInScreenCoords() override;
uint32_t GetBackgroundColor() override;
private:
diff --git a/chromium/pdf/run_all_unittests.cc b/chromium/pdf/run_all_unittests.cc
index 138e5a2361f..a700cb9765a 100644
--- a/chromium/pdf/run_all_unittests.cc
+++ b/chromium/pdf/run_all_unittests.cc
@@ -20,5 +20,5 @@ int main(int argc, char** argv) {
base::TestSuite test_suite(argc, argv);
return base::LaunchUnitTests(
argc, argv,
- base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));
+ base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite)));
}