diff options
author | Albert Astals Cid <albert.astals.cid@kdab.com> | 2021-04-13 17:00:12 +0200 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2021-05-14 16:43:12 +0200 |
commit | 5acd6659559907e3cfbfbcd8a8e94c66f38596f0 (patch) | |
tree | fca169bed63105c3d1992089ebb1fa45da33c405 | |
parent | 26f8a7d1bc9c6cd511989d74fdb54f233b25d663 (diff) |
Fancier left/right signature visual representation
-rw-r--r-- | poppler/Annot.cc | 77 | ||||
-rw-r--r-- | poppler/Annot.h | 1 | ||||
-rw-r--r-- | poppler/Form.cc | 20 | ||||
-rw-r--r-- | poppler/Form.h | 8 | ||||
-rw-r--r-- | qt5/src/poppler-pdf-converter.cc | 25 | ||||
-rw-r--r-- | qt5/src/poppler-qt5.h | 18 | ||||
-rw-r--r-- | qt6/src/poppler-pdf-converter.cc | 25 | ||||
-rw-r--r-- | qt6/src/poppler-qt6.h | 18 |
8 files changed, 172 insertions, 20 deletions
diff --git a/poppler/Annot.cc b/poppler/Annot.cc index 7b7d37b3..0e36b209 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -4904,11 +4904,30 @@ bool AnnotAppearanceBuilder::drawFormFieldText(const FormFieldText *fieldText, c bool AnnotAppearanceBuilder::drawSignatureFieldText(const FormFieldSignature *field, const Form *form, const GfxResources *resources, const GooString *_da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, XRef *xref, Dict *resourcesDict) { - DefaultAppearance da(_da); const GooString &contents = field->getCustomAppearanceContent(); if (contents.toStr().empty()) return false; + const GooString &leftText = field->getCustomAppearanceLeftContent(); + if (leftText.toStr().empty()) { + drawSignatureFieldText(contents, DefaultAppearance(_da), border, rect, xref, resourcesDict, 0, false /* don't center vertically */, false /* don't center horizontally */); + } else { + DefaultAppearance daLeft(_da); + daLeft.setFontPtSize(field->getCustomAppearanceLeftFontSize()); + const double halfWidth = (rect->x2 - rect->x1) / 2; + PDFRectangle rectLeft(rect->x1, rect->y1, rect->x1 + halfWidth, rect->y2); + drawSignatureFieldText(leftText, daLeft, border, &rectLeft, xref, resourcesDict, 0, true /* center vertically */, true /* center horizontally */); + + PDFRectangle rectRight(rectLeft.x2, rect->y1, rect->x2, rect->y2); + drawSignatureFieldText(contents, DefaultAppearance(_da), border, &rectRight, xref, resourcesDict, halfWidth, true /* center vertically */, false /* don't center horizontally */); + } + + return true; +} + +void AnnotAppearanceBuilder::drawSignatureFieldText(const GooString &text, const DefaultAppearance &da, const AnnotBorder *border, const PDFRectangle *rect, XRef *xref, Dict *resourcesDict, double leftMargin, bool centerVertically, + bool centerHorizontally) +{ double borderWidth = 0; append("q\n"); @@ -4921,40 +4940,58 @@ bool AnnotAppearanceBuilder::drawSignatureFieldText(const FormFieldSignature *fi // Box size const double width = rect->x2 - rect->x1; const double height = rect->y2 - rect->y1; - - // Setup text clipping const double textmargin = borderWidth * 2; const double textwidth = width - 2 * textmargin; - appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re W n\n", textmargin, textwidth, height - 2 * textmargin); - - GfxFont *font = nullptr; // create a Helvetica fake font - font = createAnnotDrawFont(xref, resourcesDict, da.getFontName().getName()); + GfxFont *font = createAnnotDrawFont(xref, resourcesDict, da.getFontName().getName()); + + // calculate the string tokenization + int i = 0; + std::vector<std::pair<std::string, double>> outTexts; + while (i < text.getLength()) { + GooString out; + double textWidth; + Annot::layoutText(&text, &out, &i, font, &textWidth, textwidth / da.getFontPtSize(), nullptr, false); + outTexts.emplace_back(out.toStr(), textWidth * da.getFontPtSize()); + } + + // Setup text clipping + appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re W n\n", leftMargin + textmargin, textmargin, textwidth, height - 2 * textmargin); // Set font state setDrawColor(da.getFontColor(), true); appendf("BT 1 0 0 1 {0:.2f} {1:.2f} Tm\n", textmargin, height - textmargin - da.getFontPtSize() * font->getDescent()); setTextFont(da.getFontName(), da.getFontPtSize()); - int i = 0; - double xposPrev = 0; - while (i < contents.getLength()) { - GooString out; - double linewidth, xpos; - Annot::layoutText(&contents, &out, &i, font, &linewidth, textwidth / da.getFontPtSize(), nullptr, false); - linewidth *= da.getFontPtSize(); - xpos = 0; - appendf("{0:.2f} {1:.2f} Td\n", xpos - xposPrev, -da.getFontPtSize()); - writeString(out); + double xDelta = centerHorizontally ? 0 : leftMargin; + double currentX = 0; + double yDelta = -da.getFontPtSize(); + if (centerVertically) { + const double outTextHeight = outTexts.size() * da.getFontPtSize(); + if (outTextHeight < height) { + yDelta -= (height - outTextHeight) / 2; + } + } + for (const std::pair<std::string, double> &outText : outTexts) { + if (centerHorizontally) { + const double lineX = (width - outText.second) / 2; + xDelta = (lineX - currentX); + currentX += xDelta; + } + + appendf("{0:.2f} {1:.2f} Td\n", xDelta, yDelta); + writeString(GooString(outText.first)); append("Tj\n"); - xposPrev = xpos; + + if (!centerHorizontally) { + xDelta = 0; + } + yDelta = -da.getFontPtSize(); } font->decRefCnt(); append("ET Q\n"); - - return true; } bool AnnotAppearanceBuilder::drawFormFieldChoice(const FormFieldChoice *fieldChoice, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, diff --git a/poppler/Annot.h b/poppler/Annot.h index 5eb16472..0e97a50c 100644 --- a/poppler/Annot.h +++ b/poppler/Annot.h @@ -592,6 +592,7 @@ private: bool drawFormFieldChoice(const FormFieldChoice *fieldChoice, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect); bool drawSignatureFieldText(const FormFieldSignature *field, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, XRef *xref, Dict *resourcesDict); + void drawSignatureFieldText(const GooString &text, const DefaultAppearance &da, const AnnotBorder *border, const PDFRectangle *rect, XRef *xref, Dict *resourcesDict, double leftMargin, bool centerVertically, bool centerHorizontally); bool drawText(const GooString *text, const GooString *da, const GfxResources *resources, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, bool multiline, int comb, int quadding, bool txField, bool forceZapfDingbats, XRef *xref, bool *addedDingbatsResource, // xref and addedDingbatsResource both must not be null if forceZapfDingbats is passed bool password); diff --git a/poppler/Form.cc b/poppler/Form.cc index ff0e8d4a..b6488b59 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -2018,6 +2018,26 @@ void FormFieldSignature::setCustomAppearanceContent(const GooString &s) customAppearanceContent = GooString(s.toStr()); } +const GooString &FormFieldSignature::getCustomAppearanceLeftContent() const +{ + return customAppearanceLeftContent; +} + +void FormFieldSignature::setCustomAppearanceLeftContent(const GooString &s) +{ + customAppearanceLeftContent = GooString(s.toStr()); +} + +double FormFieldSignature::getCustomAppearanceLeftFontSize() const +{ + return customAppearanceLeftFontSize; +} + +void FormFieldSignature::setCustomAppearanceLeftFontSize(double size) +{ + customAppearanceLeftFontSize = size; +} + void FormFieldSignature::setCertificateInfo(std::unique_ptr<X509CertificateInfo> &certInfo) { certificate_info.swap(certInfo); diff --git a/poppler/Form.h b/poppler/Form.h index 4a796962..13ca1f5f 100644 --- a/poppler/Form.h +++ b/poppler/Form.h @@ -615,6 +615,12 @@ public: const GooString &getCustomAppearanceContent() const; void setCustomAppearanceContent(const GooString &s); + const GooString &getCustomAppearanceLeftContent() const; + void setCustomAppearanceLeftContent(const GooString &s); + + double getCustomAppearanceLeftFontSize() const; + void setCustomAppearanceLeftFontSize(double size); + void setCertificateInfo(std::unique_ptr<X509CertificateInfo> &); FormWidget *getCreateWidget(); @@ -628,6 +634,8 @@ private: GooString *signature; SignatureInfo *signature_info; GooString customAppearanceContent; + GooString customAppearanceLeftContent; + double customAppearanceLeftFontSize = 20; std::unique_ptr<X509CertificateInfo> certificate_info; void print(int indent) override; diff --git a/qt5/src/poppler-pdf-converter.cc b/qt5/src/poppler-pdf-converter.cc index d1355764..3f6b6447 100644 --- a/qt5/src/poppler-pdf-converter.cc +++ b/qt5/src/poppler-pdf-converter.cc @@ -156,6 +156,9 @@ bool PDFConverter::sign(const NewSignatureData &data) std::unique_ptr<GooString> gSignatureText = std::unique_ptr<GooString>(QStringToUnicodeGooString(data.signatureText())); field->setCustomAppearanceContent(*gSignatureText); + std::unique_ptr<GooString> gSignatureLeftText = std::unique_ptr<GooString>(QStringToUnicodeGooString(data.signatureLeftText())); + field->setCustomAppearanceLeftContent(*gSignatureLeftText); + Object refObj(ref); AnnotWidget *signatureAnnot = new AnnotWidget(doc, &annotObj, &refObj, field.get()); signatureAnnot->setFlags(signatureAnnot->getFlags() | Annot::flagPrint | Annot::flagLocked | Annot::flagNoRotate); @@ -208,7 +211,9 @@ struct PDFConverter::NewSignatureData::NewSignatureDataPrivate int page; QRectF boundingRectangle; QString signatureText; + QString signatureLeftText; double fontSize = 10.0; + double leftFontSize = 20.0; QColor fontColor = Qt::red; QColor borderColor = Qt::red; double borderWidth = 1.5; @@ -274,6 +279,16 @@ void PDFConverter::NewSignatureData::setSignatureText(const QString &text) d->signatureText = text; } +QString PDFConverter::NewSignatureData::signatureLeftText() const +{ + return d->signatureLeftText; +} + +void PDFConverter::NewSignatureData::setSignatureLeftText(const QString &text) +{ + d->signatureLeftText = text; +} + double PDFConverter::NewSignatureData::fontSize() const { return d->fontSize; @@ -284,6 +299,16 @@ void PDFConverter::NewSignatureData::setFontSize(double fontSize) d->fontSize = fontSize; } +double PDFConverter::NewSignatureData::leftFontSize() const +{ + return d->leftFontSize; +} + +void PDFConverter::NewSignatureData::setLeftFontSize(double fontSize) +{ + d->leftFontSize = fontSize; +} + QColor PDFConverter::NewSignatureData::fontColor() const { return d->fontColor; diff --git a/qt5/src/poppler-qt5.h b/qt5/src/poppler-qt5.h index a3163572..56bab8a2 100644 --- a/qt5/src/poppler-qt5.h +++ b/qt5/src/poppler-qt5.h @@ -2172,12 +2172,30 @@ public: void setSignatureText(const QString &text); /** + * If this text is not empty, the signature representation + * will split in two, with this text on the left and signatureText + * on the right + * + * \since 21.06 + */ + QString signatureLeftText() const; + void setSignatureLeftText(const QString &text); + + /** * Default: 10 */ double fontSize() const; void setFontSize(double fontSize); /** + * Default: 20 + * + * \since 21.06 + */ + double leftFontSize() const; + void setLeftFontSize(double fontSize); + + /** * Default: red */ QColor fontColor() const; diff --git a/qt6/src/poppler-pdf-converter.cc b/qt6/src/poppler-pdf-converter.cc index 62e6d535..a0a64d62 100644 --- a/qt6/src/poppler-pdf-converter.cc +++ b/qt6/src/poppler-pdf-converter.cc @@ -156,6 +156,9 @@ bool PDFConverter::sign(const NewSignatureData &data) std::unique_ptr<GooString> gSignatureText = std::unique_ptr<GooString>(QStringToUnicodeGooString(data.signatureText())); field->setCustomAppearanceContent(*gSignatureText); + std::unique_ptr<GooString> gSignatureLeftText = std::unique_ptr<GooString>(QStringToUnicodeGooString(data.signatureLeftText())); + field->setCustomAppearanceLeftContent(*gSignatureLeftText); + Object refObj(ref); AnnotWidget *signatureAnnot = new AnnotWidget(doc, &annotObj, &refObj, field.get()); signatureAnnot->setFlags(signatureAnnot->getFlags() | Annot::flagPrint | Annot::flagLocked | Annot::flagNoRotate); @@ -208,7 +211,9 @@ struct PDFConverter::NewSignatureData::NewSignatureDataPrivate int page; QRectF boundingRectangle; QString signatureText; + QString signatureLeftText; double fontSize = 10.0; + double leftFontSize = 20.0; QColor fontColor = Qt::red; QColor borderColor = Qt::red; double borderWidth = 1.5; @@ -274,6 +279,16 @@ void PDFConverter::NewSignatureData::setSignatureText(const QString &text) d->signatureText = text; } +QString PDFConverter::NewSignatureData::signatureLeftText() const +{ + return d->signatureLeftText; +} + +void PDFConverter::NewSignatureData::setSignatureLeftText(const QString &text) +{ + d->signatureLeftText = text; +} + double PDFConverter::NewSignatureData::fontSize() const { return d->fontSize; @@ -284,6 +299,16 @@ void PDFConverter::NewSignatureData::setFontSize(double fontSize) d->fontSize = fontSize; } +double PDFConverter::NewSignatureData::leftFontSize() const +{ + return d->leftFontSize; +} + +void PDFConverter::NewSignatureData::setLeftFontSize(double fontSize) +{ + d->leftFontSize = fontSize; +} + QColor PDFConverter::NewSignatureData::fontColor() const { return d->fontColor; diff --git a/qt6/src/poppler-qt6.h b/qt6/src/poppler-qt6.h index b59d9add..dbef56ae 100644 --- a/qt6/src/poppler-qt6.h +++ b/qt6/src/poppler-qt6.h @@ -1990,12 +1990,30 @@ public: void setSignatureText(const QString &text); /** + * If this text is not empty, the signature representation + * will split in two, with this text on the left and signatureText + * on the right + * + * \since 21.06 + */ + QString signatureLeftText() const; + void setSignatureLeftText(const QString &text); + + /** * Default: 10 */ double fontSize() const; void setFontSize(double fontSize); /** + * Default: 20 + * + * \since 21.06 + */ + double leftFontSize() const; + void setLeftFontSize(double fontSize); + + /** * Default: red */ QColor fontColor() const; |