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