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

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

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

Powered by Google App Engine
This is Rietveld 408576698