beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / poppler / Form.cc
bloba46a6590f2787a70142f7f35e11d29bd829f71c5
1 //========================================================================
2 //
3 // Form.cc
4 //
5 // This file is licensed under the GPLv2 or later
6 //
7 // Copyright 2006-2008 Julien Rebetez <julienr@svn.gnome.org>
8 // Copyright 2007-2012 Albert Astals Cid <aacid@kde.org>
9 // Copyright 2007-2008, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
10 // Copyright 2007, 2013 Adrian Johnson <ajohnson@redneon.com>
11 // Copyright 2007 Iñigo Martínez <inigomartinez@gmail.com>
12 // Copyright 2008, 2011 Pino Toscano <pino@kde.org>
13 // Copyright 2008 Michael Vrable <mvrable@cs.ucsd.edu>
14 // Copyright 2009 Matthias Drochner <M.Drochner@fz-juelich.de>
15 // Copyright 2009 KDAB via Guillermo Amaral <gamaral@amaral.com.mx>
16 // Copyright 2010, 2012 Mark Riedesel <mark@klowner.com>
17 // Copyright 2012 Fabio D'Urso <fabiodurso@hotmail.it>
18 //
19 //========================================================================
21 #include <config.h>
23 #ifdef USE_GCC_PRAGMAS
24 #pragma implementation
25 #endif
27 #include <set>
28 #include <stddef.h>
29 #include <string.h>
30 #include "goo/gmem.h"
31 #include "goo/GooString.h"
32 #include "Error.h"
33 #include "Object.h"
34 #include "Array.h"
35 #include "Dict.h"
36 #include "Gfx.h"
37 #include "Form.h"
38 #include "PDFDoc.h"
39 #include "XRef.h"
40 #include "PDFDocEncoding.h"
41 #include "Annot.h"
42 #include "Link.h"
44 //return a newly allocated char* containing an UTF16BE string of size length
45 char* pdfDocEncodingToUTF16 (GooString* orig, int* length)
47 //double size, a unicode char takes 2 char, add 2 for the unicode marker
48 *length = 2+2*orig->getLength();
49 char *result = new char[(*length)];
50 char *cstring = orig->getCString();
51 //unicode marker
52 result[0] = 0xfe;
53 result[1] = 0xff;
54 //convert to utf16
55 for(int i=2,j=0; i<(*length); i+=2,j++) {
56 Unicode u = pdfDocEncoding[(unsigned int)((unsigned char)cstring[j])]&0xffff;
57 result[i] = (u >> 8) & 0xff;
58 result[i+1] = u & 0xff;
60 return result;
63 static GooString *convertToUtf16(GooString *pdfDocEncodingString)
65 int tmp_length;
66 char* tmp_str = pdfDocEncodingToUTF16(pdfDocEncodingString, &tmp_length);
67 delete pdfDocEncodingString;
68 pdfDocEncodingString = new GooString(tmp_str, tmp_length);
69 delete [] tmp_str;
70 return pdfDocEncodingString;
74 FormWidget::FormWidget(PDFDoc *docA, Object *aobj, unsigned num, Ref aref, FormField *fieldA)
76 ref = aref;
77 ID = 0;
78 childNum = num;
79 doc = docA;
80 xref = doc->getXRef();
81 aobj->copy(&obj);
82 type = formUndef;
83 field = fieldA;
84 widget = NULL;
87 FormWidget::~FormWidget()
89 if (widget)
90 widget->decRefCnt();
91 obj.free ();
94 #ifdef DEBUG_FORMS
95 void FormWidget::print(int indent) {
96 printf ("%*s+ (%d %d): [widget]\n", indent, "", ref.num, ref.gen);
98 #endif
100 void FormWidget::createWidgetAnnotation() {
101 if (widget)
102 return;
104 Object obj1;
105 obj1.initRef(ref.num, ref.gen);
106 widget = new AnnotWidget(doc, obj.getDict(), &obj1, field);
107 obj1.free();
110 GBool FormWidget::inRect(double x, double y) const {
111 return widget ? widget->inRect(x, y) : gFalse;
114 void FormWidget::getRect(double *x1, double *y1, double *x2, double *y2) const {
115 if (widget)
116 widget->getRect(x1, y1, x2, y2);
119 double FormWidget::getFontSize() const {
120 return widget ? widget->getFontSize() : 0.;
123 bool FormWidget::isReadOnly() const
125 return field->isReadOnly();
128 int FormWidget::encodeID (unsigned pageNum, unsigned fieldNum)
130 return (pageNum << 4*sizeof(unsigned)) + fieldNum;
133 void FormWidget::decodeID (unsigned id, unsigned* pageNum, unsigned* fieldNum)
135 *pageNum = id >> 4*sizeof(unsigned);
136 *fieldNum = (id << 4*sizeof(unsigned)) >> 4*sizeof(unsigned);
139 GooString *FormWidget::getPartialName() const {
140 return field->getPartialName();
143 GooString *FormWidget::getAlternateUiName() const {
144 return field->getAlternateUiName();
147 GooString *FormWidget::getMappingName() const {
148 return field->getMappingName();
151 GooString *FormWidget::getFullyQualifiedName() {
152 return field->getFullyQualifiedName();
155 LinkAction *FormWidget::getActivationAction() {
156 return widget ? widget->getAction() : NULL;
159 LinkAction *FormWidget::getAdditionalAction(Annot::FormAdditionalActionsType type) {
160 return widget ? widget->getFormAdditionalAction(type) : NULL;
163 FormWidgetButton::FormWidgetButton (PDFDoc *docA, Object *aobj, unsigned num, Ref ref, FormField *p) :
164 FormWidget(docA, aobj, num, ref, p)
166 type = formButton;
167 parent = static_cast<FormFieldButton*>(field);
168 onStr = NULL;
170 Object obj1, obj2;
172 // Find the name of the ON state in the AP dictionnary
173 // The reference say the Off state, if it existe, _must_ be stored in the AP dict under the name /Off
174 // The "on" state may be stored under any other name
175 if (obj.dictLookup("AP", &obj1)->isDict()) {
176 if (obj1.dictLookup("N", &obj2)->isDict()) {
177 for (int i = 0; i < obj2.dictGetLength(); i++) {
178 char *key = obj2.dictGetKey(i);
179 if (strcmp (key, "Off") != 0) {
180 onStr = new GooString (key);
181 break;
185 obj2.free();
187 obj1.free();
190 char *FormWidgetButton::getOnStr() {
191 if (onStr)
192 return onStr->getCString();
194 // 12.7.4.2.3 Check Boxes
195 // Yes should be used as the name for the on state
196 return parent->getButtonType() == formButtonCheck ? (char *)"Yes" : NULL;
199 FormWidgetButton::~FormWidgetButton ()
201 delete onStr;
204 FormButtonType FormWidgetButton::getButtonType () const
206 return parent->getButtonType ();
209 void FormWidgetButton::setAppearanceState(const char *state) {
210 if (!widget)
211 return;
212 widget->setAppearanceState(state);
215 void FormWidgetButton::updateWidgetAppearance()
217 // The appearance stream must NOT be regenerated for this widget type
220 void FormWidgetButton::setState (GBool astate)
222 //pushButtons don't have state
223 if (parent->getButtonType() == formButtonPush)
224 return;
226 // Silently return if can't set ON state
227 if (astate && !onStr)
228 return;
230 parent->setState(astate ? onStr->getCString() : (char *)"Off");
231 // Parent will call setAppearanceState()
234 GBool FormWidgetButton::getState ()
236 return onStr ? parent->getState(onStr->getCString()) : gFalse;
240 FormWidgetText::FormWidgetText (PDFDoc *docA, Object *aobj, unsigned num, Ref ref, FormField *p) :
241 FormWidget(docA, aobj, num, ref, p)
243 type = formText;
244 parent = static_cast<FormFieldText*>(field);
247 GooString* FormWidgetText::getContent ()
249 return parent->getContent();
252 GooString* FormWidgetText::getContentCopy ()
254 return parent->getContentCopy();
257 void FormWidgetText::updateWidgetAppearance()
259 if (widget)
260 widget->updateAppearanceStream();
263 bool FormWidgetText::isMultiline () const
265 return parent->isMultiline();
268 bool FormWidgetText::isPassword () const
270 return parent->isPassword();
273 bool FormWidgetText::isFileSelect () const
275 return parent->isFileSelect();
278 bool FormWidgetText::noSpellCheck () const
280 return parent->noSpellCheck();
283 bool FormWidgetText::noScroll () const
285 return parent->noScroll();
288 bool FormWidgetText::isComb () const
290 return parent->isComb();
293 bool FormWidgetText::isRichText () const
295 return parent->isRichText();
298 int FormWidgetText::getMaxLen () const
300 return parent->getMaxLen ();
303 void FormWidgetText::setContent(GooString* new_content)
305 if (isReadOnly()) {
306 error(errInternal, -1, "FormWidgetText::setContentCopy called on a read only field\n");
307 return;
310 parent->setContentCopy(new_content);
313 FormWidgetChoice::FormWidgetChoice(PDFDoc *docA, Object *aobj, unsigned num, Ref ref, FormField *p) :
314 FormWidget(docA, aobj, num, ref, p)
316 type = formChoice;
317 parent = static_cast<FormFieldChoice*>(field);
320 FormWidgetChoice::~FormWidgetChoice()
324 bool FormWidgetChoice::_checkRange (int i)
326 if (i < 0 || i >= parent->getNumChoices()) {
327 error(errInternal, -1, "FormWidgetChoice::_checkRange i out of range : {0:d}", i);
328 return false;
330 return true;
333 void FormWidgetChoice::select (int i)
335 if (isReadOnly()) {
336 error(errInternal, -1, "FormWidgetChoice::select called on a read only field\n");
337 return;
339 if (!_checkRange(i)) return;
340 parent->select(i);
343 void FormWidgetChoice::toggle (int i)
345 if (isReadOnly()) {
346 error(errInternal, -1, "FormWidgetChoice::toggle called on a read only field\n");
347 return;
349 if (!_checkRange(i)) return;
350 parent->toggle(i);
353 void FormWidgetChoice::deselectAll ()
355 if (isReadOnly()) {
356 error(errInternal, -1, "FormWidgetChoice::deselectAll called on a read only field\n");
357 return;
359 parent->deselectAll();
362 GooString* FormWidgetChoice::getEditChoice ()
364 if (!hasEdit()) {
365 error(errInternal, -1, "FormFieldChoice::getEditChoice called on a non-editable choice\n");
366 return NULL;
368 return parent->getEditChoice();
371 void FormWidgetChoice::updateWidgetAppearance()
373 if (widget)
374 widget->updateAppearanceStream();
377 bool FormWidgetChoice::isSelected (int i)
379 if (!_checkRange(i)) return false;
380 return parent->isSelected(i);
383 void FormWidgetChoice::setEditChoice (GooString* new_content)
385 if (isReadOnly()) {
386 error(errInternal, -1, "FormWidgetText::setEditChoice called on a read only field\n");
387 return;
389 if (!hasEdit()) {
390 error(errInternal, -1, "FormFieldChoice::setEditChoice : trying to edit an non-editable choice\n");
391 return;
394 parent->setEditChoice(new_content);
397 int FormWidgetChoice::getNumChoices()
399 return parent->getNumChoices();
402 GooString* FormWidgetChoice::getChoice(int i)
404 return parent->getChoice(i);
407 bool FormWidgetChoice::isCombo () const
409 return parent->isCombo();
412 bool FormWidgetChoice::hasEdit () const
414 return parent->hasEdit();
417 bool FormWidgetChoice::isMultiSelect () const
419 return parent->isMultiSelect();
422 bool FormWidgetChoice::noSpellCheck () const
424 return parent->noSpellCheck();
427 bool FormWidgetChoice::commitOnSelChange () const
429 return parent->commitOnSelChange();
432 bool FormWidgetChoice::isListBox () const
434 return parent->isListBox();
437 FormWidgetSignature::FormWidgetSignature(PDFDoc *docA, Object *aobj, unsigned num, Ref ref, FormField *p) :
438 FormWidget(docA, aobj, num, ref, p)
440 type = formSignature;
441 parent = static_cast<FormFieldSignature*>(field);
444 void FormWidgetSignature::updateWidgetAppearance()
446 // Unimplemented
450 //========================================================================
451 // FormField
452 //========================================================================
454 FormField::FormField(PDFDoc *docA, Object *aobj, const Ref& aref, FormField *parentA, std::set<int> *usedParents, FormFieldType ty)
456 doc = docA;
457 xref = doc->getXRef();
458 aobj->copy(&obj);
459 Dict* dict = obj.getDict();
460 ref.num = ref.gen = 0;
461 type = ty;
462 parent = parentA;
463 numChildren = 0;
464 children = NULL;
465 terminal = false;
466 widgets = NULL;
467 readOnly = false;
468 defaultAppearance = NULL;
469 fullyQualifiedName = NULL;
470 quadding = quaddingLeftJustified;
471 hasQuadding = gFalse;
473 ref = aref;
475 Object obj1;
476 //childs
477 if (dict->lookup("Kids", &obj1)->isArray()) {
478 // Load children
479 for (int i = 0 ; i < obj1.arrayGetLength(); i++) {
480 Object childRef, childObj;
482 if (!obj1.arrayGetNF(i, &childRef)->isRef()) {
483 error (errSyntaxError, -1, "Invalid form field renference");
484 childRef.free();
485 continue;
487 if (!obj1.arrayGet(i, &childObj)->isDict()) {
488 error (errSyntaxError, -1, "Form field child is not a dictionary");
489 childObj.free();
490 childRef.free();
491 continue;
494 const Ref ref = childRef.getRef();
495 if (usedParents->find(ref.num) == usedParents->end()) {
496 Object obj2, obj3;
497 // Field child: it could be a form field or a widget or composed dict
498 if (childObj.dictLookupNF("Parent", &obj2)->isRef() || childObj.dictLookup("Parent", &obj3)->isDict()) {
499 // Child is a form field or composed dict
500 // We create the field, if it's composed
501 // it will create the widget as a child
502 std::set<int> usedParentsAux = *usedParents;
503 usedParentsAux.insert(ref.num);
504 obj2.free();
505 obj3.free();
507 if (terminal) {
508 error(errSyntaxWarning, -1, "Field can't have both Widget AND Field as kids\n");
509 continue;
512 numChildren++;
513 children = (FormField**)greallocn(children, numChildren, sizeof(FormField*));
514 children[numChildren - 1] = Form::createFieldFromDict(&childObj, doc, ref, this, &usedParentsAux);
515 } else if (childObj.dictLookup("Subtype", &obj2)->isName("Widget")) {
516 // Child is a widget annotation
517 if (!terminal && numChildren > 0) {
518 error(errSyntaxWarning, -1, "Field can't have both Widget AND Field as kids\n");
519 obj2.free();
520 obj3.free();
521 continue;
523 _createWidget(&childObj, ref);
525 obj2.free();
526 obj3.free();
528 childObj.free();
529 childRef.free();
531 } else {
532 // No children, if it's a composed dict, create the child widget
533 obj1.free();
534 if (dict->lookup("Subtype", &obj1)->isName("Widget"))
535 _createWidget(&obj, ref);
537 obj1.free();
539 //flags
540 if (Form::fieldLookup(dict, "Ff", &obj1)->isInt()) {
541 int flags = obj1.getInt();
542 if (flags & 0x1) { // 1 -> ReadOnly
543 readOnly = true;
545 if (flags & 0x2) { // 2 -> Required
546 //TODO
548 if (flags & 0x4) { // 3 -> NoExport
549 //TODO
552 obj1.free();
554 // Variable Text
555 if (Form::fieldLookup(dict, "DA", &obj1)->isString())
556 defaultAppearance = obj1.getString()->copy();
557 obj1.free();
559 if (Form::fieldLookup(dict, "Q", &obj1)->isInt()) {
560 quadding = static_cast<VariableTextQuadding>(obj1.getInt());
561 hasQuadding = gTrue;
563 obj1.free();
565 if (dict->lookup("T", &obj1)->isString()) {
566 partialName = obj1.getString()->copy();
567 } else {
568 partialName = NULL;
570 obj1.free();
572 if (dict->lookup("TU", &obj1)->isString()) {
573 alternateUiName = obj1.getString()->copy();
574 } else {
575 alternateUiName = NULL;
577 obj1.free();
579 if(dict->lookup("TM", &obj1)->isString()) {
580 mappingName = obj1.getString()->copy();
581 } else {
582 mappingName = NULL;
584 obj1.free();
587 FormField::~FormField()
589 if (!terminal) {
590 if(children) {
591 for (int i=0; i<numChildren; i++)
592 delete children[i];
593 gfree(children);
595 } else {
596 for (int i = 0; i < numChildren; ++i)
597 delete widgets[i];
598 gfree (widgets);
600 obj.free();
602 delete defaultAppearance;
603 delete partialName;
604 delete alternateUiName;
605 delete mappingName;
606 delete fullyQualifiedName;
609 #ifdef DEBUG_FORMS
610 void FormField::print(int indent)
612 printf ("%*s- (%d %d): [container] terminal: %s children: %d\n", indent, "", ref.num, ref.gen,
613 terminal ? "Yes" : "No", numChildren);
616 void FormField::printTree(int indent)
618 print(indent);
619 if (terminal) {
620 for (int i = 0; i < numChildren; i++)
621 widgets[i]->print(indent + 4);
622 } else {
623 for (int i = 0; i < numChildren; i++)
624 children[i]->printTree(indent + 4);
627 #endif
629 void FormField::fillChildrenSiblingsID()
631 if (terminal)
632 return;
633 for (int i = 0; i < numChildren; i++) {
634 children[i]->fillChildrenSiblingsID();
638 void FormField::createWidgetAnnotations() {
639 if (terminal) {
640 for (int i = 0; i < numChildren; i++)
641 widgets[i]->createWidgetAnnotation();
642 } else {
643 for (int i = 0; i < numChildren; i++)
644 children[i]->createWidgetAnnotations();
648 void FormField::_createWidget (Object *obj, Ref aref)
650 terminal = true;
651 numChildren++;
652 widgets = (FormWidget**)greallocn(widgets, numChildren, sizeof(FormWidget*));
653 //ID = index in "widgets" table
654 switch (type) {
655 case formButton:
656 widgets[numChildren-1] = new FormWidgetButton(doc, obj, numChildren-1, aref, this);
657 break;
658 case formText:
659 widgets[numChildren-1] = new FormWidgetText(doc, obj, numChildren-1, aref, this);
660 break;
661 case formChoice:
662 widgets[numChildren-1] = new FormWidgetChoice(doc, obj, numChildren-1, aref, this);
663 break;
664 case formSignature:
665 widgets[numChildren-1] = new FormWidgetSignature(doc, obj, numChildren-1, aref, this);
666 break;
667 default:
668 error(errSyntaxWarning, -1, "SubType on non-terminal field, invalid document?");
669 numChildren--;
670 terminal = false;
674 FormWidget* FormField::findWidgetByRef (Ref aref)
676 if (terminal) {
677 for(int i=0; i<numChildren; i++) {
678 if (widgets[i]->getRef().num == aref.num
679 && widgets[i]->getRef().gen == aref.gen)
680 return widgets[i];
682 } else {
683 for(int i=0; i<numChildren; i++) {
684 FormWidget* result = children[i]->findWidgetByRef(aref);
685 if(result) return result;
688 return NULL;
691 GooString* FormField::getFullyQualifiedName() {
692 Object obj1, obj2;
693 Object parent;
694 GooString *parent_name;
695 GooString *full_name;
696 GBool unicode_encoded = gFalse;
698 if (fullyQualifiedName)
699 return fullyQualifiedName;
701 full_name = new GooString();
703 obj.copy(&obj1);
704 while (obj1.dictLookup("Parent", &parent)->isDict()) {
705 if (parent.dictLookup("T", &obj2)->isString()) {
706 parent_name = obj2.getString();
708 if (unicode_encoded) {
709 full_name->insert(0, "\0.", 2); // 2-byte unicode period
710 if (parent_name->hasUnicodeMarker()) {
711 full_name->insert(0, parent_name->getCString() + 2, parent_name->getLength() - 2); // Remove the unicode BOM
712 } else {
713 int tmp_length;
714 char* tmp_str = pdfDocEncodingToUTF16(parent_name, &tmp_length);
715 full_name->insert(0, tmp_str + 2, tmp_length - 2); // Remove the unicode BOM
716 delete [] tmp_str;
718 } else {
719 full_name->insert(0, '.'); // 1-byte ascii period
720 if (parent_name->hasUnicodeMarker()) {
721 unicode_encoded = gTrue;
722 full_name = convertToUtf16(full_name);
723 full_name->insert(0, parent_name->getCString() + 2, parent_name->getLength() - 2); // Remove the unicode BOM
724 } else {
725 full_name->insert(0, parent_name);
728 obj2.free();
730 obj1.free();
731 parent.copy(&obj1);
732 parent.free();
734 obj1.free();
735 parent.free();
737 if (partialName) {
738 if (unicode_encoded) {
739 if (partialName->hasUnicodeMarker()) {
740 full_name->append(partialName->getCString() + 2, partialName->getLength() - 2); // Remove the unicode BOM
741 } else {
742 int tmp_length;
743 char* tmp_str = pdfDocEncodingToUTF16(partialName, &tmp_length);
744 full_name->append(tmp_str + 2, tmp_length - 2); // Remove the unicode BOM
745 delete [] tmp_str;
747 } else {
748 if (partialName->hasUnicodeMarker()) {
749 unicode_encoded = gTrue;
750 full_name = convertToUtf16(full_name);
751 full_name->append(partialName->getCString() + 2, partialName->getLength() - 2); // Remove the unicode BOM
752 } else {
753 full_name->append(partialName);
756 } else {
757 int len = full_name->getLength();
758 // Remove the last period
759 if (unicode_encoded) {
760 if (len > 1) {
761 full_name->del(len - 2, 2);
763 } else {
764 if (len > 0) {
765 full_name->del(len - 1, 1);
770 if (unicode_encoded) {
771 full_name->insert(0, 0xff);
772 full_name->insert(0, 0xfe);
775 fullyQualifiedName = full_name;
776 return fullyQualifiedName;
779 void FormField::updateChildrenAppearance()
781 // Recursively update each child's appearance
782 if (terminal) {
783 for (int i = 0; i < numChildren; i++)
784 widgets[i]->updateWidgetAppearance();
785 } else {
786 for (int i = 0; i < numChildren; i++)
787 children[i]->updateChildrenAppearance();
791 //------------------------------------------------------------------------
792 // FormFieldButton
793 //------------------------------------------------------------------------
794 FormFieldButton::FormFieldButton(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents)
795 : FormField(docA, aobj, ref, parent, usedParents, formButton)
797 Dict* dict = obj.getDict();
798 active_child = -1;
799 noAllOff = false;
800 siblings = NULL;
801 numSiblings = 0;
802 appearanceState.initNull();
804 Object obj1;
805 btype = formButtonCheck;
806 if (Form::fieldLookup(dict, "Ff", &obj1)->isInt()) {
807 int flags = obj1.getInt();
809 if (flags & 0x10000) { // 17 -> push button
810 btype = formButtonPush;
811 } else if (flags & 0x8000) { // 16 -> radio button
812 btype = formButtonRadio;
813 if (flags & 0x4000) { // 15 -> noToggleToOff
814 noAllOff = true;
817 if (flags & 0x1000000) { // 26 -> radiosInUnison
818 error(errUnimplemented, -1, "FormFieldButton:: radiosInUnison flag unimplemented, please report a bug with a testcase\n");
822 if (btype != formButtonPush) {
823 // Even though V is inheritable we are interested in the value of this
824 // field, if not present it's probably because it's a button in a set.
825 dict->lookup("V", &appearanceState);
829 #ifdef DEBUG_FORMS
830 static char *_getButtonType(FormButtonType type)
832 switch (type) {
833 case formButtonPush:
834 return "push";
835 case formButtonCheck:
836 return "check";
837 case formButtonRadio:
838 return "radio";
839 default:
840 break;
842 return "unknown";
845 void FormFieldButton::print(int indent)
847 printf ("%*s- (%d %d): [%s] terminal: %s children: %d\n", indent, "", ref.num, ref.gen,
848 _getButtonType(btype), terminal ? "Yes" : "No", numChildren);
850 #endif
852 void FormFieldButton::setNumSiblings (int num)
854 numSiblings = num;
855 siblings = (FormFieldButton**)greallocn(siblings, numSiblings, sizeof(FormFieldButton*));
858 void FormFieldButton::fillChildrenSiblingsID()
860 if (!terminal) {
861 for(int i=0; i<numChildren; i++) {
862 FormFieldButton *child = dynamic_cast<FormFieldButton*>(children[i]);
863 if (child != NULL) {
864 // Fill the siblings of this node childs
865 child->setNumSiblings(numChildren-1);
866 for(int j=0, counter=0; j<numChildren; j++) {
867 FormFieldButton *otherChild = dynamic_cast<FormFieldButton*>(children[j]);
868 if (i == j) continue;
869 if (child == otherChild) continue;
870 child->setSibling(counter, otherChild);
871 counter++;
874 // now call ourselves on the child
875 // to fill its children data
876 child->fillChildrenSiblingsID();
882 GBool FormFieldButton::setState(char *state)
884 if (readOnly) {
885 error(errInternal, -1, "FormFieldButton::setState called on a readOnly field\n");
886 return gFalse;
889 // A check button could behave as a radio button
890 // when it's in a set of more than 1 buttons
891 if (btype != formButtonRadio && btype != formButtonCheck)
892 return gFalse;
894 if (terminal && parent && parent->getType() == formButton && appearanceState.isNull()) {
895 // It's button in a set, set state on parent
896 if (static_cast<FormFieldButton*>(parent)->setState(state)) {
897 return gTrue;
899 return gFalse;
902 GBool isOn = strcmp(state, "Off") != 0;
904 if (!isOn && noAllOff)
905 return gFalse; // Don't allow to set all radio to off
907 char *current = getAppearanceState();
908 GBool currentFound = gFalse, newFound = gFalse;
910 for (int i = 0; i < numChildren; i++) {
911 FormWidgetButton *widget;
913 // If radio button is a terminal field we want the widget at i, but
914 // if it's not terminal, the child widget is a composed dict, so
915 // we want the ony child widget of the children at i
916 if (terminal)
917 widget = static_cast<FormWidgetButton*>(widgets[i]);
918 else
919 widget = static_cast<FormWidgetButton*>(children[i]->getWidget(0));
921 if (!widget->getOnStr())
922 continue;
924 char *onStr = widget->getOnStr();
925 if (current && strcmp(current, onStr) == 0) {
926 widget->setAppearanceState("Off");
927 if (!isOn)
928 break;
929 currentFound = gTrue;
932 if (isOn && strcmp(state, onStr) == 0) {
933 widget->setAppearanceState(state);
934 newFound = gTrue;
937 if (currentFound && newFound)
938 break;
941 updateState(state);
943 return gTrue;
946 GBool FormFieldButton::getState(char *state) {
947 if (appearanceState.isName(state))
948 return gTrue;
950 return (parent && parent->getType() == formButton) ? static_cast<FormFieldButton*>(parent)->getState(state) : gFalse;
953 void FormFieldButton::updateState(char *state) {
954 Object obj1;
956 appearanceState.free();
957 appearanceState.initName(state);
959 appearanceState.copy(&obj1);
960 obj.getDict()->set("V", &obj1);
961 xref->setModifiedObject(&obj, ref);
964 FormFieldButton::~FormFieldButton()
966 appearanceState.free();
967 if (siblings)
968 gfree(siblings);
971 //------------------------------------------------------------------------
972 // FormFieldText
973 //------------------------------------------------------------------------
974 FormFieldText::FormFieldText(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents)
975 : FormField(docA, aobj, ref, parent, usedParents, formText)
977 Dict* dict = obj.getDict();
978 Object obj1;
979 content = NULL;
980 multiline = password = fileSelect = doNotSpellCheck = doNotScroll = comb = richText = false;
981 maxLen = 0;
983 if (Form::fieldLookup(dict, "Ff", &obj1)->isInt()) {
984 int flags = obj1.getInt();
985 if (flags & 0x1000) // 13 -> Multiline
986 multiline = true;
987 if (flags & 0x2000) // 14 -> Password
988 password = true;
989 if (flags & 0x100000) // 21 -> FileSelect
990 fileSelect = true;
991 if (flags & 0x400000)// 23 -> DoNotSpellCheck
992 doNotSpellCheck = true;
993 if (flags & 0x800000) // 24 -> DoNotScroll
994 doNotScroll = true;
995 if (flags & 0x1000000) // 25 -> Comb
996 comb = true;
997 if (flags & 0x2000000)// 26 -> RichText
998 richText = true;
1000 obj1.free();
1002 if (Form::fieldLookup(dict, "MaxLen", &obj1)->isInt()) {
1003 maxLen = obj1.getInt();
1005 obj1.free();
1007 if (Form::fieldLookup(dict, "V", &obj1)->isString()) {
1008 if (obj1.getString()->hasUnicodeMarker()) {
1009 if (obj1.getString()->getLength() > 2)
1010 content = obj1.getString()->copy();
1011 } else if (obj1.getString()->getLength() > 0) {
1012 //non-unicode string -- assume pdfDocEncoding and try to convert to UTF16BE
1013 int tmp_length;
1014 char* tmp_str = pdfDocEncodingToUTF16(obj1.getString(), &tmp_length);
1015 content = new GooString(tmp_str, tmp_length);
1016 delete [] tmp_str;
1019 obj1.free();
1022 #ifdef DEBUG_FORMS
1023 void FormFieldText::print(int indent)
1025 printf ("%*s- (%d %d): [text] terminal: %s children: %d\n", indent, "", ref.num, ref.gen,
1026 terminal ? "Yes" : "No", numChildren);
1028 #endif
1030 GooString* FormFieldText::getContentCopy ()
1032 if (!content) return NULL;
1033 return new GooString(content);
1036 void FormFieldText::setContentCopy (GooString* new_content)
1038 delete content;
1039 content = NULL;
1041 if (new_content) {
1042 content = new_content->copy();
1044 //append the unicode marker <FE FF> if needed
1045 if (!content->hasUnicodeMarker()) {
1046 content->insert(0, 0xff);
1047 content->insert(0, 0xfe);
1051 Object obj1;
1052 obj1.initString(content ? content->copy() : new GooString(""));
1053 obj.getDict()->set("V", &obj1);
1054 xref->setModifiedObject(&obj, ref);
1055 updateChildrenAppearance();
1058 FormFieldText::~FormFieldText()
1060 delete content;
1064 //------------------------------------------------------------------------
1065 // FormFieldChoice
1066 //------------------------------------------------------------------------
1067 FormFieldChoice::FormFieldChoice(PDFDoc *docA, Object *aobj, const Ref& ref, FormField *parent, std::set<int> *usedParents)
1068 : FormField(docA, aobj, ref, parent, usedParents, formChoice)
1070 numChoices = 0;
1071 choices = NULL;
1072 editedChoice = NULL;
1073 topIdx = 0;
1075 Dict* dict = obj.getDict();
1076 Object obj1;
1078 combo = edit = multiselect = doNotSpellCheck = doCommitOnSelChange = false;
1080 if (Form::fieldLookup(dict, "Ff", &obj1)->isInt()) {
1081 int flags = obj1.getInt();
1082 if (flags & 0x20000) // 18 -> Combo
1083 combo = true;
1084 if (flags & 0x40000) // 19 -> Edit
1085 edit = true;
1086 if (flags & 0x200000) // 22 -> MultiSelect
1087 multiselect = true;
1088 if (flags & 0x400000) // 23 -> DoNotSpellCheck
1089 doNotSpellCheck = true;
1090 if (flags & 0x4000000) // 27 -> CommitOnSelChange
1091 doCommitOnSelChange = true;
1093 obj1.free();
1095 if (dict->lookup("TI", &obj1)->isInt())
1096 topIdx = obj1.getInt();
1097 obj1.free();
1099 if (dict->lookup("Opt", &obj1)->isArray()) {
1100 Object obj2;
1102 numChoices = obj1.arrayGetLength();
1103 choices = new ChoiceOpt[numChoices];
1104 memset(choices, 0, sizeof(ChoiceOpt) * numChoices);
1106 for (int i = 0; i < numChoices; i++) {
1107 if (obj1.arrayGet(i, &obj2)->isString()) {
1108 choices[i].optionName = obj2.getString()->copy();
1109 } else if (obj2.isArray()) { // [Export_value, Displayed_text]
1110 Object obj3;
1112 if (obj2.arrayGetLength() < 2) {
1113 error(errSyntaxError, -1, "FormWidgetChoice:: invalid Opt entry -- array's length < 2\n");
1114 continue;
1116 if (obj2.arrayGet(0, &obj3)->isString())
1117 choices[i].exportVal = obj3.getString()->copy();
1118 else
1119 error(errSyntaxError, -1, "FormWidgetChoice:: invalid Opt entry -- exported value not a string\n");
1120 obj3.free();
1122 if (obj2.arrayGet(1, &obj3)->isString())
1123 choices[i].optionName = obj3.getString()->copy();
1124 else
1125 error(errSyntaxError, -1, "FormWidgetChoice:: invalid Opt entry -- choice name not a string\n");
1126 obj3.free();
1127 } else {
1128 error(errSyntaxError, -1, "FormWidgetChoice:: invalid {0:d} Opt entry\n", i);
1130 obj2.free();
1132 } else {
1133 //empty choice
1135 obj1.free();
1137 // Find selected items
1138 // Note: PDF specs say that /V has precedence over /I, but acroread seems to
1139 // do the opposite. We do the same.
1140 if (Form::fieldLookup(dict, "I", &obj1)->isArray()) {
1141 for (int i = 0; i < obj1.arrayGetLength(); i++) {
1142 Object obj2;
1143 if (obj1.arrayGet(i, &obj2)->isInt() && obj2.getInt() >= 0 && obj2.getInt() < numChoices) {
1144 choices[obj2.getInt()].selected = true;
1146 obj2.free();
1148 } else {
1149 obj1.free();
1150 // Note: According to PDF specs, /V should *never* contain the exportVal.
1151 // However, if /Opt is an array of (exportVal,optionName) pairs, acroread
1152 // seems to expect the exportVal instead of the optionName and so we do too.
1153 if (Form::fieldLookup(dict, "V", &obj1)->isString()) {
1154 GBool optionFound = gFalse;
1156 for (int i = 0; i < numChoices; i++) {
1157 if (choices[i].exportVal) {
1158 if (choices[i].exportVal->cmp(obj1.getString()) == 0) {
1159 optionFound = gTrue;
1161 } else if (choices[i].optionName) {
1162 if (choices[i].optionName->cmp(obj1.getString()) == 0) {
1163 optionFound = gTrue;
1167 if (optionFound) {
1168 choices[i].selected = true;
1169 break; // We've determined that this option is selected. No need to keep on scanning
1173 // Set custom value if /V doesn't refer to any predefined option and the field is user-editable
1174 if (!optionFound && edit) {
1175 editedChoice = obj1.getString()->copy();
1177 } else if (obj1.isArray()) {
1178 for (int i = 0; i < numChoices; i++) {
1179 for (int j = 0; j < obj1.arrayGetLength(); j++) {
1180 Object obj2;
1181 obj1.arrayGet(j, &obj2);
1182 GBool matches = gFalse;
1184 if (choices[i].exportVal) {
1185 if (choices[i].exportVal->cmp(obj2.getString()) == 0) {
1186 matches = gTrue;
1188 } else if (choices[i].optionName) {
1189 if (choices[i].optionName->cmp(obj2.getString()) == 0) {
1190 matches = gTrue;
1194 obj2.free();
1196 if (matches) {
1197 choices[i].selected = true;
1198 break; // We've determined that this option is selected. No need to keep on scanning
1204 obj1.free();
1207 FormFieldChoice::~FormFieldChoice()
1209 for (int i = 0; i < numChoices; i++) {
1210 delete choices[i].exportVal;
1211 delete choices[i].optionName;
1213 delete [] choices;
1214 delete editedChoice;
1217 #ifdef DEBUG_FORMS
1218 void FormFieldChoice::print(int indent)
1220 printf ("%*s- (%d %d): [choice] terminal: %s children: %d\n", indent, "", ref.num, ref.gen,
1221 terminal ? "Yes" : "No", numChildren);
1223 #endif
1225 void FormFieldChoice::updateSelection() {
1226 Object objV, objI, obj1;
1227 objI.initNull();
1229 if (edit && editedChoice) {
1230 // This is an editable combo-box with user-entered text
1231 objV.initString(editedChoice->copy());
1232 } else {
1233 const int numSelected = getNumSelected();
1235 // Create /I array only if multiple selection is allowed (as per PDF spec)
1236 if (multiselect) {
1237 objI.initArray(xref);
1240 if (numSelected == 0) {
1241 // No options are selected
1242 objV.initString(new GooString(""));
1243 } else if (numSelected == 1) {
1244 // Only one option is selected
1245 for (int i = 0; i < numChoices; i++) {
1246 if (choices[i].selected) {
1247 if (multiselect) {
1248 objI.arrayAdd(obj1.initInt(i));
1251 if (choices[i].exportVal) {
1252 objV.initString(choices[i].exportVal->copy());
1253 } else if (choices[i].optionName) {
1254 objV.initString(choices[i].optionName->copy());
1257 break; // We've just written the selected option. No need to keep on scanning
1260 } else {
1261 // More than one option is selected
1262 objV.initArray(xref);
1263 for (int i = 0; i < numChoices; i++) {
1264 if (choices[i].selected) {
1265 if (multiselect) {
1266 objI.arrayAdd(obj1.initInt(i));
1269 if (choices[i].exportVal) {
1270 objV.arrayAdd(obj1.initString(choices[i].exportVal->copy()));
1271 } else if (choices[i].optionName) {
1272 objV.arrayAdd(obj1.initString(choices[i].optionName->copy()));
1279 obj.getDict()->set("V", &objV);
1280 obj.getDict()->set("I", &objI);
1281 xref->setModifiedObject(&obj, ref);
1282 updateChildrenAppearance();
1285 void FormFieldChoice::unselectAll ()
1287 for (int i = 0; i < numChoices; i++) {
1288 choices[i].selected = false;
1292 void FormFieldChoice::deselectAll () {
1293 delete editedChoice;
1294 editedChoice = NULL;
1296 unselectAll();
1297 updateSelection();
1300 void FormFieldChoice::toggle (int i)
1302 delete editedChoice;
1303 editedChoice = NULL;
1305 choices[i].selected = !choices[i].selected;
1306 updateSelection();
1309 void FormFieldChoice::select (int i)
1311 delete editedChoice;
1312 editedChoice = NULL;
1314 if (!multiselect)
1315 unselectAll();
1317 choices[i].selected = true;
1318 updateSelection();
1321 void FormFieldChoice::setEditChoice (GooString* new_content)
1323 delete editedChoice;
1324 editedChoice = NULL;
1326 unselectAll();
1328 if (new_content) {
1329 editedChoice = new_content->copy();
1331 //append the unicode marker <FE FF> if needed
1332 if (!editedChoice->hasUnicodeMarker()) {
1333 editedChoice->insert(0, 0xff);
1334 editedChoice->insert(0, 0xfe);
1337 updateSelection();
1340 GooString* FormFieldChoice::getEditChoice ()
1342 return editedChoice;
1345 int FormFieldChoice::getNumSelected ()
1347 int cnt = 0;
1348 for(int i=0; i<numChoices; i++) {
1349 if (choices[i].selected)
1350 cnt++;
1352 return cnt;
1355 GooString *FormFieldChoice::getSelectedChoice() {
1356 if (edit && editedChoice)
1357 return editedChoice;
1359 for (int i = 0; i < numChoices; i++) {
1360 if (choices[i].optionName && choices[i].selected)
1361 return choices[i].optionName;
1364 return NULL;
1367 //------------------------------------------------------------------------
1368 // FormFieldSignature
1369 //------------------------------------------------------------------------
1370 FormFieldSignature::FormFieldSignature(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents)
1371 : FormField(docA, dict, ref, parent, usedParents, formSignature)
1375 FormFieldSignature::~FormFieldSignature()
1380 #ifdef DEBUG_FORMS
1381 void FormFieldSignature::print(int indent)
1383 printf ("%*s- (%d %d): [signature] terminal: %s children: %d\n", indent, "", ref.num, ref.gen,
1384 terminal ? "Yes" : "No", numChildren);
1386 #endif
1388 //------------------------------------------------------------------------
1389 // Form
1390 //------------------------------------------------------------------------
1392 Form::Form(PDFDoc *docA, Object* acroFormA)
1394 Object obj1;
1396 doc = docA;
1397 xref = doc->getXRef();
1398 acroForm = acroFormA;
1400 size = 0;
1401 numFields = 0;
1402 rootFields = NULL;
1403 quadding = quaddingLeftJustified;
1404 defaultAppearance = NULL;
1405 defaultResources = NULL;
1407 acroForm->dictLookup("NeedAppearances", &obj1);
1408 needAppearances = (obj1.isBool() && obj1.getBool());
1409 obj1.free();
1411 if (acroForm->dictLookup("DA", &obj1)->isString())
1412 defaultAppearance = obj1.getString()->copy();
1413 obj1.free();
1415 if (acroForm->dictLookup("Q", &obj1)->isInt())
1416 quadding = static_cast<VariableTextQuadding>(obj1.getInt());
1417 obj1.free();
1419 acroForm->dictLookup("DR", &resDict);
1420 if (resDict.isDict()) {
1421 // At a minimum, this dictionary shall contain a Font entry
1422 if (resDict.dictLookup("Font", &obj1)->isDict())
1423 defaultResources = new GfxResources(xref, resDict.getDict(), NULL);
1424 obj1.free();
1426 if (!defaultResources) {
1427 resDict.free();
1428 resDict.initNull();
1431 acroForm->dictLookup("Fields", &obj1);
1432 if (obj1.isArray()) {
1433 Array *array = obj1.getArray();
1434 Object obj2;
1436 for(int i=0; i<array->getLength(); i++) {
1437 Object oref;
1438 array->get(i, &obj2);
1439 array->getNF(i, &oref);
1440 if (!oref.isRef()) {
1441 error(errSyntaxWarning, -1, "Direct object in rootFields");
1442 obj2.free();
1443 oref.free();
1444 continue;
1447 if (!obj2.isDict()) {
1448 error(errSyntaxWarning, -1, "Reference in Fields array to an invalid or non existent object");
1449 obj2.free();
1450 oref.free();
1451 continue;
1454 if (numFields >= size) {
1455 size += 16;
1456 rootFields = (FormField**)greallocn(rootFields,size,sizeof(FormField*));
1459 std::set<int> usedParents;
1460 rootFields[numFields++] = createFieldFromDict (&obj2, doc, oref.getRef(), NULL, &usedParents);
1462 obj2.free();
1463 oref.free();
1465 } else {
1466 error(errSyntaxError, -1, "Can't get Fields array\n");
1468 obj1.free ();
1470 #ifdef DEBUG_FORMS
1471 for (int i = 0; i < numFields; i++)
1472 rootFields[i]->printTree();
1473 #endif
1476 Form::~Form() {
1477 int i;
1478 for(i = 0; i< numFields; ++i)
1479 delete rootFields[i];
1480 gfree (rootFields);
1481 delete defaultAppearance;
1482 delete defaultResources;
1483 resDict.free();
1486 // Look up an inheritable field dictionary entry.
1487 static Object *fieldLookup(Dict *field, const char *key, Object *obj, std::set<int> *usedParents) {
1488 Dict *dict;
1489 Object parent;
1491 dict = field;
1492 if (!dict->lookup(key, obj)->isNull()) {
1493 return obj;
1495 obj->free();
1496 dict->lookupNF("Parent", &parent);
1497 if (parent.isRef()) {
1498 const Ref ref = parent.getRef();
1499 if (usedParents->find(ref.num) == usedParents->end()) {
1500 usedParents->insert(ref.num);
1502 Object obj2;
1503 parent.fetch(dict->getXRef(), &obj2);
1504 if (obj2.isDict()) {
1505 fieldLookup(obj2.getDict(), key, obj, usedParents);
1506 } else {
1507 obj->initNull();
1509 obj2.free();
1511 } else if (parent.isDict()) {
1512 fieldLookup(parent.getDict(), key, obj, usedParents);
1513 } else {
1514 obj->initNull();
1516 parent.free();
1517 return obj;
1520 Object *Form::fieldLookup(Dict *field, const char *key, Object *obj) {
1521 std::set<int> usedParents;
1522 return ::fieldLookup(field, key, obj, &usedParents);
1525 FormField *Form::createFieldFromDict (Object* obj, PDFDoc *docA, const Ref& pref, FormField *parent, std::set<int> *usedParents)
1527 Object obj2;
1528 FormField *field;
1530 if (Form::fieldLookup(obj->getDict (), "FT", &obj2)->isName("Btn")) {
1531 field = new FormFieldButton(docA, obj, pref, parent, usedParents);
1532 } else if (obj2.isName("Tx")) {
1533 field = new FormFieldText(docA, obj, pref, parent, usedParents);
1534 } else if (obj2.isName("Ch")) {
1535 field = new FormFieldChoice(docA, obj, pref, parent, usedParents);
1536 } else if (obj2.isName("Sig")) {
1537 field = new FormFieldSignature(docA, obj, pref, parent, usedParents);
1538 } else { //we don't have an FT entry => non-terminal field
1539 field = new FormField(docA, obj, pref, parent, usedParents);
1541 obj2.free();
1543 return field;
1546 void Form::postWidgetsLoad()
1548 // We create the widget annotations associated to
1549 // every form widget here, because the AnnotWidget constructor
1550 // needs the form object that gets from the catalog. When constructing
1551 // a FormWidget the Catalog is still creating the form object
1552 for (int i = 0; i < numFields; i++) {
1553 rootFields[i]->fillChildrenSiblingsID();
1554 rootFields[i]->createWidgetAnnotations();
1558 FormWidget* Form::findWidgetByRef (Ref aref)
1560 for(int i=0; i<numFields; i++) {
1561 FormWidget *result = rootFields[i]->findWidgetByRef(aref);
1562 if(result) return result;
1564 return NULL;
1567 //------------------------------------------------------------------------
1568 // FormPageWidgets
1569 //------------------------------------------------------------------------
1571 FormPageWidgets::FormPageWidgets (Annots *annots, unsigned int page, Form *form)
1573 numWidgets = 0;
1574 widgets = NULL;
1576 if (annots && annots->getNumAnnots() > 0 && form) {
1577 size = annots->getNumAnnots();
1578 widgets = (FormWidget**)greallocn(widgets, size, sizeof(FormWidget*));
1580 /* For each entry in the page 'Annots' dict, try to find
1581 a matching form field */
1582 for (int i = 0; i < size; ++i) {
1583 Annot *annot = annots->getAnnot(i);
1585 if (annot->getType() != Annot::typeWidget)
1586 continue;
1588 if (!annot->getHasRef()) {
1589 /* Since all entry in a form field's kid dict needs to be
1590 indirect references, if this annot isn't indirect, it isn't
1591 related to a form field */
1592 continue;
1595 Ref r = annot->getRef();
1597 /* Try to find a form field which either has this Annot in its Kids entry
1598 or is merged with this Annot */
1599 FormWidget* tmp = form->findWidgetByRef(r);
1600 if (tmp) {
1601 // We've found a corresponding form field, link it
1602 tmp->setID(FormWidget::encodeID(page, numWidgets));
1603 widgets[numWidgets++] = tmp;
1609 FormPageWidgets::~FormPageWidgets()
1611 gfree (widgets);