Home | History | Annotate | Download | only in fpdfdoc
      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 "core/include/fpdfdoc/fpdf_doc.h"
      8 
      9 CPDF_Dest CPDF_Action::GetDest(CPDF_Document* pDoc) const {
     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->IsString() || pDest->IsName()) {
     22     CPDF_NameTree name_tree(pDoc, "Dests");
     23     CFX_ByteStringC name = pDest->GetString();
     24     return CPDF_Dest(name_tree.LookupNamedDest(pDoc, name));
     25   }
     26   if (CPDF_Array* pArray = pDest->AsArray())
     27     return CPDF_Dest(pArray);
     28   return CPDF_Dest();
     29 }
     30 const FX_CHAR* g_sATypes[] = {
     31     "Unknown",     "GoTo",       "GoToR",     "GoToE",      "Launch",
     32     "Thread",      "URI",        "Sound",     "Movie",      "Hide",
     33     "Named",       "SubmitForm", "ResetForm", "ImportData", "JavaScript",
     34     "SetOCGState", "Rendition",  "Trans",     "GoTo3DView", ""};
     35 CPDF_Action::ActionType CPDF_Action::GetType() const {
     36   ActionType eType = Unknown;
     37   if (m_pDict) {
     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   CFX_ByteString type = m_pDict->GetString("S");
     53   if (type != "GoToR" && type != "Launch" && type != "SubmitForm" &&
     54       type != "ImportData") {
     55     return CFX_WideString();
     56   }
     57   CPDF_Object* pFile = m_pDict->GetElementValue("F");
     58   CFX_WideString path;
     59   if (!pFile) {
     60     if (type == "Launch") {
     61       CPDF_Dictionary* pWinDict = m_pDict->GetDict("Win");
     62       if (pWinDict) {
     63         return CFX_WideString::FromLocal(pWinDict->GetString("F"));
     64       }
     65     }
     66     return path;
     67   }
     68   CPDF_FileSpec filespec(pFile);
     69   filespec.GetFileName(path);
     70   return path;
     71 }
     72 CFX_ByteString CPDF_Action::GetURI(CPDF_Document* pDoc) const {
     73   CFX_ByteString csURI;
     74   if (!m_pDict) {
     75     return csURI;
     76   }
     77   if (m_pDict->GetString("S") != "URI") {
     78     return csURI;
     79   }
     80   csURI = m_pDict->GetString("URI");
     81   CPDF_Dictionary* pRoot = pDoc->GetRoot();
     82   CPDF_Dictionary* pURI = pRoot->GetDict("URI");
     83   if (pURI) {
     84     if (csURI.Find(":", 0) < 1) {
     85       csURI = pURI->GetString("Base") + csURI;
     86     }
     87   }
     88   return csURI;
     89 }
     90 FX_DWORD CPDF_ActionFields::GetFieldsCount() const {
     91   if (!m_pAction) {
     92     return 0;
     93   }
     94   CPDF_Dictionary* pDict = m_pAction->GetDict();
     95   if (!pDict) {
     96     return 0;
     97   }
     98   CFX_ByteString csType = pDict->GetString("S");
     99   CPDF_Object* pFields = NULL;
    100   if (csType == "Hide") {
    101     pFields = pDict->GetElementValue("T");
    102   } else {
    103     pFields = pDict->GetArray("Fields");
    104   }
    105   if (!pFields)
    106     return 0;
    107   if (pFields->IsDictionary())
    108     return 1;
    109   if (pFields->IsString())
    110     return 1;
    111   if (CPDF_Array* pArray = pFields->AsArray())
    112     return pArray->GetCount();
    113   return 0;
    114 }
    115 
    116 std::vector<CPDF_Object*> CPDF_ActionFields::GetAllFields() const {
    117   std::vector<CPDF_Object*> fields;
    118   if (!m_pAction)
    119     return fields;
    120 
    121   CPDF_Dictionary* pDict = m_pAction->GetDict();
    122   if (!pDict)
    123     return fields;
    124 
    125   CFX_ByteString csType = pDict->GetString("S");
    126   CPDF_Object* pFields;
    127   if (csType == "Hide")
    128     pFields = pDict->GetElementValue("T");
    129   else
    130     pFields = pDict->GetArray("Fields");
    131   if (!pFields)
    132     return fields;
    133 
    134   if (pFields->IsDictionary() || pFields->IsString()) {
    135     fields.push_back(pFields);
    136   } else if (CPDF_Array* pArray = pFields->AsArray()) {
    137     FX_DWORD iCount = pArray->GetCount();
    138     for (FX_DWORD i = 0; i < iCount; ++i) {
    139       CPDF_Object* pObj = pArray->GetElementValue(i);
    140       if (pObj) {
    141         fields.push_back(pObj);
    142       }
    143     }
    144   }
    145   return fields;
    146 }
    147 
    148 CPDF_Object* CPDF_ActionFields::GetField(FX_DWORD iIndex) const {
    149   if (!m_pAction) {
    150     return NULL;
    151   }
    152   CPDF_Dictionary* pDict = m_pAction->GetDict();
    153   if (!pDict) {
    154     return NULL;
    155   }
    156   CFX_ByteString csType = pDict->GetString("S");
    157   CPDF_Object* pFields = NULL;
    158   if (csType == "Hide") {
    159     pFields = pDict->GetElementValue("T");
    160   } else {
    161     pFields = pDict->GetArray("Fields");
    162   }
    163   if (!pFields) {
    164     return NULL;
    165   }
    166   CPDF_Object* pFindObj = NULL;
    167   if (pFields->IsDictionary() || pFields->IsString()) {
    168     if (iIndex == 0)
    169       pFindObj = pFields;
    170   } else if (CPDF_Array* pArray = pFields->AsArray()) {
    171     pFindObj = pArray->GetElementValue(iIndex);
    172   }
    173   return pFindObj;
    174 }
    175 
    176 CFX_WideString CPDF_Action::GetJavaScript() const {
    177   CFX_WideString csJS;
    178   if (!m_pDict) {
    179     return csJS;
    180   }
    181   CPDF_Object* pJS = m_pDict->GetElementValue("JS");
    182   return pJS ? pJS->GetUnicodeText() : csJS;
    183 }
    184 CPDF_Dictionary* CPDF_Action::GetAnnot() const {
    185   if (!m_pDict) {
    186     return nullptr;
    187   }
    188   CFX_ByteString csType = m_pDict->GetString("S");
    189   if (csType == "Rendition") {
    190     return m_pDict->GetDict("AN");
    191   }
    192   if (csType == "Movie") {
    193     return m_pDict->GetDict("Annotation");
    194   }
    195   return nullptr;
    196 }
    197 int32_t CPDF_Action::GetOperationType() const {
    198   if (!m_pDict) {
    199     return 0;
    200   }
    201   CFX_ByteString csType = m_pDict->GetString("S");
    202   if (csType == "Rendition") {
    203     return m_pDict->GetInteger("OP");
    204   }
    205   if (csType == "Movie") {
    206     CFX_ByteString csOP = m_pDict->GetString("Operation");
    207     if (csOP == "Play") {
    208       return 0;
    209     }
    210     if (csOP == "Stop") {
    211       return 1;
    212     }
    213     if (csOP == "Pause") {
    214       return 2;
    215     }
    216     if (csOP == "Resume") {
    217       return 3;
    218     }
    219   }
    220   return 0;
    221 }
    222 FX_DWORD CPDF_Action::GetSubActionsCount() const {
    223   if (!m_pDict || !m_pDict->KeyExist("Next"))
    224     return 0;
    225 
    226   CPDF_Object* pNext = m_pDict->GetElementValue("Next");
    227   if (!pNext)
    228     return 0;
    229   if (pNext->IsDictionary())
    230     return 1;
    231   if (CPDF_Array* pArray = pNext->AsArray())
    232     return pArray->GetCount();
    233   return 0;
    234 }
    235 CPDF_Action CPDF_Action::GetSubAction(FX_DWORD iIndex) const {
    236   if (!m_pDict || !m_pDict->KeyExist("Next")) {
    237     return CPDF_Action();
    238   }
    239   CPDF_Object* pNext = m_pDict->GetElementValue("Next");
    240   if (CPDF_Dictionary* pDict = ToDictionary(pNext)) {
    241     if (iIndex == 0)
    242       return CPDF_Action(pDict);
    243   } else if (CPDF_Array* pArray = ToArray(pNext)) {
    244     return CPDF_Action(pArray->GetDict(iIndex));
    245   }
    246   return CPDF_Action();
    247 }
    248 const FX_CHAR* g_sAATypes[] = {"E",  "X",  "D",  "U",  "Fo", "Bl", "PO", "PC",
    249                                "PV", "PI", "O",  "C",  "K",  "F",  "V",  "C",
    250                                "WC", "WS", "DS", "WP", "DP", ""};
    251 FX_BOOL CPDF_AAction::ActionExist(AActionType eType) const {
    252   return m_pDict && m_pDict->KeyExist(g_sAATypes[(int)eType]);
    253 }
    254 CPDF_Action CPDF_AAction::GetAction(AActionType eType) const {
    255   if (!m_pDict) {
    256     return CPDF_Action();
    257   }
    258   return CPDF_Action(m_pDict->GetDict(g_sAATypes[(int)eType]));
    259 }
    260 
    261 CPDF_DocJSActions::CPDF_DocJSActions(CPDF_Document* pDoc) : m_pDocument(pDoc) {}
    262 
    263 int CPDF_DocJSActions::CountJSActions() const {
    264   ASSERT(m_pDocument);
    265   CPDF_NameTree name_tree(m_pDocument, "JavaScript");
    266   return name_tree.GetCount();
    267 }
    268 CPDF_Action CPDF_DocJSActions::GetJSAction(int index,
    269                                            CFX_ByteString& csName) const {
    270   ASSERT(m_pDocument);
    271   CPDF_NameTree name_tree(m_pDocument, "JavaScript");
    272   CPDF_Object* pAction = name_tree.LookupValue(index, csName);
    273   if (!ToDictionary(pAction)) {
    274     return CPDF_Action();
    275   }
    276   return CPDF_Action(pAction->GetDict());
    277 }
    278 CPDF_Action CPDF_DocJSActions::GetJSAction(const CFX_ByteString& csName) const {
    279   ASSERT(m_pDocument);
    280   CPDF_NameTree name_tree(m_pDocument, "JavaScript");
    281   CPDF_Object* pAction = name_tree.LookupValue(csName);
    282   if (!ToDictionary(pAction)) {
    283     return CPDF_Action();
    284   }
    285   return CPDF_Action(pAction->GetDict());
    286 }
    287 int CPDF_DocJSActions::FindJSAction(const CFX_ByteString& csName) const {
    288   ASSERT(m_pDocument);
    289   CPDF_NameTree name_tree(m_pDocument, "JavaScript");
    290   return name_tree.GetIndex(csName);
    291 }
    292