summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <albert.astals.cid@kdab.com>2021-04-13 17:00:12 +0200
committerAlbert Astals Cid <aacid@kde.org>2021-05-14 16:43:12 +0200
commit5acd6659559907e3cfbfbcd8a8e94c66f38596f0 (patch)
treefca169bed63105c3d1992089ebb1fa45da33c405
parent26f8a7d1bc9c6cd511989d74fdb54f233b25d663 (diff)
Fancier left/right signature visual representation
-rw-r--r--poppler/Annot.cc77
-rw-r--r--poppler/Annot.h1
-rw-r--r--poppler/Form.cc20
-rw-r--r--poppler/Form.h8
-rw-r--r--qt5/src/poppler-pdf-converter.cc25
-rw-r--r--qt5/src/poppler-qt5.h18
-rw-r--r--qt6/src/poppler-pdf-converter.cc25
-rw-r--r--qt6/src/poppler-qt6.h18
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;