OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../include/fpdfdoc/fpdf_doc.h" | 7 #include "../../include/fpdfdoc/fpdf_doc.h" |
8 #include "doc_utils.h" | 8 #include "doc_utils.h" |
9 | 9 |
10 const int nMaxRecursion = 32; | 10 const int nMaxRecursion = 32; |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 } | 249 } |
250 CPDF_Array* pFields = m_pFormDict->GetArray("Fields"); | 250 CPDF_Array* pFields = m_pFormDict->GetArray("Fields"); |
251 if (pFields == NULL) { | 251 if (pFields == NULL) { |
252 return; | 252 return; |
253 } | 253 } |
254 int count = pFields->GetCount(); | 254 int count = pFields->GetCount(); |
255 for (int i = 0; i < count; i++) { | 255 for (int i = 0; i < count; i++) { |
256 LoadField(pFields->GetDict(i)); | 256 LoadField(pFields->GetDict(i)); |
257 } | 257 } |
258 } | 258 } |
| 259 |
259 CPDF_InterForm::~CPDF_InterForm() { | 260 CPDF_InterForm::~CPDF_InterForm() { |
260 FX_POSITION pos = m_ControlMap.GetStartPosition(); | 261 for (auto it : m_ControlMap) |
261 while (pos) { | 262 delete it.second; |
262 void* key; | 263 if (m_pFieldTree) { |
263 void* value; | |
264 m_ControlMap.GetNextAssoc(pos, key, value); | |
265 delete (CPDF_FormControl*)value; | |
266 } | |
267 if (m_pFieldTree != NULL) { | |
268 int nCount = m_pFieldTree->m_Root.CountFields(); | 264 int nCount = m_pFieldTree->m_Root.CountFields(); |
269 for (int i = 0; i < nCount; i++) { | 265 for (int i = 0; i < nCount; ++i) { |
270 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); | 266 delete m_pFieldTree->m_Root.GetField(i); |
271 delete pField; | |
272 } | 267 } |
273 delete m_pFieldTree; | 268 delete m_pFieldTree; |
274 } | 269 } |
275 } | 270 } |
| 271 |
276 FX_BOOL CPDF_InterForm::m_bUpdateAP = TRUE; | 272 FX_BOOL CPDF_InterForm::m_bUpdateAP = TRUE; |
277 FX_BOOL CPDF_InterForm::UpdatingAPEnabled() { | 273 FX_BOOL CPDF_InterForm::UpdatingAPEnabled() { |
278 return m_bUpdateAP; | 274 return m_bUpdateAP; |
279 } | 275 } |
280 void CPDF_InterForm::EnableUpdateAP(FX_BOOL bUpdateAP) { | 276 void CPDF_InterForm::EnableUpdateAP(FX_BOOL bUpdateAP) { |
281 m_bUpdateAP = bUpdateAP; | 277 m_bUpdateAP = bUpdateAP; |
282 } | 278 } |
283 CFX_ByteString CPDF_InterForm::GenerateNewResourceName( | 279 CFX_ByteString CPDF_InterForm::GenerateNewResourceName( |
284 const CPDF_Dictionary* pResDict, | 280 const CPDF_Dictionary* pResDict, |
285 const FX_CHAR* csType, | 281 const FX_CHAR* csType, |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 return FALSE; | 780 return FALSE; |
785 } | 781 } |
786 CPDF_FormField* CPDF_InterForm::GetFieldByDict( | 782 CPDF_FormField* CPDF_InterForm::GetFieldByDict( |
787 CPDF_Dictionary* pFieldDict) const { | 783 CPDF_Dictionary* pFieldDict) const { |
788 if (pFieldDict == NULL) { | 784 if (pFieldDict == NULL) { |
789 return NULL; | 785 return NULL; |
790 } | 786 } |
791 CFX_WideString csWName = GetFullName(pFieldDict); | 787 CFX_WideString csWName = GetFullName(pFieldDict); |
792 return m_pFieldTree->GetField(csWName); | 788 return m_pFieldTree->GetField(csWName); |
793 } | 789 } |
794 FX_DWORD CPDF_InterForm::CountControls(CFX_WideString csFieldName) { | 790 |
795 if (csFieldName.IsEmpty()) { | |
796 return (FX_DWORD)m_ControlMap.GetCount(); | |
797 } | |
798 CPDF_FormField* pField = m_pFieldTree->GetField(csFieldName); | |
799 if (pField == NULL) { | |
800 return 0; | |
801 } | |
802 return pField->m_ControlList.GetSize(); | |
803 } | |
804 CPDF_FormControl* CPDF_InterForm::GetControl(FX_DWORD index, | |
805 CFX_WideString csFieldName) { | |
806 CPDF_FormField* pField = m_pFieldTree->GetField(csFieldName); | |
807 if (pField == NULL) { | |
808 return NULL; | |
809 } | |
810 if (index < (FX_DWORD)pField->m_ControlList.GetSize()) { | |
811 return (CPDF_FormControl*)pField->m_ControlList.GetAt(index); | |
812 } | |
813 return NULL; | |
814 } | |
815 FX_BOOL CPDF_InterForm::IsValidFormControl(const void* pControl) { | |
816 if (pControl == NULL) { | |
817 return FALSE; | |
818 } | |
819 FX_POSITION pos = m_ControlMap.GetStartPosition(); | |
820 while (pos) { | |
821 CPDF_Dictionary* pWidgetDict = NULL; | |
822 void* pFormControl = NULL; | |
823 m_ControlMap.GetNextAssoc(pos, (void*&)pWidgetDict, pFormControl); | |
824 if (pControl == pFormControl) { | |
825 return TRUE; | |
826 } | |
827 } | |
828 return FALSE; | |
829 } | |
830 int CPDF_InterForm::CountPageControls(CPDF_Page* pPage) const { | |
831 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); | |
832 if (pAnnotList == NULL) { | |
833 return 0; | |
834 } | |
835 int count = 0; | |
836 for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i++) { | |
837 CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i); | |
838 if (pAnnot == NULL) { | |
839 continue; | |
840 } | |
841 CPDF_FormControl* pControl; | |
842 if (!m_ControlMap.Lookup(pAnnot, (void*&)pControl)) { | |
843 continue; | |
844 } | |
845 count++; | |
846 } | |
847 return count; | |
848 } | |
849 CPDF_FormControl* CPDF_InterForm::GetPageControl(CPDF_Page* pPage, | |
850 int index) const { | |
851 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); | |
852 if (pAnnotList == NULL) { | |
853 return NULL; | |
854 } | |
855 int count = 0; | |
856 for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i++) { | |
857 CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i); | |
858 if (pAnnot == NULL) { | |
859 continue; | |
860 } | |
861 CPDF_FormControl* pControl; | |
862 if (!m_ControlMap.Lookup(pAnnot, (void*&)pControl)) { | |
863 continue; | |
864 } | |
865 if (index == count) { | |
866 return pControl; | |
867 } | |
868 count++; | |
869 } | |
870 return NULL; | |
871 } | |
872 CPDF_FormControl* CPDF_InterForm::GetControlAtPoint(CPDF_Page* pPage, | 791 CPDF_FormControl* CPDF_InterForm::GetControlAtPoint(CPDF_Page* pPage, |
873 FX_FLOAT pdf_x, | 792 FX_FLOAT pdf_x, |
874 FX_FLOAT pdf_y) const { | 793 FX_FLOAT pdf_y, |
| 794 int* z_order) const { |
875 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); | 795 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); |
876 if (pAnnotList == NULL) { | 796 if (!pAnnotList) |
877 return NULL; | 797 return nullptr; |
| 798 |
| 799 for (FX_DWORD i = pAnnotList->GetCount(); i > 0; --i) { |
| 800 FX_DWORD annot_index = i - 1; |
| 801 CPDF_Dictionary* pAnnot = pAnnotList->GetDict(annot_index); |
| 802 if (!pAnnot) |
| 803 continue; |
| 804 |
| 805 const auto it = m_ControlMap.find(pAnnot); |
| 806 if (it == m_ControlMap.end()) |
| 807 continue; |
| 808 |
| 809 CPDF_FormControl* pControl = it->second; |
| 810 CFX_FloatRect rect = pControl->GetRect(); |
| 811 if (!rect.Contains(pdf_x, pdf_y)) |
| 812 continue; |
| 813 |
| 814 if (z_order) |
| 815 *z_order = annot_index; |
| 816 return pControl; |
878 } | 817 } |
879 for (FX_DWORD i = pAnnotList->GetCount(); i > 0; i--) { | 818 return nullptr; |
880 CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i - 1); | |
881 if (pAnnot == NULL) { | |
882 continue; | |
883 } | |
884 CPDF_FormControl* pControl; | |
885 if (!m_ControlMap.Lookup(pAnnot, (void*&)pControl)) { | |
886 continue; | |
887 } | |
888 CFX_FloatRect rect = pControl->GetRect(); | |
889 if (rect.Contains(pdf_x, pdf_y)) { | |
890 return pControl; | |
891 } | |
892 } | |
893 return NULL; | |
894 } | 819 } |
| 820 |
895 CPDF_FormControl* CPDF_InterForm::GetControlByDict( | 821 CPDF_FormControl* CPDF_InterForm::GetControlByDict( |
896 CPDF_Dictionary* pWidgetDict) const { | 822 CPDF_Dictionary* pWidgetDict) const { |
897 CPDF_FormControl* pControl = NULL; | 823 const auto it = m_ControlMap.find(pWidgetDict); |
898 m_ControlMap.Lookup(pWidgetDict, (void*&)pControl); | 824 return it != m_ControlMap.end() ? it->second : nullptr; |
899 return pControl; | |
900 } | |
901 FX_DWORD CPDF_InterForm::CountInternalFields( | |
902 const CFX_WideString& csFieldName) const { | |
903 if (!m_pFormDict) { | |
904 return 0; | |
905 } | |
906 CPDF_Array* pArray = m_pFormDict->GetArray("Fields"); | |
907 if (!pArray) { | |
908 return 0; | |
909 } | |
910 if (csFieldName.IsEmpty()) { | |
911 return pArray->GetCount(); | |
912 } | |
913 int iLength = csFieldName.GetLength(); | |
914 int iPos = 0; | |
915 CPDF_Dictionary* pDict = NULL; | |
916 while (pArray != NULL) { | |
917 CFX_WideString csSub; | |
918 if (iPos < iLength && csFieldName[iPos] == L'.') { | |
919 iPos++; | |
920 } | |
921 while (iPos < iLength && csFieldName[iPos] != L'.') { | |
922 csSub += csFieldName[iPos++]; | |
923 } | |
924 int iCount = pArray->GetCount(); | |
925 FX_BOOL bFind = FALSE; | |
926 for (int i = 0; i < iCount; i++) { | |
927 pDict = pArray->GetDict(i); | |
928 if (pDict == NULL) { | |
929 continue; | |
930 } | |
931 CFX_WideString csT = pDict->GetUnicodeText("T"); | |
932 if (csT == csSub) { | |
933 bFind = TRUE; | |
934 break; | |
935 } | |
936 } | |
937 if (!bFind) { | |
938 return 0; | |
939 } | |
940 if (iPos >= iLength) { | |
941 break; | |
942 } | |
943 pArray = pDict->GetArray("Kids"); | |
944 } | |
945 if (!pDict) { | |
946 return 0; | |
947 } | |
948 pArray = pDict->GetArray("Kids"); | |
949 return pArray ? pArray->GetCount() : 1; | |
950 } | 825 } |
951 | 826 |
952 CPDF_Dictionary* CPDF_InterForm::GetInternalField( | |
953 FX_DWORD index, | |
954 const CFX_WideString& csFieldName) const { | |
955 if (!m_pFormDict) { | |
956 return nullptr; | |
957 } | |
958 CPDF_Array* pArray = m_pFormDict->GetArray("Fields"); | |
959 if (!pArray) { | |
960 return nullptr; | |
961 } | |
962 if (csFieldName.IsEmpty()) { | |
963 return pArray->GetDict(index); | |
964 } | |
965 int iLength = csFieldName.GetLength(); | |
966 int iPos = 0; | |
967 CPDF_Dictionary* pDict = NULL; | |
968 while (pArray != NULL) { | |
969 CFX_WideString csSub; | |
970 if (iPos < iLength && csFieldName[iPos] == L'.') { | |
971 iPos++; | |
972 } | |
973 while (iPos < iLength && csFieldName[iPos] != L'.') { | |
974 csSub += csFieldName[iPos++]; | |
975 } | |
976 int iCount = pArray->GetCount(); | |
977 FX_BOOL bFind = FALSE; | |
978 for (int i = 0; i < iCount; i++) { | |
979 pDict = pArray->GetDict(i); | |
980 if (pDict == NULL) { | |
981 continue; | |
982 } | |
983 CFX_WideString csT = pDict->GetUnicodeText("T"); | |
984 if (csT == csSub) { | |
985 bFind = TRUE; | |
986 break; | |
987 } | |
988 } | |
989 if (!bFind) { | |
990 return NULL; | |
991 } | |
992 if (iPos >= iLength) { | |
993 break; | |
994 } | |
995 pArray = pDict->GetArray("Kids"); | |
996 } | |
997 if (!pDict) { | |
998 return nullptr; | |
999 } | |
1000 pArray = pDict->GetArray("Kids"); | |
1001 return pArray ? pArray->GetDict(index) : pDict; | |
1002 } | |
1003 FX_BOOL CPDF_InterForm::NeedConstructAP() { | 827 FX_BOOL CPDF_InterForm::NeedConstructAP() { |
1004 if (m_pFormDict == NULL) { | 828 if (m_pFormDict == NULL) { |
1005 return FALSE; | 829 return FALSE; |
1006 } | 830 } |
1007 return m_pFormDict->GetBoolean("NeedAppearances"); | 831 return m_pFormDict->GetBoolean("NeedAppearances"); |
1008 } | 832 } |
1009 void CPDF_InterForm::NeedConstructAP(FX_BOOL bNeedAP) { | 833 void CPDF_InterForm::NeedConstructAP(FX_BOOL bNeedAP) { |
1010 if (m_pFormDict == NULL) { | 834 if (m_pFormDict == NULL) { |
1011 InitInterFormDict(m_pFormDict, m_pDocument); | 835 InitInterFormDict(m_pFormDict, m_pDocument); |
1012 } | 836 } |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 if (pField == NULL) { | 992 if (pField == NULL) { |
1169 continue; | 993 continue; |
1170 } | 994 } |
1171 pField->ResetField(bNotify); | 995 pField->ResetField(bNotify); |
1172 } | 996 } |
1173 if (bNotify && m_pFormNotify != NULL) { | 997 if (bNotify && m_pFormNotify != NULL) { |
1174 m_pFormNotify->AfterFormReset(this); | 998 m_pFormNotify->AfterFormReset(this); |
1175 } | 999 } |
1176 return TRUE; | 1000 return TRUE; |
1177 } | 1001 } |
1178 void CPDF_InterForm::ReloadForm() { | |
1179 FX_POSITION pos = m_ControlMap.GetStartPosition(); | |
1180 while (pos) { | |
1181 CPDF_Dictionary* pWidgetDict; | |
1182 CPDF_FormControl* pControl; | |
1183 m_ControlMap.GetNextAssoc(pos, (void*&)pWidgetDict, (void*&)pControl); | |
1184 delete pControl; | |
1185 } | |
1186 m_ControlMap.RemoveAll(); | |
1187 int nCount = m_pFieldTree->m_Root.CountFields(); | |
1188 for (int k = 0; k < nCount; k++) { | |
1189 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(k); | |
1190 delete pField; | |
1191 } | |
1192 m_pFieldTree->RemoveAll(); | |
1193 if (m_pFormDict == NULL) { | |
1194 return; | |
1195 } | |
1196 CPDF_Array* pFields = m_pFormDict->GetArray("Fields"); | |
1197 if (pFields == NULL) { | |
1198 return; | |
1199 } | |
1200 int iCount = pFields->GetCount(); | |
1201 for (int i = 0; i < iCount; i++) { | |
1202 LoadField(pFields->GetDict(i)); | |
1203 } | |
1204 } | |
1205 void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel) { | 1002 void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel) { |
1206 if (nLevel > nMaxRecursion) { | 1003 if (nLevel > nMaxRecursion) { |
1207 return; | 1004 return; |
1208 } | 1005 } |
1209 if (pFieldDict == NULL) { | 1006 if (pFieldDict == NULL) { |
1210 return; | 1007 return; |
1211 } | 1008 } |
1212 FX_DWORD dwParentObjNum = pFieldDict->GetObjNum(); | 1009 FX_DWORD dwParentObjNum = pFieldDict->GetObjNum(); |
1213 CPDF_Array* pKids = pFieldDict->GetArray("Kids"); | 1010 CPDF_Array* pKids = pFieldDict->GetArray("Kids"); |
1214 if (!pKids) { | 1011 if (!pKids) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 continue; | 1113 continue; |
1317 } | 1114 } |
1318 AddControl(pField, pKid); | 1115 AddControl(pField, pKid); |
1319 } | 1116 } |
1320 } | 1117 } |
1321 return pField; | 1118 return pField; |
1322 } | 1119 } |
1323 CPDF_FormControl* CPDF_InterForm::AddControl( | 1120 CPDF_FormControl* CPDF_InterForm::AddControl( |
1324 const CPDF_FormField* pField, | 1121 const CPDF_FormField* pField, |
1325 const CPDF_Dictionary* pWidgetDict) { | 1122 const CPDF_Dictionary* pWidgetDict) { |
1326 void* rValue = NULL; | 1123 const auto it = m_ControlMap.find(pWidgetDict); |
1327 if (m_ControlMap.Lookup((CPDF_Dictionary*)pWidgetDict, rValue)) { | 1124 if (it != m_ControlMap.end()) |
1328 return (CPDF_FormControl*)rValue; | 1125 return it->second; |
1329 } | 1126 |
1330 CPDF_FormControl* pControl = new CPDF_FormControl( | 1127 CPDF_FormControl* pControl = new CPDF_FormControl( |
1331 (CPDF_FormField*)pField, (CPDF_Dictionary*)pWidgetDict); | 1128 (CPDF_FormField*)pField, (CPDF_Dictionary*)pWidgetDict); |
1332 if (pControl == NULL) { | 1129 m_ControlMap[pWidgetDict] = pControl; |
1333 return NULL; | |
1334 } | |
1335 m_ControlMap.SetAt((CPDF_Dictionary*)pWidgetDict, pControl); | |
1336 ((CPDF_FormField*)pField)->m_ControlList.Add(pControl); | 1130 ((CPDF_FormField*)pField)->m_ControlList.Add(pControl); |
1337 return pControl; | 1131 return pControl; |
1338 } | 1132 } |
1339 CPDF_FormField* CPDF_InterForm::CheckRequiredFields( | 1133 CPDF_FormField* CPDF_InterForm::CheckRequiredFields( |
1340 const CFX_PtrArray* fields, | 1134 const CFX_PtrArray* fields, |
1341 FX_BOOL bIncludeOrExclude) const { | 1135 FX_BOOL bIncludeOrExclude) const { |
1342 int nCount = m_pFieldTree->m_Root.CountFields(); | 1136 int nCount = m_pFieldTree->m_Root.CountFields(); |
1343 for (int i = 0; i < nCount; i++) { | 1137 for (int i = 0; i < nCount; i++) { |
1344 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); | 1138 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); |
1345 if (pField == NULL) { | 1139 if (pField == NULL) { |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 FDF_ImportField(pField, L"", bNotify); | 1374 FDF_ImportField(pField, L"", bNotify); |
1581 } | 1375 } |
1582 if (bNotify && m_pFormNotify != NULL) { | 1376 if (bNotify && m_pFormNotify != NULL) { |
1583 m_pFormNotify->AfterFormImportData(this); | 1377 m_pFormNotify->AfterFormImportData(this); |
1584 } | 1378 } |
1585 return TRUE; | 1379 return TRUE; |
1586 } | 1380 } |
1587 void CPDF_InterForm::SetFormNotify(const CPDF_FormNotify* pNotify) { | 1381 void CPDF_InterForm::SetFormNotify(const CPDF_FormNotify* pNotify) { |
1588 m_pFormNotify = (CPDF_FormNotify*)pNotify; | 1382 m_pFormNotify = (CPDF_FormNotify*)pNotify; |
1589 } | 1383 } |
1590 int CPDF_InterForm::GetPageWithWidget(int iCurPage, FX_BOOL bNext) { | |
1591 if (iCurPage < 0) { | |
1592 return -1; | |
1593 } | |
1594 int iPageCount = m_pDocument->GetPageCount(); | |
1595 if (iCurPage >= iPageCount) { | |
1596 return -1; | |
1597 } | |
1598 int iNewPage = iCurPage; | |
1599 do { | |
1600 iNewPage += bNext ? 1 : -1; | |
1601 if (iNewPage >= iPageCount) { | |
1602 iNewPage = 0; | |
1603 } | |
1604 if (iNewPage < 0) { | |
1605 iNewPage = iPageCount - 1; | |
1606 } | |
1607 if (iNewPage == iCurPage) { | |
1608 break; | |
1609 } | |
1610 CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iNewPage); | |
1611 if (pPageDict == NULL) { | |
1612 continue; | |
1613 } | |
1614 CPDF_Array* pAnnots = pPageDict->GetArray("Annots"); | |
1615 if (pAnnots == NULL) { | |
1616 continue; | |
1617 } | |
1618 FX_DWORD dwCount = pAnnots->GetCount(); | |
1619 for (FX_DWORD i = 0; i < dwCount; i++) { | |
1620 CPDF_Object* pAnnotDict = pAnnots->GetElementValue(i); | |
1621 if (pAnnotDict == NULL) { | |
1622 continue; | |
1623 } | |
1624 CPDF_FormControl* pControl = NULL; | |
1625 if (m_ControlMap.Lookup(pAnnotDict, (void*&)pControl)) { | |
1626 return iNewPage; | |
1627 } | |
1628 } | |
1629 } while (TRUE); | |
1630 return -1; | |
1631 } | |
OLD | NEW |