From a9ae8cadc66daf631f6cbfe7fc3c7c602ac665d8 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sun, 21 Feb 2021 16:06:58 -0500 Subject: Add transformAnnotations and fix flattenRotations to use it --- include/qpdf/QPDFAcroFormDocumentHelper.hh | 30 ++++++++++++++++++++++++++++++ include/qpdf/QPDFAnnotationObjectHelper.hh | 7 +++++++ include/qpdf/QPDFPageObjectHelper.hh | 10 +++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/qpdf/QPDFAcroFormDocumentHelper.hh b/include/qpdf/QPDFAcroFormDocumentHelper.hh index d417fc08..eb9da5ad 100644 --- a/include/qpdf/QPDFAcroFormDocumentHelper.hh +++ b/include/qpdf/QPDFAcroFormDocumentHelper.hh @@ -113,6 +113,10 @@ class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper QPDF_DLL void addFormField(QPDFFormFieldObjectHelper); + // Remove fields from the fields array + QPDF_DLL + void removeFormFields(std::set const&); + // Return a vector of all terminal fields in a document. Terminal // fields are fields that have no children that are also fields. // Terminal fields may still have children that are annotations. @@ -174,6 +178,32 @@ class QPDFAcroFormDocumentHelper: public QPDFDocumentHelper QPDF_DLL void generateAppearancesIfNeeded(); + // Note: this method works on all annotations, not just ones with + // associated fields. For each annotation in old_annots, apply the + // given transformation matrix to create a new annotation. New + // annotations are appended to new_annots. If the annotation is + // associated with a form field, a new form field is created that + // points to the new annotation and is appended to new_fields, and + // the old field is added to old_fields. + // + // old_annots may belong to a different QPDF object. In that case, + // you should pass in from_qpdf, and copyForeignObject will be + // called automatically. If this is the case, for efficiency, you + // may pass in a QPDFAcroFormDocumentHelper for the other file to + // avoid the expensive process of creating one for each call to + // transformAnnotations. New fields and annotations are not added + // to the document or pages. You have to do that yourself after + // calling transformAnnotations. + QPDF_DLL + void transformAnnotations( + QPDFObjectHandle old_annots, + std::vector& new_annots, + std::vector& new_fields, + std::set& old_fields, + QPDFMatrix const& cm, + QPDF* from_qpdf = nullptr, + QPDFAcroFormDocumentHelper* from_afdh = nullptr); + private: void analyze(); void traverseField(QPDFObjectHandle field, diff --git a/include/qpdf/QPDFAnnotationObjectHelper.hh b/include/qpdf/QPDFAnnotationObjectHelper.hh index 3dd62222..39a530a3 100644 --- a/include/qpdf/QPDFAnnotationObjectHelper.hh +++ b/include/qpdf/QPDFAnnotationObjectHelper.hh @@ -40,6 +40,13 @@ class QPDFAnnotationObjectHelper: public QPDFObjectHelper // This class provides helper methods for annotations. More // functionality will likely be added in the future. + // Some functionality for annotations is also implemented in + // QPDFAcroFormDocumentHelper and QPDFFormFieldObjectHelper. In + // some cases, functions defined there work for other annotations + // besides widget annotations, but they are implemented with form + // fields so that they can properly handle form fields when + // needed. + // Return the subtype of the annotation as a string (e.g. // "/Widget"). Returns the empty string if the subtype (which is // required by the spec) is missing. diff --git a/include/qpdf/QPDFPageObjectHelper.hh b/include/qpdf/QPDFPageObjectHelper.hh index 76f42dbd..c48a7145 100644 --- a/include/qpdf/QPDFPageObjectHelper.hh +++ b/include/qpdf/QPDFPageObjectHelper.hh @@ -31,6 +31,8 @@ #include #include +class QPDFAcroFormDocumentHelper; + class QPDFPageObjectHelper: public QPDFObjectHelper { // This is a helper class for page objects, but as of qpdf 10.1, @@ -323,9 +325,15 @@ class QPDFPageObjectHelper: public QPDFObjectHelper // various page bounding boxes (/MediaBox, etc.) so that the page // will have the same semantics. This can be useful to work around // problems with PDF applications that can't properly handle - // rotated pages. + // rotated pages. If a QPDFAcroFormDocumentHelper is provided, it + // will be used for resolving any form fields that have to be + // rotated. If not, one will be created inside the function, which + // is less efficient. QPDF_DLL void flattenRotation(); + // ABI: merge versions and make afdh default to nullptr + QPDF_DLL + void flattenRotation(QPDFAcroFormDocumentHelper* afdh); private: static bool -- cgit v1.2.3-54-g00ecf