OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2015 PDFium 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 | |
5 #include "pdfium_test_embedder.h" | |
6 | |
7 #include <limits.h> | |
8 #include <stdio.h> | |
9 #include <stdlib.h> | |
10 #include <string.h> | |
11 | |
12 #include <list> | |
13 #include <string> | |
14 #include <utility> | |
15 #include <vector> | |
16 | |
17 #include "../fpdfsdk/include/fpdf_ext.h" | |
18 #include "../fpdfsdk/include/fpdftext.h" | |
19 #include "../fpdfsdk/include/fpdfview.h" | |
20 #include "../core/include/fxcrt/fx_system.h" | |
21 #include "v8/include/v8.h" | |
22 | |
23 #ifdef _WIN32 | |
24 #define snprintf _snprintf | |
25 #define PATH_SEPARATOR '\\' | |
26 #else | |
27 #define PATH_SEPARATOR '/' | |
28 #endif | |
29 | |
30 namespace { | |
31 | |
32 // Reads the entire contents of a file into a newly malloc'd buffer. | |
33 static char* GetFileContents(const char* filename, size_t* retlen) { | |
34 FILE* file = fopen(filename, "rb"); | |
35 if (!file) { | |
36 fprintf(stderr, "Failed to open: %s\n", filename); | |
37 return NULL; | |
38 } | |
39 (void) fseek(file, 0, SEEK_END); | |
40 size_t file_length = ftell(file); | |
41 if (!file_length) { | |
42 return NULL; | |
43 } | |
44 (void) fseek(file, 0, SEEK_SET); | |
45 char* buffer = (char*) malloc(file_length); | |
46 if (!buffer) { | |
47 return NULL; | |
48 } | |
49 size_t bytes_read = fread(buffer, 1, file_length, file); | |
50 (void) fclose(file); | |
51 if (bytes_read != file_length) { | |
52 fprintf(stderr, "Failed to read: %s\n", filename); | |
53 free(buffer); | |
54 return NULL; | |
55 } | |
56 *retlen = bytes_read; | |
57 return buffer; | |
58 } | |
59 | |
60 #ifdef V8_USE_EXTERNAL_STARTUP_DATA | |
61 // Returns the full path for an external V8 data file based on either | |
62 // the currect exectuable path or an explicit override. | |
63 static std::string GetFullPathForSnapshotFile(const Options& options, | |
64 const std::string& filename) { | |
65 std::string result; | |
66 if (!options.bin_directory.empty()) { | |
67 result = options.bin_directory; | |
68 if (*options.bin_directory.rbegin() != PATH_SEPARATOR) { | |
69 result += PATH_SEPARATOR; | |
70 } | |
71 } else if (!options.exe_path.empty()) { | |
72 size_t last_separator = options.exe_path.rfind(PATH_SEPARATOR); | |
73 if (last_separator != std::string::npos) { | |
74 result = options.exe_path.substr(0, last_separator + 1); | |
75 } | |
76 } | |
77 result += filename; | |
78 return result; | |
79 } | |
80 | |
81 // Reads an extenal V8 data file from the |options|-indicated location, | |
82 // returing true on success and false on error. | |
83 static bool GetExternalData(const Options& options, | |
84 const std::string& bin_filename, | |
85 v8::StartupData* result_data) { | |
86 std::string full_path = GetFullPathForSnapshotFile(options, bin_filename); | |
87 size_t data_length = 0; | |
88 char* data_buffer = GetFileContents(full_path.c_str(), &data_length); | |
89 if (!data_buffer) { | |
90 return false; | |
91 } | |
92 result_data->data = const_cast<const char*>(data_buffer); | |
93 result_data->raw_size = data_length; | |
94 return true; | |
95 } | |
96 #endif // V8_USE_EXTERNAL_STARTUP_DATA | |
97 | |
98 } // namespace | |
99 | |
100 int Form_Alert(IPDF_JSPLATFORM*, FPDF_WIDESTRING, FPDF_WIDESTRING, int, int) { | |
101 printf("Form_Alert called.\n"); | |
102 return 0; | |
103 } | |
104 | |
105 void Unsupported_Handler(UNSUPPORT_INFO*, int type) { | |
106 std::string feature = "Unknown"; | |
107 switch (type) { | |
108 case FPDF_UNSP_DOC_XFAFORM: | |
109 feature = "XFA"; | |
110 break; | |
111 case FPDF_UNSP_DOC_PORTABLECOLLECTION: | |
112 feature = "Portfolios_Packages"; | |
113 break; | |
114 case FPDF_UNSP_DOC_ATTACHMENT: | |
115 case FPDF_UNSP_ANNOT_ATTACHMENT: | |
116 feature = "Attachment"; | |
117 break; | |
118 case FPDF_UNSP_DOC_SECURITY: | |
119 feature = "Rights_Management"; | |
120 break; | |
121 case FPDF_UNSP_DOC_SHAREDREVIEW: | |
122 feature = "Shared_Review"; | |
123 break; | |
124 case FPDF_UNSP_DOC_SHAREDFORM_ACROBAT: | |
125 case FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM: | |
126 case FPDF_UNSP_DOC_SHAREDFORM_EMAIL: | |
127 feature = "Shared_Form"; | |
128 break; | |
129 case FPDF_UNSP_ANNOT_3DANNOT: | |
130 feature = "3D"; | |
131 break; | |
132 case FPDF_UNSP_ANNOT_MOVIE: | |
133 feature = "Movie"; | |
134 break; | |
135 case FPDF_UNSP_ANNOT_SOUND: | |
136 feature = "Sound"; | |
137 break; | |
138 case FPDF_UNSP_ANNOT_SCREEN_MEDIA: | |
139 case FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA: | |
140 feature = "Screen"; | |
141 break; | |
142 case FPDF_UNSP_ANNOT_SIG: | |
143 feature = "Digital_Signature"; | |
144 break; | |
145 } | |
146 printf("Unsupported feature: %s.\n", feature.c_str()); | |
147 } | |
148 | |
149 class TestLoader { | |
150 public: | |
151 TestLoader(const char* pBuf, size_t len); | |
152 | |
153 const char* m_pBuf; | |
154 size_t m_Len; | |
155 }; | |
156 | |
157 TestLoader::TestLoader(const char* pBuf, size_t len) | |
158 : m_pBuf(pBuf), m_Len(len) { | |
159 } | |
160 | |
161 int Get_Block(void* param, unsigned long pos, unsigned char* pBuf, | |
162 unsigned long size) { | |
163 TestLoader* pLoader = (TestLoader*) param; | |
164 if (pos + size < pos || pos + size > pLoader->m_Len) return 0; | |
165 memcpy(pBuf, pLoader->m_pBuf + pos, size); | |
166 return 1; | |
167 } | |
168 | |
169 bool Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { | |
170 return true; | |
171 } | |
172 | |
173 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) { | |
174 } | |
175 | |
176 void PDFiumTestEmbedder::SetUp() { | |
177 v8::V8::InitializeICU(); | |
178 | |
179 #ifdef V8_USE_EXTERNAL_STARTUP_DATA | |
180 ASSERT_TRUE(GetExternalData(options, "natives_blob.bin", &natives_)); | |
181 ASSERT_TRUE(GetExternalData(options, "snapshot_blob.bin", &snapshot_)); | |
182 v8::V8::SetNativesDataBlob(&natives); | |
183 v8::V8::SetSnapshotDataBlob(&snapshot); | |
184 #endif // V8_USE_EXTERNAL_STARTUP_DATA | |
185 | |
186 FPDF_InitLibrary(); | |
187 | |
188 UNSUPPORT_INFO unsuppored_info; | |
189 memset(&unsuppored_info, '\0', sizeof(unsuppored_info)); | |
190 unsuppored_info.version = 1; | |
191 unsuppored_info.FSDK_UnSupport_Handler = Unsupported_Handler; | |
192 FSDK_SetUnSpObjProcessHandler(&unsuppored_info); | |
193 } | |
194 | |
195 void PDFiumTestEmbedder::TearDown() { | |
196 FPDF_CloseDocument(document_); | |
197 FPDFAvail_Destroy(avail_); | |
198 if (file_contents_) { | |
199 free(file_contents_); | |
200 } | |
201 } | |
202 | |
203 bool PDFiumTestEmbedder::OpenDocument(const std::string& filename) { | |
204 file_contents_ = GetFileContents(filename.c_str(), &file_length_); | |
205 if (!file_contents_) { | |
206 return false; | |
207 } | |
208 | |
209 TestLoader loader(file_contents_, file_length_); | |
210 | |
211 file_access_.m_FileLen = static_cast<unsigned long>(file_length_); | |
212 file_access_.m_GetBlock = Get_Block; | |
213 file_access_.m_Param = &loader; | |
214 | |
215 file_avail_.version = 1; | |
216 file_avail_.IsDataAvail = Is_Data_Avail; | |
217 | |
218 hints_.version = 1; | |
219 hints_.AddSegment = Add_Segment; | |
220 | |
221 avail_ = FPDFAvail_Create(&file_avail_, &file_access_); | |
222 (void) FPDFAvail_IsDocAvail(avail_, &hints_); | |
223 | |
224 if (!FPDFAvail_IsLinearized(avail_)) { | |
225 document_ = FPDF_LoadCustomDocument(&file_access_, NULL); | |
226 } else { | |
227 document_ = FPDFAvail_GetDocument(avail_, NULL); | |
228 } | |
229 | |
230 (void) FPDF_GetDocPermissions(document_); | |
231 (void) FPDFAvail_IsFormAvail(avail_, &hints_); | |
232 return true; | |
233 } | |
234 | |
235 FPDF_FORMHANDLE PDFiumTestEmbedder::SetFormFillEnvironment() { | |
236 IPDF_JSPLATFORM platform_callbacks; | |
237 memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); | |
238 platform_callbacks.version = 1; | |
239 platform_callbacks.app_alert = Form_Alert; | |
240 | |
241 FPDF_FORMFILLINFO form_callbacks; | |
242 memset(&form_callbacks, '\0', sizeof(form_callbacks)); | |
243 form_callbacks.version = 1; | |
244 form_callbacks.m_pJsPlatform = &platform_callbacks; | |
245 | |
246 FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnvironment(document_, &form_callba cks); | |
jam
2015/01/13 19:21:18
nit: 80 chars
Tom Sepez
2015/01/15 21:24:40
Done.
| |
247 FPDF_SetFormFieldHighlightColor(form, 0, 0xFFE4DD); | |
248 FPDF_SetFormFieldHighlightAlpha(form, 100); | |
249 return form; | |
250 } | |
251 | |
252 void PDFiumTestEmbedder::ClearFormFillEnvironment(FPDF_FORMHANDLE form) { | |
253 FORM_DoDocumentAAction(form, FPDFDOC_AACTION_WC); | |
254 FPDFDOC_ExitFormFillEnvironment(form); | |
255 } | |
256 | |
257 void PDFiumTestEmbedder::DoOpenActions(FPDF_FORMHANDLE form) { | |
258 FORM_DoDocumentJSAction(form); | |
259 FORM_DoDocumentOpenAction(form); | |
260 } | |
261 | |
262 int PDFiumTestEmbedder::GetFirstPageNum() { | |
263 int first_page = FPDFAvail_GetFirstPageNum(document_); | |
264 (void) FPDFAvail_IsPageAvail(avail_, first_page, &hints_); | |
265 return first_page; | |
266 } | |
267 | |
268 int PDFiumTestEmbedder::GetPageCount() { | |
269 int page_count = FPDF_GetPageCount(document_); | |
270 for (int i = 0; i < page_count; ++i) { | |
271 (void) FPDFAvail_IsPageAvail(avail_, i, &hints_); | |
272 } | |
273 return page_count; | |
274 } | |
275 | |
276 FPDF_PAGE PDFiumTestEmbedder::LoadPage(int page_number, | |
277 FPDF_FORMHANDLE form) { | |
278 FPDF_PAGE page = FPDF_LoadPage(document_, page_number); | |
279 if (!page) { | |
280 return nullptr; | |
281 } | |
282 FORM_OnAfterLoadPage(page, form); | |
283 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_OPEN); | |
284 return page; | |
285 } | |
286 | |
287 FPDF_BITMAP PDFiumTestEmbedder::RenderPage(FPDF_PAGE page, FPDF_FORMHANDLE form) { | |
jam
2015/01/13 19:21:18
ditto
Tom Sepez
2015/01/15 21:24:40
Done.
| |
288 int width = static_cast<int>(FPDF_GetPageWidth(page)); | |
289 int height = static_cast<int>(FPDF_GetPageHeight(page)); | |
290 FPDF_BITMAP bitmap = FPDFBitmap_Create(width, height, 0); | |
291 FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF); | |
292 FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0); | |
293 FPDF_FFLDraw(form, bitmap, page, 0, 0, width, height, 0, 0); | |
294 return bitmap; | |
295 } | |
296 | |
297 void PDFiumTestEmbedder::UnloadPage(FPDF_PAGE page, FPDF_FORMHANDLE form) { | |
298 FORM_DoPageAAction(page, form, FPDFPAGE_AACTION_CLOSE); | |
299 FORM_OnBeforeClosePage(page, form); | |
300 FPDF_ClosePage(page); | |
301 } | |
OLD | NEW |