Skip to content

Commit

Permalink
Add transformAnnotations and fix flattenRotations to use it
Browse files Browse the repository at this point in the history
  • Loading branch information
jberkenbilt committed Feb 21, 2021
1 parent a76decd commit a9ae8ca
Show file tree
Hide file tree
Showing 17 changed files with 466 additions and 5 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
2021-02-21 Jay Berkenbilt <[email protected]>

* Bug fix: --flatten-rotation now applies the required
transformation to annotations on the page.

* Add QPDFAcroFormDocumentHelper::transformAnnotations to apply a
transformation to a group of annotations.

* Add QPDFObjGen::unparse()

* Add QPDFObjectHandle::copyStream() for making a copy of a stream
Expand Down
30 changes: 30 additions & 0 deletions include/qpdf/QPDFAcroFormDocumentHelper.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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<QPDFObjGen> 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.
Expand Down Expand Up @@ -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<QPDFObjectHandle>& new_annots,
std::vector<QPDFObjectHandle>& new_fields,
std::set<QPDFObjGen>& old_fields,
QPDFMatrix const& cm,
QPDF* from_qpdf = nullptr,
QPDFAcroFormDocumentHelper* from_afdh = nullptr);

private:
void analyze();
void traverseField(QPDFObjectHandle field,
Expand Down
7 changes: 7 additions & 0 deletions include/qpdf/QPDFAnnotationObjectHelper.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 9 additions & 1 deletion include/qpdf/QPDFPageObjectHelper.hh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include <qpdf/QPDFObjectHandle.hh>
#include <functional>

class QPDFAcroFormDocumentHelper;

class QPDFPageObjectHelper: public QPDFObjectHelper
{
// This is a helper class for page objects, but as of qpdf 10.1,
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit a9ae8ca

Please sign in to comment.