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 882  
883 883 // Now do the actual copies.
884 884  
885   - std::set<QPDFObjGen> added_new_fields;
  885 + QPDFObjGen::set added_new_fields;
886 886 for (auto annot: old_annots.aitems()) {
887 887 if (annot.isStream()) {
888 888 annot.warnIfPossible("ignoring annotation that's a stream");
... ... @@ -964,73 +964,68 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
964 964 // Traverse the field, copying kids, and preserving
965 965 // integrity.
966 966 std::list<QPDFObjectHandle> queue;
  967 + QPDFObjGen::set seen;
967 968 if (maybe_copy_object(top_field)) {
968 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 1053 maybe_copy_object(annot);
1059 1054  
1060 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 1057 new_fields.push_back(top_field);
1063   - added_new_fields.insert(top_field.getObjGen());
1064 1058 }
1065 1059 new_annots.push_back(annot);
1066 1060  
... ...