Commit e37ce44186b74d88551d1e8814141776cd15463e

Authored by m-holger
1 parent c12a6d06

Use QPDFObjGen::set in QPDFAcroFormDocumentHelper::transformAnnotations

libqpdf/QPDFAcroFormDocumentHelper.cc
@@ -882,7 +882,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations( @@ -882,7 +882,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
882 882
883 // Now do the actual copies. 883 // Now do the actual copies.
884 884
885 - std::set<QPDFObjGen> added_new_fields; 885 + QPDFObjGen::set added_new_fields;
886 for (auto annot: old_annots.aitems()) { 886 for (auto annot: old_annots.aitems()) {
887 if (annot.isStream()) { 887 if (annot.isStream()) {
888 annot.warnIfPossible("ignoring annotation that's a stream"); 888 annot.warnIfPossible("ignoring annotation that's a stream");
@@ -964,73 +964,68 @@ QPDFAcroFormDocumentHelper::transformAnnotations( @@ -964,73 +964,68 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
964 // Traverse the field, copying kids, and preserving 964 // Traverse the field, copying kids, and preserving
965 // integrity. 965 // integrity.
966 std::list<QPDFObjectHandle> queue; 966 std::list<QPDFObjectHandle> queue;
  967 + QPDFObjGen::set seen;
967 if (maybe_copy_object(top_field)) { 968 if (maybe_copy_object(top_field)) {
968 queue.push_back(top_field); 969 queue.push_back(top_field);
969 } 970 }
970 - std::set<QPDFObjGen> seen;  
971 - while (!queue.empty()) {  
972 - QPDFObjectHandle obj = queue.front();  
973 - queue.pop_front();  
974 - auto orig_og = obj.getObjGen();  
975 - if (seen.count(orig_og)) {  
976 - // loop  
977 - break;  
978 - }  
979 - seen.insert(orig_og);  
980 - auto parent = obj.getKey("/Parent");  
981 - if (parent.isIndirect()) {  
982 - auto parent_og = parent.getObjGen();  
983 - if (orig_to_copy.count(parent_og)) {  
984 - obj.replaceKey("/Parent", orig_to_copy[parent_og]);  
985 - } else {  
986 - parent.warnIfPossible(  
987 - "while traversing field " +  
988 - obj.getObjGen().unparse(',') + ", found parent (" +  
989 - parent_og.unparse(',') +  
990 - ") that had not been seen, indicating likely"  
991 - " invalid field structure"); 971 + for (; !queue.empty(); queue.pop_front()) {
  972 + auto& obj = queue.front();
  973 + if (seen.add(obj)) {
  974 + auto parent = obj.getKey("/Parent");
  975 + if (parent.isIndirect()) {
  976 + auto parent_og = parent.getObjGen();
  977 + if (orig_to_copy.count(parent_og)) {
  978 + obj.replaceKey("/Parent", orig_to_copy[parent_og]);
  979 + } else {
  980 + parent.warnIfPossible(
  981 + "while traversing field " +
  982 + obj.getObjGen().unparse(',') +
  983 + ", found parent (" + parent_og.unparse(',') +
  984 + ") that had not been seen, indicating likely"
  985 + " invalid field structure");
  986 + }
992 } 987 }
993 - }  
994 - auto kids = obj.getKey("/Kids");  
995 - if (kids.isArray()) {  
996 - for (int i = 0; i < kids.getArrayNItems(); ++i) {  
997 - auto kid = kids.getArrayItem(i);  
998 - if (maybe_copy_object(kid)) {  
999 - kids.setArrayItem(i, kid);  
1000 - queue.push_back(kid); 988 + auto kids = obj.getKey("/Kids");
  989 + if (kids.isArray()) {
  990 + for (int i = 0; i < kids.getArrayNItems(); ++i) {
  991 + auto kid = kids.getArrayItem(i);
  992 + if (maybe_copy_object(kid)) {
  993 + kids.setArrayItem(i, kid);
  994 + queue.push_back(kid);
  995 + }
1001 } 996 }
1002 } 997 }
1003 - }  
1004 998
1005 - if (override_da || override_q) {  
1006 - adjustInheritedFields(  
1007 - obj,  
1008 - override_da,  
1009 - from_default_da,  
1010 - override_q,  
1011 - from_default_q);  
1012 - }  
1013 - if (foreign) {  
1014 - // Lazily initialize our /DR and the conflict map.  
1015 - init_dr_map();  
1016 - // The spec doesn't say anything about /DR on the  
1017 - // field, but lots of writers put one there, and  
1018 - // it is frequently the same as the document-level  
1019 - // /DR. To avoid having the field's /DR point to  
1020 - // information that we are not maintaining, just  
1021 - // reset it to that if it exists. Empirical  
1022 - // evidence suggests that many readers, including  
1023 - // Acrobat, Adobe Acrobat Reader, chrome, firefox,  
1024 - // the mac Preview application, and several of the  
1025 - // free readers on Linux all ignore /DR at the  
1026 - // field level.  
1027 - if (obj.hasKey("/DR")) {  
1028 - obj.replaceKey("/DR", dr); 999 + if (override_da || override_q) {
  1000 + adjustInheritedFields(
  1001 + obj,
  1002 + override_da,
  1003 + from_default_da,
  1004 + override_q,
  1005 + from_default_q);
  1006 + }
  1007 + if (foreign) {
  1008 + // Lazily initialize our /DR and the conflict map.
  1009 + init_dr_map();
  1010 + // The spec doesn't say anything about /DR on the
  1011 + // field, but lots of writers put one there, and
  1012 + // it is frequently the same as the document-level
  1013 + // /DR. To avoid having the field's /DR point to
  1014 + // information that we are not maintaining, just
  1015 + // reset it to that if it exists. Empirical
  1016 + // evidence suggests that many readers, including
  1017 + // Acrobat, Adobe Acrobat Reader, chrome, firefox,
  1018 + // the mac Preview application, and several of the
  1019 + // free readers on Linux all ignore /DR at the
  1020 + // field level.
  1021 + if (obj.hasKey("/DR")) {
  1022 + obj.replaceKey("/DR", dr);
  1023 + }
  1024 + }
  1025 + if (foreign && obj.getKey("/DA").isString() &&
  1026 + (!dr_map.empty())) {
  1027 + adjustDefaultAppearances(obj, dr_map);
1029 } 1028 }
1030 - }  
1031 - if (foreign && obj.getKey("/DA").isString() &&  
1032 - (!dr_map.empty())) {  
1033 - adjustDefaultAppearances(obj, dr_map);  
1034 } 1029 }
1035 } 1030 }
1036 1031
@@ -1058,9 +1053,8 @@ QPDFAcroFormDocumentHelper::transformAnnotations( @@ -1058,9 +1053,8 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
1058 maybe_copy_object(annot); 1053 maybe_copy_object(annot);
1059 1054
1060 // Now we have copies, so we can safely mutate. 1055 // Now we have copies, so we can safely mutate.
1061 - if (have_field && !added_new_fields.count(top_field.getObjGen())) { 1056 + if (have_field && added_new_fields.add(top_field)) {
1062 new_fields.push_back(top_field); 1057 new_fields.push_back(top_field);
1063 - added_new_fields.insert(top_field.getObjGen());  
1064 } 1058 }
1065 new_annots.push_back(annot); 1059 new_annots.push_back(annot);
1066 1060