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" 8CPDF_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} 31const 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 }; 35CPDF_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} 52CFX_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} 74CFX_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} 93FX_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} 122void 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} 156CPDF_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} 186CPDF_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} 196CFX_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} 208CPDF_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} 221FX_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} 243FX_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} 261CPDF_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} 279const 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 }; 285FX_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} 292CPDF_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} 299FX_POSITION CPDF_AAction::GetStartPos() const 300{ 301 if (m_pDict == NULL) { 302 return NULL; 303 } 304 return m_pDict->GetStartPos(); 305} 306CPDF_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} 330CPDF_DocJSActions::CPDF_DocJSActions(CPDF_Document* pDoc) 331{ 332 m_pDocument = pDoc; 333} 334int 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} 340CPDF_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} 350CPDF_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} 360int 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