Commit 0132261ee06e9b94bdc011eb4dc3fcd3a403e5f3
1 parent
bac55955
Revert getOwningQPDF, and add getQPDF that returns a reference
Showing
9 changed files
with
88 additions
and
70 deletions
ChangeLog
| 1 | +2022-09-07 Jay Berkenbilt <ejb@ql.org> | ||
| 2 | + | ||
| 3 | + * Add QPDFObjectHandle::getQPDF(), which returns a reference, as | ||
| 4 | + an alternative to QPDFObjectHandle::getOwningQPDF(). | ||
| 5 | + | ||
| 1 | 2022-09-06 Jay Berkenbilt <ejb@ql.org> | 6 | 2022-09-06 Jay Berkenbilt <ejb@ql.org> |
| 2 | 7 | ||
| 3 | * For all bounding box methods in QPDFPageObjectHelper other than | 8 | * For all bounding box methods in QPDFPageObjectHelper other than |
include/qpdf/QPDFObjectHandle.hh
| @@ -661,14 +661,17 @@ class QPDFObjectHandle | @@ -661,14 +661,17 @@ class QPDFObjectHandle | ||
| 661 | static QPDFObjectHandle newReserved(QPDF* qpdf); | 661 | static QPDFObjectHandle newReserved(QPDF* qpdf); |
| 662 | 662 | ||
| 663 | // Provide an owning qpdf and object description. The library does | 663 | // Provide an owning qpdf and object description. The library does |
| 664 | - // this automatically with objects that are read from the | ||
| 665 | - // input PDF and with objects that are created programmatically | ||
| 666 | - // and inserted into the QPDF by adding them to an array or a | ||
| 667 | - // dictionary or creating a new indirect object. Most end user | 664 | + // this automatically with objects that are read from the input |
| 665 | + // PDF and with objects that are created programmatically and | ||
| 666 | + // inserted into the QPDF as a new indirect object. Most end user | ||
| 668 | // code will not need to call this. If an object has an owning | 667 | // code will not need to call this. If an object has an owning |
| 669 | // qpdf and object description, it enables qpdf to give warnings | 668 | // qpdf and object description, it enables qpdf to give warnings |
| 670 | // with proper context in some cases where it would otherwise | 669 | // with proper context in some cases where it would otherwise |
| 671 | - // raise exceptions. | 670 | + // raise exceptions. It is okay to add objects without an |
| 671 | + // owning_qpdf to objects that have one, but it is an error to | ||
| 672 | + // have a QPDF contain objects with owning_qpdf set to something | ||
| 673 | + // else. To add objects from another qpdf, use copyForeignObject | ||
| 674 | + // instead. | ||
| 672 | QPDF_DLL | 675 | QPDF_DLL |
| 673 | void setObjectDescription( | 676 | void setObjectDescription( |
| 674 | QPDF* owning_qpdf, std::string const& object_description); | 677 | QPDF* owning_qpdf, std::string const& object_description); |
| @@ -978,23 +981,34 @@ class QPDFObjectHandle | @@ -978,23 +981,34 @@ class QPDFObjectHandle | ||
| 978 | int& min_suffix, | 981 | int& min_suffix, |
| 979 | std::set<std::string>* resource_names = nullptr); | 982 | std::set<std::string>* resource_names = nullptr); |
| 980 | 983 | ||
| 981 | - // If this is an indirect object, return a pointer to the QPDF | ||
| 982 | - // object that owns an indirect object. Direct objects are not | ||
| 983 | - // owned by a QPDF. Usage notes: | ||
| 984 | - // | ||
| 985 | - // * When allow_nullptr is true, this method will return a null | ||
| 986 | - // pointer if the object is not owned by a QPDF. Otherwise, an | ||
| 987 | - // exception is thrown. | 984 | + // A QPDFObjectHandle has an owning QPDF if it is associated with |
| 985 | + // ("owned by") a specific QPDF object. Indirect objects always | ||
| 986 | + // have an owning QPDF. Direct objects that are read from the | ||
| 987 | + // input source will also have an owning QPDF. Programmatically | ||
| 988 | + // created objects will only have one if setObjectDescription was | ||
| 989 | + // called. | ||
| 988 | // | 990 | // |
| 989 | - // * You should not retain the value returned by this method for | ||
| 990 | - // longer than the lifetime of the owning QPDF object. If you | ||
| 991 | - // retain a QPDFObjectHandle longer than the owning QPDF, when | ||
| 992 | - // the QPDF object is destroyed, the QPDFObjectHandle will turn | ||
| 993 | - // into a direct "null" object, and getOwningQPDF() called on it | ||
| 994 | - // at that time will return a null pointer. | ||
| 995 | - QPDF_DLL | ||
| 996 | - QPDF* getOwningQPDF( | ||
| 997 | - bool allow_nullptr = true, std::string const& error_msg = "") const; | 991 | + // When the QPDF object that owns an object is destroyed, the |
| 992 | + // object is changed into a null, and its owner is cleared. | ||
| 993 | + // Therefore you should not retain the value of an owning QPDF | ||
| 994 | + // beyond the life of the QPDF. If in doubt, ask for it each time | ||
| 995 | + // you need it. | ||
| 996 | + | ||
| 997 | + // getOwningQPDF returns a pointer to the owning QPDF is the | ||
| 998 | + // object has one. Otherwise, it returns a null pointer. Use this | ||
| 999 | + // when you are able to handle the case of an object that doesn't | ||
| 1000 | + // have an owning QPDF. | ||
| 1001 | + QPDF_DLL | ||
| 1002 | + QPDF* getOwningQPDF() const; | ||
| 1003 | + // getQPDF, new in qpdf 11, returns a reference owning QPDF. If | ||
| 1004 | + // there is none, it throws a runtime_error. Use this when you | ||
| 1005 | + // know the object has to have an owning QPDF, such as when it's a | ||
| 1006 | + // known indirect object. Since streams are always indirect | ||
| 1007 | + // objects, this method can be used safely for streams. If | ||
| 1008 | + // error_msg is specified, it will be used at the contents of the | ||
| 1009 | + // runtime_error if there is now owner. | ||
| 1010 | + QPDF_DLL | ||
| 1011 | + QPDF& getQPDF(std::string const& error_msg = "") const; | ||
| 998 | 1012 | ||
| 999 | // Create a shallow copy of an object as a direct object, but do not | 1013 | // Create a shallow copy of an object as a direct object, but do not |
| 1000 | // traverse across indirect object boundaries. That means that, | 1014 | // traverse across indirect object boundaries. That means that, |
libqpdf/QPDF.cc
| @@ -2299,14 +2299,14 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign) | @@ -2299,14 +2299,14 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign) | ||
| 2299 | throw std::logic_error( | 2299 | throw std::logic_error( |
| 2300 | "QPDF::copyForeign called with direct object handle"); | 2300 | "QPDF::copyForeign called with direct object handle"); |
| 2301 | } | 2301 | } |
| 2302 | - QPDF* other = foreign.getOwningQPDF(false); | ||
| 2303 | - if (other == this) { | 2302 | + QPDF& other = foreign.getQPDF(); |
| 2303 | + if (&other == this) { | ||
| 2304 | QTC::TC("qpdf", "QPDF copyForeign not foreign"); | 2304 | QTC::TC("qpdf", "QPDF copyForeign not foreign"); |
| 2305 | throw std::logic_error( | 2305 | throw std::logic_error( |
| 2306 | "QPDF::copyForeign called with object from this QPDF"); | 2306 | "QPDF::copyForeign called with object from this QPDF"); |
| 2307 | } | 2307 | } |
| 2308 | 2308 | ||
| 2309 | - ObjCopier& obj_copier = this->m->object_copiers[other->m->unique_id]; | 2309 | + ObjCopier& obj_copier = this->m->object_copiers[other.m->unique_id]; |
| 2310 | if (!obj_copier.visiting.empty()) { | 2310 | if (!obj_copier.visiting.empty()) { |
| 2311 | throw std::logic_error("obj_copier.visiting is not empty" | 2311 | throw std::logic_error("obj_copier.visiting is not empty" |
| 2312 | " at the beginning of copyForeignObject"); | 2312 | " at the beginning of copyForeignObject"); |
| @@ -2490,8 +2490,8 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) | @@ -2490,8 +2490,8 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) | ||
| 2490 | // Copy information from the foreign stream so we can pipe its | 2490 | // Copy information from the foreign stream so we can pipe its |
| 2491 | // data later without keeping the original QPDF object around. | 2491 | // data later without keeping the original QPDF object around. |
| 2492 | 2492 | ||
| 2493 | - QPDF* foreign_stream_qpdf = foreign.getOwningQPDF( | ||
| 2494 | - false, "unable to retrieve owning qpdf from foreign stream"); | 2493 | + QPDF& foreign_stream_qpdf = |
| 2494 | + foreign.getQPDF("unable to retrieve owning qpdf from foreign stream"); | ||
| 2495 | 2495 | ||
| 2496 | auto stream = QPDFObjectHandle::ObjAccessor::asStream(foreign); | 2496 | auto stream = QPDFObjectHandle::ObjAccessor::asStream(foreign); |
| 2497 | if (stream == nullptr) { | 2497 | if (stream == nullptr) { |
| @@ -2499,7 +2499,7 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) | @@ -2499,7 +2499,7 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) | ||
| 2499 | " stream object from foreign stream"); | 2499 | " stream object from foreign stream"); |
| 2500 | } | 2500 | } |
| 2501 | std::shared_ptr<Buffer> stream_buffer = stream->getStreamDataBuffer(); | 2501 | std::shared_ptr<Buffer> stream_buffer = stream->getStreamDataBuffer(); |
| 2502 | - if ((foreign_stream_qpdf->m->immediate_copy_from) && | 2502 | + if ((foreign_stream_qpdf.m->immediate_copy_from) && |
| 2503 | (stream_buffer == nullptr)) { | 2503 | (stream_buffer == nullptr)) { |
| 2504 | // Pull the stream data into a buffer before attempting | 2504 | // Pull the stream data into a buffer before attempting |
| 2505 | // the copy operation. Do it on the source stream so that | 2505 | // the copy operation. Do it on the source stream so that |
| @@ -2529,8 +2529,8 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) | @@ -2529,8 +2529,8 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) | ||
| 2529 | dict.getKey("/DecodeParms")); | 2529 | dict.getKey("/DecodeParms")); |
| 2530 | } else { | 2530 | } else { |
| 2531 | auto foreign_stream_data = std::make_shared<ForeignStreamData>( | 2531 | auto foreign_stream_data = std::make_shared<ForeignStreamData>( |
| 2532 | - foreign_stream_qpdf->m->encp, | ||
| 2533 | - foreign_stream_qpdf->m->file, | 2532 | + foreign_stream_qpdf.m->encp, |
| 2533 | + foreign_stream_qpdf.m->file, | ||
| 2534 | foreign.getObjGen(), | 2534 | foreign.getObjGen(), |
| 2535 | stream->getOffset(), | 2535 | stream->getOffset(), |
| 2536 | stream->getLength(), | 2536 | stream->getLength(), |
libqpdf/QPDFFormFieldObjectHelper.cc
| @@ -362,12 +362,10 @@ QPDFFormFieldObjectHelper::setV(QPDFObjectHandle value, bool need_appearances) | @@ -362,12 +362,10 @@ QPDFFormFieldObjectHelper::setV(QPDFObjectHandle value, bool need_appearances) | ||
| 362 | setFieldAttribute("/V", value); | 362 | setFieldAttribute("/V", value); |
| 363 | } | 363 | } |
| 364 | if (need_appearances) { | 364 | if (need_appearances) { |
| 365 | - QPDF* qpdf = this->oh.getOwningQPDF( | ||
| 366 | - false, | 365 | + QPDF& qpdf = this->oh.getQPDF( |
| 367 | "QPDFFormFieldObjectHelper::setV called with need_appearances = " | 366 | "QPDFFormFieldObjectHelper::setV called with need_appearances = " |
| 368 | "true on an object that is not associated with an owning QPDF"); | 367 | "true on an object that is not associated with an owning QPDF"); |
| 369 | - | ||
| 370 | - QPDFAcroFormDocumentHelper(*qpdf).setNeedAppearances(true); | 368 | + QPDFAcroFormDocumentHelper(qpdf).setNeedAppearances(true); |
| 371 | } | 369 | } |
| 372 | } | 370 | } |
| 373 | 371 | ||
| @@ -881,7 +879,7 @@ QPDFFormFieldObjectHelper::generateTextAppearance( | @@ -881,7 +879,7 @@ QPDFFormFieldObjectHelper::generateTextAppearance( | ||
| 881 | if (found_font_in_dr && resources.isDictionary()) { | 879 | if (found_font_in_dr && resources.isDictionary()) { |
| 882 | QTC::TC("qpdf", "QPDFFormFieldObjectHelper get font from /DR"); | 880 | QTC::TC("qpdf", "QPDFFormFieldObjectHelper get font from /DR"); |
| 883 | if (resources.isIndirect()) { | 881 | if (resources.isIndirect()) { |
| 884 | - resources = resources.getOwningQPDF(false)->makeIndirectObject( | 882 | + resources = resources.getQPDF().makeIndirectObject( |
| 885 | resources.shallowCopy()); | 883 | resources.shallowCopy()); |
| 886 | AS.getDict().replaceKey("/Resources", resources); | 884 | AS.getDict().replaceKey("/Resources", resources); |
| 887 | } | 885 | } |
libqpdf/QPDFJob.cc
| @@ -2194,8 +2194,8 @@ QPDFJob::doUnderOverlayForPage( | @@ -2194,8 +2194,8 @@ QPDFJob::doUnderOverlayForPage( | ||
| 2194 | std::map<unsigned long long, std::shared_ptr<QPDFAcroFormDocumentHelper>> | 2194 | std::map<unsigned long long, std::shared_ptr<QPDFAcroFormDocumentHelper>> |
| 2195 | afdh; | 2195 | afdh; |
| 2196 | auto make_afdh = [&](QPDFPageObjectHelper& ph) { | 2196 | auto make_afdh = [&](QPDFPageObjectHelper& ph) { |
| 2197 | - QPDF* q = ph.getObjectHandle().getOwningQPDF(false); | ||
| 2198 | - return get_afdh_for_qpdf(afdh, q); | 2197 | + QPDF& q = ph.getObjectHandle().getQPDF(); |
| 2198 | + return get_afdh_for_qpdf(afdh, &q); | ||
| 2199 | }; | 2199 | }; |
| 2200 | auto dest_afdh = make_afdh(dest_page); | 2200 | auto dest_afdh = make_afdh(dest_page); |
| 2201 | 2201 | ||
| @@ -2635,7 +2635,7 @@ static QPDFObjectHandle | @@ -2635,7 +2635,7 @@ static QPDFObjectHandle | ||
| 2635 | added_page(QPDF& pdf, QPDFObjectHandle page) | 2635 | added_page(QPDF& pdf, QPDFObjectHandle page) |
| 2636 | { | 2636 | { |
| 2637 | QPDFObjectHandle result = page; | 2637 | QPDFObjectHandle result = page; |
| 2638 | - if (page.getOwningQPDF(false) != &pdf) { | 2638 | + if (&page.getQPDF() != &pdf) { |
| 2639 | // Calling copyForeignObject on an object we already copied | 2639 | // Calling copyForeignObject on an object we already copied |
| 2640 | // will give us the already existing copy. | 2640 | // will give us the already existing copy. |
| 2641 | result = pdf.copyForeignObject(page); | 2641 | result = pdf.copyForeignObject(page); |
libqpdf/QPDFObjectHandle.cc
| @@ -1668,11 +1668,10 @@ QPDFObjectHandle::coalesceContentStreams() | @@ -1668,11 +1668,10 @@ QPDFObjectHandle::coalesceContentStreams() | ||
| 1668 | // incorrect way. However, it can happen in a PDF file whose | 1668 | // incorrect way. However, it can happen in a PDF file whose |
| 1669 | // page structure is direct, which is against spec but still | 1669 | // page structure is direct, which is against spec but still |
| 1670 | // possible to hand construct, as in fuzz issue 27393. | 1670 | // possible to hand construct, as in fuzz issue 27393. |
| 1671 | - QPDF* qpdf = getOwningQPDF( | ||
| 1672 | - false, | 1671 | + QPDF& qpdf = getQPDF( |
| 1673 | "coalesceContentStreams called on object with no associated PDF file"); | 1672 | "coalesceContentStreams called on object with no associated PDF file"); |
| 1674 | 1673 | ||
| 1675 | - QPDFObjectHandle new_contents = newStream(qpdf); | 1674 | + QPDFObjectHandle new_contents = newStream(&qpdf); |
| 1676 | this->replaceKey("/Contents", new_contents); | 1675 | this->replaceKey("/Contents", new_contents); |
| 1677 | 1676 | ||
| 1678 | auto provider = std::shared_ptr<StreamDataProvider>( | 1677 | auto provider = std::shared_ptr<StreamDataProvider>( |
| @@ -2775,16 +2774,20 @@ QPDFObjectHandle::getObjGen() const | @@ -2775,16 +2774,20 @@ QPDFObjectHandle::getObjGen() const | ||
| 2775 | 2774 | ||
| 2776 | // Indirect object accessors | 2775 | // Indirect object accessors |
| 2777 | QPDF* | 2776 | QPDF* |
| 2778 | -QPDFObjectHandle::getOwningQPDF( | ||
| 2779 | - bool allow_nullptr, std::string const& error_msg) const | 2777 | +QPDFObjectHandle::getOwningQPDF() const |
| 2778 | +{ | ||
| 2779 | + return isInitialized() ? this->obj->getQPDF() : nullptr; | ||
| 2780 | +} | ||
| 2781 | + | ||
| 2782 | +QPDF& | ||
| 2783 | +QPDFObjectHandle::getQPDF(std::string const& error_msg) const | ||
| 2780 | { | 2784 | { |
| 2781 | - // Will be null for direct objects | ||
| 2782 | auto result = isInitialized() ? this->obj->getQPDF() : nullptr; | 2785 | auto result = isInitialized() ? this->obj->getQPDF() : nullptr; |
| 2783 | - if (!allow_nullptr && (result == nullptr)) { | 2786 | + if (result == nullptr) { |
| 2784 | throw std::runtime_error( | 2787 | throw std::runtime_error( |
| 2785 | error_msg == "" ? "attempt to use a null qpdf object" : error_msg); | 2788 | error_msg == "" ? "attempt to use a null qpdf object" : error_msg); |
| 2786 | } | 2789 | } |
| 2787 | - return result; | 2790 | + return *result; |
| 2788 | } | 2791 | } |
| 2789 | 2792 | ||
| 2790 | void | 2793 | void |
libqpdf/QPDFPageObjectHelper.cc
| @@ -477,8 +477,7 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow) | @@ -477,8 +477,7 @@ QPDFPageObjectHelper::externalizeInlineImages(size_t min_size, bool shallow) | ||
| 477 | this->oh.replaceKey( | 477 | this->oh.replaceKey( |
| 478 | "/Contents", | 478 | "/Contents", |
| 479 | QPDFObjectHandle::newStream( | 479 | QPDFObjectHandle::newStream( |
| 480 | - this->oh.getOwningQPDF(false), | ||
| 481 | - b.getBufferSharedPointer())); | 480 | + &this->oh.getQPDF(), b.getBufferSharedPointer())); |
| 482 | } | 481 | } |
| 483 | } | 482 | } |
| 484 | } else { | 483 | } else { |
| @@ -729,12 +728,10 @@ QPDFPageObjectHelper::removeUnreferencedResources() | @@ -729,12 +728,10 @@ QPDFPageObjectHelper::removeUnreferencedResources() | ||
| 729 | QPDFPageObjectHelper | 728 | QPDFPageObjectHelper |
| 730 | QPDFPageObjectHelper::shallowCopyPage() | 729 | QPDFPageObjectHelper::shallowCopyPage() |
| 731 | { | 730 | { |
| 732 | - QPDF* qpdf = this->oh.getOwningQPDF( | ||
| 733 | - false, | 731 | + QPDF& qpdf = this->oh.getQPDF( |
| 734 | "QPDFPageObjectHelper::shallowCopyPage called with a direct object"); | 732 | "QPDFPageObjectHelper::shallowCopyPage called with a direct object"); |
| 735 | - | ||
| 736 | QPDFObjectHandle new_page = this->oh.shallowCopy(); | 733 | QPDFObjectHandle new_page = this->oh.shallowCopy(); |
| 737 | - return QPDFPageObjectHelper(qpdf->makeIndirectObject(new_page)); | 734 | + return QPDFPageObjectHelper(qpdf.makeIndirectObject(new_page)); |
| 738 | } | 735 | } |
| 739 | 736 | ||
| 740 | QPDFObjectHandle::Matrix | 737 | QPDFObjectHandle::Matrix |
| @@ -788,11 +785,10 @@ QPDFPageObjectHelper::getMatrixForTransformations(bool invert) | @@ -788,11 +785,10 @@ QPDFPageObjectHelper::getMatrixForTransformations(bool invert) | ||
| 788 | QPDFObjectHandle | 785 | QPDFObjectHandle |
| 789 | QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations) | 786 | QPDFPageObjectHelper::getFormXObjectForPage(bool handle_transformations) |
| 790 | { | 787 | { |
| 791 | - QPDF* qpdf = this->oh.getOwningQPDF( | ||
| 792 | - false, | 788 | + QPDF& qpdf = this->oh.getQPDF( |
| 793 | "QPDFPageObjectHelper::getFormXObjectForPage called with a direct " | 789 | "QPDFPageObjectHelper::getFormXObjectForPage called with a direct " |
| 794 | "object"); | 790 | "object"); |
| 795 | - QPDFObjectHandle result = QPDFObjectHandle::newStream(qpdf); | 791 | + QPDFObjectHandle result = QPDFObjectHandle::newStream(&qpdf); |
| 796 | QPDFObjectHandle newdict = result.getDict(); | 792 | QPDFObjectHandle newdict = result.getDict(); |
| 797 | newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")); | 793 | newdict.replaceKey("/Type", QPDFObjectHandle::newName("/XObject")); |
| 798 | newdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form")); | 794 | newdict.replaceKey("/Subtype", QPDFObjectHandle::newName("/Form")); |
| @@ -961,10 +957,8 @@ QPDFPageObjectHelper::placeFormXObject( | @@ -961,10 +957,8 @@ QPDFPageObjectHelper::placeFormXObject( | ||
| 961 | void | 957 | void |
| 962 | QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh) | 958 | QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh) |
| 963 | { | 959 | { |
| 964 | - QPDF* qpdf = this->oh.getOwningQPDF( | ||
| 965 | - false, | 960 | + QPDF& qpdf = this->oh.getQPDF( |
| 966 | "QPDFPageObjectHelper::flattenRotation called with a direct object"); | 961 | "QPDFPageObjectHelper::flattenRotation called with a direct object"); |
| 967 | - | ||
| 968 | auto rotate_oh = this->oh.getKey("/Rotate"); | 962 | auto rotate_oh = this->oh.getKey("/Rotate"); |
| 969 | int rotate = 0; | 963 | int rotate = 0; |
| 970 | if (rotate_oh.isInteger()) { | 964 | if (rotate_oh.isInteger()) { |
| @@ -1067,8 +1061,9 @@ QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh) | @@ -1067,8 +1061,9 @@ QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh) | ||
| 1067 | break; | 1061 | break; |
| 1068 | } | 1062 | } |
| 1069 | std::string cm_str = std::string("q\n") + cm.unparse() + " cm\n"; | 1063 | std::string cm_str = std::string("q\n") + cm.unparse() + " cm\n"; |
| 1070 | - this->oh.addPageContents(QPDFObjectHandle::newStream(qpdf, cm_str), true); | ||
| 1071 | - this->oh.addPageContents(QPDFObjectHandle::newStream(qpdf, "\nQ\n"), false); | 1064 | + this->oh.addPageContents(QPDFObjectHandle::newStream(&qpdf, cm_str), true); |
| 1065 | + this->oh.addPageContents( | ||
| 1066 | + QPDFObjectHandle::newStream(&qpdf, "\nQ\n"), false); | ||
| 1072 | this->oh.removeKey("/Rotate"); | 1067 | this->oh.removeKey("/Rotate"); |
| 1073 | QPDFObjectHandle rotate_obj = getAttribute("/Rotate", false); | 1068 | QPDFObjectHandle rotate_obj = getAttribute("/Rotate", false); |
| 1074 | if (!rotate_obj.isNull()) { | 1069 | if (!rotate_obj.isNull()) { |
| @@ -1083,7 +1078,7 @@ QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh) | @@ -1083,7 +1078,7 @@ QPDFPageObjectHelper::flattenRotation(QPDFAcroFormDocumentHelper* afdh) | ||
| 1083 | std::set<QPDFObjGen> old_fields; | 1078 | std::set<QPDFObjGen> old_fields; |
| 1084 | std::shared_ptr<QPDFAcroFormDocumentHelper> afdhph; | 1079 | std::shared_ptr<QPDFAcroFormDocumentHelper> afdhph; |
| 1085 | if (!afdh) { | 1080 | if (!afdh) { |
| 1086 | - afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(*qpdf); | 1081 | + afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(qpdf); |
| 1087 | afdh = afdhph.get(); | 1082 | afdh = afdhph.get(); |
| 1088 | } | 1083 | } |
| 1089 | afdh->transformAnnotations( | 1084 | afdh->transformAnnotations( |
| @@ -1108,11 +1103,9 @@ QPDFPageObjectHelper::copyAnnotations( | @@ -1108,11 +1103,9 @@ QPDFPageObjectHelper::copyAnnotations( | ||
| 1108 | return; | 1103 | return; |
| 1109 | } | 1104 | } |
| 1110 | 1105 | ||
| 1111 | - QPDF* from_qpdf = from_page.getObjectHandle().getOwningQPDF( | ||
| 1112 | - false, | 1106 | + QPDF& from_qpdf = from_page.getObjectHandle().getQPDF( |
| 1113 | "QPDFPageObjectHelper::copyAnnotations: from page is a direct object"); | 1107 | "QPDFPageObjectHelper::copyAnnotations: from page is a direct object"); |
| 1114 | - QPDF* this_qpdf = this->oh.getOwningQPDF( | ||
| 1115 | - false, | 1108 | + QPDF& this_qpdf = this->oh.getQPDF( |
| 1116 | "QPDFPageObjectHelper::copyAnnotations: this page is a direct object"); | 1109 | "QPDFPageObjectHelper::copyAnnotations: this page is a direct object"); |
| 1117 | 1110 | ||
| 1118 | std::vector<QPDFObjectHandle> new_annots; | 1111 | std::vector<QPDFObjectHandle> new_annots; |
| @@ -1121,19 +1114,19 @@ QPDFPageObjectHelper::copyAnnotations( | @@ -1121,19 +1114,19 @@ QPDFPageObjectHelper::copyAnnotations( | ||
| 1121 | std::shared_ptr<QPDFAcroFormDocumentHelper> afdhph; | 1114 | std::shared_ptr<QPDFAcroFormDocumentHelper> afdhph; |
| 1122 | std::shared_ptr<QPDFAcroFormDocumentHelper> from_afdhph; | 1115 | std::shared_ptr<QPDFAcroFormDocumentHelper> from_afdhph; |
| 1123 | if (!afdh) { | 1116 | if (!afdh) { |
| 1124 | - afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(*this_qpdf); | 1117 | + afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(this_qpdf); |
| 1125 | afdh = afdhph.get(); | 1118 | afdh = afdhph.get(); |
| 1126 | } | 1119 | } |
| 1127 | - if (this_qpdf == from_qpdf) { | 1120 | + if (&this_qpdf == &from_qpdf) { |
| 1128 | from_afdh = afdh; | 1121 | from_afdh = afdh; |
| 1129 | } else if (from_afdh) { | 1122 | } else if (from_afdh) { |
| 1130 | - if (from_afdh->getQPDF().getUniqueId() != from_qpdf->getUniqueId()) { | 1123 | + if (from_afdh->getQPDF().getUniqueId() != from_qpdf.getUniqueId()) { |
| 1131 | throw std::logic_error( | 1124 | throw std::logic_error( |
| 1132 | "QPDFAcroFormDocumentHelper::copyAnnotations: from_afdh" | 1125 | "QPDFAcroFormDocumentHelper::copyAnnotations: from_afdh" |
| 1133 | " is not from the same QPDF as from_page"); | 1126 | " is not from the same QPDF as from_page"); |
| 1134 | } | 1127 | } |
| 1135 | } else { | 1128 | } else { |
| 1136 | - from_afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(*from_qpdf); | 1129 | + from_afdhph = std::make_shared<QPDFAcroFormDocumentHelper>(from_qpdf); |
| 1137 | from_afdh = from_afdhph.get(); | 1130 | from_afdh = from_afdhph.get(); |
| 1138 | } | 1131 | } |
| 1139 | 1132 | ||
| @@ -1143,7 +1136,7 @@ QPDFPageObjectHelper::copyAnnotations( | @@ -1143,7 +1136,7 @@ QPDFPageObjectHelper::copyAnnotations( | ||
| 1143 | new_fields, | 1136 | new_fields, |
| 1144 | old_fields, | 1137 | old_fields, |
| 1145 | cm, | 1138 | cm, |
| 1146 | - from_qpdf, | 1139 | + &from_qpdf, |
| 1147 | from_afdh); | 1140 | from_afdh); |
| 1148 | afdh->addAndRenameFormFields(new_fields); | 1141 | afdh->addAndRenameFormFields(new_fields); |
| 1149 | auto annots = this->oh.getKey("/Annots"); | 1142 | auto annots = this->oh.getKey("/Annots"); |
libqpdf/QPDF_pages.cc
| @@ -233,7 +233,7 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos) | @@ -233,7 +233,7 @@ QPDF::insertPage(QPDFObjectHandle newpage, int pos) | ||
| 233 | newpage = makeIndirectObject(newpage); | 233 | newpage = makeIndirectObject(newpage); |
| 234 | } else if (newpage.getOwningQPDF() != this) { | 234 | } else if (newpage.getOwningQPDF() != this) { |
| 235 | QTC::TC("qpdf", "QPDF insert foreign page"); | 235 | QTC::TC("qpdf", "QPDF insert foreign page"); |
| 236 | - newpage.getOwningQPDF(false)->pushInheritedAttributesToPage(); | 236 | + newpage.getQPDF().pushInheritedAttributesToPage(); |
| 237 | newpage = copyForeignObject(newpage); | 237 | newpage = copyForeignObject(newpage); |
| 238 | } else { | 238 | } else { |
| 239 | QTC::TC("qpdf", "QPDF insert indirect page"); | 239 | QTC::TC("qpdf", "QPDF insert indirect page"); |
manual/release-notes.rst
| @@ -208,6 +208,11 @@ For a detailed list of changes, please see the file | @@ -208,6 +208,11 @@ For a detailed list of changes, please see the file | ||
| 208 | generally not happen for correct code, but at least the | 208 | generally not happen for correct code, but at least the |
| 209 | situation is detectible now. | 209 | situation is detectible now. |
| 210 | 210 | ||
| 211 | + - The method ``QPDFObjectHandle::getQPDF`` returns a ``QPDF&`` | ||
| 212 | + (rather than a ``QPDF*``) and is an alternative to | ||
| 213 | + ``QPDFObjectHandle::getOwningQPDF`` for when the object is known | ||
| 214 | + to have an owning ``QPDF``. | ||
| 215 | + | ||
| 211 | - It is now possible to test ``QPDFObjectHandle`` equality with | 216 | - It is now possible to test ``QPDFObjectHandle`` equality with |
| 212 | ``==`` and ``!=``. Two ``QPDFObjectHandle`` objects are equal if | 217 | ``==`` and ``!=``. Two ``QPDFObjectHandle`` objects are equal if |
| 213 | they point to the same underlying object, meaning changes to one | 218 | they point to the same underlying object, meaning changes to one |