5#include "testing/embedder_test.h"
13#include "core/fdrm/fx_crypt.h"
14#include "public/cpp/fpdf_scopers.h"
15#include "public/fpdf_dataavail.h"
16#include "public/fpdf_edit.h"
17#include "public/fpdf_text.h"
18#include "public/fpdfview.h"
19#include "testing/embedder_test_environment.h"
20#include "testing/gmock/include/gmock/gmock.h"
21#include "testing/test_loader.h"
22#include "testing/utils/bitmap_saver.h"
23#include "testing/utils/file_util.h"
24#include "testing/utils/hash.h"
25#include "testing/utils/path_service.h"
26#include "third_party/base/check.h"
27#include "third_party/base/check_op.h"
28#include "third_party/base/containers/contains.h"
29#include "third_party/base/notreached.h"
30#include "third_party/base/numerics/checked_math.h"
31#include "third_party/base/numerics/safe_conversions.h"
35int GetBitmapBytesPerPixel(FPDF_BITMAP bitmap) {
40int CALLBACK GetRecordProc(HDC hdc,
41 HANDLETABLE* handle_table,
42 const ENHMETARECORD* record,
45 auto& records = *
reinterpret_cast<std::vector<
const ENHMETARECORD*>*>(param);
46 records.push_back(record);
52void UnsupportedHandlerTrampoline(UNSUPPORT_INFO* info,
int type) {
57int AlertTrampoline(IPDF_JSPLATFORM* platform,
58 FPDF_WIDESTRING message,
59 FPDF_WIDESTRING title,
66int SetTimerTrampoline(FPDF_FORMFILLINFO* info,
int msecs,
TimerCallback fn) {
71void KillTimerTrampoline(FPDF_FORMFILLINFO* info,
int id) {
76FPDF_PAGE GetPageTrampoline(FPDF_FORMFILLINFO* info,
77 FPDF_DOCUMENT document,
83void DoURIActionTrampoline(FPDF_FORMFILLINFO* info, FPDF_BYTESTRING uri) {
88void DoGoToActionTrampoline(FPDF_FORMFILLINFO* info,
98void OnFocusChangeTrampoline(FPDF_FORMFILLINFO* info,
99 FPDF_ANNOTATION annot,
105void DoURIActionWithKeyboardModifierTrampoline(FPDF_FORMFILLINFO* info,
113void InvalidateStub(FPDF_FORMFILLINFO* pThis,
120void OutputSelectedRectStub(FPDF_FORMFILLINFO* pThis,
127void SetCursorStub(FPDF_FORMFILLINFO* pThis,
int nCursorType) {}
129FPDF_SYSTEMTIME GetLocalTimeStub(FPDF_FORMFILLINFO* pThis) {
130 return {122, 11, 6, 28, 12, 59, 59, 500};
133void OnChangeStub(FPDF_FORMFILLINFO* pThis) {}
135FPDF_PAGE GetCurrentPageStub(FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document) {
136 return GetPageTrampoline(pThis, document, 0);
139int GetRotationStub(FPDF_FORMFILLINFO* pThis, FPDF_PAGE page) {
143void ExecuteNamedActionStub(FPDF_FORMFILLINFO* pThis, FPDF_BYTESTRING name) {}
145void SetTextFieldFocusStub(FPDF_FORMFILLINFO* pThis,
146 FPDF_WIDESTRING value,
148 FPDF_BOOL is_focus) {}
151void DisplayCaretStub(FPDF_FORMFILLINFO* pThis,
159int GetCurrentPageIndexStub(FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document) {
163void SetCurrentPageStub(FPDF_FORMFILLINFO* pThis,
164 FPDF_DOCUMENT document,
167void GotoURLStub(FPDF_FORMFILLINFO* pThis,
168 FPDF_DOCUMENT document,
169 FPDF_WIDESTRING wsURL) {}
171void GetPageViewRectStub(FPDF_FORMFILLINFO* pThis,
183void PageEventStub(FPDF_FORMFILLINFO* pThis,
185 FPDF_DWORD event_type) {}
187FPDF_BOOL PopupMenuStub(FPDF_FORMFILLINFO* pThis,
196FPDF_FILEHANDLER* OpenFileStub(FPDF_FORMFILLINFO* pThis,
198 FPDF_WIDESTRING wsURL,
203void EmailToStub(FPDF_FORMFILLINFO* pThis,
204 FPDF_FILEHANDLER* fileHandler,
206 FPDF_WIDESTRING pSubject,
208 FPDF_WIDESTRING pBcc,
209 FPDF_WIDESTRING pMsg) {}
211void UploadToStub(FPDF_FORMFILLINFO* pThis,
212 FPDF_FILEHANDLER* fileHandler,
214 FPDF_WIDESTRING uploadTo) {}
216int GetPlatformStub(FPDF_FORMFILLINFO* pThis,
void* platform,
int length) {
220int GetLanguageStub(FPDF_FORMFILLINFO* pThis,
void* language,
int length) {
224FPDF_FILEHANDLER* DownloadFromURLStub(FPDF_FORMFILLINFO* pThis,
225 FPDF_WIDESTRING URL) {
226 static const char kString[] =
"<body>secrets</body>";
227 static FPDF_FILEHANDLER kFakeFileHandler = {
229 [](
void*) ->
void {},
230 [](
void*) -> FPDF_DWORD {
return sizeof(kString); },
231 [](
void*, FPDF_DWORD off,
void* buffer, FPDF_DWORD size) -> FPDF_RESULT {
232 memcpy(buffer, kString, std::min<size_t>(size,
sizeof(kString)));
235 [](
void*, FPDF_DWORD,
const void*, FPDF_DWORD) -> FPDF_RESULT {
238 [](
void*) -> FPDF_RESULT {
return 0; },
239 [](
void*, FPDF_DWORD) -> FPDF_RESULT {
return 0; }};
240 return &kFakeFileHandler;
243FPDF_BOOL PostRequestURLStub(FPDF_FORMFILLINFO* pThis,
244 FPDF_WIDESTRING wsURL,
245 FPDF_WIDESTRING wsData,
246 FPDF_WIDESTRING wsContentType,
247 FPDF_WIDESTRING wsEncode,
248 FPDF_WIDESTRING wsHeader,
249 FPDF_BSTR* response) {
250 const char kString[] =
"p\0o\0s\0t\0e\0d\0";
251 FPDF_BStr_Set(response, kString,
sizeof(kString) - 1);
255FPDF_BOOL PutRequestURLStub(FPDF_FORMFILLINFO* pThis,
256 FPDF_WIDESTRING wsURL,
257 FPDF_WIDESTRING wsData,
258 FPDF_WIDESTRING wsEncode) {
275 UNSUPPORT_INFO* info =
static_cast<UNSUPPORT_INFO*>(
this);
276 memset(info, 0,
sizeof(UNSUPPORT_INFO));
285 EXPECT_EQ(0U, page_map_.size());
286 EXPECT_EQ(0U, saved_page_map_.size());
293 form_handle_.reset(SetupFormFillEnvironment(
294 document(), JavaScriptOption::kEnableJavaScript));
298 document_.reset(FPDF_CreateNewDocument());
303 return OpenDocumentWithOptions(filename,
nullptr,
309 return OpenDocumentWithOptions(filename,
nullptr,
315 const char* password) {
316 return OpenDocumentWithOptions(filename, password,
322 return OpenDocumentWithOptions(filename,
nullptr,
328 const char* password,
331 std::string file_path = PathService::GetTestFilePath(filename);
332 if (file_path.empty()) {
336 file_contents_ = GetFileContents(file_path.c_str());
337 if (file_contents_.empty()) {
341 EXPECT_TRUE(!loader_);
342 loader_ = std::make_unique<TestLoader>(file_contents_);
344 memset(&file_access_, 0,
sizeof(file_access_));
345 file_access_.m_FileLen =
346 pdfium::base::checked_cast<
unsigned long>(file_contents_.size());
348 file_access_.m_Param = loader_.get();
350 fake_file_access_ = std::make_unique<FakeFileAccess>(&file_access_);
351 return OpenDocumentHelper(password, linearize_option, javascript_option,
352 fake_file_access_.get(), &document_, &avail_,
360 ScopedFPDFDocument* document,
361 ScopedFPDFAvail* avail,
362 ScopedFPDFFormHandle* form_handle) {
363 network_simulator->AddSegment(0, 1024);
367 FPDF_AVAIL avail_ptr = avail->get();
368 FPDF_DOCUMENT document_ptr =
nullptr;
380 document_ptr = document->get();
394 for (
int i = 0; i < page_count; ++i) {
410 document_ptr = document->get();
425 form_handle_.reset();
428 fake_file_access_.reset();
429 memset(&file_access_, 0,
sizeof(file_access_));
437 IPDF_JSPLATFORM* platform =
static_cast<IPDF_JSPLATFORM*>(
this);
438 memset(platform,
'\0',
sizeof(IPDF_JSPLATFORM));
442 FPDF_FORMFILLINFO* formfillinfo =
static_cast<FPDF_FORMFILLINFO*>(
this);
443 memset(formfillinfo, 0,
sizeof(FPDF_FORMFILLINFO));
444 formfillinfo
->version = form_fill_info_version_;
450 formfillinfo->FFI_GetLocalTime = GetLocalTimeStub;
452 formfillinfo->FFI_GetPage = GetPageTrampoline;
453 formfillinfo->FFI_GetCurrentPage = GetCurrentPageStub;
460 formfillinfo->FFI_DisplayCaret = DisplayCaretStub;
461 formfillinfo->FFI_GetCurrentPageIndex = GetCurrentPageIndexStub;
462 formfillinfo->FFI_SetCurrentPage = SetCurrentPageStub;
463 formfillinfo->FFI_GotoURL = GotoURLStub;
464 formfillinfo->FFI_GetPageViewRect = GetPageViewRectStub;
465 formfillinfo->FFI_PageEvent = PageEventStub;
466 formfillinfo->FFI_PopupMenu = PopupMenuStub;
467 formfillinfo->FFI_OpenFile = OpenFileStub;
468 formfillinfo->FFI_EmailTo = EmailToStub;
469 formfillinfo->FFI_UploadTo = UploadToStub;
470 formfillinfo->FFI_GetPlatform = GetPlatformStub;
471 formfillinfo->FFI_GetLanguage = GetLanguageStub;
472 formfillinfo->FFI_DownloadFromURL = DownloadFromURLStub;
473 formfillinfo->FFI_PostRequestURL = PostRequestURLStub;
474 formfillinfo->FFI_PutRequestURL = PutRequestURLStub;
478 DoURIActionWithKeyboardModifierTrampoline;
483 FPDF_FORMHANDLE form_handle =
490 DCHECK(form_handle());
497 (
void)FPDFAvail_IsPageAvail(avail(), first_page,
498 fake_file_access_->GetDownloadHints());
504 for (
int i = 0; i < page_count; ++i)
505 (
void)FPDFAvail_IsPageAvail(avail(), i,
506 fake_file_access_->GetDownloadHints());
511 return LoadPageCommon(page_number,
true);
515 return LoadPageCommon(page_number,
false);
518FPDF_PAGE
EmbedderTest::LoadPageCommon(
int page_number,
bool do_events) {
519 DCHECK(form_handle());
520 DCHECK(page_number >= 0);
521 DCHECK(!pdfium::Contains(page_map_, page_number));
531 page_map_[page_number] = page;
536 UnloadPageCommon(page,
true);
540 UnloadPageCommon(page,
false);
543void EmbedderTest::UnloadPageCommon(FPDF_PAGE page,
bool do_events) {
544 DCHECK(form_handle());
545 int page_number = GetPageNumberForLoadedPage(page);
546 CHECK_GE(page_number, 0);
553 page_map_.erase(page_number);
562 return RenderLoadedPageWithFlags(page, 0);
567 int page_number = GetPageNumberForLoadedPage(page);
568 CHECK_GE(page_number, 0);
573 return RenderSavedPageWithFlags(page, 0);
578 int page_number = GetPageNumberForSavedPage(page);
579 CHECK_GE(page_number, 0);
585 FPDF_FORMHANDLE handle,
591 FPDF_DWORD fill_color = alpha ? 0x00000000 : 0xFFFFFFFF;
592 FPDFBitmap_FillRect(bitmap.get(), 0, 0, width, height, fill_color);
593 FPDF_RenderPageBitmap(bitmap.get(), page, 0, 0, width, height, 0, flags);
594 FPDF_FFLDraw(handle, bitmap.get(), page, 0, 0, width, height, 0, flags);
600 return RenderPageWithFlags(page,
nullptr, 0);
605std::vector<uint8_t> EmbedderTest::RenderPageWithFlagsToEmf(FPDF_PAGE page,
607 HDC dc = CreateEnhMetaFileA(
nullptr,
nullptr,
nullptr,
nullptr);
609 int width =
static_cast<
int>(FPDF_GetPageWidthF(page));
610 int height =
static_cast<
int>(FPDF_GetPageHeightF(page));
611 HRGN rgn = CreateRectRgn(0, 0, width, height);
612 SelectClipRgn(dc, rgn);
615 SelectObject(dc, GetStockObject(NULL_PEN));
616 SelectObject(dc, GetStockObject(WHITE_BRUSH));
618 Rectangle(dc, 0, 0, width + 1, height + 1);
620 FPDF_RenderPage(dc, page, 0, 0, width, height, 0, flags);
622 HENHMETAFILE emf = CloseEnhMetaFile(dc);
623 UINT size_in_bytes = GetEnhMetaFileBits(emf, 0,
nullptr);
624 std::vector<uint8_t> buffer(size_in_bytes);
625 GetEnhMetaFileBits(emf, size_in_bytes, buffer.data());
626 DeleteEnhMetaFile(emf);
631std::string EmbedderTest::GetPostScriptFromEmf(
632 pdfium::span<
const uint8_t> emf_data) {
634 HENHMETAFILE emf = SetEnhMetaFileBits(
635 pdfium::base::checked_cast<UINT>(emf_data.size()), emf_data.data());
637 return std::string();
640 std::vector<
const ENHMETARECORD*> records;
641 if (!EnumEnhMetaFile(
nullptr, emf, &GetRecordProc, &records,
nullptr)) {
642 DeleteEnhMetaFile(emf);
643 return std::string();
648 for (
const auto* record : records) {
649 if (record->iType != EMR_GDICOMMENT)
655 const auto* comment =
reinterpret_cast<
const EMRGDICOMMENT*>(record);
656 const char* data =
reinterpret_cast<
const char*>(comment->Data);
657 uint16_t size = *
reinterpret_cast<
const uint16_t*>(data);
659 ps_data.append(data, size);
661 DeleteEnhMetaFile(emf);
681 NOTREACHED_NORETURN();
686 const char* password) {
687 memset(&saved_file_access_, 0,
sizeof(saved_file_access_));
688 saved_file_access_.m_FileLen =
689 pdfium::base::checked_cast<
unsigned long>(data_string_.size());
692 saved_document_file_data_ = data_string_;
693 saved_file_access_.m_Param = &saved_document_file_data_;
695 saved_fake_file_access_ =
696 std::make_unique<FakeFileAccess>(&saved_file_access_);
698 EXPECT_TRUE(OpenDocumentHelper(
699 password, LinearizeOption::kDefaultLinearize,
700 JavaScriptOption::kEnableJavaScript, saved_fake_file_access_.get(),
701 &saved_document_, &saved_avail_, &saved_form_handle_));
706 DCHECK(saved_document());
708 saved_form_handle_.reset();
709 saved_document_.reset();
710 saved_avail_.reset();
714 DCHECK(saved_form_handle());
715 DCHECK(page_number >= 0);
716 DCHECK(!pdfium::Contains(saved_page_map_, page_number));
724 saved_page_map_[page_number] = page;
729 DCHECK(saved_form_handle());
731 int page_number = GetPageNumberForSavedPage(page);
732 CHECK_GE(page_number, 0);
738 saved_page_map_.erase(page_number);
745 DCHECK(saved_document());
748 ScopedFPDFBitmap bitmap = RenderSavedPageWithFlags(page,
FPDF_ANNOT);
761 DCHECK(fake_file_access_);
762 fake_file_access_->SetWholeFileAvailable();
766 document_.reset(FPDFAvail_GetDocument(avail(),
nullptr));
770 FPDF_FILEACCESS* file) {
771 avail_.reset(FPDFAvail_Create(file_avail, file));
775 FPDF_DOCUMENT document,
778 auto it = test->page_map_.find(page_index);
779 return it != test->page_map_.end() ? it->second :
nullptr;
785 int usable_bytes_per_row =
790 static_cast<size_t>(stride) * height);
793 for (
int i = 0; i < height; ++i)
794 CRYPT_MD5Update(&context, span.subspan(i * stride, usable_bytes_per_row));
797 return CryptToBase16(digest);
802 const std::string& filename) {
810 const char* expected_md5sum) {
816 const int expected_stride =
817 (expected_width * GetBitmapBytesPerPixel(bitmap) * 8 + 31) / 32 * 4;
820 if (!expected_md5sum)
823 std::string actual_md5sum = HashBitmap(bitmap);
824 EXPECT_EQ(expected_md5sum, actual_md5sum);
826 WriteBitmapToPng(bitmap, actual_md5sum +
".png");
831int EmbedderTest::WriteBlockCallback(FPDF_FILEWRITE* pFileWrite,
833 unsigned long size) {
836 pThis->data_string_.append(
static_cast<
const char*>(data), size);
838 if (pThis->filestream_.is_open())
839 pThis->filestream_.write(
static_cast<
const char*>(data), size);
848 unsigned long size) {
849 std::string* new_file =
static_cast<
std::string*>(param);
852 pdfium::base::CheckedNumeric<size_t> end = pos;
854 CHECK_LE(end.ValueOrDie(), new_file->size());
856 memcpy(buf, new_file->data() + pos, size);
861int EmbedderTest::GetPageNumberForPage(
const PageNumberToHandleMap& page_map,
863 for (
const auto& it : page_map) {
864 if (it.second == page) {
865 int page_number = it.first;
866 DCHECK(page_number >= 0);
873int EmbedderTest::GetPageNumberForLoadedPage(FPDF_PAGE page)
const {
874 return GetPageNumberForPage(page_map_, page);
877int EmbedderTest::GetPageNumberForSavedPage(FPDF_PAGE page)
const {
878 return GetPageNumberForPage(saved_page_map_, page);
883 filestream_.open(filename,
std::ios_base::binary);
static void WriteBitmapToPng(FPDF_BITMAP bitmap, const std::string &filename)
static EmbedderTestEnvironment * GetInstance()
virtual void UnsupportedHandler(int type)
virtual void DoGoToAction(FPDF_FORMFILLINFO *info, int page_index, int zoom_mode, float *pos_arry, int array_size)
virtual int SetTimer(int msecs, TimerCallback fn)
virtual int Alert(FPDF_WIDESTRING message, FPDF_WIDESTRING title, int type, int icon)
virtual void DoURIAction(FPDF_BYTESTRING uri)
virtual FPDF_PAGE GetPage(FPDF_FORMFILLINFO *info, FPDF_DOCUMENT document, int page_index)
virtual void KillTimer(int id)
virtual void OnFocusChange(FPDF_FORMFILLINFO *info, FPDF_ANNOTATION annot, int page_index)
virtual void DoURIActionWithKeyboardModifier(FPDF_FORMFILLINFO *info, FPDF_BYTESTRING uri, int modifiers)
ScopedFPDFBitmap RenderLoadedPage(FPDF_PAGE page)
ScopedFPDFBitmap RenderLoadedPageWithFlags(FPDF_PAGE page, int flags)
void SetWholeFileAvailable()
void VerifySavedDocument(int width, int height, const char *md5)
FPDF_DOCUMENT OpenSavedDocumentWithPassword(const char *password)
void VerifySavedRendering(FPDF_PAGE page, int width, int height, const char *md5)
void SetInitialFormFieldHighlight(FPDF_FORMHANDLE form)
FPDF_DOCUMENT saved_document() const
void CloseSavedDocument()
FPDF_DOCUMENT OpenSavedDocument()
ScopedFPDFBitmap RenderSavedPageWithFlags(FPDF_PAGE page, int flags)
FPDF_FORMHANDLE SetupFormFillEnvironment(FPDF_DOCUMENT doc, JavaScriptOption javascript_option)
FPDF_FORMHANDLE saved_form_handle() const
FPDF_PAGE LoadPageNoEvents(int page_number)
static void CompareBitmap(FPDF_BITMAP bitmap, int expected_width, int expected_height, const char *expected_md5sum)
void UnloadPage(FPDF_PAGE page)
bool OpenDocumentHelper(const char *password, LinearizeOption linearize_option, JavaScriptOption javascript_option, FakeFileAccess *network_simulator, ScopedFPDFDocument *document, ScopedFPDFAvail *avail, ScopedFPDFFormHandle *form_handle)
void ClosePDFFileForWrite()
static int GetBlockFromString(void *param, unsigned long pos, unsigned char *buf, unsigned long size)
FPDF_DOCUMENT document() const
ScopedFPDFBitmap RenderSavedPage(FPDF_PAGE page)
void UnloadPageNoEvents(FPDF_PAGE page)
void CreateAvail(FX_FILEAVAIL *file_avail, FPDF_FILEACCESS *file)
void CloseSavedPage(FPDF_PAGE page)
FPDF_PAGE LoadPage(int page_number)
static std::string HashBitmap(FPDF_BITMAP bitmap)
void SetDocumentFromAvail()
FPDF_PAGE LoadSavedPage(int page_number)
FPDF_FORMHANDLE form_handle() const
static int BytesPerPixelForFormat(int format)
void CreateEmptyDocument()
void CreateEmptyDocumentWithoutFormFillEnvironment()
void SetRequestedDataAvailable()
void SetWholeFileAvailable()
FX_DOWNLOADHINTS * GetDownloadHints() const
FX_FILEAVAIL * GetFileAvail() const
FPDF_FILEACCESS * GetFileAccess() const
static int GetBlock(void *param, unsigned long pos, unsigned char *pBuf, unsigned long size)
#define PDF_DATA_NOTAVAIL
FPDF_EXPORT int FPDF_CALLCONV FPDFAvail_IsFormAvail(FPDF_AVAIL avail, FX_DOWNLOADHINTS *hints)
FPDF_EXPORT int FPDF_CALLCONV FPDFAvail_IsPageAvail(FPDF_AVAIL avail, int page_index, FX_DOWNLOADHINTS *hints)
FPDF_EXPORT FPDF_DOCUMENT FPDF_CALLCONV FPDFAvail_GetDocument(FPDF_AVAIL avail, FPDF_BYTESTRING password)
FPDF_EXPORT int FPDF_CALLCONV FPDFAvail_IsDocAvail(FPDF_AVAIL avail, FX_DOWNLOADHINTS *hints)
FPDF_EXPORT int FPDF_CALLCONV FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc)
FPDF_EXPORT int FPDF_CALLCONV FPDFAvail_IsLinearized(FPDF_AVAIL avail)
FPDF_EXPORT FPDF_AVAIL FPDF_CALLCONV FPDFAvail_Create(FX_FILEAVAIL *file_avail, FPDF_FILEACCESS *file)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPage_HasTransparency(FPDF_PAGE page)
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FSDK_SetUnSpObjProcessHandler(UNSUPPORT_INFO *unsp_info)
FPDF_EXPORT FPDF_PAGE FPDF_CALLCONV FPDF_LoadPage(FPDF_DOCUMENT document, int page_index)
FPDF_EXPORT int FPDF_CALLCONV FPDF_GetPageCount(FPDF_DOCUMENT document)
FPDF_EXPORT FPDF_DOCUMENT FPDF_CALLCONV FPDF_LoadCustomDocument(FPDF_FILEACCESS *pFileAccess, FPDF_BYTESTRING password)
FPDF_EXPORT int FPDF_CALLCONV FPDFBitmap_GetHeight(FPDF_BITMAP bitmap)
FPDF_EXPORT float FPDF_CALLCONV FPDF_GetPageHeightF(FPDF_PAGE page)
FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV FPDFBitmap_Create(int width, int height, int alpha)
FPDF_EXPORT int FPDF_CALLCONV FPDFBitmap_GetStride(FPDF_BITMAP bitmap)
FPDF_EXPORT int FPDF_CALLCONV FPDFBitmap_GetFormat(FPDF_BITMAP bitmap)
FPDF_EXPORT void *FPDF_CALLCONV FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap)
FPDF_EXPORT int FPDF_CALLCONV FPDFBitmap_GetWidth(FPDF_BITMAP bitmap)
FPDF_EXPORT float FPDF_CALLCONV FPDF_GetPageWidthF(FPDF_PAGE page)
FPDF_EXPORT void FPDF_CALLCONV FPDF_ClosePage(FPDF_PAGE page)
void CRYPT_MD5Finish(CRYPT_md5_context *context, uint8_t digest[16])
CRYPT_md5_context CRYPT_MD5Start()
int(* WriteBlock)(struct FPDF_FILEWRITE_ *pThis, const void *pData, unsigned long size)
void(* FSDK_UnSupport_Handler)(struct _UNSUPPORT_INFO *pThis, int nType)