diff options
Diffstat (limited to 'core/fpdfdoc/doc_action.cpp')
-rw-r--r-- | core/fpdfdoc/doc_action.cpp | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/core/fpdfdoc/doc_action.cpp b/core/fpdfdoc/doc_action.cpp new file mode 100644 index 0000000000..0af219e47e --- /dev/null +++ b/core/fpdfdoc/doc_action.cpp @@ -0,0 +1,295 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include <vector> + +#include "core/include/fpdfapi/cpdf_array.h" +#include "core/include/fpdfapi/cpdf_document.h" +#include "core/include/fpdfdoc/fpdf_doc.h" + +CPDF_Dest CPDF_Action::GetDest(CPDF_Document* pDoc) const { + if (!m_pDict) { + return CPDF_Dest(); + } + CFX_ByteString type = m_pDict->GetStringBy("S"); + if (type != "GoTo" && type != "GoToR") { + return CPDF_Dest(); + } + CPDF_Object* pDest = m_pDict->GetElementValue("D"); + if (!pDest) { + return CPDF_Dest(); + } + if (pDest->IsString() || pDest->IsName()) { + CPDF_NameTree name_tree(pDoc, "Dests"); + CFX_ByteStringC name = pDest->GetString(); + return CPDF_Dest(name_tree.LookupNamedDest(pDoc, name)); + } + if (CPDF_Array* pArray = pDest->AsArray()) + return CPDF_Dest(pArray); + return CPDF_Dest(); +} +const FX_CHAR* g_sATypes[] = { + "Unknown", "GoTo", "GoToR", "GoToE", "Launch", + "Thread", "URI", "Sound", "Movie", "Hide", + "Named", "SubmitForm", "ResetForm", "ImportData", "JavaScript", + "SetOCGState", "Rendition", "Trans", "GoTo3DView", ""}; +CPDF_Action::ActionType CPDF_Action::GetType() const { + ActionType eType = Unknown; + if (m_pDict) { + CFX_ByteString csType = m_pDict->GetStringBy("S"); + if (!csType.IsEmpty()) { + int i = 0; + while (g_sATypes[i][0] != '\0') { + if (csType == g_sATypes[i]) { + return (ActionType)i; + } + i++; + } + } + } + return eType; +} +CFX_WideString CPDF_Action::GetFilePath() const { + CFX_ByteString type = m_pDict->GetStringBy("S"); + if (type != "GoToR" && type != "Launch" && type != "SubmitForm" && + type != "ImportData") { + return CFX_WideString(); + } + CPDF_Object* pFile = m_pDict->GetElementValue("F"); + CFX_WideString path; + if (!pFile) { + if (type == "Launch") { + CPDF_Dictionary* pWinDict = m_pDict->GetDictBy("Win"); + if (pWinDict) { + return CFX_WideString::FromLocal(pWinDict->GetStringBy("F")); + } + } + return path; + } + CPDF_FileSpec filespec(pFile); + filespec.GetFileName(&path); + return path; +} +CFX_ByteString CPDF_Action::GetURI(CPDF_Document* pDoc) const { + CFX_ByteString csURI; + if (!m_pDict) { + return csURI; + } + if (m_pDict->GetStringBy("S") != "URI") { + return csURI; + } + csURI = m_pDict->GetStringBy("URI"); + CPDF_Dictionary* pRoot = pDoc->GetRoot(); + CPDF_Dictionary* pURI = pRoot->GetDictBy("URI"); + if (pURI) { + if (csURI.Find(":", 0) < 1) { + csURI = pURI->GetStringBy("Base") + csURI; + } + } + return csURI; +} +FX_DWORD CPDF_ActionFields::GetFieldsCount() const { + if (!m_pAction) { + return 0; + } + CPDF_Dictionary* pDict = m_pAction->GetDict(); + if (!pDict) { + return 0; + } + CFX_ByteString csType = pDict->GetStringBy("S"); + CPDF_Object* pFields = NULL; + if (csType == "Hide") { + pFields = pDict->GetElementValue("T"); + } else { + pFields = pDict->GetArrayBy("Fields"); + } + if (!pFields) + return 0; + if (pFields->IsDictionary()) + return 1; + if (pFields->IsString()) + return 1; + if (CPDF_Array* pArray = pFields->AsArray()) + return pArray->GetCount(); + return 0; +} + +std::vector<CPDF_Object*> CPDF_ActionFields::GetAllFields() const { + std::vector<CPDF_Object*> fields; + if (!m_pAction) + return fields; + + CPDF_Dictionary* pDict = m_pAction->GetDict(); + if (!pDict) + return fields; + + CFX_ByteString csType = pDict->GetStringBy("S"); + CPDF_Object* pFields; + if (csType == "Hide") + pFields = pDict->GetElementValue("T"); + else + pFields = pDict->GetArrayBy("Fields"); + if (!pFields) + return fields; + + if (pFields->IsDictionary() || pFields->IsString()) { + fields.push_back(pFields); + } else if (CPDF_Array* pArray = pFields->AsArray()) { + FX_DWORD iCount = pArray->GetCount(); + for (FX_DWORD i = 0; i < iCount; ++i) { + CPDF_Object* pObj = pArray->GetElementValue(i); + if (pObj) { + fields.push_back(pObj); + } + } + } + return fields; +} + +CPDF_Object* CPDF_ActionFields::GetField(FX_DWORD iIndex) const { + if (!m_pAction) { + return NULL; + } + CPDF_Dictionary* pDict = m_pAction->GetDict(); + if (!pDict) { + return NULL; + } + CFX_ByteString csType = pDict->GetStringBy("S"); + CPDF_Object* pFields = NULL; + if (csType == "Hide") { + pFields = pDict->GetElementValue("T"); + } else { + pFields = pDict->GetArrayBy("Fields"); + } + if (!pFields) { + return NULL; + } + CPDF_Object* pFindObj = NULL; + if (pFields->IsDictionary() || pFields->IsString()) { + if (iIndex == 0) + pFindObj = pFields; + } else if (CPDF_Array* pArray = pFields->AsArray()) { + pFindObj = pArray->GetElementValue(iIndex); + } + return pFindObj; +} + +CFX_WideString CPDF_Action::GetJavaScript() const { + CFX_WideString csJS; + if (!m_pDict) { + return csJS; + } + CPDF_Object* pJS = m_pDict->GetElementValue("JS"); + return pJS ? pJS->GetUnicodeText() : csJS; +} +CPDF_Dictionary* CPDF_Action::GetAnnot() const { + if (!m_pDict) { + return nullptr; + } + CFX_ByteString csType = m_pDict->GetStringBy("S"); + if (csType == "Rendition") { + return m_pDict->GetDictBy("AN"); + } + if (csType == "Movie") { + return m_pDict->GetDictBy("Annotation"); + } + return nullptr; +} +int32_t CPDF_Action::GetOperationType() const { + if (!m_pDict) { + return 0; + } + CFX_ByteString csType = m_pDict->GetStringBy("S"); + if (csType == "Rendition") { + return m_pDict->GetIntegerBy("OP"); + } + if (csType == "Movie") { + CFX_ByteString csOP = m_pDict->GetStringBy("Operation"); + if (csOP == "Play") { + return 0; + } + if (csOP == "Stop") { + return 1; + } + if (csOP == "Pause") { + return 2; + } + if (csOP == "Resume") { + return 3; + } + } + return 0; +} +FX_DWORD CPDF_Action::GetSubActionsCount() const { + if (!m_pDict || !m_pDict->KeyExist("Next")) + return 0; + + CPDF_Object* pNext = m_pDict->GetElementValue("Next"); + if (!pNext) + return 0; + if (pNext->IsDictionary()) + return 1; + if (CPDF_Array* pArray = pNext->AsArray()) + return pArray->GetCount(); + return 0; +} +CPDF_Action CPDF_Action::GetSubAction(FX_DWORD iIndex) const { + if (!m_pDict || !m_pDict->KeyExist("Next")) { + return CPDF_Action(); + } + CPDF_Object* pNext = m_pDict->GetElementValue("Next"); + if (CPDF_Dictionary* pDict = ToDictionary(pNext)) { + if (iIndex == 0) + return CPDF_Action(pDict); + } else if (CPDF_Array* pArray = ToArray(pNext)) { + return CPDF_Action(pArray->GetDictAt(iIndex)); + } + return CPDF_Action(); +} +const FX_CHAR* g_sAATypes[] = {"E", "X", "D", "U", "Fo", "Bl", "PO", "PC", + "PV", "PI", "O", "C", "K", "F", "V", "C", + "WC", "WS", "DS", "WP", "DP", ""}; +FX_BOOL CPDF_AAction::ActionExist(AActionType eType) const { + return m_pDict && m_pDict->KeyExist(g_sAATypes[(int)eType]); +} +CPDF_Action CPDF_AAction::GetAction(AActionType eType) const { + if (!m_pDict) { + return CPDF_Action(); + } + return CPDF_Action(m_pDict->GetDictBy(g_sAATypes[(int)eType])); +} + +CPDF_DocJSActions::CPDF_DocJSActions(CPDF_Document* pDoc) : m_pDocument(pDoc) {} + +int CPDF_DocJSActions::CountJSActions() const { + ASSERT(m_pDocument); + CPDF_NameTree name_tree(m_pDocument, "JavaScript"); + return name_tree.GetCount(); +} +CPDF_Action CPDF_DocJSActions::GetJSAction(int index, + CFX_ByteString& csName) const { + ASSERT(m_pDocument); + CPDF_NameTree name_tree(m_pDocument, "JavaScript"); + CPDF_Object* pAction = name_tree.LookupValue(index, csName); + if (!ToDictionary(pAction)) { + return CPDF_Action(); + } + return CPDF_Action(pAction->GetDict()); +} +CPDF_Action CPDF_DocJSActions::GetJSAction(const CFX_ByteString& csName) const { + ASSERT(m_pDocument); + CPDF_NameTree name_tree(m_pDocument, "JavaScript"); + CPDF_Object* pAction = name_tree.LookupValue(csName); + if (!ToDictionary(pAction)) { + return CPDF_Action(); + } + return CPDF_Action(pAction->GetDict()); +} +int CPDF_DocJSActions::FindJSAction(const CFX_ByteString& csName) const { + ASSERT(m_pDocument); + CPDF_NameTree name_tree(m_pDocument, "JavaScript"); + return name_tree.GetIndex(csName); +} |