[poppler] poppler/Annot.cc poppler/Annot.h

Albert Astals Cid aacid at kemper.freedesktop.org
Fri Apr 6 08:35:44 UTC 2018


 poppler/Annot.cc |   88 ++++++++++++++++++++++++++++++++++---------------------
 poppler/Annot.h  |   24 ++++++++-------
 2 files changed, 68 insertions(+), 44 deletions(-)

New commits:
commit 8821c04f36cb737776cd9077a46f1a9f86ca54e7
Author: Albert Astals Cid <albert.astals.cid at kdab.com>
Date:   Wed Apr 4 10:20:52 2018 +0200

    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

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;
 };
 


More information about the poppler mailing list