Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(271)

Side by Side Diff: core/src/fpdfdoc/doc_form.cpp

Issue 1295893005: Merge to XFA: Add new public APIs to find the z-order for links and widgets. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@xfa
Patch Set: self review Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/include/fpdfdoc/fpdf_doc.h ('k') | core/src/fpdfdoc/doc_formcontrol.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « core/include/fpdfdoc/fpdf_doc.h ('k') | core/src/fpdfdoc/doc_formcontrol.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698