1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2014 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdf_doc.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
10*3ac0a46fSAndroid Build Coastguard Worker #include <set>
11*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
12*3ac0a46fSAndroid Build Coastguard Worker
13*3ac0a46fSAndroid Build Coastguard Worker #include "constants/form_fields.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/page/cpdf_annotcontext.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/page/cpdf_page.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_array.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_dictionary.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_document.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_number.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/cpdf_string.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfapi/parser/fpdf_parser_decode.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_aaction.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_bookmark.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_bookmarktree.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_dest.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_linklist.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "core/fpdfdoc/cpdf_pagelabel.h"
28*3ac0a46fSAndroid Build Coastguard Worker #include "fpdfsdk/cpdfsdk_helpers.h"
29*3ac0a46fSAndroid Build Coastguard Worker #include "public/fpdf_formfill.h"
30*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
31*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/containers/contains.h"
32*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/numerics/safe_conversions.h"
33*3ac0a46fSAndroid Build Coastguard Worker
34*3ac0a46fSAndroid Build Coastguard Worker namespace {
35*3ac0a46fSAndroid Build Coastguard Worker
FindBookmark(const CPDF_BookmarkTree & tree,CPDF_Bookmark bookmark,const WideString & title,std::set<const CPDF_Dictionary * > * visited)36*3ac0a46fSAndroid Build Coastguard Worker CPDF_Bookmark FindBookmark(const CPDF_BookmarkTree& tree,
37*3ac0a46fSAndroid Build Coastguard Worker CPDF_Bookmark bookmark,
38*3ac0a46fSAndroid Build Coastguard Worker const WideString& title,
39*3ac0a46fSAndroid Build Coastguard Worker std::set<const CPDF_Dictionary*>* visited) {
40*3ac0a46fSAndroid Build Coastguard Worker // Return if already checked to avoid circular calling.
41*3ac0a46fSAndroid Build Coastguard Worker if (pdfium::Contains(*visited, bookmark.GetDict()))
42*3ac0a46fSAndroid Build Coastguard Worker return CPDF_Bookmark();
43*3ac0a46fSAndroid Build Coastguard Worker visited->insert(bookmark.GetDict());
44*3ac0a46fSAndroid Build Coastguard Worker
45*3ac0a46fSAndroid Build Coastguard Worker if (bookmark.GetDict() &&
46*3ac0a46fSAndroid Build Coastguard Worker bookmark.GetTitle().CompareNoCase(title.c_str()) == 0) {
47*3ac0a46fSAndroid Build Coastguard Worker // First check this item.
48*3ac0a46fSAndroid Build Coastguard Worker return bookmark;
49*3ac0a46fSAndroid Build Coastguard Worker }
50*3ac0a46fSAndroid Build Coastguard Worker
51*3ac0a46fSAndroid Build Coastguard Worker // Go into children items.
52*3ac0a46fSAndroid Build Coastguard Worker CPDF_Bookmark child = tree.GetFirstChild(bookmark);
53*3ac0a46fSAndroid Build Coastguard Worker while (child.GetDict() && !pdfium::Contains(*visited, child.GetDict())) {
54*3ac0a46fSAndroid Build Coastguard Worker // Check this item and its children.
55*3ac0a46fSAndroid Build Coastguard Worker CPDF_Bookmark found = FindBookmark(tree, child, title, visited);
56*3ac0a46fSAndroid Build Coastguard Worker if (found.GetDict())
57*3ac0a46fSAndroid Build Coastguard Worker return found;
58*3ac0a46fSAndroid Build Coastguard Worker child = tree.GetNextSibling(child);
59*3ac0a46fSAndroid Build Coastguard Worker }
60*3ac0a46fSAndroid Build Coastguard Worker return CPDF_Bookmark();
61*3ac0a46fSAndroid Build Coastguard Worker }
62*3ac0a46fSAndroid Build Coastguard Worker
GetLinkList(CPDF_Page * page)63*3ac0a46fSAndroid Build Coastguard Worker CPDF_LinkList* GetLinkList(CPDF_Page* page) {
64*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = page->GetDocument();
65*3ac0a46fSAndroid Build Coastguard Worker auto* pList = static_cast<CPDF_LinkList*>(pDoc->GetLinksContext());
66*3ac0a46fSAndroid Build Coastguard Worker if (pList)
67*3ac0a46fSAndroid Build Coastguard Worker return pList;
68*3ac0a46fSAndroid Build Coastguard Worker
69*3ac0a46fSAndroid Build Coastguard Worker auto pNewList = std::make_unique<CPDF_LinkList>();
70*3ac0a46fSAndroid Build Coastguard Worker pList = pNewList.get();
71*3ac0a46fSAndroid Build Coastguard Worker pDoc->SetLinksContext(std::move(pNewList));
72*3ac0a46fSAndroid Build Coastguard Worker return pList;
73*3ac0a46fSAndroid Build Coastguard Worker }
74*3ac0a46fSAndroid Build Coastguard Worker
75*3ac0a46fSAndroid Build Coastguard Worker } // namespace
76*3ac0a46fSAndroid Build Coastguard Worker
77*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_BOOKMARK FPDF_CALLCONV
FPDFBookmark_GetFirstChild(FPDF_DOCUMENT document,FPDF_BOOKMARK bookmark)78*3ac0a46fSAndroid Build Coastguard Worker FPDFBookmark_GetFirstChild(FPDF_DOCUMENT document, FPDF_BOOKMARK bookmark) {
79*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
80*3ac0a46fSAndroid Build Coastguard Worker if (!pDoc)
81*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
82*3ac0a46fSAndroid Build Coastguard Worker CPDF_BookmarkTree tree(pDoc);
83*3ac0a46fSAndroid Build Coastguard Worker CPDF_Bookmark cBookmark(
84*3ac0a46fSAndroid Build Coastguard Worker pdfium::WrapRetain(CPDFDictionaryFromFPDFBookmark(bookmark)));
85*3ac0a46fSAndroid Build Coastguard Worker return FPDFBookmarkFromCPDFDictionary(
86*3ac0a46fSAndroid Build Coastguard Worker tree.GetFirstChild(cBookmark).GetDict());
87*3ac0a46fSAndroid Build Coastguard Worker }
88*3ac0a46fSAndroid Build Coastguard Worker
89*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_BOOKMARK FPDF_CALLCONV
FPDFBookmark_GetNextSibling(FPDF_DOCUMENT document,FPDF_BOOKMARK bookmark)90*3ac0a46fSAndroid Build Coastguard Worker FPDFBookmark_GetNextSibling(FPDF_DOCUMENT document, FPDF_BOOKMARK bookmark) {
91*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
92*3ac0a46fSAndroid Build Coastguard Worker if (!pDoc)
93*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
94*3ac0a46fSAndroid Build Coastguard Worker
95*3ac0a46fSAndroid Build Coastguard Worker if (!bookmark)
96*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
97*3ac0a46fSAndroid Build Coastguard Worker
98*3ac0a46fSAndroid Build Coastguard Worker CPDF_BookmarkTree tree(pDoc);
99*3ac0a46fSAndroid Build Coastguard Worker CPDF_Bookmark cBookmark(
100*3ac0a46fSAndroid Build Coastguard Worker pdfium::WrapRetain(CPDFDictionaryFromFPDFBookmark(bookmark)));
101*3ac0a46fSAndroid Build Coastguard Worker return FPDFBookmarkFromCPDFDictionary(
102*3ac0a46fSAndroid Build Coastguard Worker tree.GetNextSibling(cBookmark).GetDict());
103*3ac0a46fSAndroid Build Coastguard Worker }
104*3ac0a46fSAndroid Build Coastguard Worker
105*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFBookmark_GetTitle(FPDF_BOOKMARK bookmark,void * buffer,unsigned long buflen)106*3ac0a46fSAndroid Build Coastguard Worker FPDFBookmark_GetTitle(FPDF_BOOKMARK bookmark,
107*3ac0a46fSAndroid Build Coastguard Worker void* buffer,
108*3ac0a46fSAndroid Build Coastguard Worker unsigned long buflen) {
109*3ac0a46fSAndroid Build Coastguard Worker if (!bookmark)
110*3ac0a46fSAndroid Build Coastguard Worker return 0;
111*3ac0a46fSAndroid Build Coastguard Worker CPDF_Bookmark cBookmark(
112*3ac0a46fSAndroid Build Coastguard Worker pdfium::WrapRetain(CPDFDictionaryFromFPDFBookmark(bookmark)));
113*3ac0a46fSAndroid Build Coastguard Worker WideString title = cBookmark.GetTitle();
114*3ac0a46fSAndroid Build Coastguard Worker return Utf16EncodeMaybeCopyAndReturnLength(title, buffer, buflen);
115*3ac0a46fSAndroid Build Coastguard Worker }
116*3ac0a46fSAndroid Build Coastguard Worker
FPDFBookmark_GetCount(FPDF_BOOKMARK bookmark)117*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT int FPDF_CALLCONV FPDFBookmark_GetCount(FPDF_BOOKMARK bookmark) {
118*3ac0a46fSAndroid Build Coastguard Worker if (!bookmark)
119*3ac0a46fSAndroid Build Coastguard Worker return 0;
120*3ac0a46fSAndroid Build Coastguard Worker CPDF_Bookmark cBookmark(
121*3ac0a46fSAndroid Build Coastguard Worker pdfium::WrapRetain(CPDFDictionaryFromFPDFBookmark(bookmark)));
122*3ac0a46fSAndroid Build Coastguard Worker return cBookmark.GetCount();
123*3ac0a46fSAndroid Build Coastguard Worker }
124*3ac0a46fSAndroid Build Coastguard Worker
125*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_BOOKMARK FPDF_CALLCONV
FPDFBookmark_Find(FPDF_DOCUMENT document,FPDF_WIDESTRING title)126*3ac0a46fSAndroid Build Coastguard Worker FPDFBookmark_Find(FPDF_DOCUMENT document, FPDF_WIDESTRING title) {
127*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
128*3ac0a46fSAndroid Build Coastguard Worker if (!pDoc)
129*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
130*3ac0a46fSAndroid Build Coastguard Worker
131*3ac0a46fSAndroid Build Coastguard Worker WideString encodedTitle = WideStringFromFPDFWideString(title);
132*3ac0a46fSAndroid Build Coastguard Worker if (encodedTitle.IsEmpty())
133*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
134*3ac0a46fSAndroid Build Coastguard Worker
135*3ac0a46fSAndroid Build Coastguard Worker CPDF_BookmarkTree tree(pDoc);
136*3ac0a46fSAndroid Build Coastguard Worker std::set<const CPDF_Dictionary*> visited;
137*3ac0a46fSAndroid Build Coastguard Worker return FPDFBookmarkFromCPDFDictionary(
138*3ac0a46fSAndroid Build Coastguard Worker FindBookmark(tree, CPDF_Bookmark(), encodedTitle, &visited).GetDict());
139*3ac0a46fSAndroid Build Coastguard Worker }
140*3ac0a46fSAndroid Build Coastguard Worker
141*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_DEST FPDF_CALLCONV
FPDFBookmark_GetDest(FPDF_DOCUMENT document,FPDF_BOOKMARK bookmark)142*3ac0a46fSAndroid Build Coastguard Worker FPDFBookmark_GetDest(FPDF_DOCUMENT document, FPDF_BOOKMARK bookmark) {
143*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
144*3ac0a46fSAndroid Build Coastguard Worker if (!pDoc)
145*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
146*3ac0a46fSAndroid Build Coastguard Worker
147*3ac0a46fSAndroid Build Coastguard Worker if (!bookmark)
148*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
149*3ac0a46fSAndroid Build Coastguard Worker
150*3ac0a46fSAndroid Build Coastguard Worker CPDF_Bookmark cBookmark(
151*3ac0a46fSAndroid Build Coastguard Worker pdfium::WrapRetain(CPDFDictionaryFromFPDFBookmark(bookmark)));
152*3ac0a46fSAndroid Build Coastguard Worker CPDF_Dest dest = cBookmark.GetDest(pDoc);
153*3ac0a46fSAndroid Build Coastguard Worker if (dest.GetArray())
154*3ac0a46fSAndroid Build Coastguard Worker return FPDFDestFromCPDFArray(dest.GetArray());
155*3ac0a46fSAndroid Build Coastguard Worker // If this bookmark is not directly associated with a dest, we try to get
156*3ac0a46fSAndroid Build Coastguard Worker // action
157*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action action = cBookmark.GetAction();
158*3ac0a46fSAndroid Build Coastguard Worker if (!action.HasDict())
159*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
160*3ac0a46fSAndroid Build Coastguard Worker return FPDFDestFromCPDFArray(action.GetDest(pDoc).GetArray());
161*3ac0a46fSAndroid Build Coastguard Worker }
162*3ac0a46fSAndroid Build Coastguard Worker
163*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_ACTION FPDF_CALLCONV
FPDFBookmark_GetAction(FPDF_BOOKMARK bookmark)164*3ac0a46fSAndroid Build Coastguard Worker FPDFBookmark_GetAction(FPDF_BOOKMARK bookmark) {
165*3ac0a46fSAndroid Build Coastguard Worker if (!bookmark)
166*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
167*3ac0a46fSAndroid Build Coastguard Worker
168*3ac0a46fSAndroid Build Coastguard Worker CPDF_Bookmark cBookmark(
169*3ac0a46fSAndroid Build Coastguard Worker pdfium::WrapRetain(CPDFDictionaryFromFPDFBookmark(bookmark)));
170*3ac0a46fSAndroid Build Coastguard Worker return FPDFActionFromCPDFDictionary(cBookmark.GetAction().GetDict());
171*3ac0a46fSAndroid Build Coastguard Worker }
172*3ac0a46fSAndroid Build Coastguard Worker
FPDFAction_GetType(FPDF_ACTION action)173*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT unsigned long FPDF_CALLCONV FPDFAction_GetType(FPDF_ACTION action) {
174*3ac0a46fSAndroid Build Coastguard Worker if (!action)
175*3ac0a46fSAndroid Build Coastguard Worker return PDFACTION_UNSUPPORTED;
176*3ac0a46fSAndroid Build Coastguard Worker
177*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action cAction(pdfium::WrapRetain(CPDFDictionaryFromFPDFAction(action)));
178*3ac0a46fSAndroid Build Coastguard Worker switch (cAction.GetType()) {
179*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kGoTo:
180*3ac0a46fSAndroid Build Coastguard Worker return PDFACTION_GOTO;
181*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kGoToR:
182*3ac0a46fSAndroid Build Coastguard Worker return PDFACTION_REMOTEGOTO;
183*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kGoToE:
184*3ac0a46fSAndroid Build Coastguard Worker return PDFACTION_EMBEDDEDGOTO;
185*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kURI:
186*3ac0a46fSAndroid Build Coastguard Worker return PDFACTION_URI;
187*3ac0a46fSAndroid Build Coastguard Worker case CPDF_Action::Type::kLaunch:
188*3ac0a46fSAndroid Build Coastguard Worker return PDFACTION_LAUNCH;
189*3ac0a46fSAndroid Build Coastguard Worker default:
190*3ac0a46fSAndroid Build Coastguard Worker return PDFACTION_UNSUPPORTED;
191*3ac0a46fSAndroid Build Coastguard Worker }
192*3ac0a46fSAndroid Build Coastguard Worker }
193*3ac0a46fSAndroid Build Coastguard Worker
FPDFAction_GetDest(FPDF_DOCUMENT document,FPDF_ACTION action)194*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_DEST FPDF_CALLCONV FPDFAction_GetDest(FPDF_DOCUMENT document,
195*3ac0a46fSAndroid Build Coastguard Worker FPDF_ACTION action) {
196*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
197*3ac0a46fSAndroid Build Coastguard Worker if (!pDoc)
198*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
199*3ac0a46fSAndroid Build Coastguard Worker
200*3ac0a46fSAndroid Build Coastguard Worker unsigned long type = FPDFAction_GetType(action);
201*3ac0a46fSAndroid Build Coastguard Worker if (type != PDFACTION_GOTO && type != PDFACTION_REMOTEGOTO &&
202*3ac0a46fSAndroid Build Coastguard Worker type != PDFACTION_EMBEDDEDGOTO) {
203*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
204*3ac0a46fSAndroid Build Coastguard Worker }
205*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action cAction(pdfium::WrapRetain(CPDFDictionaryFromFPDFAction(action)));
206*3ac0a46fSAndroid Build Coastguard Worker return FPDFDestFromCPDFArray(cAction.GetDest(pDoc).GetArray());
207*3ac0a46fSAndroid Build Coastguard Worker }
208*3ac0a46fSAndroid Build Coastguard Worker
209*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFAction_GetFilePath(FPDF_ACTION action,void * buffer,unsigned long buflen)210*3ac0a46fSAndroid Build Coastguard Worker FPDFAction_GetFilePath(FPDF_ACTION action, void* buffer, unsigned long buflen) {
211*3ac0a46fSAndroid Build Coastguard Worker unsigned long type = FPDFAction_GetType(action);
212*3ac0a46fSAndroid Build Coastguard Worker if (type != PDFACTION_REMOTEGOTO && type != PDFACTION_EMBEDDEDGOTO &&
213*3ac0a46fSAndroid Build Coastguard Worker type != PDFACTION_LAUNCH) {
214*3ac0a46fSAndroid Build Coastguard Worker return 0;
215*3ac0a46fSAndroid Build Coastguard Worker }
216*3ac0a46fSAndroid Build Coastguard Worker
217*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action cAction(pdfium::WrapRetain(CPDFDictionaryFromFPDFAction(action)));
218*3ac0a46fSAndroid Build Coastguard Worker ByteString path = cAction.GetFilePath().ToUTF8();
219*3ac0a46fSAndroid Build Coastguard Worker return NulTerminateMaybeCopyAndReturnLength(path, buffer, buflen);
220*3ac0a46fSAndroid Build Coastguard Worker }
221*3ac0a46fSAndroid Build Coastguard Worker
222*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFAction_GetURIPath(FPDF_DOCUMENT document,FPDF_ACTION action,void * buffer,unsigned long buflen)223*3ac0a46fSAndroid Build Coastguard Worker FPDFAction_GetURIPath(FPDF_DOCUMENT document,
224*3ac0a46fSAndroid Build Coastguard Worker FPDF_ACTION action,
225*3ac0a46fSAndroid Build Coastguard Worker void* buffer,
226*3ac0a46fSAndroid Build Coastguard Worker unsigned long buflen) {
227*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
228*3ac0a46fSAndroid Build Coastguard Worker if (!pDoc)
229*3ac0a46fSAndroid Build Coastguard Worker return 0;
230*3ac0a46fSAndroid Build Coastguard Worker
231*3ac0a46fSAndroid Build Coastguard Worker unsigned long type = FPDFAction_GetType(action);
232*3ac0a46fSAndroid Build Coastguard Worker if (type != PDFACTION_URI)
233*3ac0a46fSAndroid Build Coastguard Worker return 0;
234*3ac0a46fSAndroid Build Coastguard Worker
235*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action cAction(pdfium::WrapRetain(CPDFDictionaryFromFPDFAction(action)));
236*3ac0a46fSAndroid Build Coastguard Worker ByteString path = cAction.GetURI(pDoc);
237*3ac0a46fSAndroid Build Coastguard Worker
238*3ac0a46fSAndroid Build Coastguard Worker const unsigned long len =
239*3ac0a46fSAndroid Build Coastguard Worker pdfium::base::checked_cast<unsigned long>(path.GetLength() + 1);
240*3ac0a46fSAndroid Build Coastguard Worker if (buffer && len <= buflen)
241*3ac0a46fSAndroid Build Coastguard Worker memcpy(buffer, path.c_str(), len);
242*3ac0a46fSAndroid Build Coastguard Worker return len;
243*3ac0a46fSAndroid Build Coastguard Worker }
244*3ac0a46fSAndroid Build Coastguard Worker
FPDFDest_GetDestPageIndex(FPDF_DOCUMENT document,FPDF_DEST dest)245*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT int FPDF_CALLCONV FPDFDest_GetDestPageIndex(FPDF_DOCUMENT document,
246*3ac0a46fSAndroid Build Coastguard Worker FPDF_DEST dest) {
247*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
248*3ac0a46fSAndroid Build Coastguard Worker if (!pDoc)
249*3ac0a46fSAndroid Build Coastguard Worker return -1;
250*3ac0a46fSAndroid Build Coastguard Worker
251*3ac0a46fSAndroid Build Coastguard Worker if (!dest)
252*3ac0a46fSAndroid Build Coastguard Worker return -1;
253*3ac0a46fSAndroid Build Coastguard Worker
254*3ac0a46fSAndroid Build Coastguard Worker CPDF_Dest destination(pdfium::WrapRetain(CPDFArrayFromFPDFDest(dest)));
255*3ac0a46fSAndroid Build Coastguard Worker return destination.GetDestPageIndex(pDoc);
256*3ac0a46fSAndroid Build Coastguard Worker }
257*3ac0a46fSAndroid Build Coastguard Worker
258*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFDest_GetView(FPDF_DEST dest,unsigned long * pNumParams,FS_FLOAT * pParams)259*3ac0a46fSAndroid Build Coastguard Worker FPDFDest_GetView(FPDF_DEST dest, unsigned long* pNumParams, FS_FLOAT* pParams) {
260*3ac0a46fSAndroid Build Coastguard Worker if (!dest) {
261*3ac0a46fSAndroid Build Coastguard Worker *pNumParams = 0;
262*3ac0a46fSAndroid Build Coastguard Worker return 0;
263*3ac0a46fSAndroid Build Coastguard Worker }
264*3ac0a46fSAndroid Build Coastguard Worker
265*3ac0a46fSAndroid Build Coastguard Worker CPDF_Dest destination(pdfium::WrapRetain(CPDFArrayFromFPDFDest(dest)));
266*3ac0a46fSAndroid Build Coastguard Worker const unsigned long nParams =
267*3ac0a46fSAndroid Build Coastguard Worker pdfium::base::checked_cast<unsigned long>(destination.GetNumParams());
268*3ac0a46fSAndroid Build Coastguard Worker DCHECK(nParams <= 4);
269*3ac0a46fSAndroid Build Coastguard Worker *pNumParams = nParams;
270*3ac0a46fSAndroid Build Coastguard Worker for (unsigned long i = 0; i < nParams; ++i)
271*3ac0a46fSAndroid Build Coastguard Worker pParams[i] = destination.GetParam(i);
272*3ac0a46fSAndroid Build Coastguard Worker return destination.GetZoomMode();
273*3ac0a46fSAndroid Build Coastguard Worker }
274*3ac0a46fSAndroid Build Coastguard Worker
275*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFDest_GetLocationInPage(FPDF_DEST dest,FPDF_BOOL * hasXVal,FPDF_BOOL * hasYVal,FPDF_BOOL * hasZoomVal,FS_FLOAT * x,FS_FLOAT * y,FS_FLOAT * zoom)276*3ac0a46fSAndroid Build Coastguard Worker FPDFDest_GetLocationInPage(FPDF_DEST dest,
277*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL* hasXVal,
278*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL* hasYVal,
279*3ac0a46fSAndroid Build Coastguard Worker FPDF_BOOL* hasZoomVal,
280*3ac0a46fSAndroid Build Coastguard Worker FS_FLOAT* x,
281*3ac0a46fSAndroid Build Coastguard Worker FS_FLOAT* y,
282*3ac0a46fSAndroid Build Coastguard Worker FS_FLOAT* zoom) {
283*3ac0a46fSAndroid Build Coastguard Worker if (!dest)
284*3ac0a46fSAndroid Build Coastguard Worker return false;
285*3ac0a46fSAndroid Build Coastguard Worker
286*3ac0a46fSAndroid Build Coastguard Worker CPDF_Dest destination(pdfium::WrapRetain(CPDFArrayFromFPDFDest(dest)));
287*3ac0a46fSAndroid Build Coastguard Worker
288*3ac0a46fSAndroid Build Coastguard Worker // FPDF_BOOL is an int, GetXYZ expects bools.
289*3ac0a46fSAndroid Build Coastguard Worker bool bHasX;
290*3ac0a46fSAndroid Build Coastguard Worker bool bHasY;
291*3ac0a46fSAndroid Build Coastguard Worker bool bHasZoom;
292*3ac0a46fSAndroid Build Coastguard Worker if (!destination.GetXYZ(&bHasX, &bHasY, &bHasZoom, x, y, zoom))
293*3ac0a46fSAndroid Build Coastguard Worker return false;
294*3ac0a46fSAndroid Build Coastguard Worker
295*3ac0a46fSAndroid Build Coastguard Worker *hasXVal = bHasX;
296*3ac0a46fSAndroid Build Coastguard Worker *hasYVal = bHasY;
297*3ac0a46fSAndroid Build Coastguard Worker *hasZoomVal = bHasZoom;
298*3ac0a46fSAndroid Build Coastguard Worker return true;
299*3ac0a46fSAndroid Build Coastguard Worker }
300*3ac0a46fSAndroid Build Coastguard Worker
FPDFLink_GetLinkAtPoint(FPDF_PAGE page,double x,double y)301*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_LINK FPDF_CALLCONV FPDFLink_GetLinkAtPoint(FPDF_PAGE page,
302*3ac0a46fSAndroid Build Coastguard Worker double x,
303*3ac0a46fSAndroid Build Coastguard Worker double y) {
304*3ac0a46fSAndroid Build Coastguard Worker CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
305*3ac0a46fSAndroid Build Coastguard Worker if (!pPage)
306*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
307*3ac0a46fSAndroid Build Coastguard Worker
308*3ac0a46fSAndroid Build Coastguard Worker CPDF_LinkList* pLinkList = GetLinkList(pPage);
309*3ac0a46fSAndroid Build Coastguard Worker if (!pLinkList)
310*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
311*3ac0a46fSAndroid Build Coastguard Worker
312*3ac0a46fSAndroid Build Coastguard Worker CPDF_Link link = pLinkList->GetLinkAtPoint(
313*3ac0a46fSAndroid Build Coastguard Worker pPage, CFX_PointF(static_cast<float>(x), static_cast<float>(y)), nullptr);
314*3ac0a46fSAndroid Build Coastguard Worker
315*3ac0a46fSAndroid Build Coastguard Worker // Unretained reference in public API. NOLINTNEXTLINE
316*3ac0a46fSAndroid Build Coastguard Worker return FPDFLinkFromCPDFDictionary(link.GetMutableDict());
317*3ac0a46fSAndroid Build Coastguard Worker }
318*3ac0a46fSAndroid Build Coastguard Worker
FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page,double x,double y)319*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT int FPDF_CALLCONV FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page,
320*3ac0a46fSAndroid Build Coastguard Worker double x,
321*3ac0a46fSAndroid Build Coastguard Worker double y) {
322*3ac0a46fSAndroid Build Coastguard Worker CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
323*3ac0a46fSAndroid Build Coastguard Worker if (!pPage)
324*3ac0a46fSAndroid Build Coastguard Worker return -1;
325*3ac0a46fSAndroid Build Coastguard Worker
326*3ac0a46fSAndroid Build Coastguard Worker CPDF_LinkList* pLinkList = GetLinkList(pPage);
327*3ac0a46fSAndroid Build Coastguard Worker if (!pLinkList)
328*3ac0a46fSAndroid Build Coastguard Worker return -1;
329*3ac0a46fSAndroid Build Coastguard Worker
330*3ac0a46fSAndroid Build Coastguard Worker int z_order = -1;
331*3ac0a46fSAndroid Build Coastguard Worker pLinkList->GetLinkAtPoint(
332*3ac0a46fSAndroid Build Coastguard Worker pPage, CFX_PointF(static_cast<float>(x), static_cast<float>(y)),
333*3ac0a46fSAndroid Build Coastguard Worker &z_order);
334*3ac0a46fSAndroid Build Coastguard Worker return z_order;
335*3ac0a46fSAndroid Build Coastguard Worker }
336*3ac0a46fSAndroid Build Coastguard Worker
FPDFLink_GetDest(FPDF_DOCUMENT document,FPDF_LINK link)337*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_DEST FPDF_CALLCONV FPDFLink_GetDest(FPDF_DOCUMENT document,
338*3ac0a46fSAndroid Build Coastguard Worker FPDF_LINK link) {
339*3ac0a46fSAndroid Build Coastguard Worker if (!link)
340*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
341*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
342*3ac0a46fSAndroid Build Coastguard Worker if (!pDoc)
343*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
344*3ac0a46fSAndroid Build Coastguard Worker CPDF_Link cLink(pdfium::WrapRetain(CPDFDictionaryFromFPDFLink(link)));
345*3ac0a46fSAndroid Build Coastguard Worker FPDF_DEST dest = FPDFDestFromCPDFArray(cLink.GetDest(pDoc).GetArray());
346*3ac0a46fSAndroid Build Coastguard Worker if (dest)
347*3ac0a46fSAndroid Build Coastguard Worker return dest;
348*3ac0a46fSAndroid Build Coastguard Worker // If this link is not directly associated with a dest, we try to get action
349*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action action = cLink.GetAction();
350*3ac0a46fSAndroid Build Coastguard Worker if (!action.HasDict())
351*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
352*3ac0a46fSAndroid Build Coastguard Worker return FPDFDestFromCPDFArray(action.GetDest(pDoc).GetArray());
353*3ac0a46fSAndroid Build Coastguard Worker }
354*3ac0a46fSAndroid Build Coastguard Worker
FPDFLink_GetAction(FPDF_LINK link)355*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_ACTION FPDF_CALLCONV FPDFLink_GetAction(FPDF_LINK link) {
356*3ac0a46fSAndroid Build Coastguard Worker if (!link)
357*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
358*3ac0a46fSAndroid Build Coastguard Worker
359*3ac0a46fSAndroid Build Coastguard Worker CPDF_Link cLink(pdfium::WrapRetain(CPDFDictionaryFromFPDFLink(link)));
360*3ac0a46fSAndroid Build Coastguard Worker return FPDFActionFromCPDFDictionary(cLink.GetAction().GetDict());
361*3ac0a46fSAndroid Build Coastguard Worker }
362*3ac0a46fSAndroid Build Coastguard Worker
FPDFLink_Enumerate(FPDF_PAGE page,int * start_pos,FPDF_LINK * link_annot)363*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFLink_Enumerate(FPDF_PAGE page,
364*3ac0a46fSAndroid Build Coastguard Worker int* start_pos,
365*3ac0a46fSAndroid Build Coastguard Worker FPDF_LINK* link_annot) {
366*3ac0a46fSAndroid Build Coastguard Worker if (!start_pos || !link_annot)
367*3ac0a46fSAndroid Build Coastguard Worker return false;
368*3ac0a46fSAndroid Build Coastguard Worker CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
369*3ac0a46fSAndroid Build Coastguard Worker if (!pPage)
370*3ac0a46fSAndroid Build Coastguard Worker return false;
371*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDF_Array> pAnnots = pPage->GetMutableAnnotsArray();
372*3ac0a46fSAndroid Build Coastguard Worker if (!pAnnots)
373*3ac0a46fSAndroid Build Coastguard Worker return false;
374*3ac0a46fSAndroid Build Coastguard Worker for (size_t i = *start_pos; i < pAnnots->size(); i++) {
375*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDF_Dictionary> pDict =
376*3ac0a46fSAndroid Build Coastguard Worker ToDictionary(pAnnots->GetMutableDirectObjectAt(i));
377*3ac0a46fSAndroid Build Coastguard Worker if (!pDict)
378*3ac0a46fSAndroid Build Coastguard Worker continue;
379*3ac0a46fSAndroid Build Coastguard Worker if (pDict->GetByteStringFor("Subtype") == "Link") {
380*3ac0a46fSAndroid Build Coastguard Worker *start_pos = static_cast<int>(i + 1);
381*3ac0a46fSAndroid Build Coastguard Worker *link_annot = FPDFLinkFromCPDFDictionary(pDict.Get());
382*3ac0a46fSAndroid Build Coastguard Worker return true;
383*3ac0a46fSAndroid Build Coastguard Worker }
384*3ac0a46fSAndroid Build Coastguard Worker }
385*3ac0a46fSAndroid Build Coastguard Worker return false;
386*3ac0a46fSAndroid Build Coastguard Worker }
387*3ac0a46fSAndroid Build Coastguard Worker
388*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_ANNOTATION FPDF_CALLCONV
FPDFLink_GetAnnot(FPDF_PAGE page,FPDF_LINK link_annot)389*3ac0a46fSAndroid Build Coastguard Worker FPDFLink_GetAnnot(FPDF_PAGE page, FPDF_LINK link_annot) {
390*3ac0a46fSAndroid Build Coastguard Worker CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
391*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<CPDF_Dictionary> pAnnotDict(CPDFDictionaryFromFPDFLink(link_annot));
392*3ac0a46fSAndroid Build Coastguard Worker if (!pPage || !pAnnotDict)
393*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
394*3ac0a46fSAndroid Build Coastguard Worker
395*3ac0a46fSAndroid Build Coastguard Worker auto pAnnotContext = std::make_unique<CPDF_AnnotContext>(
396*3ac0a46fSAndroid Build Coastguard Worker std::move(pAnnotDict), IPDFPageFromFPDFPage(page));
397*3ac0a46fSAndroid Build Coastguard Worker
398*3ac0a46fSAndroid Build Coastguard Worker // Caller takes the ownership of the object.
399*3ac0a46fSAndroid Build Coastguard Worker return FPDFAnnotationFromCPDFAnnotContext(pAnnotContext.release());
400*3ac0a46fSAndroid Build Coastguard Worker }
401*3ac0a46fSAndroid Build Coastguard Worker
FPDFLink_GetAnnotRect(FPDF_LINK link_annot,FS_RECTF * rect)402*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFLink_GetAnnotRect(FPDF_LINK link_annot,
403*3ac0a46fSAndroid Build Coastguard Worker FS_RECTF* rect) {
404*3ac0a46fSAndroid Build Coastguard Worker if (!link_annot || !rect)
405*3ac0a46fSAndroid Build Coastguard Worker return false;
406*3ac0a46fSAndroid Build Coastguard Worker
407*3ac0a46fSAndroid Build Coastguard Worker CPDF_Dictionary* pAnnotDict = CPDFDictionaryFromFPDFLink(link_annot);
408*3ac0a46fSAndroid Build Coastguard Worker *rect = FSRectFFromCFXFloatRect(pAnnotDict->GetRectFor("Rect"));
409*3ac0a46fSAndroid Build Coastguard Worker return true;
410*3ac0a46fSAndroid Build Coastguard Worker }
411*3ac0a46fSAndroid Build Coastguard Worker
FPDFLink_CountQuadPoints(FPDF_LINK link_annot)412*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT int FPDF_CALLCONV FPDFLink_CountQuadPoints(FPDF_LINK link_annot) {
413*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Array> pArray =
414*3ac0a46fSAndroid Build Coastguard Worker GetQuadPointsArrayFromDictionary(CPDFDictionaryFromFPDFLink(link_annot));
415*3ac0a46fSAndroid Build Coastguard Worker return pArray ? static_cast<int>(pArray->size() / 8) : 0;
416*3ac0a46fSAndroid Build Coastguard Worker }
417*3ac0a46fSAndroid Build Coastguard Worker
418*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFLink_GetQuadPoints(FPDF_LINK link_annot,int quad_index,FS_QUADPOINTSF * quad_points)419*3ac0a46fSAndroid Build Coastguard Worker FPDFLink_GetQuadPoints(FPDF_LINK link_annot,
420*3ac0a46fSAndroid Build Coastguard Worker int quad_index,
421*3ac0a46fSAndroid Build Coastguard Worker FS_QUADPOINTSF* quad_points) {
422*3ac0a46fSAndroid Build Coastguard Worker if (!quad_points || quad_index < 0)
423*3ac0a46fSAndroid Build Coastguard Worker return false;
424*3ac0a46fSAndroid Build Coastguard Worker
425*3ac0a46fSAndroid Build Coastguard Worker const CPDF_Dictionary* pLinkDict = CPDFDictionaryFromFPDFLink(link_annot);
426*3ac0a46fSAndroid Build Coastguard Worker if (!pLinkDict)
427*3ac0a46fSAndroid Build Coastguard Worker return false;
428*3ac0a46fSAndroid Build Coastguard Worker
429*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Array> pArray =
430*3ac0a46fSAndroid Build Coastguard Worker GetQuadPointsArrayFromDictionary(pLinkDict);
431*3ac0a46fSAndroid Build Coastguard Worker if (!pArray)
432*3ac0a46fSAndroid Build Coastguard Worker return false;
433*3ac0a46fSAndroid Build Coastguard Worker
434*3ac0a46fSAndroid Build Coastguard Worker return GetQuadPointsAtIndex(std::move(pArray),
435*3ac0a46fSAndroid Build Coastguard Worker static_cast<size_t>(quad_index), quad_points);
436*3ac0a46fSAndroid Build Coastguard Worker }
437*3ac0a46fSAndroid Build Coastguard Worker
FPDF_GetPageAAction(FPDF_PAGE page,int aa_type)438*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT FPDF_ACTION FPDF_CALLCONV FPDF_GetPageAAction(FPDF_PAGE page,
439*3ac0a46fSAndroid Build Coastguard Worker int aa_type) {
440*3ac0a46fSAndroid Build Coastguard Worker CPDF_Page* pdf_page = CPDFPageFromFPDFPage(page);
441*3ac0a46fSAndroid Build Coastguard Worker if (!pdf_page)
442*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
443*3ac0a46fSAndroid Build Coastguard Worker
444*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction aa(pdf_page->GetDict()->GetDictFor(pdfium::form_fields::kAA));
445*3ac0a46fSAndroid Build Coastguard Worker CPDF_AAction::AActionType type;
446*3ac0a46fSAndroid Build Coastguard Worker if (aa_type == FPDFPAGE_AACTION_OPEN)
447*3ac0a46fSAndroid Build Coastguard Worker type = CPDF_AAction::kOpenPage;
448*3ac0a46fSAndroid Build Coastguard Worker else if (aa_type == FPDFPAGE_AACTION_CLOSE)
449*3ac0a46fSAndroid Build Coastguard Worker type = CPDF_AAction::kClosePage;
450*3ac0a46fSAndroid Build Coastguard Worker else
451*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
452*3ac0a46fSAndroid Build Coastguard Worker
453*3ac0a46fSAndroid Build Coastguard Worker if (!aa.ActionExist(type))
454*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
455*3ac0a46fSAndroid Build Coastguard Worker
456*3ac0a46fSAndroid Build Coastguard Worker CPDF_Action action = aa.GetAction(type);
457*3ac0a46fSAndroid Build Coastguard Worker return FPDFActionFromCPDFDictionary(action.GetDict());
458*3ac0a46fSAndroid Build Coastguard Worker }
459*3ac0a46fSAndroid Build Coastguard Worker
460*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDF_GetFileIdentifier(FPDF_DOCUMENT document,FPDF_FILEIDTYPE id_type,void * buffer,unsigned long buflen)461*3ac0a46fSAndroid Build Coastguard Worker FPDF_GetFileIdentifier(FPDF_DOCUMENT document,
462*3ac0a46fSAndroid Build Coastguard Worker FPDF_FILEIDTYPE id_type,
463*3ac0a46fSAndroid Build Coastguard Worker void* buffer,
464*3ac0a46fSAndroid Build Coastguard Worker unsigned long buflen) {
465*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
466*3ac0a46fSAndroid Build Coastguard Worker if (!pDoc)
467*3ac0a46fSAndroid Build Coastguard Worker return 0;
468*3ac0a46fSAndroid Build Coastguard Worker
469*3ac0a46fSAndroid Build Coastguard Worker // Check if |id_type| is valid.
470*3ac0a46fSAndroid Build Coastguard Worker if (id_type != FILEIDTYPE_PERMANENT && id_type != FILEIDTYPE_CHANGING)
471*3ac0a46fSAndroid Build Coastguard Worker return 0;
472*3ac0a46fSAndroid Build Coastguard Worker
473*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Array> pFileId = pDoc->GetFileIdentifier();
474*3ac0a46fSAndroid Build Coastguard Worker if (!pFileId)
475*3ac0a46fSAndroid Build Coastguard Worker return 0;
476*3ac0a46fSAndroid Build Coastguard Worker
477*3ac0a46fSAndroid Build Coastguard Worker size_t nIndex = id_type == FILEIDTYPE_PERMANENT ? 0 : 1;
478*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_String> pValue =
479*3ac0a46fSAndroid Build Coastguard Worker ToString(pFileId->GetDirectObjectAt(nIndex));
480*3ac0a46fSAndroid Build Coastguard Worker if (!pValue)
481*3ac0a46fSAndroid Build Coastguard Worker return 0;
482*3ac0a46fSAndroid Build Coastguard Worker
483*3ac0a46fSAndroid Build Coastguard Worker return NulTerminateMaybeCopyAndReturnLength(pValue->GetString(), buffer,
484*3ac0a46fSAndroid Build Coastguard Worker buflen);
485*3ac0a46fSAndroid Build Coastguard Worker }
486*3ac0a46fSAndroid Build Coastguard Worker
FPDF_GetMetaText(FPDF_DOCUMENT document,FPDF_BYTESTRING tag,void * buffer,unsigned long buflen)487*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT unsigned long FPDF_CALLCONV FPDF_GetMetaText(FPDF_DOCUMENT document,
488*3ac0a46fSAndroid Build Coastguard Worker FPDF_BYTESTRING tag,
489*3ac0a46fSAndroid Build Coastguard Worker void* buffer,
490*3ac0a46fSAndroid Build Coastguard Worker unsigned long buflen) {
491*3ac0a46fSAndroid Build Coastguard Worker if (!tag)
492*3ac0a46fSAndroid Build Coastguard Worker return 0;
493*3ac0a46fSAndroid Build Coastguard Worker CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
494*3ac0a46fSAndroid Build Coastguard Worker if (!pDoc)
495*3ac0a46fSAndroid Build Coastguard Worker return 0;
496*3ac0a46fSAndroid Build Coastguard Worker
497*3ac0a46fSAndroid Build Coastguard Worker RetainPtr<const CPDF_Dictionary> pInfo = pDoc->GetInfo();
498*3ac0a46fSAndroid Build Coastguard Worker if (!pInfo)
499*3ac0a46fSAndroid Build Coastguard Worker return 0;
500*3ac0a46fSAndroid Build Coastguard Worker
501*3ac0a46fSAndroid Build Coastguard Worker WideString text = pInfo->GetUnicodeTextFor(tag);
502*3ac0a46fSAndroid Build Coastguard Worker return Utf16EncodeMaybeCopyAndReturnLength(text, buffer, buflen);
503*3ac0a46fSAndroid Build Coastguard Worker }
504*3ac0a46fSAndroid Build Coastguard Worker
505*3ac0a46fSAndroid Build Coastguard Worker FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDF_GetPageLabel(FPDF_DOCUMENT document,int page_index,void * buffer,unsigned long buflen)506*3ac0a46fSAndroid Build Coastguard Worker FPDF_GetPageLabel(FPDF_DOCUMENT document,
507*3ac0a46fSAndroid Build Coastguard Worker int page_index,
508*3ac0a46fSAndroid Build Coastguard Worker void* buffer,
509*3ac0a46fSAndroid Build Coastguard Worker unsigned long buflen) {
510*3ac0a46fSAndroid Build Coastguard Worker if (page_index < 0)
511*3ac0a46fSAndroid Build Coastguard Worker return 0;
512*3ac0a46fSAndroid Build Coastguard Worker
513*3ac0a46fSAndroid Build Coastguard Worker // CPDF_PageLabel can deal with NULL |document|.
514*3ac0a46fSAndroid Build Coastguard Worker CPDF_PageLabel label(CPDFDocumentFromFPDFDocument(document));
515*3ac0a46fSAndroid Build Coastguard Worker absl::optional<WideString> str = label.GetLabel(page_index);
516*3ac0a46fSAndroid Build Coastguard Worker return str.has_value()
517*3ac0a46fSAndroid Build Coastguard Worker ? Utf16EncodeMaybeCopyAndReturnLength(str.value(), buffer, buflen)
518*3ac0a46fSAndroid Build Coastguard Worker : 0;
519*3ac0a46fSAndroid Build Coastguard Worker }
520