diff options
Diffstat (limited to 'libqpdf')
-rw-r--r-- | libqpdf/QPDFAnnotationObjectHelper.cc | 10 | ||||
-rw-r--r-- | libqpdf/QPDFPageDocumentHelper.cc | 127 |
2 files changed, 132 insertions, 5 deletions
diff --git a/libqpdf/QPDFAnnotationObjectHelper.cc b/libqpdf/QPDFAnnotationObjectHelper.cc index a5b824f3..4c305149 100644 --- a/libqpdf/QPDFAnnotationObjectHelper.cc +++ b/libqpdf/QPDFAnnotationObjectHelper.cc @@ -149,12 +149,12 @@ QPDFAnnotationObjectHelper::getAnnotationAppearanceMatrix(int rotate) QPDFMatrix matrix; if (matrix_obj.isMatrix()) { -/// QTC::TC("qpdf", "QPDFAnnotationObjectHelper explicit matrix"); + QTC::TC("qpdf", "QPDFAnnotationObjectHelper explicit matrix"); matrix = QPDFMatrix(matrix_obj.getArrayAsMatrix()); } else { -/// QTC::TC("qpdf", "QPDFAnnotationObjectHelper default matrix"); + QTC::TC("qpdf", "QPDFAnnotationObjectHelper default matrix"); } QPDFObjectHandle::Rectangle rect = rect_obj.getArrayAsRectangle(); if (rotate && flags.isInteger() && (flags.getIntValue() & 16)) @@ -176,7 +176,7 @@ QPDFAnnotationObjectHelper::getAnnotationAppearanceMatrix(int rotate) switch (rotate) { case 90: -/// QTC::TC("qpdf", "QPDFAnnotationObjectHelper rotate 90"); + QTC::TC("qpdf", "QPDFAnnotationObjectHelper rotate 90"); rect = QPDFObjectHandle::Rectangle( rect.llx, rect.ury, @@ -184,7 +184,7 @@ QPDFAnnotationObjectHelper::getAnnotationAppearanceMatrix(int rotate) rect.ury + rect_w); break; case 180: -/// QTC::TC("qpdf", "QPDFAnnotationObjectHelper rotate 180"); + QTC::TC("qpdf", "QPDFAnnotationObjectHelper rotate 180"); rect = QPDFObjectHandle::Rectangle( rect.llx - rect_w, rect.ury, @@ -192,7 +192,7 @@ QPDFAnnotationObjectHelper::getAnnotationAppearanceMatrix(int rotate) rect.ury + rect_h); break; case 270: -/// QTC::TC("qpdf", "QPDFAnnotationObjectHelper rotate 270"); + QTC::TC("qpdf", "QPDFAnnotationObjectHelper rotate 270"); rect = QPDFObjectHandle::Rectangle( rect.llx - rect_h, rect.ury - rect_w, diff --git a/libqpdf/QPDFPageDocumentHelper.cc b/libqpdf/QPDFPageDocumentHelper.cc index f4774896..4d117017 100644 --- a/libqpdf/QPDFPageDocumentHelper.cc +++ b/libqpdf/QPDFPageDocumentHelper.cc @@ -1,4 +1,6 @@ #include <qpdf/QPDFPageDocumentHelper.hh> +#include <qpdf/QPDFAcroFormDocumentHelper.hh> +#include <qpdf/QTC.hh> QPDFPageDocumentHelper::Members::~Members() { @@ -62,3 +64,128 @@ QPDFPageDocumentHelper::removePage(QPDFPageObjectHelper page) { this->qpdf.removePage(page.getObjectHandle()); } + + +void +QPDFPageDocumentHelper::flattenAnnotations() +{ + QPDFAcroFormDocumentHelper afdh(this->qpdf); + if (afdh.getNeedAppearances()) + { + this->qpdf.getRoot().getKey("/AcroForm").warnIfPossible( + "document does not have updated appearance streams," + " so form fields will not be flattened"); + } + pushInheritedAttributesToPage(); + std::vector<QPDFPageObjectHelper> pages = getAllPages(); + for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin(); + iter != pages.end(); ++iter) + { + QPDFPageObjectHelper ph(*iter); + QPDFObjectHandle page_oh = ph.getObjectHandle(); + if (page_oh.getKey("/Resources").isIndirect()) + { + QTC::TC("qpdf", "QPDFPageDocumentHelper indirect resources"); + page_oh.replaceKey("/Resources", + page_oh.getKey("/Resources").shallowCopy()); + } + QPDFObjectHandle resources = ph.getObjectHandle().getKey("/Resources"); + if (! resources.isDictionary()) + { + // This should never happen and is not exercised in the + // test suite + resources = QPDFObjectHandle::newDictionary(); + } + flattenAnnotationsForPage(ph, resources, afdh); + } + if (! afdh.getNeedAppearances()) + { + this->qpdf.getRoot().removeKey("/AcroForm"); + } +} + +void +QPDFPageDocumentHelper::flattenAnnotationsForPage( + QPDFPageObjectHelper& page, + QPDFObjectHandle& resources, + QPDFAcroFormDocumentHelper& afdh) +{ + bool need_appearances = afdh.getNeedAppearances(); + std::vector<QPDFAnnotationObjectHelper> annots = page.getAnnotations(); + std::vector<QPDFObjectHandle> new_annots; + std::string new_content; + int rotate = 0; + QPDFObjectHandle rotate_obj = + page.getObjectHandle().getKey("/Rotate"); + if (rotate_obj.isInteger() && rotate_obj.getIntValue()) + { + rotate = rotate_obj.getIntValue(); + } + for (std::vector<QPDFAnnotationObjectHelper>::iterator iter = + annots.begin(); + iter != annots.end(); ++iter) + { + QPDFAnnotationObjectHelper& aoh(*iter); + QPDFObjectHandle as = aoh.getAppearanceStream("/N"); + bool is_widget = (aoh.getSubtype() == "/Widget"); + bool process = true; + if (need_appearances && is_widget) + { + QTC::TC("qpdf", "QPDFPageDocumentHelper skip widget need appearances"); + process = false; + } + if (process && (! as.isStream())) + { + process = false; + } + if (process) + { + resources.mergeDictionary(as.getDict().getKey("/Resources")); + if (is_widget) + { + QTC::TC("qpdf", "QPDFPageDocumentHelper merge DR"); + QPDFFormFieldObjectHelper ff = afdh.getFieldForAnnotation(aoh); + resources.mergeDictionary(ff.getInheritableFieldValue("/DR")); + } + else + { + QTC::TC("qpdf", "QPDFPageDocumentHelper non-widget annotation"); + } + new_content += aoh.getPageContentForAppearance(rotate); + } + else + { + new_annots.push_back(aoh.getObjectHandle()); + } + } + if (new_annots.size() != annots.size()) + { + QPDFObjectHandle page_oh = page.getObjectHandle(); + if (new_annots.empty()) + { + QTC::TC("qpdf", "QPDFPageDocumentHelper remove annots"); + page_oh.removeKey("/Annots"); + } + else + { + QPDFObjectHandle old_annots = page_oh.getKey("/Annots"); + QPDFObjectHandle new_annots_oh = + QPDFObjectHandle::newArray(new_annots); + if (old_annots.isIndirect()) + { + QTC::TC("qpdf", "QPDFPageDocumentHelper replace indirect annots"); + this->qpdf.replaceObject( + old_annots.getObjGen(), new_annots_oh); + } + else + { + QTC::TC("qpdf", "QPDFPageDocumentHelper replace direct annots"); + page_oh.replaceKey("/Annots", new_annots_oh); + } + } + page.addPageContents( + QPDFObjectHandle::newStream(&qpdf, "q\n"), true); + page.addPageContents( + QPDFObjectHandle::newStream(&qpdf, "\nQ\n" + new_content), false); + } +} |