pdfium_engine.h 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef PDF_PDFIUM_PDFIUM_ENGINE_H_
  5. #define PDF_PDFIUM_PDFIUM_ENGINE_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <map>
  9. #include <memory>
  10. #include <string>
  11. #include <vector>
  12. #include "base/check.h"
  13. #include "base/containers/flat_map.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "base/memory/weak_ptr.h"
  16. #include "base/time/time.h"
  17. #include "base/timer/timer.h"
  18. #include "base/values.h"
  19. #include "pdf/document_attachment_info.h"
  20. #include "pdf/document_layout.h"
  21. #include "pdf/document_metadata.h"
  22. #include "pdf/loader/document_loader.h"
  23. #include "pdf/pdf_engine.h"
  24. #include "pdf/pdfium/pdfium_form_filler.h"
  25. #include "pdf/pdfium/pdfium_page.h"
  26. #include "pdf/pdfium/pdfium_print.h"
  27. #include "pdf/pdfium/pdfium_range.h"
  28. #include "third_party/abseil-cpp/absl/types/optional.h"
  29. #include "third_party/pdfium/public/cpp/fpdf_scopers.h"
  30. #include "third_party/pdfium/public/fpdf_formfill.h"
  31. #include "third_party/pdfium/public/fpdf_progressive.h"
  32. #include "third_party/pdfium/public/fpdfview.h"
  33. #include "third_party/skia/include/core/SkBitmap.h"
  34. #include "ui/gfx/geometry/point.h"
  35. #include "ui/gfx/geometry/rect.h"
  36. #include "ui/gfx/geometry/size.h"
  37. #include "ui/gfx/geometry/vector2d.h"
  38. namespace blink {
  39. class WebKeyboardEvent;
  40. class WebMouseEvent;
  41. class WebTouchEvent;
  42. } // namespace blink
  43. namespace chrome_pdf {
  44. enum class AccessibilityScrollAlignment;
  45. class PDFiumDocument;
  46. class PDFiumPermissions;
  47. struct AccessibilityActionData;
  48. struct AccessibilityTextRunInfo;
  49. struct PageCharacterIndex;
  50. namespace draw_utils {
  51. class ShadowMatrix;
  52. struct PageInsetSizes;
  53. } // namespace draw_utils
  54. class PDFiumEngine : public PDFEngine,
  55. public DocumentLoader::Client,
  56. public IFSDK_PAUSE {
  57. public:
  58. // State transition when tabbing forward:
  59. // None -> Document -> Page -> None (when focusable annotations on all pages
  60. // are done).
  61. // Exposed for testing.
  62. enum class FocusElementType { kNone, kDocument, kPage };
  63. // NOTE: `script_option` is ignored when PDF_ENABLE_V8 is not defined.
  64. PDFiumEngine(PDFEngine::Client* client,
  65. PDFiumFormFiller::ScriptOption script_option);
  66. PDFiumEngine(const PDFiumEngine&) = delete;
  67. PDFiumEngine& operator=(const PDFiumEngine&) = delete;
  68. ~PDFiumEngine() override;
  69. // Replaces the normal DocumentLoader for testing. Must be called before
  70. // HandleDocumentLoad().
  71. void SetDocumentLoaderForTesting(std::unique_ptr<DocumentLoader> loader);
  72. // Returns the FontMappingMode set during PDFium SDK initialization.
  73. static FontMappingMode GetFontMappingMode();
  74. // Starts loading the document from `loader`. Follow-up requests (such as for
  75. // partial loading) will use `original_url`.
  76. bool HandleDocumentLoad(std::unique_ptr<UrlLoader> loader,
  77. const std::string& original_url);
  78. // PDFEngine:
  79. void PageOffsetUpdated(const gfx::Vector2d& page_offset) override;
  80. void PluginSizeUpdated(const gfx::Size& size) override;
  81. void ScrolledToXPosition(int position) override;
  82. void ScrolledToYPosition(int position) override;
  83. void PrePaint() override;
  84. void Paint(const gfx::Rect& rect,
  85. SkBitmap& image_data,
  86. std::vector<gfx::Rect>& ready,
  87. std::vector<gfx::Rect>& pending) override;
  88. void PostPaint() override;
  89. bool HandleInputEvent(const blink::WebInputEvent& event) override;
  90. void PrintBegin() override;
  91. std::vector<uint8_t> PrintPages(
  92. const std::vector<int>& page_numbers,
  93. const blink::WebPrintParams& print_params) override;
  94. void PrintEnd() override;
  95. void StartFind(const std::string& text, bool case_sensitive) override;
  96. bool SelectFindResult(bool forward) override;
  97. void StopFind() override;
  98. void ZoomUpdated(double new_zoom_level) override;
  99. void RotateClockwise() override;
  100. void RotateCounterclockwise() override;
  101. bool IsReadOnly() const override;
  102. void SetReadOnly(bool enable) override;
  103. void SetDocumentLayout(DocumentLayout::PageSpread page_spread) override;
  104. void DisplayAnnotations(bool display) override;
  105. gfx::Size ApplyDocumentLayout(
  106. const DocumentLayout::Options& options) override;
  107. std::string GetSelectedText() override;
  108. bool CanEditText() const override;
  109. bool HasEditableText() const override;
  110. void ReplaceSelection(const std::string& text) override;
  111. bool CanUndo() const override;
  112. bool CanRedo() const override;
  113. void Undo() override;
  114. void Redo() override;
  115. void HandleAccessibilityAction(
  116. const AccessibilityActionData& action_data) override;
  117. std::string GetLinkAtPosition(const gfx::Point& point) override;
  118. bool HasPermission(DocumentPermission permission) const override;
  119. void SelectAll() override;
  120. const std::vector<DocumentAttachmentInfo>& GetDocumentAttachmentInfoList()
  121. const override;
  122. std::vector<uint8_t> GetAttachmentData(size_t index) override;
  123. const DocumentMetadata& GetDocumentMetadata() const override;
  124. int GetNumberOfPages() const override;
  125. base::Value::List GetBookmarks() override;
  126. absl::optional<PDFEngine::NamedDestination> GetNamedDestination(
  127. const std::string& destination) override;
  128. int GetMostVisiblePage() override;
  129. gfx::Rect GetPageBoundsRect(int index) override;
  130. gfx::Rect GetPageContentsRect(int index) override;
  131. gfx::Rect GetPageScreenRect(int page_index) const override;
  132. void SetGrayscale(bool grayscale) override;
  133. int GetCharCount(int page_index) override;
  134. gfx::RectF GetCharBounds(int page_index, int char_index) override;
  135. uint32_t GetCharUnicode(int page_index, int char_index) override;
  136. absl::optional<AccessibilityTextRunInfo> GetTextRunInfo(
  137. int page_index,
  138. int start_char_index) override;
  139. std::vector<AccessibilityLinkInfo> GetLinkInfo(
  140. int page_index,
  141. const std::vector<AccessibilityTextRunInfo>& text_runs) override;
  142. std::vector<AccessibilityImageInfo> GetImageInfo(
  143. int page_index,
  144. uint32_t text_run_count) override;
  145. std::vector<AccessibilityHighlightInfo> GetHighlightInfo(
  146. int page_index,
  147. const std::vector<AccessibilityTextRunInfo>& text_runs) override;
  148. std::vector<AccessibilityTextFieldInfo> GetTextFieldInfo(
  149. int page_index,
  150. uint32_t text_run_count) override;
  151. bool GetPrintScaling() override;
  152. int GetCopiesToPrint() override;
  153. printing::mojom::DuplexMode GetDuplexMode() override;
  154. absl::optional<gfx::Size> GetUniformPageSizePoints() override;
  155. void AppendBlankPages(size_t num_pages) override;
  156. void AppendPage(PDFEngine* engine, int index) override;
  157. std::vector<uint8_t> GetSaveData() override;
  158. void SetCaretPosition(const gfx::Point& position) override;
  159. void MoveRangeSelectionExtent(const gfx::Point& extent) override;
  160. void SetSelectionBounds(const gfx::Point& base,
  161. const gfx::Point& extent) override;
  162. void GetSelection(uint32_t* selection_start_page_index,
  163. uint32_t* selection_start_char_index,
  164. uint32_t* selection_end_page_index,
  165. uint32_t* selection_end_char_index) override;
  166. void KillFormFocus() override;
  167. void UpdateFocus(bool has_focus) override;
  168. AccessibilityFocusInfo GetFocusInfo() override;
  169. uint32_t GetLoadedByteSize() override;
  170. bool ReadLoadedBytes(uint32_t length, void* buffer) override;
  171. void RequestThumbnail(int page_index,
  172. float device_pixel_ratio,
  173. SendThumbnailCallback send_callback) override;
  174. // DocumentLoader::Client:
  175. std::unique_ptr<URLLoaderWrapper> CreateURLLoader() override;
  176. void OnPendingRequestComplete() override;
  177. void OnNewDataReceived() override;
  178. void OnDocumentComplete() override;
  179. void OnDocumentCanceled() override;
  180. #if defined(PDF_ENABLE_XFA)
  181. void UpdatePageCount();
  182. #endif // defined(PDF_ENABLE_XFA)
  183. void UnsupportedFeature(const std::string& feature);
  184. FPDF_AVAIL fpdf_availability() const;
  185. FPDF_DOCUMENT doc() const;
  186. FPDF_FORMHANDLE form() const;
  187. // Returns the PDFiumPage pointer of a given index. Returns nullptr if `index`
  188. // is out of range.
  189. PDFiumPage* GetPage(size_t index);
  190. bool IsValidLink(const std::string& url);
  191. private:
  192. // This helper class is used to detect the difference in selection between
  193. // construction and destruction. At destruction, it invalidates all the
  194. // parts that are newly selected, along with all the parts that used to be
  195. // selected but are not anymore.
  196. class SelectionChangeInvalidator {
  197. public:
  198. explicit SelectionChangeInvalidator(PDFiumEngine* engine);
  199. ~SelectionChangeInvalidator();
  200. private:
  201. // Returns all the currently visible selection rectangles, in screen
  202. // coordinates.
  203. std::vector<gfx::Rect> GetVisibleSelections() const;
  204. // Invalidates `selection`, but with `selection` slightly expanded to
  205. // compensate for any rounding errors.
  206. void Invalidate(const gfx::Rect& selection);
  207. const raw_ptr<PDFiumEngine> engine_;
  208. // The origin at the time this object was constructed.
  209. const gfx::Point previous_origin_;
  210. // Screen rectangles that were selected on construction.
  211. std::vector<gfx::Rect> old_selections_;
  212. };
  213. // Used to store mouse down state to handle it in other mouse event handlers.
  214. class MouseDownState {
  215. public:
  216. MouseDownState(const PDFiumPage::Area& area,
  217. const PDFiumPage::LinkTarget& target);
  218. MouseDownState(const MouseDownState&) = delete;
  219. MouseDownState& operator=(const MouseDownState&) = delete;
  220. ~MouseDownState();
  221. void Set(const PDFiumPage::Area& area,
  222. const PDFiumPage::LinkTarget& target);
  223. void Reset();
  224. bool Matches(const PDFiumPage::Area& area,
  225. const PDFiumPage::LinkTarget& target) const;
  226. private:
  227. PDFiumPage::Area area_;
  228. PDFiumPage::LinkTarget target_;
  229. };
  230. friend class FormFillerTest;
  231. friend class PDFiumEngineTabbingTest;
  232. friend class PDFiumFormFiller;
  233. friend class PDFiumTestBase;
  234. friend class SelectionChangeInvalidator;
  235. gfx::Size plugin_size() const {
  236. // TODO(crbug.com/1237952): Just use .value() after fixing call sites.
  237. DCHECK(plugin_size_.has_value());
  238. return plugin_size_.value_or(gfx::Size());
  239. }
  240. // We finished getting the pdf file, so load it. This will complete
  241. // asynchronously (due to password fetching) and may be run multiple times.
  242. void LoadDocument();
  243. // Try loading the document. Returns true if the document is successfully
  244. // loaded or is already loaded otherwise it will return false. If there is a
  245. // password, then `password` is non-empty. If the document could not be loaded
  246. // and needs a password, `needs_password` will be set to true.
  247. bool TryLoadingDoc(const std::string& password, bool* needs_password);
  248. // Asks the user for the document password and then continue loading the
  249. // document.
  250. void GetPasswordAndLoad();
  251. // Called when the password has been retrieved.
  252. void OnGetPasswordComplete(const std::string& password);
  253. // Continues loading the document when the password has been retrieved, or if
  254. // there is no password. If there is no password, then `password` is empty.
  255. void ContinueLoadingDocument(const std::string& password);
  256. // Finishes loading the document. Recalculate the document size if there were
  257. // pages that were not previously available.
  258. // Also notifies the client that the document has been loaded.
  259. // This should only be called after `doc_` has been loaded and the document is
  260. // fully downloaded.
  261. // If this has been run once, it will not notify the client again.
  262. void FinishLoadingDocument();
  263. // Loads information about the pages in the document and performs layout.
  264. void LoadPageInfo();
  265. // Refreshes the document layout using the current pages and layout options.
  266. void RefreshCurrentDocumentLayout();
  267. // Proposes the next document layout using the current pages and
  268. // `desired_layout_options_`.
  269. void ProposeNextDocumentLayout();
  270. // Updates `layout` using the current page sizes.
  271. void UpdateDocumentLayout(DocumentLayout* layout);
  272. // Loads information about the pages in the document, calculating and
  273. // returning the individual page sizes.
  274. //
  275. // Note that the page rects of any new pages will be left uninitialized, so
  276. // layout must be performed immediately after calling this method.
  277. //
  278. // TODO(kmoon): LoadPageSizes() is a bit misnomer, but LoadPageInfo() is
  279. // taken right now...
  280. std::vector<gfx::Size> LoadPageSizes(
  281. const DocumentLayout::Options& layout_options);
  282. void LoadBody();
  283. void LoadPages();
  284. void LoadForm();
  285. // Checks whether the document is optimized by linearization.
  286. bool IsLinearized();
  287. // Calculates which pages should be displayed right now.
  288. void CalculateVisiblePages();
  289. // Returns true iff the given page index is visible. CalculateVisiblePages
  290. // must have been called first.
  291. bool IsPageVisible(int index) const;
  292. // Internal interface that caches the page index requested by PDFium to get
  293. // scrolled to. The cache is to be be used during the interval the PDF
  294. // plugin has not finished handling the scroll request.
  295. void ScrollToPage(int page);
  296. // Checks if a page is now available, and if so marks it as such and returns
  297. // true. Otherwise, it will return false and will add the index to the given
  298. // array if it's not already there.
  299. bool CheckPageAvailable(int index, std::vector<int>* pending);
  300. // Helper function to get a given page's size in pixels. This is not part of
  301. // PDFiumPage because we might not have that structure when we need this.
  302. gfx::Size GetPageSize(int index);
  303. gfx::Size GetPageSizeForLayout(int index,
  304. const DocumentLayout::Options& layout_options);
  305. // Helper function for getting the inset sizes for the current layout. If
  306. // two-up view is enabled, the configuration of inset sizes depends on
  307. // the position of the page, specified by `page_index` and `num_of_pages`.
  308. draw_utils::PageInsetSizes GetInsetSizes(
  309. const DocumentLayout::Options& layout_options,
  310. size_t page_index,
  311. size_t num_of_pages) const;
  312. // If two-up view is disabled, enlarges `page_size` with inset sizes for
  313. // single-view. If two-up view is enabled, calls GetInsetSizes() with
  314. // `page_index` and `num_of_pages`, and uses the returned inset sizes to
  315. // enlarge `page_size`.
  316. void EnlargePage(const DocumentLayout::Options& layout_options,
  317. size_t page_index,
  318. size_t num_of_pages,
  319. gfx::Size* page_size) const;
  320. // Similar to EnlargePage(), but insets a `rect`. Also multiplies the inset
  321. // sizes by `multiplier`, using the ceiling of the result.
  322. void InsetPage(const DocumentLayout::Options& layout_options,
  323. size_t page_index,
  324. size_t num_of_pages,
  325. double multiplier,
  326. gfx::Rect& rect) const;
  327. // If two-up view is enabled, returns the index of the page beside
  328. // `page_index` page. Returns absl::nullopt if there is no adjacent page or
  329. // if two-up view is disabled.
  330. absl::optional<size_t> GetAdjacentPageIndexForTwoUpView(
  331. size_t page_index,
  332. size_t num_of_pages) const;
  333. std::vector<gfx::Rect> GetAllScreenRectsUnion(
  334. const std::vector<PDFiumRange>& rect_range,
  335. const gfx::Point& point) const;
  336. void UpdateTickMarks();
  337. // Called to continue searching so we don't block the main thread.
  338. void ContinueFind(bool case_sensitive);
  339. // Inserts a find result into `find_results_`, which is sorted.
  340. void AddFindResult(const PDFiumRange& result);
  341. // Search a page using PDFium's methods. Doesn't work with unicode. This
  342. // function is just kept arount in case PDFium code is fixed.
  343. void SearchUsingPDFium(const std::u16string& term,
  344. bool case_sensitive,
  345. bool first_search,
  346. int character_to_start_searching_from,
  347. int current_page);
  348. // Search a page ourself using ICU.
  349. void SearchUsingICU(const std::u16string& term,
  350. bool case_sensitive,
  351. bool first_search,
  352. int character_to_start_searching_from,
  353. int current_page);
  354. // Input event handlers.
  355. bool OnMouseDown(const blink::WebMouseEvent& event);
  356. bool OnMouseUp(const blink::WebMouseEvent& event);
  357. bool OnMouseMove(const blink::WebMouseEvent& event);
  358. void OnMouseEnter(const blink::WebMouseEvent& event);
  359. bool OnKeyDown(const blink::WebKeyboardEvent& event);
  360. bool OnKeyUp(const blink::WebKeyboardEvent& event);
  361. bool OnChar(const blink::WebKeyboardEvent& event);
  362. // Decide what cursor should be displayed.
  363. ui::mojom::CursorType DetermineCursorType(PDFiumPage::Area area,
  364. int form_type) const;
  365. bool ExtendSelection(int page_index, int char_index);
  366. std::vector<uint8_t> PrintPagesAsRasterPdf(
  367. const std::vector<int>& page_numbers,
  368. const blink::WebPrintParams& print_params);
  369. std::vector<uint8_t> PrintPagesAsPdf(
  370. const std::vector<int>& page_numbers,
  371. const blink::WebPrintParams& print_params);
  372. // Checks if `page` has selected text in a form element. If so, sets that as
  373. // the plugin's text selection.
  374. void SetFormSelectedText(FPDF_FORMHANDLE form_handle, FPDF_PAGE page);
  375. // Given `point`, returns which page and character location it's closest to,
  376. // as well as extra information about objects at that point.
  377. PDFiumPage::Area GetCharIndex(const gfx::Point& point,
  378. int* page_index,
  379. int* char_index,
  380. int* form_type,
  381. PDFiumPage::LinkTarget* target);
  382. void OnSingleClick(int page_index, int char_index);
  383. void OnMultipleClick(int click_count, int page_index, int char_index);
  384. bool OnLeftMouseDown(const blink::WebMouseEvent& event);
  385. bool OnMiddleMouseDown(const blink::WebMouseEvent& event);
  386. bool OnRightMouseDown(const blink::WebMouseEvent& event);
  387. // Starts a progressive paint operation given a rectangle in screen
  388. // coordinates. Returns the index in progressive_rects_.
  389. int StartPaint(int page_index, const gfx::Rect& dirty);
  390. // Continues a paint operation that was started earlier. Returns true if the
  391. // paint is done, or false if it needs to be continued.
  392. bool ContinuePaint(int progressive_index, SkBitmap& image_data);
  393. // Called once PDFium is finished rendering a page so that we draw our
  394. // borders, highlighting etc.
  395. void FinishPaint(int progressive_index, SkBitmap& image_data);
  396. // Stops any paints that are in progress.
  397. void CancelPaints();
  398. // Invalidates all pages. Use this when some global parameter, such as page
  399. // orientation, has changed.
  400. void InvalidateAllPages();
  401. // If the page is narrower than the document size, paint the extra space
  402. // with the page background.
  403. void FillPageSides(int progressive_index);
  404. void PaintPageShadow(int progressive_index, SkBitmap& image_data);
  405. // Highlight visible find results and selections.
  406. void DrawSelections(int progressive_index, SkBitmap& image_data) const;
  407. // Paints an page that hasn't finished downloading.
  408. void PaintUnavailablePage(int page_index,
  409. const gfx::Rect& dirty,
  410. SkBitmap& image_data);
  411. // Given a page index, returns the corresponding index in progressive_rects_,
  412. // or -1 if it doesn't exist.
  413. int GetProgressiveIndex(int page_index) const;
  414. // Creates a FPDF_BITMAP from a rectangle in screen coordinates.
  415. ScopedFPDFBitmap CreateBitmap(const gfx::Rect& rect,
  416. bool has_alpha,
  417. SkBitmap& image_data) const;
  418. // Given a rectangle in screen coordinates, returns the coordinates in the
  419. // units that PDFium rendering functions expect.
  420. void GetPDFiumRect(int page_index,
  421. const gfx::Rect& rect,
  422. int* start_x,
  423. int* start_y,
  424. int* size_x,
  425. int* size_y) const;
  426. // Returns the rendering flags to pass to PDFium.
  427. int GetRenderingFlags() const;
  428. // Returns the currently visible rectangle in document coordinates.
  429. gfx::Rect GetVisibleRect() const;
  430. // Given `rect` in document coordinates, returns the rectangle in screen
  431. // coordinates. (i.e. 0,0 is top left corner of plugin area)
  432. gfx::Rect GetScreenRect(const gfx::Rect& rect) const;
  433. // Given an image `buffer` with `stride`, highlights `rect`.
  434. // `highlighted_rects` contains the already highlighted rectangles and will be
  435. // updated to include `rect` if `rect` has not already been highlighted.
  436. void Highlight(void* buffer,
  437. int stride,
  438. const gfx::Rect& rect,
  439. int color_red,
  440. int color_green,
  441. int color_blue,
  442. std::vector<gfx::Rect>& highlighted_rects) const;
  443. // Helper function to convert a device to page coordinates. If the page is
  444. // not yet loaded, `page_x` and `page_y` will be set to 0.
  445. void DeviceToPage(int page_index,
  446. const gfx::Point& device_point,
  447. double* page_x,
  448. double* page_y);
  449. // Helper function to get the index of a given FPDF_PAGE. Returns -1 if not
  450. // found.
  451. int GetVisiblePageIndex(FPDF_PAGE page);
  452. // Helper function to change the current page, running page open/close
  453. // triggers as necessary.
  454. void SetCurrentPage(int index);
  455. void DrawPageShadow(const gfx::Rect& page_rect,
  456. const gfx::Rect& shadow_rect,
  457. const gfx::Rect& clip_rect,
  458. SkBitmap& image_data);
  459. void GetRegion(const gfx::Point& location,
  460. SkBitmap& image_data,
  461. void*& region,
  462. int& stride) const;
  463. // Called when the selection changes.
  464. void OnSelectionTextChanged();
  465. void OnSelectionPositionChanged();
  466. // Sets text selection status of document. This does not include text
  467. // within form text fields.
  468. void SetSelecting(bool selecting);
  469. // Sets the type of field that has focus.
  470. void SetFieldFocus(PDFEngine::FocusFieldType type);
  471. // Sets whether or not left mouse button is currently being held down.
  472. void SetMouseLeftButtonDown(bool is_mouse_left_button_down);
  473. // Given an annotation which is a form of `form_type` which is known to be a
  474. // form text area, check if it is an editable form text area.
  475. bool IsAnnotationAnEditableFormTextArea(FPDF_ANNOTATION annot,
  476. int form_type) const;
  477. bool PageIndexInBounds(int index) const;
  478. bool IsPageCharacterIndexInBounds(const PageCharacterIndex& index) const;
  479. void ScheduleTouchTimer(const blink::WebTouchEvent& event);
  480. void KillTouchTimer();
  481. void HandleLongPress(const blink::WebTouchEvent& event);
  482. // Returns a dictionary representing a bookmark, which in turn contains child
  483. // dictionaries representing the child bookmarks. If `bookmark` is null, then
  484. // this method traverses from the root of the bookmarks tree. Note that the
  485. // root bookmark contains no useful information.
  486. base::Value::Dict TraverseBookmarks(FPDF_BOOKMARK bookmark,
  487. unsigned int depth);
  488. void ScrollBasedOnScrollAlignment(
  489. const gfx::Rect& scroll_rect,
  490. const AccessibilityScrollAlignment& horizontal_scroll_alignment,
  491. const AccessibilityScrollAlignment& vertical_scroll_alignment);
  492. // Scrolls top left of a rect in page `target_rect` to `global_point`.
  493. // Global point is point relative to viewport in screen.
  494. void ScrollToGlobalPoint(const gfx::Rect& target_rect,
  495. const gfx::Point& global_point);
  496. // Set if the document has any local edits.
  497. void EnteredEditMode();
  498. // Navigates to a link destination depending on the type of destination.
  499. // Returns false if `area` is not a link.
  500. bool NavigateToLinkDestination(PDFiumPage::Area area,
  501. const PDFiumPage::LinkTarget& target,
  502. WindowOpenDisposition disposition);
  503. // IFSDK_PAUSE callbacks
  504. static FPDF_BOOL Pause_NeedToPauseNow(IFSDK_PAUSE* param);
  505. // Used for text selection. Given the start and end of selection, sets the
  506. // text range in `selection_`.
  507. void SetSelection(const PageCharacterIndex& selection_start_index,
  508. const PageCharacterIndex& selection_end_index);
  509. // Scroll the current focused annotation into view if not already in view.
  510. void ScrollFocusedAnnotationIntoView();
  511. // Given `annot`, scroll the `annot` into view if not already in view.
  512. void ScrollAnnotationIntoView(FPDF_ANNOTATION annot, int page_index);
  513. void OnFocusedAnnotationUpdated(FPDF_ANNOTATION annot, int page_index);
  514. // Read the attachments' information inside the PDF document, and set
  515. // `doc_attachment_info_list_`. To be called after the document is loaded.
  516. void LoadDocumentAttachmentInfoList();
  517. // Fetches and populates the fields of `doc_metadata_`. To be called after the
  518. // document is loaded.
  519. void LoadDocumentMetadata();
  520. // Retrieves the value of `field` in the document information dictionary.
  521. // Trims whitespace characters from the retrieved value.
  522. std::string GetTrimmedMetadataByField(FPDF_BYTESTRING field) const;
  523. // Retrieves the version of the PDF (e.g. 1.4 or 2.0) as an enum.
  524. PdfVersion GetDocumentVersion() const;
  525. // This is a layer between OnKeyDown() and actual tab handling to facilitate
  526. // testing.
  527. bool HandleTabEvent(int modifiers);
  528. // Helper functions to handle tab events.
  529. bool HandleTabEventWithModifiers(int modifiers);
  530. bool HandleTabForward(int modifiers);
  531. bool HandleTabBackward(int modifiers);
  532. // Updates the currently focused object stored in `focus_element_type_`.
  533. // Notifies `client_` about document focus change, if any.
  534. void UpdateFocusElementType(FocusElementType focus_element_type);
  535. void UpdateLinkUnderCursor(const std::string& target_url);
  536. void SetLinkUnderCursorForAnnotation(FPDF_ANNOTATION annot, int page_index);
  537. // Checks whether a given `page_index` exists in `pending_thumbnails_`. If so,
  538. // requests the thumbnail for that page.
  539. void MaybeRequestPendingThumbnail(int page_index);
  540. const raw_ptr<PDFEngine::Client> client_;
  541. // The current document layout.
  542. DocumentLayout layout_;
  543. // The options for the desired document layout.
  544. DocumentLayout::Options desired_layout_options_;
  545. // The scroll position in screen coordinates.
  546. gfx::Point position_;
  547. // The offset of the page into the viewport.
  548. gfx::Vector2d page_offset_;
  549. // The plugin size in screen coordinates.
  550. absl::optional<gfx::Size> plugin_size_;
  551. double current_zoom_ = 1.0;
  552. // The caret position and bound in plugin viewport coordinates.
  553. gfx::Rect caret_rect_;
  554. std::unique_ptr<DocumentLoader> doc_loader_; // Main document's loader.
  555. bool doc_loader_set_for_testing_ = false;
  556. // Set to true if the user is being prompted for their password. Will be set
  557. // to false after the user finishes getting their password.
  558. bool getting_password_ = false;
  559. int password_tries_remaining_ = 0;
  560. // Needs to be above pages_, as destroying a page may call some methods of
  561. // form filler.
  562. PDFiumFormFiller form_filler_;
  563. std::unique_ptr<PDFiumDocument> document_;
  564. bool document_pending_ = false;
  565. bool document_loaded_ = false;
  566. // The page(s) of the document.
  567. std::vector<std::unique_ptr<PDFiumPage>> pages_;
  568. // The indexes of the pages currently visible.
  569. std::vector<int> visible_pages_;
  570. // The indexes of the pages pending download.
  571. std::vector<int> pending_pages_;
  572. // During handling of input events we don't want to unload any pages in
  573. // callbacks to us from PDFium, since the current page can change while PDFium
  574. // code still has a pointer to it.
  575. bool defer_page_unload_ = false;
  576. std::vector<int> deferred_page_unloads_;
  577. // Used for text selection, but does not include text within form text areas.
  578. // There could be more than one range if selection spans more than one page.
  579. std::vector<PDFiumRange> selection_;
  580. // True if we're in the middle of text selection.
  581. bool selecting_ = false;
  582. MouseDownState mouse_down_state_;
  583. // Text selection within form text fields and form combobox text fields.
  584. std::string selected_form_text_;
  585. // True if left mouse button is currently being held down.
  586. bool mouse_left_button_down_ = false;
  587. // True if middle mouse button is currently being held down.
  588. bool mouse_middle_button_down_ = false;
  589. // Last known position while performing middle mouse button pan.
  590. gfx::Point mouse_middle_button_last_position_;
  591. // The current text used for searching.
  592. std::string current_find_text_;
  593. // The results found.
  594. std::vector<PDFiumRange> find_results_;
  595. // Whether a search is in progress.
  596. bool search_in_progress_ = false;
  597. // Which page to search next.
  598. int next_page_to_search_ = -1;
  599. // Where to stop searching.
  600. int last_page_to_search_ = -1;
  601. int last_character_index_to_search_ = -1; // -1 if search until end of page.
  602. // Which result the user has currently selected. (0-based)
  603. absl::optional<size_t> current_find_index_;
  604. // Where to resume searching. (0-based)
  605. absl::optional<size_t> resume_find_index_;
  606. std::unique_ptr<PDFiumPermissions> permissions_;
  607. gfx::Size default_page_size_;
  608. // Timer for touch long press detection.
  609. base::OneShotTimer touch_timer_;
  610. // Set to true when handling long touch press.
  611. bool handling_long_press_ = false;
  612. // Set to true when updating plugin focus.
  613. bool updating_focus_ = false;
  614. // True if `focus_field_type_` is currently set to `FocusFieldType::kText` and
  615. // the focused form text area is not read-only.
  616. bool editable_form_text_area_ = false;
  617. // The type of the currently focused form field.
  618. FocusFieldType focus_field_type_ = FocusFieldType::kNoFocus;
  619. // The focus element type for the currently focused object.
  620. FocusElementType focus_element_type_ = FocusElementType::kNone;
  621. // Stores the last focused object's focus element type before PDF loses focus.
  622. FocusElementType last_focused_element_type_ = FocusElementType::kNone;
  623. // Stores the last focused annotation's index before PDF loses focus.
  624. int last_focused_annot_index_ = -1;
  625. // Holds the zero-based page index of the last page that had the focused
  626. // object.
  627. int last_focused_page_ = -1;
  628. // Holds the zero-based page index of the most visible page; refreshed by
  629. // calling CalculateVisiblePages()
  630. int most_visible_page_ = -1;
  631. // Holds the page index requested by PDFium while the scroll operation
  632. // is being handled (asynchronously).
  633. absl::optional<int> in_flight_visible_page_;
  634. // Set to true after FORM_DoDocumentJSAction/FORM_DoDocumentOpenAction have
  635. // been called. Only after that can we call FORM_DoPageAAction.
  636. bool called_do_document_action_ = false;
  637. // Records parts of form fields that need to be highlighted at next paint, in
  638. // screen coordinates.
  639. std::vector<gfx::Rect> form_highlights_;
  640. // Whether to render in grayscale or in color.
  641. bool render_grayscale_ = false;
  642. // Whether to render PDF annotations.
  643. bool render_annots_ = true;
  644. // Pending progressive paints.
  645. class ProgressivePaint {
  646. public:
  647. ProgressivePaint(int page_index, const gfx::Rect& rect);
  648. ProgressivePaint(ProgressivePaint&& that);
  649. ProgressivePaint& operator=(ProgressivePaint&& that);
  650. ~ProgressivePaint();
  651. int page_index() const { return page_index_; }
  652. const gfx::Rect& rect() const { return rect_; }
  653. FPDF_BITMAP bitmap() const { return bitmap_.get(); }
  654. bool painted() const { return painted_; }
  655. void set_painted(bool enable) { painted_ = enable; }
  656. void SetBitmapAndImageData(ScopedFPDFBitmap bitmap, SkBitmap image_data);
  657. private:
  658. int page_index_;
  659. gfx::Rect rect_; // In screen coordinates.
  660. SkBitmap image_data_; // Maintains reference while |bitmap_| exists.
  661. ScopedFPDFBitmap bitmap_; // Must come after |image_data_|.
  662. // Temporary used to figure out if in a series of Paint() calls whether this
  663. // pending paint was updated or not.
  664. bool painted_ = false;
  665. };
  666. std::vector<ProgressivePaint> progressive_paints_;
  667. // Keeps track of when we started the last progressive paint, so that in our
  668. // callback we can determine if we need to pause.
  669. base::Time last_progressive_start_time_;
  670. // The timeout to use for the current progressive paint.
  671. base::TimeDelta progressive_paint_timeout_;
  672. // Shadow matrix for generating the page shadow bitmap.
  673. std::unique_ptr<draw_utils::ShadowMatrix> page_shadow_;
  674. // Pending thumbnail requests.
  675. struct PendingThumbnail {
  676. PendingThumbnail();
  677. PendingThumbnail(PendingThumbnail&& that);
  678. PendingThumbnail& operator=(PendingThumbnail&& that);
  679. ~PendingThumbnail();
  680. float device_pixel_ratio = 1.0f;
  681. SendThumbnailCallback send_callback;
  682. };
  683. // Map of page indices to pending thumbnail requests.
  684. base::flat_map<int, PendingThumbnail> pending_thumbnails_;
  685. // A list of information of document attachments.
  686. std::vector<DocumentAttachmentInfo> doc_attachment_info_list_;
  687. // Stores parsed document metadata.
  688. DocumentMetadata doc_metadata_;
  689. // While true, the document try to be opened and parsed after download each
  690. // part. Else the document will be opened and parsed only on finish of
  691. // downloading.
  692. bool process_when_pending_request_complete_ = true;
  693. enum class RangeSelectionDirection { Left, Right };
  694. RangeSelectionDirection range_selection_direction_ =
  695. RangeSelectionDirection::Right;
  696. gfx::Point range_selection_base_;
  697. bool edit_mode_ = false;
  698. // When true, interactive portions of the content, such as forms and links,
  699. // are restricted.
  700. bool read_only_ = false;
  701. PDFiumPrint print_;
  702. base::WeakPtrFactory<PDFiumEngine> weak_factory_{this};
  703. // Weak pointers from this factory are used to bind the ContinueFind()
  704. // function. This allows those weak pointers to be invalidated during
  705. // StopFind(), and keeps the invalidation separated from `weak_factory_`.
  706. base::WeakPtrFactory<PDFiumEngine> find_weak_factory_{this};
  707. };
  708. } // namespace chrome_pdf
  709. #endif // PDF_PDFIUM_PDFIUM_ENGINE_H_