summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Astals Cid <albert.astals.cid@kdab.com>2018-04-04 10:20:52 +0200
committerAlbert Astals Cid <aacid@kde.org>2018-04-06 10:35:36 +0200
commit8821c04f36cb737776cd9077a46f1a9f86ca54e7 (patch)
tree1966c38536a16162afa2a4fba4a48502e4be2d7b
parentafb053d652cc1f670465d471f671652b112dbf51 (diff)
Workaround form field text not being drawn on broken files
Try drawing with the form appearance instead of the field apparance if drawing with the field appearance fails Bug #103245
-rw-r--r--poppler/Annot.cc88
-rw-r--r--poppler/Annot.h24
2 files changed, 68 insertions, 44 deletions
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 629b65b2..c66096e7 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -4035,7 +4035,7 @@ void AnnotAppearanceBuilder::writeString(const GooString &str)
}
// Draw the variable text or caption for a field.
-void AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da, const GfxResources *resources,
+bool AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da, const GfxResources *resources,
const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect,
GBool multiline, int comb, int quadding,
GBool txField, GBool forceZapfDingbats,
@@ -4131,7 +4131,7 @@ void AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da
if (daToks) {
deleteGooList(daToks, GooString);
}
- return;
+ return false;
}
// get the border width
@@ -4448,10 +4448,12 @@ void AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da
if (fontToFree) {
fontToFree->decRefCnt();
}
+
+ return true;
}
// Draw the variable text or caption for a field.
-void AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, const AnnotBorder *border, const PDFRectangle *rect,
+bool AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, const AnnotBorder *border, const PDFRectangle *rect,
const GooString *da, const GfxResources *resources, int quadding) {
GooList *daToks;
GooString *tok, *convertedText;
@@ -4512,7 +4514,7 @@ void AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, con
if (daToks) {
deleteGooList(daToks, GooString);
}
- return;
+ return false;
}
convertedText = new GooString;
@@ -4531,7 +4533,7 @@ void AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, con
deleteGooList(daToks, GooString);
}
delete convertedText;
- return;
+ return false;
}
Annot::layoutText(fieldChoice->getChoice(i), convertedText, &j, font, &w, 0.0, nullptr, gFalse);
if (w > wMax) {
@@ -4630,6 +4632,8 @@ void AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, con
}
delete convertedText;
+
+ return true;
}
void AnnotAppearanceBuilder::drawFieldBorder(const FormField *field, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect) {
@@ -4736,7 +4740,31 @@ void AnnotAppearanceBuilder::drawFieldBorder(const FormField *field, const Annot
}
}
-void AnnotAppearanceBuilder::drawFormFieldButton(const FormFieldButton *field, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource) {
+bool AnnotAppearanceBuilder::drawFormField(const FormField *field, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource)
+{
+ // draw the field contents
+ switch (field->getType()) {
+ case formButton:
+ return drawFormFieldButton(static_cast<const FormFieldButton *>(field), resources, da, border, appearCharacs, rect, appearState, xref, addedDingbatsResource);
+ break;
+ case formText:
+ return drawFormFieldText(static_cast<const FormFieldText *>(field), form, resources, da, border, appearCharacs, rect);
+ case formChoice:
+ return drawFormFieldChoice(static_cast<const FormFieldChoice *>(field), form, resources, da, border, appearCharacs, rect);
+ break;
+ case formSignature:
+ //~unimp
+ break;
+ case formUndef:
+ default:
+ error(errSyntaxError, -1, "Unknown field type");
+ }
+
+ return false;
+}
+
+
+bool AnnotAppearanceBuilder::drawFormFieldButton(const FormFieldButton *field, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource) {
const GooString *caption = nullptr;
if (appearCharacs)
caption = appearCharacs->getNormalCaption();
@@ -4747,7 +4775,7 @@ void AnnotAppearanceBuilder::drawFormFieldButton(const FormFieldButton *field, c
if (appearState && appearState->cmp("Off") != 0 &&
field->getState(appearState->getCString())) {
if (caption) {
- drawText(caption, da, resources, border, appearCharacs, rect, gFalse, 0, fieldQuadCenter, gFalse, gTrue, xref, addedDingbatsResource, gFalse);
+ return drawText(caption, da, resources, border, appearCharacs, rect, gFalse, 0, fieldQuadCenter, gFalse, gTrue, xref, addedDingbatsResource, gFalse);
} else if (appearCharacs) {
const AnnotColor *aColor = appearCharacs->getBorderColor();
if (aColor) {
@@ -4756,28 +4784,31 @@ void AnnotAppearanceBuilder::drawFormFieldButton(const FormFieldButton *field, c
setDrawColor(aColor, gTrue);
drawCircle(0.5 * dx, 0.5 * dy, 0.2 * (dx < dy ? dx : dy), gTrue);
}
+ return true;
}
}
}
break;
case formButtonPush:
if (caption)
- drawText(caption, da, resources, border, appearCharacs, rect, gFalse, 0, fieldQuadCenter, gFalse, gFalse, xref, addedDingbatsResource, gFalse);
+ return drawText(caption, da, resources, border, appearCharacs, rect, gFalse, 0, fieldQuadCenter, gFalse, gFalse, xref, addedDingbatsResource, gFalse);
break;
case formButtonCheck:
if (appearState && appearState->cmp("Off") != 0) {
if (!caption) {
GooString checkMark("3");
- drawText(&checkMark, da, resources, border, appearCharacs, rect, gFalse, 0, fieldQuadCenter, gFalse, gTrue, xref, addedDingbatsResource, gFalse);
+ return drawText(&checkMark, da, resources, border, appearCharacs, rect, gFalse, 0, fieldQuadCenter, gFalse, gTrue, xref, addedDingbatsResource, gFalse);
} else {
- drawText(caption, da, resources, border, appearCharacs, rect, gFalse, 0, fieldQuadCenter, gFalse, gTrue, xref, addedDingbatsResource, gFalse);
+ return drawText(caption, da, resources, border, appearCharacs, rect, gFalse, 0, fieldQuadCenter, gFalse, gTrue, xref, addedDingbatsResource, gFalse);
}
}
break;
}
+
+ return true;
}
-void AnnotAppearanceBuilder::drawFormFieldText(const FormFieldText *fieldText, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect) {
+bool AnnotAppearanceBuilder::drawFormFieldText(const FormFieldText *fieldText, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect) {
VariableTextQuadding quadding;
const GooString *contents;
@@ -4789,12 +4820,14 @@ void AnnotAppearanceBuilder::drawFormFieldText(const FormFieldText *fieldText, c
if (fieldText->isComb())
comb = fieldText->getMaxLen();
- drawText(contents, da, resources, border, appearCharacs, rect,
+ return drawText(contents, da, resources, border, appearCharacs, rect,
fieldText->isMultiline(), comb, quadding, gTrue, gFalse, nullptr, nullptr, fieldText->isPassword());
}
+
+ return true;
}
-void AnnotAppearanceBuilder::drawFormFieldChoice(const FormFieldChoice *fieldChoice, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect) {
+bool AnnotAppearanceBuilder::drawFormFieldChoice(const FormFieldChoice *fieldChoice, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect) {
const GooString *selected;
VariableTextQuadding quadding;
@@ -4803,18 +4836,20 @@ void AnnotAppearanceBuilder::drawFormFieldChoice(const FormFieldChoice *fieldCho
if (fieldChoice->isCombo()) {
selected = fieldChoice->getSelectedChoice();
if (selected) {
- drawText(selected, da, resources, border, appearCharacs, rect, gFalse, 0, quadding, gTrue, gFalse, nullptr, nullptr, gFalse);
+ return drawText(selected, da, resources, border, appearCharacs, rect, gFalse, 0, quadding, gTrue, gFalse, nullptr, nullptr, gFalse);
//~ Acrobat draws a popup icon on the right side
}
// list box
} else {
- drawListBox(fieldChoice, border, rect, da, resources, quadding);
+ return drawListBox(fieldChoice, border, rect, da, resources, quadding);
}
+
+ return true;
}
void AnnotWidget::generateFieldAppearance(bool *addedDingbatsResource) {
GfxResources *resources;
- GooString *da;
+ const GooString *da;
AnnotAppearanceBuilder appearBuilder;
@@ -4838,23 +4873,10 @@ void AnnotWidget::generateFieldAppearance(bool *addedDingbatsResource) {
resources = form->getDefaultResources();
- // draw the field contents
- switch (field->getType()) {
- case formButton:
- appearBuilder.drawFormFieldButton(static_cast<FormFieldButton *>(field), resources, da, border, appearCharacs, rect, appearState, xref, addedDingbatsResource);
- break;
- case formText:
- appearBuilder.drawFormFieldText(static_cast<FormFieldText *>(field), form, resources, da, border, appearCharacs, rect);
- break;
- case formChoice:
- appearBuilder.drawFormFieldChoice(static_cast<FormFieldChoice *>(field), form, resources, da, border, appearCharacs, rect);
- break;
- case formSignature:
- //~unimp
- break;
- case formUndef:
- default:
- error(errSyntaxError, -1, "Unknown field type");
+ const bool success = appearBuilder.drawFormField(field, form, resources, da, border, appearCharacs, rect, appearState, xref, addedDingbatsResource);
+ if (!success && da != form->getDefaultAppearance()) {
+ da = form->getDefaultAppearance();
+ appearBuilder.drawFormField(field, form, resources, da, border, appearCharacs, rect, appearState, xref, addedDingbatsResource);
}
const GooString *appearBuf = appearBuilder.buffer();
diff --git a/poppler/Annot.h b/poppler/Annot.h
index d5944a13..c1acc065 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -514,18 +514,8 @@ public:
void drawCircle(double cx, double cy, double r, GBool fill);
void drawCircleTopLeft(double cx, double cy, double r);
void drawCircleBottomRight(double cx, double cy, double r);
- void drawText(const GooString *text, const GooString *da, const GfxResources *resources,
- const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect,
- GBool multiline, int comb, int quadding,
- GBool txField, GBool forceZapfDingbats,
- XRef *xref, bool *addedDingbatsResource, // xref and addedDingbatsResource both must not be null if forceZapfDingbats is passed
- GBool password);
- void drawListBox(const FormFieldChoice *fieldChoice, const AnnotBorder *border, const PDFRectangle *rect,
- const GooString *da, const GfxResources *resources, int quadding);
void drawFieldBorder(const FormField *field, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
- void drawFormFieldButton(const FormFieldButton *field, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource);
- void drawFormFieldText(const FormFieldText *fieldText, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
- void drawFormFieldChoice(const FormFieldChoice *fieldChoice, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
+ bool drawFormField(const FormField *field, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource);
void writeString(const GooString &str);
@@ -535,6 +525,18 @@ public:
const GooString *buffer() const;
private:
+ bool drawListBox(const FormFieldChoice *fieldChoice, const AnnotBorder *border, const PDFRectangle *rect,
+ const GooString *da, const GfxResources *resources, int quadding);
+ bool drawFormFieldButton(const FormFieldButton *field, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource);
+ bool drawFormFieldText(const FormFieldText *fieldText, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
+ bool drawFormFieldChoice(const FormFieldChoice *fieldChoice, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
+ bool drawText(const GooString *text, const GooString *da, const GfxResources *resources,
+ const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect,
+ GBool multiline, int comb, int quadding,
+ GBool txField, GBool forceZapfDingbats,
+ XRef *xref, bool *addedDingbatsResource, // xref and addedDingbatsResource both must not be null if forceZapfDingbats is passed
+ GBool password);
+
GooString *appearBuf;
};