aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2021-02-22 23:44:13 +0100
committerJay Berkenbilt <ejb@ql.org>2021-02-23 00:42:06 +0100
commit1f35ec9988eaf1ad3705655c434701d175c5b49f (patch)
tree0b60da6e5f35a5ee00d98f272f9ec1d59ef85694 /libqpdf
parentf02aa74bf5387c30e4ff6082beeb4b0d078b6294 (diff)
downloadqpdf-1f35ec9988eaf1ad3705655c434701d175c5b49f.tar.zst
Add methods for copying form fields
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/QPDFAcroFormDocumentHelper.cc47
-rw-r--r--libqpdf/QPDFFormFieldObjectHelper.cc23
2 files changed, 56 insertions, 14 deletions
diff --git a/libqpdf/QPDFAcroFormDocumentHelper.cc b/libqpdf/QPDFAcroFormDocumentHelper.cc
index 84ddd432..dce413bd 100644
--- a/libqpdf/QPDFAcroFormDocumentHelper.cc
+++ b/libqpdf/QPDFAcroFormDocumentHelper.cc
@@ -132,6 +132,23 @@ QPDFAcroFormDocumentHelper::getWidgetAnnotationsForPage(QPDFPageObjectHelper h)
return h.getAnnotations("/Widget");
}
+std::vector<QPDFFormFieldObjectHelper>
+QPDFAcroFormDocumentHelper::getFormFieldsForPage(QPDFPageObjectHelper ph)
+{
+ std::vector<QPDFFormFieldObjectHelper> result;
+ auto widget_annotations = getWidgetAnnotationsForPage(ph);
+ for (auto annot: widget_annotations)
+ {
+ auto field = getFieldForAnnotation(annot);
+ field = field.getTopLevelField();
+ if (field.getObjectHandle().isDictionary())
+ {
+ result.push_back(field);
+ }
+ }
+ return result;
+}
+
QPDFFormFieldObjectHelper
QPDFAcroFormDocumentHelper::getFieldForAnnotation(QPDFAnnotationObjectHelper h)
{
@@ -501,19 +518,8 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
// annotation and field separately in this case.
have_field = true;
// Find the top-level field. It may be the field itself.
- top_field = ffield_oh;
- std::set<QPDFObjGen> seen;
- while (! top_field.getKey("/Parent").isNull())
- {
- top_field = top_field.getKey("/Parent");
- have_parent = true;
- auto og = top_field.getObjGen();
- if (seen.count(og))
- {
- break;
- }
- seen.insert(og);
- }
+ top_field = ffield.getTopLevelField(
+ &have_parent).getObjectHandle();
if (foreign)
{
// copyForeignObject returns the same value if called
@@ -537,7 +543,7 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
{
queue.push_back(top_field);
}
- seen.clear();
+ std::set<QPDFObjGen> seen;
while (! queue.empty())
{
QPDFObjectHandle obj = queue.front();
@@ -664,3 +670,16 @@ QPDFAcroFormDocumentHelper::transformAnnotations(
"/Rect", QPDFObjectHandle::newFromRectangle(rect));
}
}
+
+void
+QPDFAcroFormDocumentHelper::copyFieldsFromForeignPage(
+ QPDFPageObjectHelper foreign_page,
+ QPDFAcroFormDocumentHelper& foreign_afdh)
+{
+ for (auto field: foreign_afdh.getFormFieldsForPage(foreign_page))
+ {
+ auto new_field = this->qpdf.copyForeignObject(
+ field.getObjectHandle());
+ addFormField(new_field);
+ }
+}
diff --git a/libqpdf/QPDFFormFieldObjectHelper.cc b/libqpdf/QPDFFormFieldObjectHelper.cc
index 97257c85..6933cb54 100644
--- a/libqpdf/QPDFFormFieldObjectHelper.cc
+++ b/libqpdf/QPDFFormFieldObjectHelper.cc
@@ -39,6 +39,29 @@ QPDFFormFieldObjectHelper::getParent()
return this->oh.getKey("/Parent"); // may be null
}
+QPDFFormFieldObjectHelper
+QPDFFormFieldObjectHelper::getTopLevelField(bool* is_different)
+{
+ auto top_field = this->oh;
+ std::set<QPDFObjGen> seen;
+ while (top_field.isDictionary() &&
+ (! top_field.getKey("/Parent").isNull()))
+ {
+ top_field = top_field.getKey("/Parent");
+ if (is_different)
+ {
+ *is_different = true;
+ }
+ auto og = top_field.getObjGen();
+ if (seen.count(og))
+ {
+ break;
+ }
+ seen.insert(og);
+ }
+ return QPDFFormFieldObjectHelper(top_field);
+}
+
QPDFObjectHandle
QPDFFormFieldObjectHelper::getInheritableFieldValue(std::string const& name)
{