[poppler] 3 commits - poppler/Annot.cc poppler/Form.cc poppler/Form.h
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Sun Apr 3 04:15:21 PDT 2011
poppler/Annot.cc | 4
poppler/Form.cc | 317 +++++++++++++++++++++++++++++++++++--------------------
poppler/Form.h | 44 ++++++-
3 files changed, 242 insertions(+), 123 deletions(-)
New commits:
commit d6786edc2549164214342a50782b72c2fd904b63
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Sun Apr 3 13:11:18 2011 +0200
forms: Remove unused parameter
diff --git a/poppler/Form.cc b/poppler/Form.cc
index fdc405f..b9a4a02 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -205,7 +205,7 @@ void FormWidgetButton::setAppearanceState(char *state) {
widget->setAppearanceState(state);
}
-void FormWidgetButton::setState (GBool astate, GBool calledByParent)
+void FormWidgetButton::setState (GBool astate)
{
//pushButtons don't have state
if (parent->getButtonType() == formButtonPush)
diff --git a/poppler/Form.h b/poppler/Form.h
index 16bbe26..0cfc95b 100644
--- a/poppler/Form.h
+++ b/poppler/Form.h
@@ -148,7 +148,7 @@ public:
FormButtonType getButtonType() const;
- void setState (GBool state, GBool calledByParent=gFalse);
+ void setState (GBool state);
GBool getState ();
char* getOnStr();
commit 62692ff381f3b7907b330bfc2019416ed058ea46
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Sun Apr 3 13:01:42 2011 +0200
forms: rework the way form fields tree is built
Now we build the tree as described by the doc, without ignoring
container fields and always creating a child widget for composed (field
+ annot) dictionaries. The way check and radio buttons are set has been
reworked too, since now it's possible to have a set of buttons where
children are not widgets, but form fields with a child widget.
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 7d1136c..fe8cb2d 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -3684,9 +3684,7 @@ void AnnotWidget::drawFormFieldButton(GfxResources *resources, GooString *da) {
switch (static_cast<FormFieldButton *>(field)->getButtonType()) {
case formButtonRadio: {
//~ Acrobat doesn't draw a caption if there is no AP dict (?)
- char *buttonState = static_cast<FormFieldButton *>(field)->getAppearanceState();
- if (buttonState && appearState && appearState->cmp(buttonState) == 0 &&
- strcmp (buttonState, "Off") != 0) {
+ if (appearState && appearState->cmp("Off") != 0) {
if (caption) {
drawText(caption, da, resources, gFalse, 0, fieldQuadCenter,
gFalse, gTrue);
diff --git a/poppler/Form.cc b/poppler/Form.cc
index 000381b..fdc405f 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -221,7 +221,7 @@ void FormWidgetButton::setState (GBool astate, GBool calledByParent)
GBool FormWidgetButton::getState ()
{
- return (onStr && parent->getAppearanceState() && strcmp(parent->getAppearanceState(), onStr->getCString()) == 0);
+ return onStr ? parent->getState(onStr->getCString()) : gFalse;
}
void FormWidgetButton::setNumSiblingsID (int i)
@@ -428,13 +428,14 @@ FormWidgetSignature::FormWidgetSignature(XRef *xrefA, Object *aobj, unsigned num
// FormField
//========================================================================
-FormField::FormField(XRef* xrefA, Object *aobj, const Ref& aref, std::set<int> *usedParents, FormFieldType ty)
+FormField::FormField(XRef* xrefA, Object *aobj, const Ref& aref, FormField *parentA, std::set<int> *usedParents, FormFieldType ty)
{
xref = xrefA;
aobj->copy(&obj);
Dict* dict = obj.getDict();
ref.num = ref.gen = 0;
type = ty;
+ parent = parentA;
numChildren = 0;
children = NULL;
terminal = false;
@@ -451,65 +452,60 @@ FormField::FormField(XRef* xrefA, Object *aobj, const Ref& aref, std::set<int> *
Object obj1;
//childs
if (dict->lookup("Kids", &obj1)->isArray()) {
- Array *array = obj1.getArray();
- int length = array->getLength();
// Load children
- for(int i=0; i<length; i++) {
- Object obj2,obj3;
- array->get(i, &obj2);
- if (!obj2.isDict ()) {
- error (-1, "Reference to an invalid or non existant object");
- obj2.free();
- continue;
+ for (int i = 0 ; i < obj1.arrayGetLength(); i++) {
+ Object childRef, childObj;
+
+ if (!obj1.arrayGetNF(i, &childRef)->isRef()) {
+ error (-1, "Invalid form field renference");
+ childRef.free();
+ continue;
}
- Object childRef;
- array->getNF(i, &childRef);
- if (childRef.isRef()) {
- const Ref ref = childRef.getRef();
- if (usedParents->find(ref.num) == usedParents->end()) {
- //field child
- if (dict->lookup ("FT", &obj3)->isName()) {
- // If I'm not a generic container field and my children
- // are widgets, create widgets for them
- Object obj4;
-
- if (obj2.dictLookup("Subtype",&obj4)->isName()) {
- _createWidget(&obj2, childRef.getRef());
- }
- obj4.free();
- } else if(obj2.dictLookup("FT", &obj3)->isName() || obj2.dictLookup("Kids", &obj3)->isArray()) {
- std::set<int> usedParentsAux = *usedParents;
- usedParentsAux.insert(ref.num);
- if(terminal) error(-1, "Field can't have both Widget AND Field as kids\n");
-
- numChildren++;
- children = (FormField**)greallocn(children, numChildren, sizeof(FormField*));
-
- obj3.free();
- children[numChildren-1] = Form::createFieldFromDict (&obj2, xref, childRef.getRef(), &usedParentsAux);
- }
- // 1 - we will handle 'collapsed' fields (field + annot in the same dict)
- // as if the annot was in the Kids array of the field
- else if (obj2.dictLookup("Subtype",&obj3)->isName()) {
- _createWidget(&obj2, childRef.getRef());
- }
+ if (!obj1.arrayGet(i, &childObj)->isDict()) {
+ error (-1, "Form field child is not a dictionary");
+ childObj.free();
+ childRef.free();
+ continue;
+ }
+
+ const Ref ref = childRef.getRef();
+ if (usedParents->find(ref.num) == usedParents->end()) {
+ Object obj2, obj3;
+ // Field child: it could be a form field or a widget or composed dict
+ if (childObj.dictLookupNF("Parent", &obj2)->isRef() || childObj.dictLookup("Parent", &obj3)->isDict()) {
+ // Child is a form field or composed dict
+ // We create the field, if it's composed
+ // it will create the widget as a child
+ std::set<int> usedParentsAux = *usedParents;
+ usedParentsAux.insert(ref.num);
+ obj2.free();
obj3.free();
- } else {
- error(-1, "Found loop in FormField creation");
+
+ if (terminal) {
+ error(-1, "Field can't have both Widget AND Field as kids\n");
+ continue;
+ }
+
+ numChildren++;
+ children = (FormField**)greallocn(children, numChildren, sizeof(FormField*));
+ children[numChildren - 1] = Form::createFieldFromDict(&childObj, xref, ref, this, &usedParentsAux);
+ } else if (childObj.dictLookup("Subtype", &obj2)->isName("Widget")) {
+ // Child is a widget annotation
+ _createWidget(&childObj, ref);
}
- } else {
- error(-1, "FormField child is not a Ref as expected");
+ obj2.free();
+ obj3.free();
}
- obj2.free();
+ childObj.free();
+ childRef.free();
}
+ } else {
+ // No children, if it's a composed dict, create the child widget
+ obj1.free();
+ if (dict->lookup("Subtype", &obj1)->isName("Widget"))
+ _createWidget(&obj, ref);
+ obj1.free();
}
- obj1.free();
- // As said in 1, if this is a 'collapsed' field, behave like if we had a
- // child annot
- if (dict->lookup("Subtype", &obj1)->isName()) {
- _createWidget(&obj, ref);
- }
- obj1.free();
//flags
if (Form::fieldLookup(dict, "Ff", &obj1)->isInt()) {
@@ -620,6 +616,10 @@ void FormField::createWidgetAnnotations(Catalog *catalog) {
}
}
+GBool FormField::isModified() const {
+ return modified ? gTrue : parent ? parent->isModified() : gFalse;
+}
+
void FormField::_createWidget (Object *obj, Ref aref)
{
terminal = true;
@@ -712,12 +712,13 @@ GooString* FormField::getFullyQualifiedName() {
//------------------------------------------------------------------------
// FormFieldButton
//------------------------------------------------------------------------
-FormFieldButton::FormFieldButton(XRef *xrefA, Object *aobj, const Ref& ref, std::set<int> *usedParents)
- : FormField(xrefA, aobj, ref, usedParents, formButton)
+FormFieldButton::FormFieldButton(XRef *xrefA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents)
+ : FormField(xrefA, aobj, ref, parent, usedParents, formButton)
{
Dict* dict = obj.getDict();
active_child = -1;
noAllOff = false;
+ appearanceState.initNull();
Object obj1;
btype = formButtonCheck;
@@ -737,8 +738,11 @@ FormFieldButton::FormFieldButton(XRef *xrefA, Object *aobj, const Ref& ref, std:
}
}
- if (btype != formButtonPush)
- Form::fieldLookup(dict, "V", &appearanceState);
+ if (btype != formButtonPush) {
+ // Even though V is inheritable we are interested in the value of this
+ // field, if not present it's probably because it's a button in a set.
+ dict->lookup("V", &appearanceState);
+ }
}
#ifdef DEBUG_FORMS
@@ -792,57 +796,68 @@ GBool FormFieldButton::setState(char *state)
// A check button could behave as a radio button
// when it's in a set of more than 1 buttons
- if (btype == formButtonRadio || btype == formButtonCheck) {
- GBool isOn = strcmp(state, "Off") != 0;
+ if (btype != formButtonRadio && btype != formButtonCheck)
+ return gFalse;
- if (!isOn && noAllOff)
- return gFalse; //don't allow to set all radio to off
+ if (terminal && parent && parent->getType() == formButton && appearanceState.isNull()) {
+ // It's button in a set, set state on parent
+ if (static_cast<FormFieldButton*>(parent)->setState(state)) {
+ modified = gTrue;
+ return gTrue;
+ }
+ return gFalse;
+ }
- char *current = getAppearanceState();
+ GBool isOn = strcmp(state, "Off") != 0;
- if (isOn) {
- char *current = getAppearanceState();
- GBool currentFound = gFalse, newFound = gFalse;
+ if (!isOn && noAllOff)
+ return gFalse; // Don't allow to set all radio to off
- for (int i = 0; i < numChildren; i++) {
- FormWidgetButton *widget = static_cast<FormWidgetButton*>(widgets[i]);
+ char *current = getAppearanceState();
+ GBool currentFound = gFalse, newFound = gFalse;
- if (!widget->getOnStr())
- continue;
+ for (int i = 0; i < numChildren; i++) {
+ FormWidgetButton *widget;
+
+ // If radio button is a terminal field we want the widget at i, but
+ // if it's not terminal, the child widget is a composed dict, so
+ // we want the ony child widget of the children at i
+ if (terminal)
+ widget = static_cast<FormWidgetButton*>(widgets[i]);
+ else
+ widget = static_cast<FormWidgetButton*>(children[i]->getWidget(0));
+
+ if (!widget->getOnStr())
+ continue;
+
+ char *onStr = widget->getOnStr();
+ if (current && strcmp(current, onStr) == 0) {
+ widget->setAppearanceState("Off");
+ if (!isOn)
+ break;
+ currentFound = gTrue;
+ }
- char *onStr = widget->getOnStr();
- if (current && strcmp(current, onStr) == 0) {
- widget->setAppearanceState("Off");
- currentFound = gTrue;
- }
+ if (isOn && strcmp(state, onStr) == 0) {
+ widget->setAppearanceState(state);
+ newFound = gTrue;
+ }
- if (strcmp(state, onStr) == 0) {
- widget->setAppearanceState(state);
- newFound = gTrue;
- }
+ if (currentFound && newFound)
+ break;
+ }
- if (currentFound && newFound)
- break;
- }
- } else {
- for (int i = 0; i < numChildren; i++) {
- FormWidgetButton *widget = static_cast<FormWidgetButton*>(widgets[i]);
+ updateState(state);
+ modified = gTrue;
- if (!widget->getOnStr())
- continue;
+ return gTrue;
+}
- char *onStr = widget->getOnStr();
- if (current && strcmp(current, onStr) == 0) {
- widget->setAppearanceState("Off");
- break;
- }
- }
- }
- updateState(state);
- modified = gTrue;
- }
+GBool FormFieldButton::getState(char *state) {
+ if (appearanceState.isName(state))
+ return gTrue;
- return gTrue;
+ return (parent && parent->getType() == formButton) ? static_cast<FormFieldButton*>(parent)->getState(state) : gFalse;
}
void FormFieldButton::updateState(char *state) {
@@ -864,8 +879,8 @@ FormFieldButton::~FormFieldButton()
//------------------------------------------------------------------------
// FormFieldText
//------------------------------------------------------------------------
-FormFieldText::FormFieldText(XRef *xrefA, Object *aobj, const Ref& ref, std::set<int> *usedParents)
- : FormField(xrefA, aobj, ref, usedParents, formText)
+FormFieldText::FormFieldText(XRef *xrefA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents)
+ : FormField(xrefA, aobj, ref, parent, usedParents, formText)
{
Dict* dict = obj.getDict();
Object obj1;
@@ -957,8 +972,8 @@ FormFieldText::~FormFieldText()
//------------------------------------------------------------------------
// FormFieldChoice
//------------------------------------------------------------------------
-FormFieldChoice::FormFieldChoice(XRef *xrefA, Object *aobj, const Ref& ref, std::set<int> *usedParents)
- : FormField(xrefA, aobj, ref, usedParents, formChoice)
+FormFieldChoice::FormFieldChoice(XRef *xrefA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents)
+ : FormField(xrefA, aobj, ref, parent, usedParents, formChoice)
{
numChoices = 0;
choices = NULL;
@@ -1198,8 +1213,8 @@ GooString *FormFieldChoice::getSelectedChoice() {
//------------------------------------------------------------------------
// FormFieldSignature
//------------------------------------------------------------------------
-FormFieldSignature::FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref, std::set<int> *usedParents)
- : FormField(xrefA, dict, ref, usedParents, formSignature)
+FormFieldSignature::FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents)
+ : FormField(xrefA, dict, ref, parent, usedParents, formSignature)
{
}
@@ -1287,7 +1302,7 @@ Form::Form(XRef *xrefA, Object* acroFormA)
}
std::set<int> usedParents;
- rootFields[numFields++] = createFieldFromDict (&obj2, xrefA, oref.getRef(), &usedParents);
+ rootFields[numFields++] = createFieldFromDict (&obj2, xrefA, oref.getRef(), NULL, &usedParents);
obj2.free();
oref.free();
@@ -1352,21 +1367,21 @@ Object *Form::fieldLookup(Dict *field, char *key, Object *obj) {
return ::fieldLookup(field, key, obj, &usedParents);
}
-FormField *Form::createFieldFromDict (Object* obj, XRef *xrefA, const Ref& pref, std::set<int> *usedParents)
+FormField *Form::createFieldFromDict (Object* obj, XRef *xrefA, const Ref& pref, FormField *parent, std::set<int> *usedParents)
{
Object obj2;
FormField *field;
if (Form::fieldLookup(obj->getDict (), "FT", &obj2)->isName("Btn")) {
- field = new FormFieldButton(xrefA, obj, pref, usedParents);
+ field = new FormFieldButton(xrefA, obj, pref, parent, usedParents);
} else if (obj2.isName("Tx")) {
- field = new FormFieldText(xrefA, obj, pref, usedParents);
+ field = new FormFieldText(xrefA, obj, pref, parent, usedParents);
} else if (obj2.isName("Ch")) {
- field = new FormFieldChoice(xrefA, obj, pref, usedParents);
+ field = new FormFieldChoice(xrefA, obj, pref, parent, usedParents);
} else if (obj2.isName("Sig")) {
- field = new FormFieldSignature(xrefA, obj, pref, usedParents);
+ field = new FormFieldSignature(xrefA, obj, pref, parent, usedParents);
} else { //we don't have an FT entry => non-terminal field
- field = new FormField(xrefA, obj, pref, usedParents);
+ field = new FormField(xrefA, obj, pref, parent, usedParents);
}
obj2.free();
diff --git a/poppler/Form.h b/poppler/Form.h
index 1ddddb5..16bbe26 100644
--- a/poppler/Form.h
+++ b/poppler/Form.h
@@ -256,7 +256,7 @@ protected:
class FormField {
public:
- FormField(XRef* xrefa, Object *aobj, const Ref& aref, std::set<int> *usedParents, FormFieldType t=formUndef);
+ FormField(XRef* xrefa, Object *aobj, const Ref& aref, FormField *parent, std::set<int> *usedParents, FormFieldType t=formUndef);
virtual ~FormField();
@@ -268,7 +268,7 @@ public:
void setReadOnly (bool b) { readOnly = b; }
bool isReadOnly () const { return readOnly; }
- GBool isModified () const { return modified; }
+ GBool isModified () const;
GooString* getDefaultAppearance() const { return defaultAppearance; }
GBool hasTextQuadding() const { return hasQuadding; }
@@ -280,6 +280,7 @@ public:
GooString *getFullyQualifiedName();
FormWidget* findWidgetByRef (Ref aref);
+ FormWidget *getWidget(int i) { return terminal ? widgets[i] : NULL; }
// only implemented in FormFieldButton
virtual void fillChildrenSiblingsID ();
@@ -302,6 +303,7 @@ public:
Object obj;
XRef *xref;
FormField **children;
+ FormField *parent;
int numChildren;
FormWidget **widgets;
bool readOnly;
@@ -328,7 +330,7 @@ private:
class FormFieldButton: public FormField {
public:
- FormFieldButton(XRef *xrefA, Object *dict, const Ref& ref, std::set<int> *usedParents);
+ FormFieldButton(XRef *xrefA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents);
FormButtonType getButtonType () { return btype; }
@@ -336,6 +338,7 @@ public:
// returns gTrue if the state modification is accepted
GBool setState (char *state);
+ GBool getState(char *state);
char *getAppearanceState() { return appearanceState.isName() ? appearanceState.getName() : NULL; }
@@ -362,7 +365,7 @@ protected:
class FormFieldText: public FormField {
public:
- FormFieldText(XRef *xrefA, Object *dict, const Ref& ref, std::set<int> *usedParents);
+ FormFieldText(XRef *xrefA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents);
GooString* getContent () { return content; }
GooString* getContentCopy ();
@@ -400,7 +403,7 @@ protected:
class FormFieldChoice: public FormField {
public:
- FormFieldChoice(XRef *xrefA, Object *aobj, const Ref& ref, std::set<int> *usedParents);
+ FormFieldChoice(XRef *xrefA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents);
virtual ~FormFieldChoice();
@@ -469,7 +472,7 @@ protected:
class FormFieldSignature: public FormField {
public:
- FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref, std::set<int> *usedParents);
+ FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents);
virtual ~FormFieldSignature();
@@ -495,7 +498,7 @@ public:
/* Creates a new Field of the type specified in obj's dict.
used in Form::Form and FormField::FormField */
- static FormField *createFieldFromDict (Object* obj, XRef *xref, const Ref& aref, std::set<int> *usedParents);
+ static FormField *createFieldFromDict (Object* obj, XRef *xref, const Ref& aref, FormField *parent, std::set<int> *usedParents);
Object *getObj () const { return acroForm; }
GBool getNeedAppearances () const { return needAppearances; }
commit a6802301d9c3ab8bf68bd8821f562f8ecced8491
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Mon Mar 28 17:42:37 2011 +0200
forms: Add debug methods to print the forms tree
diff --git a/poppler/Form.cc b/poppler/Form.cc
index 158cd57..000381b 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -80,6 +80,12 @@ FormWidget::~FormWidget()
obj.free ();
}
+#ifdef DEBUG_FORMS
+void FormWidget::print(int indent) {
+ printf ("%*s+ (%d %d): [widget]\n", indent, "", ref.num, ref.gen);
+}
+#endif
+
void FormWidget::createWidgetAnnotation(Catalog *catalog) {
if (widget)
return;
@@ -575,6 +581,26 @@ FormField::~FormField()
delete fullyQualifiedName;
}
+#ifdef DEBUG_FORMS
+void FormField::print(int indent)
+{
+ printf ("%*s- (%d %d): [container] terminal: %s children: %d\n", indent, "", ref.num, ref.gen,
+ terminal ? "Yes" : "No", numChildren);
+}
+
+void FormField::printTree(int indent)
+{
+ print(indent);
+ if (terminal) {
+ for (int i = 0; i < numChildren; i++)
+ widgets[i]->print(indent + 4);
+ } else {
+ for (int i = 0; i < numChildren; i++)
+ children[i]->printTree(indent + 4);
+ }
+}
+#endif
+
void FormField::fillChildrenSiblingsID()
{
if (terminal)
@@ -715,6 +741,29 @@ FormFieldButton::FormFieldButton(XRef *xrefA, Object *aobj, const Ref& ref, std:
Form::fieldLookup(dict, "V", &appearanceState);
}
+#ifdef DEBUG_FORMS
+static char *_getButtonType(FormButtonType type)
+{
+ switch (type) {
+ case formButtonPush:
+ return "push";
+ case formButtonCheck:
+ return "check";
+ case formButtonRadio:
+ return "radio";
+ default:
+ break;
+ }
+ return "unknown";
+}
+
+void FormFieldButton::print(int indent)
+{
+ printf ("%*s- (%d %d): [%s] terminal: %s children: %d\n", indent, "", ref.num, ref.gen,
+ _getButtonType(btype), terminal ? "Yes" : "No", numChildren);
+}
+#endif
+
void FormFieldButton::fillChildrenSiblingsID()
{
if (!terminal) {
@@ -863,6 +912,14 @@ FormFieldText::FormFieldText(XRef *xrefA, Object *aobj, const Ref& ref, std::set
obj1.free();
}
+#ifdef DEBUG_FORMS
+void FormFieldText::print(int indent)
+{
+ printf ("%*s- (%d %d): [text] terminal: %s children: %d\n", indent, "", ref.num, ref.gen,
+ terminal ? "Yes" : "No", numChildren);
+}
+#endif
+
GooString* FormFieldText::getContentCopy ()
{
if (!content) return NULL;
@@ -1024,6 +1081,14 @@ FormFieldChoice::~FormFieldChoice()
delete editedChoice;
}
+#ifdef DEBUG_FORMS
+void FormFieldChoice::print(int indent)
+{
+ printf ("%*s- (%d %d): [choice] terminal: %s children: %d\n", indent, "", ref.num, ref.gen,
+ terminal ? "Yes" : "No", numChildren);
+}
+#endif
+
void FormFieldChoice::updateSelection() {
Object obj1;
@@ -1143,6 +1208,14 @@ FormFieldSignature::~FormFieldSignature()
}
+#ifdef DEBUG_FORMS
+void FormFieldSignature::print(int indent)
+{
+ printf ("%*s- (%d %d): [signature] terminal: %s children: %d\n", indent, "", ref.num, ref.gen,
+ terminal ? "Yes" : "No", numChildren);
+}
+#endif
+
//------------------------------------------------------------------------
// Form
//------------------------------------------------------------------------
@@ -1223,6 +1296,11 @@ Form::Form(XRef *xrefA, Object* acroFormA)
error(-1, "Can't get Fields array\n");
}
obj1.free ();
+
+#ifdef DEBUG_FORMS
+ for (int i = 0; i < numFields; i++)
+ rootFields[i]->printTree();
+#endif
}
Form::~Form() {
diff --git a/poppler/Form.h b/poppler/Form.h
index 8f0eeb3..1ddddb5 100644
--- a/poppler/Form.h
+++ b/poppler/Form.h
@@ -109,6 +109,10 @@ public:
void createWidgetAnnotation(Catalog *catalog);
AnnotWidget *getWidgetAnnotation() const { return widget; }
+#ifdef DEBUG_FORMS
+ void print(int indent = 0);
+#endif
+
protected:
FormWidget(XRef *xrefA, Object *aobj, unsigned num, Ref aref, FormField *fieldA);
@@ -282,6 +286,11 @@ public:
void createWidgetAnnotations(Catalog *catalog);
+#ifdef DEBUG_FORMS
+ void printTree(int indent = 0);
+ virtual void print(int indent = 0);
+#endif
+
protected:
void _createWidget (Object *obj, Ref aref);
@@ -332,6 +341,10 @@ public:
void fillChildrenSiblingsID ();
+#ifdef DEBUG_FORMS
+ void print(int indent = 0);
+#endif
+
virtual ~FormFieldButton();
protected:
void updateState(char *state);
@@ -365,6 +378,10 @@ public:
bool isRichText () const { return richText; }
int getMaxLen () const { return maxLen; }
+
+#ifdef DEBUG_FORMS
+ void print(int indent = 0);
+#endif
protected:
GooString* content;
bool multiline;
@@ -420,6 +437,10 @@ public:
int getTopIndex() const { return topIdx; }
+#ifdef DEBUG_FORMS
+ void print(int indent = 0);
+#endif
+
protected:
void unselectAll();
void updateSelection();
@@ -451,6 +472,10 @@ public:
FormFieldSignature(XRef *xrefA, Object *dict, const Ref& ref, std::set<int> *usedParents);
virtual ~FormFieldSignature();
+
+#ifdef DEBUG_FORMS
+ void print(int indent = 0);
+#endif
};
//------------------------------------------------------------------------
More information about the poppler
mailing list