DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc, FPDF_DOCUMENT src_doc, FPDF_BYTESTRING pagerange, int index) { CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc); if (!dest_doc) return FALSE; CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); if (!pSrcDoc) return FALSE; CFX_WordArray pageArray; int nCount = pSrcDoc->GetPageCount(); if (pagerange) { if (!ParserPageRangeString(pagerange, &pageArray, nCount)) return FALSE; } else { for (int i = 1; i <= nCount; ++i) { pageArray.Add(i); } } CPDF_PageOrganizer pageOrg; pageOrg.PDFDocInit(pDestDoc, pSrcDoc); return pageOrg.ExportPage(pSrcDoc, &pageArray, pDestDoc, index); }
DLLEXPORT int FPDFDoc_GetPageMode(FPDF_DOCUMENT document) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return PAGEMODE_UNKNOWN; CPDF_Dictionary* pRoot = pDoc->GetRoot(); if (!pRoot) return PAGEMODE_UNKNOWN; CPDF_Object* pName = pRoot->GetElement("PageMode"); if (!pName) return PAGEMODE_USENONE; CFX_ByteString strPageMode = pName->GetString(); if (strPageMode.IsEmpty() || strPageMode.EqualNoCase("UseNone")) return PAGEMODE_USENONE; if (strPageMode.EqualNoCase("UseOutlines")) return PAGEMODE_USEOUTLINES; if (strPageMode.EqualNoCase("UseThumbs")) return PAGEMODE_USETHUMBS; if (strPageMode.EqualNoCase("FullScreen")) return PAGEMODE_FULLSCREEN; if (strPageMode.EqualNoCase("UseOC")) return PAGEMODE_USEOC; if (strPageMode.EqualNoCase("UseAttachments")) return PAGEMODE_USEATTACHMENTS; return PAGEMODE_UNKNOWN; }
DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc || page_index < 0 || page_index >= pDoc->GetPageCount()) return; pDoc->DeletePage(page_index); }
DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index, double width, double height) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; if (page_index < 0) page_index = 0; if (pDoc->GetPageCount() < page_index) page_index = pDoc->GetPageCount(); CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index); if (!pPageDict) return NULL; CPDF_Array* pMediaBoxArray = new CPDF_Array; pMediaBoxArray->Add(new CPDF_Number(0)); pMediaBoxArray->Add(new CPDF_Number(0)); pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width))); pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height))); pPageDict->SetAt("MediaBox", pMediaBoxArray); pPageDict->SetAt("Rotate", new CPDF_Number(0)); pPageDict->SetAt("Resources", new CPDF_Dictionary); CPDF_Page* pPage = new CPDF_Page; pPage->Load(pDoc, pPageDict); pPage->ParseContent(); return pPage; }
DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index, double width, double height) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; page_index = std::min(std::max(page_index, 0), pDoc->GetPageCount()); CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(page_index); if (!pPageDict) return nullptr; CPDF_Array* pMediaBoxArray = new CPDF_Array; pMediaBoxArray->Add(new CPDF_Number(0)); pMediaBoxArray->Add(new CPDF_Number(0)); pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(width))); pMediaBoxArray->Add(new CPDF_Number(FX_FLOAT(height))); pPageDict->SetAt("MediaBox", pMediaBoxArray); pPageDict->SetAt("Rotate", new CPDF_Number(0)); pPageDict->SetAt("Resources", new CPDF_Dictionary); #ifdef PDF_ENABLE_XFA CPDFXFA_Page* pPage = new CPDFXFA_Page((CPDFXFA_Document*)document, page_index); pPage->LoadPDFPage(pPageDict); #else // PDF_ENABLE_XFA CPDF_Page* pPage = new CPDF_Page(pDoc, pPageDict, true); pPage->ParseContent(); #endif // PDF_ENABLE_XFA return pPage; }
FPDF_EXPORT FPDF_BOOKMARK FPDF_CALLCONV FPDFBookmark_GetFirstChild(FPDF_DOCUMENT document, FPDF_BOOKMARK pDict) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; CPDF_BookmarkTree tree(pDoc); CPDF_Bookmark bookmark(CPDFDictionaryFromFPDFBookmark(pDict)); return FPDFBookmarkFromCPDFDictionary(tree.GetFirstChild(bookmark).GetDict()); }
DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_NewImgeObj(FPDF_DOCUMENT document) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; CPDF_ImageObject* pImageObj = new CPDF_ImageObject; pImageObj->SetOwnedImage(pdfium::MakeUnique<CPDF_Image>(pDoc)); return pImageObj; }
DLLEXPORT unsigned long STDCALL FPDFDest_GetPageIndex(FPDF_DOCUMENT document, FPDF_DEST pDict) { if (!pDict) return 0; CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return 0; CPDF_Dest dest(static_cast<CPDF_Array*>(pDict)); return dest.GetPageIndex(pDoc); }
DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_GetFirstChild(FPDF_DOCUMENT document, FPDF_BOOKMARK pDict) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; CPDF_BookmarkTree tree(pDoc); CPDF_Bookmark bookmark = CPDF_Bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict))); return tree.GetFirstChild(bookmark).GetDict(); }
DLLEXPORT FPDF_DEST STDCALL FPDFAction_GetDest(FPDF_DOCUMENT document, FPDF_ACTION pDict) { if (!pDict) return nullptr; CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict))); return action.GetDest(pDoc).GetObject(); }
FPDF_EXPORT int FPDF_CALLCONV FPDFDest_GetDestPageIndex(FPDF_DOCUMENT document, FPDF_DEST dest) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return -1; if (!dest) return -1; CPDF_Dest destination(CPDFArrayFromFPDFDest(dest)); return destination.GetDestPageIndex(pDoc); }
DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document, FPDF_WIDESTRING title) { if (!title || title[0] == 0) return nullptr; CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; CPDF_BookmarkTree tree(pDoc); FX_STRSIZE len = CFX_WideString::WStringLength(title); CFX_WideString encodedTitle = CFX_WideString::FromUTF16LE(title, len); return FindBookmark(tree, CPDF_Bookmark(), encodedTitle).GetDict(); }
DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, FPDF_DOCUMENT src_doc) { CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc); if (!pDstDoc) return FALSE; CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); if (!pSrcDoc) return FALSE; CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot(); pSrcDict = pSrcDict->GetDict(FX_BSTRC("ViewerPreferences")); if (!pSrcDict) return FALSE; CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); if (!pDstDict) return FALSE; pDstDict->SetAt(FX_BSTRC("ViewerPreferences"), pSrcDict->Clone(TRUE)); return TRUE; }
FPDF_EXPORT FPDF_DEST FPDF_CALLCONV FPDFAction_GetDest(FPDF_DOCUMENT document, FPDF_ACTION pDict) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; unsigned long type = FPDFAction_GetType(pDict); if (type != PDFACTION_GOTO && type != PDFACTION_REMOTEGOTO) return nullptr; CPDF_Action action(CPDFDictionaryFromFPDFAction(pDict)); return FPDFDestFromCPDFArray(action.GetDest(pDoc).GetArray()); }
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_GetPageLabel(FPDF_DOCUMENT document, int page_index, void* buffer, unsigned long buflen) { if (page_index < 0) return 0; // CPDF_PageLabel can deal with NULL |document|. CPDF_PageLabel label(CPDFDocumentFromFPDFDocument(document)); Optional<WideString> str = label.GetLabel(page_index); return str.has_value() ? Utf16EncodeMaybeCopyAndReturnLength(str.value(), buffer, buflen) : 0; }
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_GetMetaText(FPDF_DOCUMENT document, FPDF_BYTESTRING tag, void* buffer, unsigned long buflen) { if (!tag) return 0; CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return 0; const CPDF_Dictionary* pInfo = pDoc->GetInfo(); if (!pInfo) return 0; WideString text = pInfo->GetUnicodeTextFor(tag); return Utf16EncodeMaybeCopyAndReturnLength(text, buffer, buflen); }
FPDF_EXPORT FPDF_BOOKMARK FPDF_CALLCONV FPDFBookmark_Find(FPDF_DOCUMENT document, FPDF_WIDESTRING title) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; if (!title || title[0] == 0) return nullptr; CPDF_BookmarkTree tree(pDoc); size_t len = WideString::WStringLength(title); WideString encodedTitle = WideString::FromUTF16LE(title, len); std::set<const CPDF_Dictionary*> visited; return FPDFBookmarkFromCPDFDictionary( FindBookmark(tree, CPDF_Bookmark(), encodedTitle, &visited).GetDict()); }
DLLEXPORT unsigned long STDCALL FPDFAction_GetURIPath(FPDF_DOCUMENT document, FPDF_ACTION pDict, void* buffer, unsigned long buflen) { if (!pDict) return 0; CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return 0; CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict))); CFX_ByteString path = action.GetURI(pDoc); unsigned long len = path.GetLength() + 1; if (buffer && buflen >= len) FXSYS_memcpy(buffer, path.c_str(), len); return len; }
FPDF_EXPORT FPDF_DEST FPDF_CALLCONV FPDFLink_GetDest(FPDF_DOCUMENT document, FPDF_LINK pDict) { if (!pDict) return nullptr; CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; CPDF_Link link(CPDFDictionaryFromFPDFLink(pDict)); FPDF_DEST dest = FPDFDestFromCPDFArray(link.GetDest(pDoc).GetArray()); if (dest) return dest; // If this link is not directly associated with a dest, we try to get action CPDF_Action action = link.GetAction(); if (!action.GetDict()) return nullptr; return FPDFDestFromCPDFArray(action.GetDest(pDoc).GetArray()); }
DLLEXPORT FPDF_DEST STDCALL FPDFLink_GetDest(FPDF_DOCUMENT document, FPDF_LINK pDict) { if (!pDict) return nullptr; CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; CPDF_Link link(ToDictionary(static_cast<CPDF_Object*>(pDict))); FPDF_DEST dest = link.GetDest(pDoc).GetObject(); if (dest) return dest; // If this link is not directly associated with a dest, we try to get action CPDF_Action action = link.GetAction(); if (!action.GetDict()) return nullptr; return action.GetDest(pDoc).GetObject(); }
DLLEXPORT FPDF_DEST STDCALL FPDFBookmark_GetDest(FPDF_DOCUMENT document, FPDF_BOOKMARK pDict) { if (!pDict) return nullptr; CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict))); CPDF_Dest dest = bookmark.GetDest(pDoc); if (dest.GetObject()) return dest.GetObject(); // If this bookmark is not directly associated with a dest, we try to get // action CPDF_Action action = bookmark.GetAction(); if (!action.GetDict()) return nullptr; return action.GetDest(pDoc).GetObject(); }
TEST_F(FPDFDocEmbedderTest, MultipleSamePage) { EXPECT_TRUE(OpenDocument("hello_world.pdf")); CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document()); std::set<FPDF_PAGE> unique_pages; std::vector<ScopedFPDFPage> owned_pages(4); for (auto& ref : owned_pages) { ref.reset(FPDF_LoadPage(document(), 0)); unique_pages.insert(ref.get()); } #ifdef PDF_ENABLE_XFA EXPECT_EQ(1u, unique_pages.size()); EXPECT_EQ(1u, pDoc->GetParsedPageCountForTesting()); #else // PDF_ENABLE_XFA EXPECT_EQ(4u, unique_pages.size()); EXPECT_EQ(4u, pDoc->GetParsedPageCountForTesting()); #endif // PDF_ENABLE_XFA }
FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document, FPDF_FILEWRITE* pFileWrite, FPDF_DWORD flags, FPDF_BOOL bSetVersion, int fileVerion) { CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document); if (!pPDFDoc) return 0; #ifdef PDF_ENABLE_XFA CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document; CFX_PtrArray fileList; _SendPreSaveToXFADoc(pDoc, fileList); #endif // PDF_ENABLE_XFA if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY) { flags = 0; } CPDF_Creator FileMaker(pPDFDoc); if (bSetVersion) FileMaker.SetFileVersion(fileVerion); if (flags == FPDF_REMOVE_SECURITY) { flags = 0; FileMaker.RemoveSecurity(); } CFX_IFileWrite* pStreamWrite = NULL; FX_BOOL bRet; pStreamWrite = new CFX_IFileWrite; pStreamWrite->Init(pFileWrite); bRet = FileMaker.Create(pStreamWrite, flags); #ifdef PDF_ENABLE_XFA _SendPostSaveToXFADoc(pDoc); for (int i = 0; i < fileList.GetSize(); i++) { IFX_FileStream* pFile = (IFX_FileStream*)fileList.GetAt(i); pFile->Release(); } fileList.RemoveAll(); #endif // PDF_ENABLE_XFA pStreamWrite->Release(); return bRet; }
FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAction_GetURIPath(FPDF_DOCUMENT document, FPDF_ACTION pDict, void* buffer, unsigned long buflen) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return 0; unsigned long type = FPDFAction_GetType(pDict); if (type != PDFACTION_URI) return 0; CPDF_Action action(CPDFDictionaryFromFPDFAction(pDict)); ByteString path = action.GetURI(pDoc); unsigned long len = path.GetLength() + 1; if (buffer && len <= buflen) memcpy(buffer, path.c_str(), len); return len; }
FPDF_EXPORT FPDF_DEST FPDF_CALLCONV FPDFBookmark_GetDest(FPDF_DOCUMENT document, FPDF_BOOKMARK pDict) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); if (!pDoc) return nullptr; if (!pDict) return nullptr; CPDF_Bookmark bookmark(CPDFDictionaryFromFPDFBookmark(pDict)); CPDF_Dest dest = bookmark.GetDest(pDoc); if (dest.GetArray()) return FPDFDestFromCPDFArray(dest.GetArray()); // If this bookmark is not directly associated with a dest, we try to get // action CPDF_Action action = bookmark.GetAction(); if (!action.GetDict()) return nullptr; return FPDFDestFromCPDFArray(action.GetDest(pDoc).GetArray()); }
DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT doc, FPDF_BYTESTRING tag, void* buffer, unsigned long buflen) { if (!tag) return 0; CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc); if (!pDoc) return 0; CPDF_Dictionary* pInfo = pDoc->GetInfo(); if (!pInfo) return 0; CFX_WideString text = pInfo->GetUnicodeTextFor(tag); // Use UTF-16LE encoding CFX_ByteString encodedText = text.UTF16LE_Encode(); unsigned long len = encodedText.GetLength(); if (buffer && buflen >= len) { FXSYS_memcpy(buffer, encodedText.c_str(), len); } return len; }
DLLEXPORT int STDCALL FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc) { CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc); return pDoc ? pDoc->GetParser()->GetFirstPageNo() : 0; }