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