Commit ca5fafb0f8779507c95a75e5d9eb712613e43702
Committed by
GitHub
Merge pull request #1637 from m-holger/ca
Enhance `AcroForm::transformAnnotations` to update '/P' field
Showing
6 changed files
with
94 additions
and
73 deletions
libqpdf/QPDFAcroFormDocumentHelper.cc
| ... | ... | @@ -843,7 +843,14 @@ QPDFAcroFormDocumentHelper::transformAnnotations( |
| 843 | 843 | from_afdh = &QPDFAcroFormDocumentHelper::get(*from_qpdf); |
| 844 | 844 | } |
| 845 | 845 | m->transformAnnotations( |
| 846 | - a_old_annots, new_annots, new_fields, old_fields, cm, from_qpdf, from_afdh->m.get()); | |
| 846 | + a_old_annots, | |
| 847 | + new_annots, | |
| 848 | + new_fields, | |
| 849 | + old_fields, | |
| 850 | + cm, | |
| 851 | + from_qpdf, | |
| 852 | + from_afdh->m.get(), | |
| 853 | + nullptr); | |
| 847 | 854 | } |
| 848 | 855 | |
| 849 | 856 | void |
| ... | ... | @@ -854,7 +861,8 @@ AcroForm::transformAnnotations( |
| 854 | 861 | std::set<QPDFObjGen>& old_fields, |
| 855 | 862 | QPDFMatrix const& cm, |
| 856 | 863 | QPDF* from_qpdf, |
| 857 | - AcroForm* from_afdh) | |
| 864 | + AcroForm* from_afdh, | |
| 865 | + QPDFObjectHandle* new_page) | |
| 858 | 866 | { |
| 859 | 867 | qpdf_expect(from_qpdf); |
| 860 | 868 | qpdf_expect(from_afdh); |
| ... | ... | @@ -1149,6 +1157,9 @@ AcroForm::transformAnnotations( |
| 1149 | 1157 | } |
| 1150 | 1158 | auto rect = cm.transformRectangle(annot["/Rect"].getArrayAsRectangle()); |
| 1151 | 1159 | annot.replaceKey("/Rect", QPDFObjectHandle::newFromRectangle(rect)); |
| 1160 | + if (new_page && annot.contains("/P")) { | |
| 1161 | + annot.replace("/P", *new_page); | |
| 1162 | + } | |
| 1152 | 1163 | } |
| 1153 | 1164 | } |
| 1154 | 1165 | |
| ... | ... | @@ -1169,7 +1180,7 @@ AcroForm::fixCopiedAnnotations( |
| 1169 | 1180 | AcroForm& from_afdh, |
| 1170 | 1181 | std::set<QPDFObjGen>* added_fields) |
| 1171 | 1182 | { |
| 1172 | - auto old_annots = from_page.getKey("/Annots"); | |
| 1183 | + auto const& old_annots = from_page.getKey("/Annots"); | |
| 1173 | 1184 | if (old_annots.empty() || !old_annots.isArray()) { |
| 1174 | 1185 | return; |
| 1175 | 1186 | } |
| ... | ... | @@ -1184,7 +1195,8 @@ AcroForm::fixCopiedAnnotations( |
| 1184 | 1195 | old_fields, |
| 1185 | 1196 | QPDFMatrix(), |
| 1186 | 1197 | &(from_afdh.qpdf), |
| 1187 | - &from_afdh); | |
| 1198 | + &from_afdh, | |
| 1199 | + &to_page); | |
| 1188 | 1200 | |
| 1189 | 1201 | to_page.replaceKey("/Annots", QPDFObjectHandle::newArray(new_annots)); |
| 1190 | 1202 | addAndRenameFormFields(new_fields); | ... | ... |
libqpdf/qpdf/AcroForm.hh
| ... | ... | @@ -166,7 +166,8 @@ namespace qpdf::impl |
| 166 | 166 | std::set<QPDFObjGen>& old_fields, |
| 167 | 167 | QPDFMatrix const& cm, |
| 168 | 168 | QPDF* from_qpdf, |
| 169 | - AcroForm* from_afdh); | |
| 169 | + AcroForm* from_afdh, | |
| 170 | + QPDFObjectHandle* new_page); | |
| 170 | 171 | |
| 171 | 172 | // Copy form fields and annotations from one page to another, allowing the from page to be |
| 172 | 173 | // in a different QPDF or in the same QPDF. This would typically be called after calling | ... | ... |
libqpdf/qpdf/QPDFObjectHandle_private.hh
| ... | ... | @@ -324,6 +324,12 @@ namespace qpdf |
| 324 | 324 | { |
| 325 | 325 | } |
| 326 | 326 | |
| 327 | + explicit | |
| 328 | + operator bool() const | |
| 329 | + { | |
| 330 | + return obj != nullptr; | |
| 331 | + } | |
| 332 | + | |
| 327 | 333 | // Return the integer value. If the object is not a valid Integer, throw a |
| 328 | 334 | // std::invalid_argument exception. If the object is out of range for the target type, |
| 329 | 335 | // throw a std::overflow_error or std::underflow_error exception. | ... | ... |
manual/release-notes.rst
| ... | ... | @@ -43,6 +43,9 @@ more detail. |
| 43 | 43 | - When parsing qpdf JSON input files allow empty name objects. These are |
| 44 | 44 | allowed by the PDF specification but were previously rejected. |
| 45 | 45 | |
| 46 | + - ``QPDFAcroFormDocumentHelper::fixCopiedAnnotations`` now correctly | |
| 47 | + updates any annotation's ``/P`` entries to point to the owning page. | |
| 48 | + | |
| 46 | 49 | - Library Enhancements |
| 47 | 50 | |
| 48 | 51 | - Add ``QPDFNameTreeObjectHelper`` and ``QPDFNumberTreeObjectHelper`` | ... | ... |
qpdf/qtest/copy-annotations.test
| ... | ... | @@ -71,8 +71,7 @@ $td->runtest("copy annotations with /P entry", |
| 71 | 71 | |
| 72 | 72 | $td->runtest("check output", |
| 73 | 73 | {$td->FILE => "a.pdf"}, |
| 74 | - {$td->FILE => "annotations-no-acroform-with-p.out.pdf"}, | |
| 75 | - $td->EXPECT_FAILURE); | |
| 74 | + {$td->FILE => "annotations-no-acroform-with-p.out.pdf"}); | |
| 76 | 75 | |
| 77 | 76 | $td->runtest("copy annotations no acroform from foreign file", |
| 78 | 77 | {$td->COMMAND => |
| ... | ... | @@ -167,7 +166,7 @@ $td->runtest("check output", |
| 167 | 166 | # field-resource-conflict.pdf was crafted so that an appearance stream |
| 168 | 167 | # had an existing resource that it actually referenced in the |
| 169 | 168 | # appearance stream whose name, /F1_1, clashed with the result of |
| 170 | -# resolving conflicts in /DR. It's a crazy corner case, but it if it | |
| 169 | +# resolving conflicts in /DR. It's a crazy corner case, but if it | |
| 171 | 170 | # ever happened, it would be really hard to track down, and it could |
| 172 | 171 | # arise through multiple passes through qpdf with intervening edits. |
| 173 | 172 | $td->runtest("appearance stream resource conflict", | ... | ... |
qpdf/qtest/qpdf/resolved-appearance-conflicts.pdf
| ... | ... | @@ -119,7 +119,7 @@ endobj |
| 119 | 119 | /MK << |
| 120 | 120 | /CA (8) |
| 121 | 121 | >> |
| 122 | - /P 17 0 R | |
| 122 | + /P 26 0 R | |
| 123 | 123 | /Rect [ |
| 124 | 124 | 174.5 |
| 125 | 125 | 719.7 |
| ... | ... | @@ -136,7 +136,7 @@ endobj |
| 136 | 136 | 6 0 obj |
| 137 | 137 | << |
| 138 | 138 | /AP << |
| 139 | - /N 26 0 R | |
| 139 | + /N 27 0 R | |
| 140 | 140 | >> |
| 141 | 141 | /DA (0.29803 0.29803 0.29803 rg /F1 12 Tf) |
| 142 | 142 | /DR << |
| ... | ... | @@ -145,7 +145,7 @@ endobj |
| 145 | 145 | /DV <feff> |
| 146 | 146 | /F 4 |
| 147 | 147 | /FT /Tx |
| 148 | - /P 17 0 R | |
| 148 | + /P 26 0 R | |
| 149 | 149 | /Rect [ |
| 150 | 150 | 59.6 |
| 151 | 151 | 715 |
| ... | ... | @@ -163,8 +163,8 @@ endobj |
| 163 | 163 | << |
| 164 | 164 | /AP << |
| 165 | 165 | /N << |
| 166 | - /Off 28 0 R | |
| 167 | - /Yes 30 0 R | |
| 166 | + /Off 29 0 R | |
| 167 | + /Yes 31 0 R | |
| 168 | 168 | >> |
| 169 | 169 | >> |
| 170 | 170 | /AS /Off |
| ... | ... | @@ -176,7 +176,7 @@ endobj |
| 176 | 176 | /MK << |
| 177 | 177 | /CA (8) |
| 178 | 178 | >> |
| 179 | - /P 32 0 R | |
| 179 | + /P 33 0 R | |
| 180 | 180 | /Rect [ |
| 181 | 181 | 174.5 |
| 182 | 182 | 719.7 |
| ... | ... | @@ -193,14 +193,14 @@ endobj |
| 193 | 193 | 8 0 obj |
| 194 | 194 | << |
| 195 | 195 | /AP << |
| 196 | - /N 33 0 R | |
| 196 | + /N 34 0 R | |
| 197 | 197 | >> |
| 198 | 198 | /DA (0.29803 0.29803 0.29803 rg /F1_1 12 Tf) |
| 199 | 199 | /DR 2 0 R |
| 200 | 200 | /DV <feff> |
| 201 | 201 | /F 4 |
| 202 | 202 | /FT /Tx |
| 203 | - /P 32 0 R | |
| 203 | + /P 33 0 R | |
| 204 | 204 | /Rect [ |
| 205 | 205 | 59.6 |
| 206 | 206 | 715 |
| ... | ... | @@ -219,8 +219,8 @@ endobj |
| 219 | 219 | /Count 3 |
| 220 | 220 | /Kids [ |
| 221 | 221 | 17 0 R |
| 222 | - 35 0 R | |
| 223 | - 32 0 R | |
| 222 | + 26 0 R | |
| 223 | + 33 0 R | |
| 224 | 224 | ] |
| 225 | 225 | /Type /Pages |
| 226 | 226 | >> |
| ... | ... | @@ -431,8 +431,41 @@ endobj |
| 431 | 431 | 81 |
| 432 | 432 | endobj |
| 433 | 433 | |
| 434 | +%% Page 2 | |
| 434 | 435 | 26 0 obj |
| 435 | 436 | << |
| 437 | + /Annots [ | |
| 438 | + 5 0 R | |
| 439 | + 6 0 R | |
| 440 | + ] | |
| 441 | + /Contents 37 0 R | |
| 442 | + /Group << | |
| 443 | + /CS /DeviceRGB | |
| 444 | + /I true | |
| 445 | + /S /Transparency | |
| 446 | + >> | |
| 447 | + /MediaBox [ | |
| 448 | + 0 | |
| 449 | + 0 | |
| 450 | + 611.971653543307 | |
| 451 | + 791.971653543307 | |
| 452 | + ] | |
| 453 | + /Parent 9 0 R | |
| 454 | + /Resources << | |
| 455 | + /Font << | |
| 456 | + /F1 10 0 R | |
| 457 | + >> | |
| 458 | + /ProcSet [ | |
| 459 | ||
| 460 | + /Text | |
| 461 | + ] | |
| 462 | + >> | |
| 463 | + /Type /Page | |
| 464 | +>> | |
| 465 | +endobj | |
| 466 | + | |
| 467 | +27 0 obj | |
| 468 | +<< | |
| 436 | 469 | /BBox [ |
| 437 | 470 | 0 |
| 438 | 471 | 0 |
| ... | ... | @@ -447,7 +480,7 @@ endobj |
| 447 | 480 | >> |
| 448 | 481 | /Subtype /Form |
| 449 | 482 | /Type /XObject |
| 450 | - /Length 27 0 R | |
| 483 | + /Length 28 0 R | |
| 451 | 484 | >> |
| 452 | 485 | stream |
| 453 | 486 | BT /F1_1 12 Tf ET |
| ... | ... | @@ -456,11 +489,11 @@ EMC |
| 456 | 489 | endstream |
| 457 | 490 | endobj |
| 458 | 491 | |
| 459 | -27 0 obj | |
| 492 | +28 0 obj | |
| 460 | 493 | 30 |
| 461 | 494 | endobj |
| 462 | 495 | |
| 463 | -28 0 obj | |
| 496 | +29 0 obj | |
| 464 | 497 | << |
| 465 | 498 | /BBox [ |
| 466 | 499 | 0 |
| ... | ... | @@ -471,7 +504,7 @@ endobj |
| 471 | 504 | /Resources 39 0 R |
| 472 | 505 | /Subtype /Form |
| 473 | 506 | /Type /XObject |
| 474 | - /Length 29 0 R | |
| 507 | + /Length 30 0 R | |
| 475 | 508 | >> |
| 476 | 509 | stream |
| 477 | 510 | /Tx BMC |
| ... | ... | @@ -479,11 +512,11 @@ EMC |
| 479 | 512 | endstream |
| 480 | 513 | endobj |
| 481 | 514 | |
| 482 | -29 0 obj | |
| 515 | +30 0 obj | |
| 483 | 516 | 12 |
| 484 | 517 | endobj |
| 485 | 518 | |
| 486 | -30 0 obj | |
| 519 | +31 0 obj | |
| 487 | 520 | << |
| 488 | 521 | /BBox [ |
| 489 | 522 | 0 |
| ... | ... | @@ -494,7 +527,7 @@ endobj |
| 494 | 527 | /Resources 40 0 R |
| 495 | 528 | /Subtype /Form |
| 496 | 529 | /Type /XObject |
| 497 | - /Length 31 0 R | |
| 530 | + /Length 32 0 R | |
| 498 | 531 | >> |
| 499 | 532 | stream |
| 500 | 533 | /Tx BMC |
| ... | ... | @@ -507,12 +540,12 @@ EMC |
| 507 | 540 | endstream |
| 508 | 541 | endobj |
| 509 | 542 | |
| 510 | -31 0 obj | |
| 543 | +32 0 obj | |
| 511 | 544 | 83 |
| 512 | 545 | endobj |
| 513 | 546 | |
| 514 | 547 | %% Page 3 |
| 515 | -32 0 obj | |
| 548 | +33 0 obj | |
| 516 | 549 | << |
| 517 | 550 | /Annots [ |
| 518 | 551 | 7 0 R |
| ... | ... | @@ -544,7 +577,7 @@ endobj |
| 544 | 577 | >> |
| 545 | 578 | endobj |
| 546 | 579 | |
| 547 | -33 0 obj | |
| 580 | +34 0 obj | |
| 548 | 581 | << |
| 549 | 582 | /BBox [ |
| 550 | 583 | 0 |
| ... | ... | @@ -560,7 +593,7 @@ endobj |
| 560 | 593 | >> |
| 561 | 594 | /Subtype /Form |
| 562 | 595 | /Type /XObject |
| 563 | - /Length 34 0 R | |
| 596 | + /Length 35 0 R | |
| 564 | 597 | >> |
| 565 | 598 | stream |
| 566 | 599 | BT /F1_1_1 12 Tf ET |
| ... | ... | @@ -569,41 +602,8 @@ EMC |
| 569 | 602 | endstream |
| 570 | 603 | endobj |
| 571 | 604 | |
| 572 | -34 0 obj | |
| 573 | -32 | |
| 574 | -endobj | |
| 575 | - | |
| 576 | -%% Page 2 | |
| 577 | 605 | 35 0 obj |
| 578 | -<< | |
| 579 | - /Annots [ | |
| 580 | - 5 0 R | |
| 581 | - 6 0 R | |
| 582 | - ] | |
| 583 | - /Contents 37 0 R | |
| 584 | - /Group << | |
| 585 | - /CS /DeviceRGB | |
| 586 | - /I true | |
| 587 | - /S /Transparency | |
| 588 | - >> | |
| 589 | - /MediaBox [ | |
| 590 | - 0 | |
| 591 | - 0 | |
| 592 | - 611.971653543307 | |
| 593 | - 791.971653543307 | |
| 594 | - ] | |
| 595 | - /Parent 9 0 R | |
| 596 | - /Resources << | |
| 597 | - /Font << | |
| 598 | - /F1 10 0 R | |
| 599 | - >> | |
| 600 | - /ProcSet [ | |
| 601 | ||
| 602 | - /Text | |
| 603 | - ] | |
| 604 | - >> | |
| 605 | - /Type /Page | |
| 606 | ->> | |
| 606 | +32 | |
| 607 | 607 | endobj |
| 608 | 608 | |
| 609 | 609 | 36 0 obj |
| ... | ... | @@ -742,16 +742,16 @@ xref |
| 742 | 742 | 0000004092 00000 n |
| 743 | 743 | 0000004112 00000 n |
| 744 | 744 | 0000004347 00000 n |
| 745 | -0000004367 00000 n | |
| 746 | -0000004610 00000 n | |
| 747 | -0000004630 00000 n | |
| 748 | -0000004797 00000 n | |
| 749 | -0000004817 00000 n | |
| 750 | -0000005055 00000 n | |
| 751 | -0000005085 00000 n | |
| 752 | -0000005436 00000 n | |
| 753 | -0000005685 00000 n | |
| 754 | -0000005715 00000 n | |
| 745 | +0000004377 00000 n | |
| 746 | +0000004728 00000 n | |
| 747 | +0000004971 00000 n | |
| 748 | +0000004991 00000 n | |
| 749 | +0000005158 00000 n | |
| 750 | +0000005178 00000 n | |
| 751 | +0000005416 00000 n | |
| 752 | +0000005446 00000 n | |
| 753 | +0000005797 00000 n | |
| 754 | +0000006046 00000 n | |
| 755 | 755 | 0000006066 00000 n |
| 756 | 756 | 0000006194 00000 n |
| 757 | 757 | 0000006531 00000 n | ... | ... |