diff --git a/Pdf4QtLib/sources/pdfdocumentbuilder.cpp b/Pdf4QtLib/sources/pdfdocumentbuilder.cpp index 190a51b..e7b04a5 100644 --- a/Pdf4QtLib/sources/pdfdocumentbuilder.cpp +++ b/Pdf4QtLib/sources/pdfdocumentbuilder.cpp @@ -1928,6 +1928,30 @@ PDFObjectReference PDFDocumentBuilder::appendPage(QRectF mediaBox) } +PDFObjectReference PDFDocumentBuilder::createAcroForm(PDFObjectReferenceVector fields) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Fields"); + objectBuilder << fields; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("NeedAppearances"); + objectBuilder << false; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("SigFlags"); + objectBuilder << 0; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("XFA"); + objectBuilder << PDFObject(); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObjectReference acroForm = addObject(objectBuilder.takeObject()); + setCatalogAcroForm(acroForm); + return acroForm; +} + + PDFObjectReference PDFDocumentBuilder::createActionGoTo(PDFDestination destination) { PDFObjectFactory objectBuilder; @@ -2692,88 +2716,6 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationFileAttachment(PDFObjectR } -PDFObjectReference PDFDocumentBuilder::createAnnotationFreeText(PDFObjectReference page, - QRectF boundingRectangle, - QRectF textRectangle, - QString title, - QString subject, - QString contents, - TextAlignment textAlignment, - QPointF startPoint, - QPointF endPoint, - AnnotationLineEnding startLineType, - AnnotationLineEnding endLineType) -{ - PDFObjectFactory objectBuilder; - - objectBuilder.beginDictionary(); - objectBuilder.beginDictionaryItem("Type"); - objectBuilder << WrapName("Annot"); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Subtype"); - objectBuilder << WrapName("FreeText"); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Rect"); - objectBuilder << boundingRectangle; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("F"); - objectBuilder << 4; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("P"); - objectBuilder << page; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("M"); - objectBuilder << WrapCurrentDateTime(); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("CreationDate"); - objectBuilder << WrapCurrentDateTime(); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("T"); - objectBuilder << title; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Contents"); - objectBuilder << contents; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Subj"); - objectBuilder << subject; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Q"); - objectBuilder << WrapFreeTextAlignment(textAlignment); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("DA"); - objectBuilder << WrapString("/Arial 10 Tf"); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("RD"); - objectBuilder << getAnnotationReductionRectangle(boundingRectangle, textRectangle); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("CL"); - objectBuilder.beginArray(); - objectBuilder << startPoint; - objectBuilder << endPoint; - objectBuilder.endArray(); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("LE"); - objectBuilder.beginArray(); - objectBuilder << startLineType; - objectBuilder << endLineType; - objectBuilder.endArray(); - objectBuilder.endDictionaryItem(); - objectBuilder.endDictionary(); - PDFObjectReference annotationObject = addObject(objectBuilder.takeObject()); - objectBuilder.beginDictionary(); - objectBuilder.beginDictionaryItem("Annots"); - objectBuilder.beginArray(); - objectBuilder << annotationObject; - objectBuilder.endArray(); - objectBuilder.endDictionaryItem(); - objectBuilder.endDictionary(); - PDFObject pageAnnots = objectBuilder.takeObject(); - appendTo(page, pageAnnots); - updateAnnotationAppearanceStreams(annotationObject); - return annotationObject; -} - - PDFObjectReference PDFDocumentBuilder::createAnnotationFreeText(PDFObjectReference page, QRectF boundingRectangle, QRectF textRectangle, @@ -2920,6 +2862,88 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationFreeText(PDFObjectReferen } +PDFObjectReference PDFDocumentBuilder::createAnnotationFreeText(PDFObjectReference page, + QRectF boundingRectangle, + QRectF textRectangle, + QString title, + QString subject, + QString contents, + TextAlignment textAlignment, + QPointF startPoint, + QPointF endPoint, + AnnotationLineEnding startLineType, + AnnotationLineEnding endLineType) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Type"); + objectBuilder << WrapName("Annot"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Subtype"); + objectBuilder << WrapName("FreeText"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Rect"); + objectBuilder << boundingRectangle; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("F"); + objectBuilder << 4; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("P"); + objectBuilder << page; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("M"); + objectBuilder << WrapCurrentDateTime(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("CreationDate"); + objectBuilder << WrapCurrentDateTime(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("T"); + objectBuilder << title; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Contents"); + objectBuilder << contents; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Subj"); + objectBuilder << subject; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Q"); + objectBuilder << WrapFreeTextAlignment(textAlignment); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("DA"); + objectBuilder << WrapString("/Arial 10 Tf"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("RD"); + objectBuilder << getAnnotationReductionRectangle(boundingRectangle, textRectangle); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("CL"); + objectBuilder.beginArray(); + objectBuilder << startPoint; + objectBuilder << endPoint; + objectBuilder.endArray(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("LE"); + objectBuilder.beginArray(); + objectBuilder << startLineType; + objectBuilder << endLineType; + objectBuilder.endArray(); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObjectReference annotationObject = addObject(objectBuilder.takeObject()); + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Annots"); + objectBuilder.beginArray(); + objectBuilder << annotationObject; + objectBuilder.endArray(); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject pageAnnots = objectBuilder.takeObject(); + appendTo(page, pageAnnots); + updateAnnotationAppearanceStreams(annotationObject); + return annotationObject; +} + + PDFObjectReference PDFDocumentBuilder::createAnnotationHighlight(PDFObjectReference page, QRectF rectangle, QColor color, @@ -3845,6 +3869,47 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationSquiggly(PDFObjectReferen } +PDFObjectReference PDFDocumentBuilder::createAnnotationSquiggly(PDFObjectReference page, + QPolygonF quadrilaterals, + QColor color) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Type"); + objectBuilder << WrapName("Annot"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Subtype"); + objectBuilder << WrapName("Squiggly"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("P"); + objectBuilder << page; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("CreationDate"); + objectBuilder << WrapCurrentDateTime(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("C"); + objectBuilder << color; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("QuadPoints"); + objectBuilder << quadrilaterals; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObjectReference annotationObject = addObject(objectBuilder.takeObject()); + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Annots"); + objectBuilder.beginArray(); + objectBuilder << annotationObject; + objectBuilder.endArray(); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject pageAnnots = objectBuilder.takeObject(); + appendTo(page, pageAnnots); + updateAnnotationAppearanceStreams(annotationObject); + return annotationObject; +} + + PDFObjectReference PDFDocumentBuilder::createAnnotationSquiggly(PDFObjectReference page, QRectF rectangle, QColor color, @@ -3909,47 +3974,6 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationSquiggly(PDFObjectReferen } -PDFObjectReference PDFDocumentBuilder::createAnnotationSquiggly(PDFObjectReference page, - QPolygonF quadrilaterals, - QColor color) -{ - PDFObjectFactory objectBuilder; - - objectBuilder.beginDictionary(); - objectBuilder.beginDictionaryItem("Type"); - objectBuilder << WrapName("Annot"); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Subtype"); - objectBuilder << WrapName("Squiggly"); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("P"); - objectBuilder << page; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("CreationDate"); - objectBuilder << WrapCurrentDateTime(); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("C"); - objectBuilder << color; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("QuadPoints"); - objectBuilder << quadrilaterals; - objectBuilder.endDictionaryItem(); - objectBuilder.endDictionary(); - PDFObjectReference annotationObject = addObject(objectBuilder.takeObject()); - objectBuilder.beginDictionary(); - objectBuilder.beginDictionaryItem("Annots"); - objectBuilder.beginArray(); - objectBuilder << annotationObject; - objectBuilder.endArray(); - objectBuilder.endDictionaryItem(); - objectBuilder.endDictionary(); - PDFObject pageAnnots = objectBuilder.takeObject(); - appendTo(page, pageAnnots); - updateAnnotationAppearanceStreams(annotationObject); - return annotationObject; -} - - PDFObjectReference PDFDocumentBuilder::createAnnotationStamp(PDFObjectReference page, QRectF rectangle, Stamp stampType, @@ -4233,70 +4257,6 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationText(PDFObjectReference p } -PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectReference page, - QRectF rectangle, - QColor color, - QString title, - QString subject, - QString contents) -{ - PDFObjectFactory objectBuilder; - - objectBuilder.beginDictionary(); - objectBuilder.beginDictionaryItem("Type"); - objectBuilder << WrapName("Annot"); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Subtype"); - objectBuilder << WrapName("Underline"); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Rect"); - objectBuilder << rectangle; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("P"); - objectBuilder << page; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("M"); - objectBuilder << WrapCurrentDateTime(); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("CreationDate"); - objectBuilder << WrapCurrentDateTime(); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("C"); - objectBuilder << color; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("T"); - objectBuilder << title; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Contents"); - objectBuilder << contents; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Subj"); - objectBuilder << subject; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("QuadPoints"); - objectBuilder.beginArray(); - objectBuilder << rectangle.bottomLeft(); - objectBuilder << rectangle.bottomRight(); - objectBuilder << rectangle.topLeft(); - objectBuilder << rectangle.topRight(); - objectBuilder.endArray(); - objectBuilder.endDictionaryItem(); - objectBuilder.endDictionary(); - PDFObjectReference annotationObject = addObject(objectBuilder.takeObject()); - objectBuilder.beginDictionary(); - objectBuilder.beginDictionaryItem("Annots"); - objectBuilder.beginArray(); - objectBuilder << annotationObject; - objectBuilder.endArray(); - objectBuilder.endDictionaryItem(); - objectBuilder.endDictionary(); - PDFObject pageAnnots = objectBuilder.takeObject(); - appendTo(page, pageAnnots); - updateAnnotationAppearanceStreams(annotationObject); - return annotationObject; -} - - PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectReference page, QRectF rectangle, QColor color) @@ -4387,6 +4347,70 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectRefere } +PDFObjectReference PDFDocumentBuilder::createAnnotationUnderline(PDFObjectReference page, + QRectF rectangle, + QColor color, + QString title, + QString subject, + QString contents) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Type"); + objectBuilder << WrapName("Annot"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Subtype"); + objectBuilder << WrapName("Underline"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Rect"); + objectBuilder << rectangle; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("P"); + objectBuilder << page; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("M"); + objectBuilder << WrapCurrentDateTime(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("CreationDate"); + objectBuilder << WrapCurrentDateTime(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("C"); + objectBuilder << color; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("T"); + objectBuilder << title; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Contents"); + objectBuilder << contents; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Subj"); + objectBuilder << subject; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("QuadPoints"); + objectBuilder.beginArray(); + objectBuilder << rectangle.bottomLeft(); + objectBuilder << rectangle.bottomRight(); + objectBuilder << rectangle.topLeft(); + objectBuilder << rectangle.topRight(); + objectBuilder.endArray(); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObjectReference annotationObject = addObject(objectBuilder.takeObject()); + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Annots"); + objectBuilder.beginArray(); + objectBuilder << annotationObject; + objectBuilder.endArray(); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject pageAnnots = objectBuilder.takeObject(); + appendTo(page, pageAnnots); + updateAnnotationAppearanceStreams(annotationObject); + return annotationObject; +} + + PDFObjectReference PDFDocumentBuilder::createCatalog() { PDFObjectFactory objectBuilder; @@ -4518,6 +4542,39 @@ PDFObjectReference PDFDocumentBuilder::createFileSpecification(QString fileName) } +PDFObjectReference PDFDocumentBuilder::createSignatureDictionary(QByteArray filter, + QByteArray subfilter, + QByteArray contents, + QDateTime signingTime, + PDFInteger byteRangeItem) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Type"); + objectBuilder << WrapName("Sig"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Filter"); + objectBuilder << WrapName(filter); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("SubFilter"); + objectBuilder << WrapName(subfilter); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("ByteRange"); + objectBuilder << std::array{ byteRangeItem, byteRangeItem, byteRangeItem, byteRangeItem }; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Contents"); + objectBuilder << contents; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("M"); + objectBuilder << signingTime; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObjectReference signatureDictionary = addObject(objectBuilder.takeObject()); + return signatureDictionary; +} + + PDFObject PDFDocumentBuilder::createTrailerDictionary(PDFObjectReference catalog) { PDFObjectFactory objectBuilder; diff --git a/Pdf4QtLib/sources/pdfdocumentbuilder.h b/Pdf4QtLib/sources/pdfdocumentbuilder.h index 0f1f7ea..efef069 100644 --- a/Pdf4QtLib/sources/pdfdocumentbuilder.h +++ b/Pdf4QtLib/sources/pdfdocumentbuilder.h @@ -39,6 +39,12 @@ struct WrapName } + WrapName(QByteArray name) : + name(std::move(name)) + { + + } + QByteArray name; }; @@ -468,6 +474,11 @@ public: PDFObjectReference appendPage(QRectF mediaBox); + /// Creates AcroForm dictionary. Erases XFA form if present. + /// \param fields Fields + PDFObjectReference createAcroForm(PDFObjectReferenceVector fields); + + /// Creates GoTo action. This action changes view to a specific destination in the same document. /// \param destination Destination PDFObjectReference createActionGoTo(PDFDestination destination); @@ -684,36 +695,6 @@ public: QString description); - /// Free text annotation displays text directly on a page. Text appears directly on the page, in the - /// same way, as standard text in PDF document. Free text annotations are usually used to comment - /// the document. Free text annotation can also have callout line, with, or without a knee. Specify - /// start/end point parameters of this function to get callout line. - /// \param page Page to which is annotation added - /// \param boundingRectangle Bounding rectangle of free text annotation. It must contain both - /// callout line and text rectangle. - /// \param textRectangle Rectangle with text, in absolute coordinates. They are then recomputed to - /// match bounding rectangle. - /// \param title Title - /// \param subject Subject - /// \param contents Contents (text displayed) - /// \param textAlignment Text alignment. Only horizontal alignment flags are valid. - /// \param startPoint Start point of callout line - /// \param endPoint End point of callout line - /// \param startLineType Line ending at the start point - /// \param endLineType Line ending at the end point - PDFObjectReference createAnnotationFreeText(PDFObjectReference page, - QRectF boundingRectangle, - QRectF textRectangle, - QString title, - QString subject, - QString contents, - TextAlignment textAlignment, - QPointF startPoint, - QPointF endPoint, - AnnotationLineEnding startLineType, - AnnotationLineEnding endLineType); - - /// Free text annotation displays text directly on a page. Text appears directly on the page, in the /// same way, as standard text in PDF document. Free text annotations are usually used to comment /// the document. Free text annotation can also have callout line, with, or without a knee. Specify @@ -763,6 +744,36 @@ public: TextAlignment textAlignment); + /// Free text annotation displays text directly on a page. Text appears directly on the page, in the + /// same way, as standard text in PDF document. Free text annotations are usually used to comment + /// the document. Free text annotation can also have callout line, with, or without a knee. Specify + /// start/end point parameters of this function to get callout line. + /// \param page Page to which is annotation added + /// \param boundingRectangle Bounding rectangle of free text annotation. It must contain both + /// callout line and text rectangle. + /// \param textRectangle Rectangle with text, in absolute coordinates. They are then recomputed to + /// match bounding rectangle. + /// \param title Title + /// \param subject Subject + /// \param contents Contents (text displayed) + /// \param textAlignment Text alignment. Only horizontal alignment flags are valid. + /// \param startPoint Start point of callout line + /// \param endPoint End point of callout line + /// \param startLineType Line ending at the start point + /// \param endLineType Line ending at the end point + PDFObjectReference createAnnotationFreeText(PDFObjectReference page, + QRectF boundingRectangle, + QRectF textRectangle, + QString title, + QString subject, + QString contents, + TextAlignment textAlignment, + QPointF startPoint, + QPointF endPoint, + AnnotationLineEnding startLineType, + AnnotationLineEnding endLineType); + + /// Text markup annotation is used to highlight text. It is a markup annotation, so it can contain /// window to be opened (and commented). This annotation is usually used to highlight text, but can /// also highlight other things, such as images, or other graphics. @@ -1046,6 +1057,16 @@ public: QColor color); + /// Text markup annotation is used to squiggly underline text. It is a markup annotation, so it can + /// contain window to be opened (and commented). + /// \param page Page to which is annotation added + /// \param quadrilaterals Area in which is markup displayed + /// \param color Color + PDFObjectReference createAnnotationSquiggly(PDFObjectReference page, + QPolygonF quadrilaterals, + QColor color); + + /// Text markup annotation is used to squiggly underline text. It is a markup annotation, so it can /// contain window to be opened (and commented). /// \param page Page to which is annotation added @@ -1062,16 +1083,6 @@ public: QString contents); - /// Text markup annotation is used to squiggly underline text. It is a markup annotation, so it can - /// contain window to be opened (and commented). - /// \param page Page to which is annotation added - /// \param quadrilaterals Area in which is markup displayed - /// \param color Color - PDFObjectReference createAnnotationSquiggly(PDFObjectReference page, - QPolygonF quadrilaterals, - QColor color); - - /// Stamp annotation /// \param page Page to which is annotation added /// \param rectangle Stamp area @@ -1144,22 +1155,6 @@ public: bool open); - /// Text markup annotation is used to underline text. It is a markup annotation, so it can contain - /// window to be opened (and commented). - /// \param page Page to which is annotation added - /// \param rectangle Area in which is markup displayed - /// \param color Color - /// \param title Title - /// \param subject Subject - /// \param contents Contents - PDFObjectReference createAnnotationUnderline(PDFObjectReference page, - QRectF rectangle, - QColor color, - QString title, - QString subject, - QString contents); - - /// Text markup annotation is used to underline text. It is a markup annotation, so it can contain /// window to be opened (and commented). /// \param page Page to which is annotation added @@ -1180,6 +1175,22 @@ public: QColor color); + /// Text markup annotation is used to underline text. It is a markup annotation, so it can contain + /// window to be opened (and commented). + /// \param page Page to which is annotation added + /// \param rectangle Area in which is markup displayed + /// \param color Color + /// \param title Title + /// \param subject Subject + /// \param contents Contents + PDFObjectReference createAnnotationUnderline(PDFObjectReference page, + QRectF rectangle, + QColor color, + QString title, + QString subject, + QString contents); + + /// Creates empty catalog. This function is used, when a new document is being created. Do not call /// this function manually. PDFObjectReference createCatalog(); @@ -1215,6 +1226,21 @@ public: PDFObjectReference createFileSpecification(QString fileName); + /// Creates signature dictionary used for preparation in signing process. Can define parameters of the + /// signature. + /// \param filter Filter (for example, Adobe.PPKLite, Entrust.PPKEF, CiCi.SignIt, ...) + /// \param subfilter Subfilter (for example, adbe.pkcs7.detached, adbe.pkcs7.sha1, + /// ETSI.CAdES.detached, ...) + /// \param contents Contents (reserved data for signature). + /// \param signingTime Signing date/time + /// \param byteRangeItem Item which will fill byte range array. + PDFObjectReference createSignatureDictionary(QByteArray filter, + QByteArray subfilter, + QByteArray contents, + QDateTime signingTime, + PDFInteger byteRangeItem); + + /// This function is used to create a new trailer dictionary, when blank document is created. Do not /// call this function manually. /// \param catalog Reference to document catalog diff --git a/Pdf4QtViewerPlugins/SignaturePlugin/certificatemanager.cpp b/Pdf4QtViewerPlugins/SignaturePlugin/certificatemanager.cpp index 6854c3a..2fd5c08 100644 --- a/Pdf4QtViewerPlugins/SignaturePlugin/certificatemanager.cpp +++ b/Pdf4QtViewerPlugins/SignaturePlugin/certificatemanager.cpp @@ -190,4 +190,61 @@ bool CertificateManager::isCertificateValid(QString fileName, QString password) return false; } +bool SignatureFactory::sign(QString certificateName, QString password, QByteArray data, QByteArray& result) +{ + QFile file(certificateName); + if (file.open(QFile::ReadOnly)) + { + QByteArray certificateData = file.readAll(); + file.close(); + + openssl_ptr certificateBuffer(BIO_new(BIO_s_mem()), &BIO_free_all); + BIO_write(certificateBuffer.get(), certificateData.constData(), certificateData.length()); + + openssl_ptr pkcs12(d2i_PKCS12_bio(certificateBuffer.get(), nullptr), &PKCS12_free); + if (pkcs12) + { + const char* passwordPointer = nullptr; + QByteArray passwordByteArray = password.isEmpty() ? QByteArray() : password.toUtf8(); + if (!passwordByteArray.isEmpty()) + { + passwordPointer = passwordByteArray.constData(); + } + + EVP_PKEY* key = nullptr; + X509* certificate = nullptr; + STACK_OF(X509)* certificates = nullptr; + if (PKCS12_parse(pkcs12.get(), passwordPointer, &key, &certificate, &certificates) == 1) + { + openssl_ptr signedDataBuffer(BIO_new(BIO_s_mem()), &BIO_free_all); + BIO_write(signedDataBuffer.get(), data.constData(), data.length()); + + PKCS7* signature = PKCS7_sign(certificate, key, certificates, signedDataBuffer.get(), PKCS7_DETACHED | PKCS7_BINARY); + if (signature) + { + openssl_ptr outputBuffer(BIO_new(BIO_s_mem()), &BIO_free_all); + i2d_PKCS7_bio(outputBuffer.get(), signature); + + BUF_MEM* pksMemoryBuffer = nullptr; + BIO_get_mem_ptr(outputBuffer.get(), &pksMemoryBuffer); + + result = QByteArray(pksMemoryBuffer->data, int(pksMemoryBuffer->length)); + + EVP_PKEY_free(key); + X509_free(certificate); + sk_X509_free(certificates); + return true; + } + + EVP_PKEY_free(key); + X509_free(certificate); + sk_X509_free(certificates); + return false; + } + } + } + + return false; +} + } // namespace pdfplugin diff --git a/Pdf4QtViewerPlugins/SignaturePlugin/certificatemanager.h b/Pdf4QtViewerPlugins/SignaturePlugin/certificatemanager.h index 7a52f4e..94de089 100644 --- a/Pdf4QtViewerPlugins/SignaturePlugin/certificatemanager.h +++ b/Pdf4QtViewerPlugins/SignaturePlugin/certificatemanager.h @@ -53,6 +53,12 @@ public: static bool isCertificateValid(QString fileName, QString password); }; +class SignatureFactory +{ +public: + static bool sign(QString certificateName, QString password, QByteArray data, QByteArray& result); +}; + } // namespace pdfplugin #endif // CERTIFICATEMANAGER_H diff --git a/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp b/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp index 6b9ae9c..d5a28e8 100644 --- a/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp +++ b/Pdf4QtViewerPlugins/SignaturePlugin/signatureplugin.cpp @@ -325,7 +325,16 @@ void SignaturePlugin::onSignDigitally() SignDialog dialog(m_dataExchangeInterface->getMainWindow(), m_scene.isEmpty()); if (dialog.exec() == SignDialog::Accepted) { + QByteArray data = "xxgaghre"; + QByteArray result; + SignatureFactory::sign(dialog.getCertificatePath(), dialog.getPassword(), data, result); + for (int i = 1; i < 15; ++i) + { + data.append(data); + } + + SignatureFactory::sign(dialog.getCertificatePath(), dialog.getPassword(), data, result); } } diff --git a/Pdf4QtViewerPlugins/SignaturePlugin/signdialog.cpp b/Pdf4QtViewerPlugins/SignaturePlugin/signdialog.cpp index eebadd4..32ab351 100644 --- a/Pdf4QtViewerPlugins/SignaturePlugin/signdialog.cpp +++ b/Pdf4QtViewerPlugins/SignaturePlugin/signdialog.cpp @@ -63,6 +63,11 @@ QString SignDialog::getCertificatePath() const return ui->certificateCombo->currentData().toString(); } +QString SignDialog::getPassword() const +{ + return ui->certificatePasswordEdit->text(); +} + void SignDialog::accept() { // Check certificate diff --git a/Pdf4QtViewerPlugins/SignaturePlugin/signdialog.h b/Pdf4QtViewerPlugins/SignaturePlugin/signdialog.h index aa727da..9e5f96e 100644 --- a/Pdf4QtViewerPlugins/SignaturePlugin/signdialog.h +++ b/Pdf4QtViewerPlugins/SignaturePlugin/signdialog.h @@ -46,6 +46,7 @@ public: SignMethod getSignMethod() const; QString getCertificatePath() const; + QString getPassword() const; private: Ui::SignDialog* ui; diff --git a/generated_code_definition.xml b/generated_code_definition.xml index 0429049..8af42b7 100644 --- a/generated_code_definition.xml +++ b/generated_code_definition.xml @@ -112,6 +112,85 @@ return pageReference; Appends a new page after last page. _PDFObjectReference + + + + + + + + + + fields + _PDFObjectReferenceVector + Fields + + + Parameters + + _void + + + + + + + + + + + + Fields + DictionaryItemSimple + fields + + + + + NeedAppearances + DictionaryItemSimple + false + + + + + SigFlags + DictionaryItemSimple + 0 + + + + + XFA + DictionaryItemSimple + PDFObject() + + + + Dictionary + + + + CreateObject + acroForm + _PDFObjectReference + + + + + + Code + + _void + setCatalogAcroForm(acroForm); +return acroForm; + + + Structure + createAcroForm + Creates AcroForm dictionary. Erases XFA form if present. + _PDFObjectReference + @@ -2716,281 +2795,6 @@ return annotationReference; Creates a new file attachment annotation. This annotation needs file specification as parameter. _PDFObjectReference - - - - - - - - - - page - _PDFObjectReference - Page to which is annotation added - - - - - boundingRectangle - _QRectF - Bounding rectangle of free text annotation. It must contain both callout line and text rectangle. - - - - - textRectangle - _QRectF - Rectangle with text, in absolute coordinates. They are then recomputed to match bounding rectangle. - - - - - title - _QString - Title - - - - - subject - _QString - Subject - - - - - contents - _QString - Contents (text displayed) - - - - - textAlignment - _TextAlignment - Text alignment. Only horizontal alignment flags are valid. - - - - - startPoint - _QPointF - Start point of callout line - - - - - endPoint - _QPointF - End point of callout line - - - - - startLineType - _AnnotationLineEnding - Line ending at the start point - - - - - endLineType - _AnnotationLineEnding - Line ending at the end point - - - Parameters - - _void - - - - - - - - - - - - Type - DictionaryItemSimple - WrapName("Annot") - - - - - Subtype - DictionaryItemSimple - WrapName("FreeText") - - - - - Rect - DictionaryItemSimple - boundingRectangle - - - - - F - DictionaryItemSimple - 4 - - - - - P - DictionaryItemSimple - page - - - - - M - DictionaryItemSimple - WrapCurrentDateTime() - - - - - CreationDate - DictionaryItemSimple - WrapCurrentDateTime() - - - - - T - DictionaryItemSimple - title - - - - - Contents - DictionaryItemSimple - contents - - - - - Subj - DictionaryItemSimple - subject - - - - - Q - DictionaryItemSimple - WrapFreeTextAlignment(textAlignment) - - - - - DA - DictionaryItemSimple - WrapString("/Arial 10 Tf") - - - - - RD - DictionaryItemSimple - getAnnotationReductionRectangle(boundingRectangle, textRectangle) - - - - - - - - - ArraySimple - startPoint;endPoint - - - CL - DictionaryItemComplex - - - - - - - - - - ArraySimple - startLineType;endLineType - - - LE - DictionaryItemComplex - - - - - Dictionary - - - - CreateObject - annotationObject - _PDFObjectReference - - - - - - - - - - - - - - - - ArraySimple - annotationObject - - - Annots - DictionaryItemComplex - - - - - Dictionary - - - - CreateObject - pageAnnots - _PDFObject - - - - - - Code - - _void - appendTo(page, pageAnnots); -updateAnnotationAppearanceStreams(annotationObject); -return annotationObject; - - - Annotations - createAnnotationFreeText - Free text annotation displays text directly on a page. Text appears directly on the page, in the same way, as standard text in PDF document. Free text annotations are usually used to comment the document. Free text annotation can also have callout line, with, or without a knee. Specify start/end point parameters of this function to get callout line. - _PDFObjectReference - @@ -3476,6 +3280,281 @@ return annotationObject; Free text annotation displays text directly on a page. Text appears directly on the page, in the same way, as standard text in PDF document. Free text annotations are usually used to comment the document. Free text annotation can also have callout line, with, or without a knee. _PDFObjectReference + + + + + + + + + + page + _PDFObjectReference + Page to which is annotation added + + + + + boundingRectangle + _QRectF + Bounding rectangle of free text annotation. It must contain both callout line and text rectangle. + + + + + textRectangle + _QRectF + Rectangle with text, in absolute coordinates. They are then recomputed to match bounding rectangle. + + + + + title + _QString + Title + + + + + subject + _QString + Subject + + + + + contents + _QString + Contents (text displayed) + + + + + textAlignment + _TextAlignment + Text alignment. Only horizontal alignment flags are valid. + + + + + startPoint + _QPointF + Start point of callout line + + + + + endPoint + _QPointF + End point of callout line + + + + + startLineType + _AnnotationLineEnding + Line ending at the start point + + + + + endLineType + _AnnotationLineEnding + Line ending at the end point + + + Parameters + + _void + + + + + + + + + + + + Type + DictionaryItemSimple + WrapName("Annot") + + + + + Subtype + DictionaryItemSimple + WrapName("FreeText") + + + + + Rect + DictionaryItemSimple + boundingRectangle + + + + + F + DictionaryItemSimple + 4 + + + + + P + DictionaryItemSimple + page + + + + + M + DictionaryItemSimple + WrapCurrentDateTime() + + + + + CreationDate + DictionaryItemSimple + WrapCurrentDateTime() + + + + + T + DictionaryItemSimple + title + + + + + Contents + DictionaryItemSimple + contents + + + + + Subj + DictionaryItemSimple + subject + + + + + Q + DictionaryItemSimple + WrapFreeTextAlignment(textAlignment) + + + + + DA + DictionaryItemSimple + WrapString("/Arial 10 Tf") + + + + + RD + DictionaryItemSimple + getAnnotationReductionRectangle(boundingRectangle, textRectangle) + + + + + + + + + ArraySimple + startPoint;endPoint + + + CL + DictionaryItemComplex + + + + + + + + + + ArraySimple + startLineType;endLineType + + + LE + DictionaryItemComplex + + + + + Dictionary + + + + CreateObject + annotationObject + _PDFObjectReference + + + + + + + + + + + + + + + + ArraySimple + annotationObject + + + Annots + DictionaryItemComplex + + + + + Dictionary + + + + CreateObject + pageAnnots + _PDFObject + + + + + + Code + + _void + appendTo(page, pageAnnots); +updateAnnotationAppearanceStreams(annotationObject); +return annotationObject; + + + Annotations + createAnnotationFreeText + Free text annotation displays text directly on a page. Text appears directly on the page, in the same way, as standard text in PDF document. Free text annotations are usually used to comment the document. Free text annotation can also have callout line, with, or without a knee. Specify start/end point parameters of this function to get callout line. + _PDFObjectReference + @@ -6548,6 +6627,146 @@ return annotationObject; _void appendTo(page, pageAnnots); updateAnnotationAppearanceStreams(annotationObject); +return annotationObject; + + + Annotations + createAnnotationSquiggly + Text markup annotation is used to squiggly underline text. It is a markup annotation, so it can contain window to be opened (and commented). + _PDFObjectReference + + + + + + + + + + + page + _PDFObjectReference + Page to which is annotation added + + + + + quadrilaterals + _QPolygonF + Area in which is markup displayed + + + + + color + _QColor + Color + + + Parameters + + _void + + + + + + + + + + + + Type + DictionaryItemSimple + WrapName("Annot") + + + + + Subtype + DictionaryItemSimple + WrapName("Squiggly") + + + + + P + DictionaryItemSimple + page + + + + + CreationDate + DictionaryItemSimple + WrapCurrentDateTime() + + + + + C + DictionaryItemSimple + color + + + + + QuadPoints + DictionaryItemSimple + quadrilaterals + + + + Dictionary + + + + CreateObject + annotationObject + _PDFObjectReference + + + + + + + + + + + + + + + + ArraySimple + annotationObject + + + Annots + DictionaryItemComplex + + + + + Dictionary + + + + CreateObject + pageAnnots + _PDFObject + + + + + + Code + + _void + appendTo(page, pageAnnots); +updateAnnotationAppearanceStreams(annotationObject); return annotationObject; @@ -6752,146 +6971,6 @@ return annotationObject; _void appendTo(page, pageAnnots); updateAnnotationAppearanceStreams(annotationObject); -return annotationObject; - - - Annotations - createAnnotationSquiggly - Text markup annotation is used to squiggly underline text. It is a markup annotation, so it can contain window to be opened (and commented). - _PDFObjectReference - - - - - - - - - - - page - _PDFObjectReference - Page to which is annotation added - - - - - quadrilaterals - _QPolygonF - Area in which is markup displayed - - - - - color - _QColor - Color - - - Parameters - - _void - - - - - - - - - - - - Type - DictionaryItemSimple - WrapName("Annot") - - - - - Subtype - DictionaryItemSimple - WrapName("Squiggly") - - - - - P - DictionaryItemSimple - page - - - - - CreationDate - DictionaryItemSimple - WrapCurrentDateTime() - - - - - C - DictionaryItemSimple - color - - - - - QuadPoints - DictionaryItemSimple - quadrilaterals - - - - Dictionary - - - - CreateObject - annotationObject - _PDFObjectReference - - - - - - - - - - - - - - - - ArraySimple - annotationObject - - - Annots - DictionaryItemComplex - - - - - Dictionary - - - - CreateObject - pageAnnots - _PDFObject - - - - - - Code - - _void - appendTo(page, pageAnnots); -updateAnnotationAppearanceStreams(annotationObject); return annotationObject; @@ -7831,210 +7910,6 @@ return annotationObject; Creates text annotation. Text annotation is "sticky note" attached to a point in the PDF document. When closed, it is displayed as icon, if opened, widget appears with attached text. Text annotations do not scale or rotate, they appear independent of zoom/rotate. So, they behave as if flags NoZoom or NoRotate to the annotations are being set. Popup annotation is automatically created for this annotation. _PDFObjectReference - - - - - - - - - - page - _PDFObjectReference - Page to which is annotation added - - - - - rectangle - _QRectF - Area in which is markup displayed - - - - - color - _QColor - Color - - - - - title - _QString - Title - - - - - subject - _QString - Subject - - - - - contents - _QString - Contents - - - Parameters - - _void - - - - - - - - - - - - Type - DictionaryItemSimple - WrapName("Annot") - - - - - Subtype - DictionaryItemSimple - WrapName("Underline") - - - - - Rect - DictionaryItemSimple - rectangle - - - - - P - DictionaryItemSimple - page - - - - - M - DictionaryItemSimple - WrapCurrentDateTime() - - - - - CreationDate - DictionaryItemSimple - WrapCurrentDateTime() - - - - - C - DictionaryItemSimple - color - - - - - T - DictionaryItemSimple - title - - - - - Contents - DictionaryItemSimple - contents - - - - - Subj - DictionaryItemSimple - subject - - - - - - - - - ArraySimple - rectangle.bottomLeft();rectangle.bottomRight();rectangle.topLeft();rectangle.topRight() - - - QuadPoints - DictionaryItemComplex - - - - - Dictionary - - - - CreateObject - annotationObject - _PDFObjectReference - - - - - - - - - - - - - - - - ArraySimple - annotationObject - - - Annots - DictionaryItemComplex - - - - - Dictionary - - - - CreateObject - pageAnnots - _PDFObject - - - - - - Code - - _void - appendTo(page, pageAnnots); -updateAnnotationAppearanceStreams(annotationObject); -return annotationObject; - - - Annotations - createAnnotationUnderline - Text markup annotation is used to underline text. It is a markup annotation, so it can contain window to be opened (and commented). - _PDFObjectReference - @@ -8322,6 +8197,210 @@ return annotationObject; _void appendTo(page, pageAnnots); updateAnnotationAppearanceStreams(annotationObject); +return annotationObject; + + + Annotations + createAnnotationUnderline + Text markup annotation is used to underline text. It is a markup annotation, so it can contain window to be opened (and commented). + _PDFObjectReference + + + + + + + + + + + page + _PDFObjectReference + Page to which is annotation added + + + + + rectangle + _QRectF + Area in which is markup displayed + + + + + color + _QColor + Color + + + + + title + _QString + Title + + + + + subject + _QString + Subject + + + + + contents + _QString + Contents + + + Parameters + + _void + + + + + + + + + + + + Type + DictionaryItemSimple + WrapName("Annot") + + + + + Subtype + DictionaryItemSimple + WrapName("Underline") + + + + + Rect + DictionaryItemSimple + rectangle + + + + + P + DictionaryItemSimple + page + + + + + M + DictionaryItemSimple + WrapCurrentDateTime() + + + + + CreationDate + DictionaryItemSimple + WrapCurrentDateTime() + + + + + C + DictionaryItemSimple + color + + + + + T + DictionaryItemSimple + title + + + + + Contents + DictionaryItemSimple + contents + + + + + Subj + DictionaryItemSimple + subject + + + + + + + + + ArraySimple + rectangle.bottomLeft();rectangle.bottomRight();rectangle.topLeft();rectangle.topRight() + + + QuadPoints + DictionaryItemComplex + + + + + Dictionary + + + + CreateObject + annotationObject + _PDFObjectReference + + + + + + + + + + + + + + + + ArraySimple + annotationObject + + + Annots + DictionaryItemComplex + + + + + Dictionary + + + + CreateObject + pageAnnots + _PDFObject + + + + + + Code + + _void + appendTo(page, pageAnnots); +updateAnnotationAppearanceStreams(annotationObject); return annotationObject; @@ -8775,6 +8854,126 @@ return rootNodeReference; Creates file specification for external file. _PDFObjectReference + + + + + + + + + + filter + _QByteArray + Filter (for example, Adobe.PPKLite, Entrust.PPKEF, CiCi.SignIt, ...) + + + + + subfilter + _QByteArray + Subfilter (for example, adbe.pkcs7.detached, adbe.pkcs7.sha1, ETSI.CAdES.detached, ...) + + + + + contents + _QByteArray + Contents (reserved data for signature). + + + + + signingTime + _QDateTime + Signing date/time + + + + + byteRangeItem + _PDFInteger + Item which will fill byte range array. + + + Parameters + + _void + + + + + + + + + + + + Type + DictionaryItemSimple + WrapName("Sig") + + + + + Filter + DictionaryItemSimple + WrapName(filter) + + + + + SubFilter + DictionaryItemSimple + WrapName(subfilter) + + + + + ByteRange + DictionaryItemSimple + std::array{ byteRangeItem, byteRangeItem, byteRangeItem, byteRangeItem } + + + + + Contents + DictionaryItemSimple + contents + + + + + M + DictionaryItemSimple + signingTime + + + + Dictionary + + + + CreateObject + signatureDictionary + _PDFObjectReference + + + + + + Code + + _void + return signatureDictionary; + + + Structure + createSignatureDictionary + Creates signature dictionary used for preparation in signing process. Can define parameters of the signature. + _PDFObjectReference +