diff options
author | tonikitoo <tonikitoo@igalia.com> | 2016-08-26 08:37:10 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-08-26 08:37:10 -0700 |
commit | 3e98158a6c47361ca7d6c2c18d47c9f8f3aabb8a (patch) | |
tree | 704926c3b5edbabde50fbee3aa1abceb8e180e72 /samples | |
parent | 9b57ec9ff50aeab53cf3f028222f69c78840385d (diff) | |
download | pdfium-3e98158a6c47361ca7d6c2c18d47c9f8f3aabb8a.tar.xz |
Extend pdfium_test capability so that more Javascript can be executedchromium/2841
In [1], the lack of support of pdfium_test to some application
level hooks was felt.
More specifically, the lack of implementation of the hook FFI_GetPage,
called when 'this.getAnnot()' is executed in an Acrobar JS context,
makes it non-trivial to JS texts that manipulate PDF annotations.
[1] https://codereview.chromium.org/2265313002/
Here is the failing call stack in pdfium_test:
0 ::RenderPdf (samples/pdfium_test.cc)
1 ::FORM_DoDocumentOpenAction (fpdfsdk/fpdfformfill.cpp)
2 CPDFSDK_Document::ProcOpenAction (fpdfsdk/fsdk_mgr.cpp)
3 CPDFSDK_ActionHandler::DoAction_DocOpen (fpdfsdk/fsdk_actionhandler.cpp)
<----v8---->
4 Document::getAnnot (fpdfsdk/javascript/Document.cpp)
5 CPDFSDK_Document::GetPageView (fpdfsdk/fsdk_mgr.cpp)
6 CPDFDoc_Environment::FFI_GetPage (fpdfsdk/include/fsdk_mgr.h)
(frame 6 returns nullptr, and getAnnot call in frame 4 bails)
CL extends pdfium_test app with a FFI_GetPage hook implementation.
Basically what FFI_GetPage does is returning a FPDF_PAGE instance.
In case of pdfium_test, FPDF_PAGE instances were only created on demand
when the page was going to get rendered, and then discarded.
Since FFI_GetPage can be called by JS before pages are rendered,
CL moved the page creation code into a helper function, and cached
the FPDF_PAGE instances created in a map, so it does not recreate
them needlessly.
BUG=pdfium:492
Review-Url: https://codereview.chromium.org/2277063003
Diffstat (limited to 'samples')
-rw-r--r-- | samples/pdfium_test.cc | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc index da2d1f6977..421df39bf3 100644 --- a/samples/pdfium_test.cc +++ b/samples/pdfium_test.cc @@ -7,6 +7,7 @@ #include <stdlib.h> #include <string.h> +#include <map> #include <sstream> #include <string> #include <utility> @@ -53,6 +54,14 @@ enum OutputFormat { #endif }; +// Hold a map of the currently loaded pages in order to avoid them +// to get loaded twice. +std::map<int, FPDF_PAGE> g_loadedPages; + +// Hold a global pointer of FPDF_FORMHANDLE so that PDFium +// app hooks can made use of it. +FPDF_FORMHANDLE g_formHandle; + struct Options { Options() : show_config(false), send_events(false), output_format(OUTPUT_NONE) {} @@ -520,19 +529,35 @@ void SendPageEvents(const FPDF_FORMHANDLE& form, } } +FPDF_PAGE GetPageForIndex(FPDF_FORMFILLINFO* param, + FPDF_DOCUMENT doc, + int index) { + auto iter = g_loadedPages.find(index); + if (iter != g_loadedPages.end()) + return iter->second; + + FPDF_PAGE page = FPDF_LoadPage(doc, index); + if (!page) + return nullptr; + + FORM_OnAfterLoadPage(page, g_formHandle); + FORM_DoPageAAction(page, g_formHandle, FPDFPAGE_AACTION_OPEN); + + g_loadedPages[index] = page; + return page; +} + bool RenderPage(const std::string& name, - const FPDF_DOCUMENT& doc, - const FPDF_FORMHANDLE& form, + FPDF_DOCUMENT doc, + FPDF_FORMHANDLE& form, const int page_index, const Options& options, const std::string& events) { - FPDF_PAGE page = FPDF_LoadPage(doc, page_index); + FPDF_PAGE page = GetPageForIndex(nullptr, doc, page_index); if (!page) return false; FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page); - FORM_OnAfterLoadPage(page, form); - FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_OPEN); if (options.send_events) SendPageEvents(form, page, events); @@ -593,6 +618,8 @@ bool RenderPage(const std::string& name, } else { fprintf(stderr, "Page was too large to be rendered.\n"); } + + g_loadedPages.erase(page_index); FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE); FORM_OnBeforeClosePage(page, form); FPDFText_ClosePage(text_page); @@ -620,6 +647,7 @@ void RenderPdf(const std::string& name, #else // PDF_ENABLE_XFA form_callbacks.version = 1; #endif // PDF_ENABLE_XFA + form_callbacks.FFI_GetPage = GetPageForIndex; form_callbacks.m_pJsPlatform = &platform_callbacks; TestLoader loader(pBuf, len); @@ -703,7 +731,8 @@ void RenderPdf(const std::string& name, (void)FPDF_GetDocPermissions(doc); - FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnvironment(doc, &form_callbacks); + FPDF_FORMHANDLE form = g_formHandle = + FPDFDOC_InitFormFillEnvironment(doc, &form_callbacks); #ifdef PDF_ENABLE_XFA int docType = DOCTYPE_PDF; if (FPDF_HasXFAField(doc, &docType) && docType != DOCTYPE_PDF && |