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" 8 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 }; 34 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 } 51 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 } 73 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 } 92 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 } 121 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 } 155 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 } 185 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 } 195 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 } 207 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 } 220 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 } 242 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 } 260 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 }; 283 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 } 290 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 } 297 FX_POSITION CPDF_AAction::GetStartPos() const 298 { 299 if (m_pDict == NULL) { 300 return NULL; 301 } 302 return m_pDict->GetStartPos(); 303 } 304 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 } 327 CPDF_DocJSActions::CPDF_DocJSActions(CPDF_Document* pDoc) 328 { 329 m_pDocument = pDoc; 330 } 331 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 } 337 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 } 347 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 } 357 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