1 // Copyright 2014 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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../include/fpdfdoc/fpdf_doc.h"
GetDest(CPDF_Document * pDoc) const8 CPDF_Dest CPDF_Action::GetDest(CPDF_Document* pDoc) const
9 {
10 if (!m_pDict) {
11 return CPDF_Dest();
12 }
13 CFX_ByteString type = m_pDict->GetString("S");
14 if (type != "GoTo" && type != "GoToR") {
15 return CPDF_Dest();
16 }
17 CPDF_Object* pDest = m_pDict->GetElementValue("D");
18 if (!pDest) {
19 return CPDF_Dest();
20 }
21 if (pDest->GetType() == PDFOBJ_STRING || pDest->GetType() == PDFOBJ_NAME) {
22 CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests"));
23 CFX_ByteStringC name = pDest->GetString();
24 return CPDF_Dest(name_tree.LookupNamedDest(pDoc, name));
25 }
26 if (pDest->GetType() == PDFOBJ_ARRAY) {
27 return CPDF_Dest((CPDF_Array*)pDest);
28 }
29 return CPDF_Dest();
30 }
31 const FX_CHAR* g_sATypes[] = {"Unknown", "GoTo", "GoToR", "GoToE", "Launch", "Thread", "URI", "Sound", "Movie",
32 "Hide", "Named", "SubmitForm", "ResetForm", "ImportData", "JavaScript", "SetOCGState",
33 "Rendition", "Trans", "GoTo3DView", ""
34 };
GetType() const35 CPDF_Action::ActionType CPDF_Action::GetType() const
36 {
37 ActionType eType = Unknown;
38 if (m_pDict != NULL) {
39 CFX_ByteString csType = m_pDict->GetString("S");
40 if (!csType.IsEmpty()) {
41 int i = 0;
42 while (g_sATypes[i][0] != '\0') {
43 if (csType == g_sATypes[i]) {
44 return (ActionType)i;
45 }
46 i ++;
47 }
48 }
49 }
50 return eType;
51 }
GetFilePath() const52 CFX_WideString CPDF_Action::GetFilePath() const
53 {
54 CFX_ByteString type = m_pDict->GetString("S");
55 if (type != "GoToR" && type != "Launch" &&
56 type != "SubmitForm" && type != "ImportData") {
57 return CFX_WideString();
58 }
59 CPDF_Object* pFile = m_pDict->GetElementValue("F");
60 CFX_WideString path;
61 if (pFile == NULL) {
62 if (type == "Launch") {
63 CPDF_Dictionary* pWinDict = m_pDict->GetDict(FX_BSTRC("Win"));
64 if (pWinDict) {
65 return CFX_WideString::FromLocal(pWinDict->GetString(FX_BSTRC("F")));
66 }
67 }
68 return path;
69 }
70 CPDF_FileSpec filespec(pFile);
71 filespec.GetFileName(path);
72 return path;
73 }
GetURI(CPDF_Document * pDoc) const74 CFX_ByteString CPDF_Action::GetURI(CPDF_Document* pDoc) const
75 {
76 CFX_ByteString csURI;
77 if (m_pDict == NULL) {
78 return csURI;
79 }
80 if (m_pDict->GetString("S") != "URI") {
81 return csURI;
82 }
83 csURI = m_pDict->GetString("URI");
84 CPDF_Dictionary* pRoot = pDoc->GetRoot();
85 CPDF_Dictionary* pURI = pRoot->GetDict("URI");
86 if (pURI != NULL) {
87 if (csURI.Find(FX_BSTRC(":"), 0) < 1) {
88 csURI = pURI->GetString("Base") + csURI;
89 }
90 }
91 return csURI;
92 }
GetFieldsCount() const93 FX_DWORD CPDF_ActionFields::GetFieldsCount() const
94 {
95 if (m_pAction == NULL) {
96 return 0;
97 }
98 CPDF_Dictionary* pDict = m_pAction->GetDict();
99 if (pDict == NULL) {
100 return 0;
101 }
102 CFX_ByteString csType = pDict->GetString("S");
103 CPDF_Object* pFields = NULL;
104 if (csType == "Hide") {
105 pFields = pDict->GetElementValue("T");
106 } else {
107 pFields = pDict->GetArray("Fields");
108 }
109 if (pFields == NULL) {
110 return 0;
111 }
112 int iType = pFields->GetType();
113 if (iType == PDFOBJ_DICTIONARY) {
114 return 1;
115 } else if (iType == PDFOBJ_STRING) {
116 return 1;
117 } else if (iType == PDFOBJ_ARRAY) {
118 return ((CPDF_Array*)pFields)->GetCount();
119 }
120 return 0;
121 }
GetAllFields(CFX_PtrArray & fieldObjects) const122 void CPDF_ActionFields::GetAllFields(CFX_PtrArray& fieldObjects) const
123 {
124 fieldObjects.RemoveAll();
125 if (m_pAction == NULL) {
126 return;
127 }
128 CPDF_Dictionary* pDict = m_pAction->GetDict();
129 if (pDict == NULL) {
130 return;
131 }
132 CFX_ByteString csType = pDict->GetString("S");
133 CPDF_Object* pFields = NULL;
134 if (csType == "Hide") {
135 pFields = pDict->GetElementValue("T");
136 } else {
137 pFields = pDict->GetArray("Fields");
138 }
139 if (pFields == NULL) {
140 return;
141 }
142 int iType = pFields->GetType();
143 if (iType == PDFOBJ_DICTIONARY || iType == PDFOBJ_STRING) {
144 fieldObjects.Add(pFields);
145 } else if (iType == PDFOBJ_ARRAY) {
146 CPDF_Array* pArray = (CPDF_Array*)pFields;
147 FX_DWORD iCount = pArray->GetCount();
148 for (FX_DWORD i = 0; i < iCount; i ++) {
149 CPDF_Object* pObj = pArray->GetElementValue(i);
150 if (pObj != NULL) {
151 fieldObjects.Add(pObj);
152 }
153 }
154 }
155 }
GetField(FX_DWORD iIndex) const156 CPDF_Object* CPDF_ActionFields::GetField(FX_DWORD iIndex) const
157 {
158 if (m_pAction == NULL) {
159 return NULL;
160 }
161 CPDF_Dictionary* pDict = m_pAction->GetDict();
162 if (pDict == NULL) {
163 return NULL;
164 }
165 CFX_ByteString csType = pDict->GetString("S");
166 CPDF_Object* pFields = NULL;
167 if (csType == "Hide") {
168 pFields = pDict->GetElementValue("T");
169 } else {
170 pFields = pDict->GetArray("Fields");
171 }
172 if (pFields == NULL) {
173 return NULL;
174 }
175 CPDF_Object* pFindObj = NULL;
176 int iType = pFields->GetType();
177 if (iType == PDFOBJ_DICTIONARY || iType == PDFOBJ_STRING) {
178 if (iIndex == 0) {
179 pFindObj = pFields;
180 }
181 } else if (iType == PDFOBJ_ARRAY) {
182 pFindObj = ((CPDF_Array*)pFields)->GetElementValue(iIndex);
183 }
184 return pFindObj;
185 }
GetWinParam() const186 CPDF_LWinParam CPDF_Action::GetWinParam() const
187 {
188 if (m_pDict == NULL) {
189 return NULL;
190 }
191 if (m_pDict->GetString("S") != "Launch") {
192 return NULL;
193 }
194 return m_pDict->GetDict("Win");
195 }
GetJavaScript() const196 CFX_WideString CPDF_Action::GetJavaScript() const
197 {
198 CFX_WideString csJS;
199 if (m_pDict == NULL) {
200 return csJS;
201 }
202 CPDF_Object* pJS = m_pDict->GetElementValue("JS");
203 if (pJS != NULL) {
204 return pJS->GetUnicodeText();
205 }
206 return csJS;
207 }
GetAnnot() const208 CPDF_Dictionary* CPDF_Action::GetAnnot() const
209 {
210 if (m_pDict == NULL) {
211 return NULL;
212 }
213 CFX_ByteString csType = m_pDict->GetString("S");
214 if (csType == FX_BSTRC("Rendition")) {
215 return m_pDict->GetDict("AN");
216 } else if (csType == FX_BSTRC("Movie")) {
217 return m_pDict->GetDict("Annotation");
218 }
219 return NULL;
220 }
GetOperationType() const221 FX_INT32 CPDF_Action::GetOperationType() const
222 {
223 if (m_pDict == NULL) {
224 return 0;
225 }
226 CFX_ByteString csType = m_pDict->GetString("S");
227 if (csType == FX_BSTRC("Rendition")) {
228 return m_pDict->GetInteger("OP");
229 } else if (csType == FX_BSTRC("Movie")) {
230 CFX_ByteString csOP = m_pDict->GetString("Operation");
231 if (csOP == FX_BSTRC("Play")) {
232 return 0;
233 } else if (csOP == FX_BSTRC("Stop")) {
234 return 1;
235 } else if (csOP == FX_BSTRC("Pause")) {
236 return 2;
237 } else if (csOP == FX_BSTRC("Resume")) {
238 return 3;
239 }
240 }
241 return 0;
242 }
GetSubActionsCount() const243 FX_DWORD CPDF_Action::GetSubActionsCount() const
244 {
245 if (m_pDict == NULL || !m_pDict->KeyExist("Next")) {
246 return 0;
247 }
248 CPDF_Object* pNext = m_pDict->GetElementValue("Next");
249 if (!pNext) {
250 return 0;
251 }
252 int iObjType = pNext->GetType();
253 if (iObjType == PDFOBJ_DICTIONARY) {
254 return 1;
255 }
256 if (iObjType == PDFOBJ_ARRAY) {
257 return ((CPDF_Array*)pNext)->GetCount();
258 }
259 return 0;
260 }
GetSubAction(FX_DWORD iIndex) const261 CPDF_Action CPDF_Action::GetSubAction(FX_DWORD iIndex) const
262 {
263 if (m_pDict == NULL || !m_pDict->KeyExist("Next")) {
264 return CPDF_Action();
265 }
266 CPDF_Object* pNext = m_pDict->GetElementValue("Next");
267 int iObjType = pNext->GetType();
268 if (iObjType == PDFOBJ_DICTIONARY) {
269 CPDF_Dictionary *pDict = static_cast<CPDF_Dictionary*>(pNext);
270 if (iIndex == 0) {
271 return CPDF_Action(pDict);
272 }
273 } else if (iObjType == PDFOBJ_ARRAY) {
274 CPDF_Array* pArray = static_cast<CPDF_Array*>(pNext);
275 return CPDF_Action(pArray->GetDict(iIndex));
276 }
277 return CPDF_Action();
278 }
279 const FX_CHAR* g_sAATypes[] = {"E", "X", "D", "U", "Fo", "Bl", "PO", "PC", "PV", "PI",
280 "O", "C",
281 "K", "F", "V", "C",
282 "WC", "WS", "DS", "WP", "DP",
283 ""
284 };
ActionExist(AActionType eType) const285 FX_BOOL CPDF_AAction::ActionExist(AActionType eType) const
286 {
287 if (m_pDict == NULL) {
288 return FALSE;
289 }
290 return m_pDict->KeyExist(g_sAATypes[(int)eType]);
291 }
GetAction(AActionType eType) const292 CPDF_Action CPDF_AAction::GetAction(AActionType eType) const
293 {
294 if (!m_pDict) {
295 return CPDF_Action();
296 }
297 return CPDF_Action(m_pDict->GetDict(g_sAATypes[(int)eType]));
298 }
GetStartPos() const299 FX_POSITION CPDF_AAction::GetStartPos() const
300 {
301 if (m_pDict == NULL) {
302 return NULL;
303 }
304 return m_pDict->GetStartPos();
305 }
GetNextAction(FX_POSITION & pos,AActionType & eType) const306 CPDF_Action CPDF_AAction::GetNextAction(FX_POSITION& pos, AActionType& eType) const
307 {
308 if (m_pDict == NULL) {
309 return CPDF_Action();
310 }
311 CFX_ByteString csKey;
312 CPDF_Object* pObj = m_pDict->GetNextElement(pos, csKey);
313 if (!pObj) {
314 return CPDF_Action();
315 }
316 CPDF_Object* pDirect = pObj->GetDirect();
317 if (!pDirect || pDirect->GetType() != PDFOBJ_DICTIONARY) {
318 return CPDF_Action();
319 }
320 int i = 0;
321 while (g_sAATypes[i][0] != '\0') {
322 if (csKey == g_sAATypes[i]) {
323 break;
324 }
325 i++;
326 }
327 eType = (AActionType)i;
328 return CPDF_Action(static_cast<CPDF_Dictionary*>(pDirect));
329 }
CPDF_DocJSActions(CPDF_Document * pDoc)330 CPDF_DocJSActions::CPDF_DocJSActions(CPDF_Document* pDoc)
331 {
332 m_pDocument = pDoc;
333 }
CountJSActions() const334 int CPDF_DocJSActions::CountJSActions() const
335 {
336 ASSERT(m_pDocument != NULL);
337 CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));
338 return name_tree.GetCount();
339 }
GetJSAction(int index,CFX_ByteString & csName) const340 CPDF_Action CPDF_DocJSActions::GetJSAction(int index, CFX_ByteString& csName) const
341 {
342 ASSERT(m_pDocument != NULL);
343 CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));
344 CPDF_Object *pAction = name_tree.LookupValue(index, csName);
345 if (pAction == NULL || pAction->GetType() != PDFOBJ_DICTIONARY) {
346 return CPDF_Action();
347 }
348 return CPDF_Action(pAction->GetDict());
349 }
GetJSAction(const CFX_ByteString & csName) const350 CPDF_Action CPDF_DocJSActions::GetJSAction(const CFX_ByteString& csName) const
351 {
352 ASSERT(m_pDocument != NULL);
353 CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));
354 CPDF_Object *pAction = name_tree.LookupValue(csName);
355 if (pAction == NULL || pAction->GetType() != PDFOBJ_DICTIONARY) {
356 return CPDF_Action();
357 }
358 return CPDF_Action(pAction->GetDict());
359 }
FindJSAction(const CFX_ByteString & csName) const360 int CPDF_DocJSActions::FindJSAction(const CFX_ByteString& csName) const
361 {
362 ASSERT(m_pDocument != NULL);
363 CPDF_NameTree name_tree(m_pDocument, FX_BSTRC("JavaScript"));
364 return name_tree.GetIndex(csName);
365 }
366