[poppler] poppler/Annot.cc poppler/Annot.h poppler/Catalog.cc poppler/Form.cc poppler/Form.h
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Wed Mar 9 08:39:58 PST 2011
poppler/Annot.cc | 42 ++++++++++++--------
poppler/Annot.h | 2
poppler/Catalog.cc | 2
poppler/Form.cc | 107 ++++++++++++++++++++++++-----------------------------
poppler/Form.h | 23 +++++------
5 files changed, 89 insertions(+), 87 deletions(-)
New commits:
commit d59561212253302d4dcb23392bb8306b8e5c68d1
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Wed Mar 9 17:35:28 2011 +0100
forms: Make FormWidget use a real widget annotation instead of duplicating code
When creating annotations, if it's a widget annotation, look first
whether it has already been created by a FormWidget and reuse it instead
of duplicating it.
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index ef1aa64..b8acbab 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -2664,7 +2664,14 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
AnnotWidget::AnnotWidget(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj) :
Annot(xrefA, dict, catalog, obj) {
type = typeWidget;
- widget = NULL;
+ field = NULL;
+ initialize(xrefA, catalog, dict);
+}
+
+AnnotWidget::AnnotWidget(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj, FormField *fieldA) :
+ Annot(xrefA, dict, catalog, obj) {
+ type = typeWidget;
+ field = fieldA;
initialize(xrefA, catalog, dict);
}
@@ -2686,13 +2693,11 @@ void AnnotWidget::initialize(XRef *xrefA, Catalog *catalog, Dict *dict) {
Object obj1;
if ((form = catalog->getForm ())) {
- widget = form->findWidgetByRef (ref);
-
// check if field apperances need to be regenerated
// Only text or choice fields needs to have appearance regenerated
// see section 8.6.2 "Variable Text" of PDFReference
regen = gFalse;
- if (widget != NULL && (widget->getType () == formText || widget->getType () == formChoice)) {
+ if (field != NULL && (field->getType () == formText || field->getType () == formChoice)) {
regen = form->getNeedAppearances ();
}
}
@@ -3651,7 +3656,7 @@ void AnnotWidget::drawBorder() {
void AnnotWidget::drawFormFieldButton(GfxResources *resources, GooString *da) {
Object obj1;
- Dict *annot = widget->getObj()->getDict();
+ Dict *annot = annotObj.getDict();
GooString *caption = NULL;
if (appearCharacs)
caption = appearCharacs->getNormalCaption();
@@ -3736,22 +3741,19 @@ void AnnotWidget::drawFormFieldChoice(GfxResources *resources, GooString *da) {
void AnnotWidget::generateFieldAppearance() {
Object appearDict, obj1, obj2;
- Dict *fieldDict;
Dict *annot;
GfxResources *resources;
MemStream *appearStream;
GooString *da;
GBool modified;
- if (widget == NULL || !widget->getField () || !widget->getField ()->getObj ()->isDict ())
+ if (field == NULL)
return;
- field = widget->getField();
- fieldDict = field->getObj()->getDict();
- annot = widget->getObj ()->getDict ();
+ annot = annotObj.getDict ();
// do not regenerate appearence if widget has not changed
- modified = widget->isModified ();
+ modified = field->isModified ();
// only regenerate when it doesn't have an AP or
// it already has an AP but widget has been modified
@@ -3827,7 +3829,7 @@ void AnnotWidget::generateFieldAppearance() {
appearStream->setNeedFree(gTrue);
- if (widget->isModified()) {
+ if (field->isModified()) {
//create a new object that will contains the new appearance
//if we already have a N entry in our AP dict, reuse it
@@ -5133,7 +5135,7 @@ void Annots::appendAnnot(Annot *annot) {
}
Annot *Annots::createAnnot(XRef *xref, Dict* dict, Catalog *catalog, Object *obj) {
- Annot *annot;
+ Annot *annot = NULL;
Object obj1;
if (dict->lookup("Subtype", &obj1)->isName()) {
@@ -5176,7 +5178,17 @@ Annot *Annots::createAnnot(XRef *xref, Dict* dict, Catalog *catalog, Object *obj
} else if(!strcmp(typeName, "Movie")) {
annot = new AnnotMovie(xref, dict, catalog, obj);
} else if(!strcmp(typeName, "Widget")) {
- annot = new AnnotWidget(xref, dict, catalog, obj);
+ // Find the annot in forms
+ if (obj->isRef()) {
+ Form *form = catalog->getForm();
+ FormWidget *widget = form->findWidgetByRef(obj->getRef());
+ if (widget) {
+ annot = widget->getWidgetAnnotation();
+ annot->incRefCnt();
+ }
+ }
+ if (!annot)
+ annot = new AnnotWidget(xref, dict, catalog, obj);
} else if(!strcmp(typeName, "Screen")) {
annot = new AnnotScreen(xref, dict, catalog, obj);
} else if(!strcmp(typeName, "PrinterMark")) {
@@ -5203,8 +5215,6 @@ Annot *Annots::createAnnot(XRef *xref, Dict* dict, Catalog *catalog, Object *obj
} else {
annot = new Annot(xref, dict, catalog, obj);
}
- } else {
- annot = NULL;
}
obj1.free();
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 3126e53..055fa21 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -1131,6 +1131,7 @@ public:
};
AnnotWidget(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj);
+ AnnotWidget(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj, FormField *fieldA);
virtual ~AnnotWidget();
virtual void draw(Gfx *gfx, GBool printing);
@@ -1163,7 +1164,6 @@ private:
void writeString(GooString *str, GooString *appearBuf);
Form *form;
- FormWidget *widget; // FormWidget object for this annotation
FormField *field; // FormField object for this annotation
AnnotWidgetHighlightMode mode; // H (Default I)
AnnotAppearanceCharacs *appearCharacs; // MK
diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc
index 297cac5..d489b10 100644
--- a/poppler/Catalog.cc
+++ b/poppler/Catalog.cc
@@ -111,7 +111,7 @@ Catalog::Catalog(XRef *xrefA) {
// perform form-related loading after all widgets have been loaded
if (getForm())
- getForm()->postWidgetsLoad();
+ getForm()->postWidgetsLoad(this);
catDict.free();
return;
diff --git a/poppler/Form.cc b/poppler/Form.cc
index 2af8d3d..bc816d1 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -63,70 +63,46 @@ char* pdfDocEncodingToUTF16 (GooString* orig, int* length)
FormWidget::FormWidget(XRef *xrefA, Object *aobj, unsigned num, Ref aref, FormField *fieldA)
{
- Object obj1, obj2;
ref = aref;
- double t;
ID = 0;
- fontSize = 0.0;
childNum = num;
xref = xrefA;
aobj->copy(&obj);
type = formUndef;
field = fieldA;
- Dict *dict = obj.getDict();
-
- if (!dict->lookup("Rect", &obj1)->isArray()) {
- error(-1, "Annotation rectangle is wrong type");
- goto err2;
- }
- if (!obj1.arrayGet(0, &obj2)->isNum()) {
- error(-1, "Bad annotation rectangle");
- goto err1;
- }
- x1 = obj2.getNum();
- obj2.free();
- if (!obj1.arrayGet(1, &obj2)->isNum()) {
- error(-1, "Bad annotation rectangle");
- goto err1;
- }
- y1 = obj2.getNum();
- obj2.free();
- if (!obj1.arrayGet(2, &obj2)->isNum()) {
- error(-1, "Bad annotation rectangle");
- goto err1;
- }
- x2 = obj2.getNum();
- obj2.free();
- if (!obj1.arrayGet(3, &obj2)->isNum()) {
- error(-1, "Bad annotation rectangle");
- goto err1;
- }
- y2 = obj2.getNum();
- obj2.free();
- obj1.free();
- //swap coords if needed
- if (x1 > x2) {
- t = x1;
- x1 = x2;
- x2 = t;
- }
- if (y1 > y2) {
- t = y1;
- y1 = y2;
- y2 = t;
- }
-
- err1:
- obj2.free();
- err2:
- obj1.free();
+ widget = NULL;
}
FormWidget::~FormWidget()
{
+ if (widget)
+ widget->decRefCnt();
obj.free ();
}
+void FormWidget::createWidgetAnnotation(Catalog *catalog) {
+ if (widget)
+ return;
+
+ Object obj1;
+ obj1.initRef(ref.num, ref.gen);
+ widget = new AnnotWidget(xref, obj.getDict(), catalog, &obj1, field);
+ obj1.free();
+}
+
+GBool FormWidget::inRect(double x, double y) const {
+ return widget ? widget->inRect(x, y) : gFalse;
+}
+
+void FormWidget::getRect(double *x1, double *y1, double *x2, double *y2) const {
+ if (widget)
+ widget->getRect(x1, y1, x2, y2);
+}
+
+double FormWidget::getFontSize() const {
+ return widget ? widget->getFontSize() : 0.;
+}
+
bool FormWidget::isReadOnly() const
{
return field->isReadOnly();
@@ -631,12 +607,22 @@ FormField::~FormField()
void FormField::fillChildrenSiblingsID()
{
- if(terminal) return;
- for (int i=0; i<numChildren; i++) {
+ if (terminal)
+ return;
+ for (int i = 0; i < numChildren; i++) {
children[i]->fillChildrenSiblingsID();
}
}
+void FormField::createWidgetAnnotations(Catalog *catalog) {
+ if (terminal) {
+ for (int i = 0; i < numChildren; i++)
+ widgets[i]->createWidgetAnnotation(catalog);
+ } else {
+ for (int i = 0; i < numChildren; i++)
+ children[i]->createWidgetAnnotations(catalog);
+ }
+}
void FormField::_createWidget (Object *obj, Ref aref)
{
@@ -1336,11 +1322,16 @@ FormField *Form::createFieldFromDict (Object* obj, XRef *xrefA, const Ref& pref,
return field;
}
-void Form::postWidgetsLoad ()
+void Form::postWidgetsLoad (Catalog *catalog)
{
- for(int i=0; i<numFields; i++) {
- rootFields[i]->fillChildrenSiblingsID();
- }
+ // We create the widget annotations associated to
+ // every form widget here, because the AnnotWidget constructor
+ // needs the form object that gets from the catalog. When constructing
+ // a FormWidget the Catalog is still creating the form object
+ for (int i = 0; i < numFields; i++) {
+ rootFields[i]->fillChildrenSiblingsID();
+ rootFields[i]->createWidgetAnnotations(catalog);
+ }
}
FormWidget* Form::findWidgetByRef (Ref aref)
@@ -1370,6 +1361,9 @@ FormPageWidgets::FormPageWidgets (Annots *annots, unsigned int page, Form *form)
for (int i = 0; i < size; ++i) {
Annot *annot = annots->getAnnot(i);
+ if (annot->getType() != Annot::typeWidget)
+ continue;
+
if (!annot->getHasRef()) {
/* Since all entry in a form field's kid dict needs to be
indirect references, if this annot isn't indirect, it isn't
@@ -1385,7 +1379,6 @@ FormPageWidgets::FormPageWidgets (Annots *annots, unsigned int page, Form *form)
if (tmp) {
// We've found a corresponding form field, link it
tmp->setID(FormWidget::encodeID(page, numWidgets));
- tmp->setFontSize(annot->getFontSize());
widgets[numWidgets++] = tmp;
}
}
diff --git a/poppler/Form.h b/poppler/Form.h
index b5b4edd..f7bf33e 100644
--- a/poppler/Form.h
+++ b/poppler/Form.h
@@ -27,6 +27,7 @@ class GooString;
class Array;
class Dict;
class Annot;
+class AnnotWidget;
class Annots;
class Catalog;
class LinkAction;
@@ -70,12 +71,10 @@ public:
virtual ~FormWidget();
// Check if point is inside the field bounding rect
- GBool inRect(double x, double y)
- { return x1 <= x && x <= x2 && y1 <= y && y <= y2; }
+ GBool inRect(double x, double y) const;
// Get the field bounding rect
- void getRect(double *xa1, double *ya1, double *xa2, double *ya2)
- { *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; }
+ void getRect(double *x1, double *y1, double *x2, double *y2) const;
unsigned getID () { return ID; }
void setID (unsigned int i) { ID=i; }
@@ -89,8 +88,7 @@ public:
void setChildNum (unsigned i) { childNum = i; }
unsigned getChildNum () { return childNum; }
- void setFontSize(double f) { fontSize = f; }
- double getFontSize () { return fontSize; }
+ double getFontSize() const;
GooString *getPartialName() const;
GooString *getAlternateUiName() const;
@@ -108,11 +106,15 @@ public:
// decode id and retrieve pageNum and fieldNum
static void decodeID (unsigned id, unsigned* pageNum, unsigned* fieldNum);
+ void createWidgetAnnotation(Catalog *catalog);
+ AnnotWidget *getWidgetAnnotation() const { return widget; }
+
protected:
FormWidget(XRef *xrefA, Object *aobj, unsigned num, Ref aref, FormField *fieldA);
void updateField (const char *key, Object *value);
+ AnnotWidget *widget;
FormField* field;
FormFieldType type;
Object obj;
@@ -131,11 +133,6 @@ protected:
(decoding) pageNum = id >> 4*sizeof(unsigned); fieldNum = (id << 4*sizeof(unsigned)) >> 4*sizeof(unsigned);
*/
unsigned ID;
-
- double x1, y1; // lower left corner
- double x2, y2; // upper right corner
- double fontSize; //font size if this widget has text
-
};
//------------------------------------------------------------------------
@@ -285,6 +282,8 @@ public:
// only implemented in FormFieldButton
virtual void fillChildrenSiblingsID ();
+ void createWidgetAnnotations(Catalog *catalog);
+
protected:
void _createWidget (Object *obj, Ref aref);
@@ -486,7 +485,7 @@ public:
FormWidget* findWidgetByRef (Ref aref);
- void postWidgetsLoad();
+ void postWidgetsLoad(Catalog *catalog);
private:
FormField** rootFields;
int numFields;
More information about the poppler
mailing list