Which of these 2 approaches should be used to iterate through interactive fields?

Hello:

I am developing a utility that will traverse the widgets (fields) in a document.
The output should contains the specific types (text, check mark, radio buttons)
as well as the rectangles.

There are 2 possible approaches. The first one is the simplest, it comes from the
Windows help file, BUT it seems that it cannot provide the rectangles:

FieldIterator itr = pdfdoc.GetFieldIterator();
for(; itr.HasNext(); itr.Next()) {
Field field = itr.Current();
Console.WriteLine("Field name: {0}", field.GetName());
}

Can anyone confirm or deny such shortcoming?

The second approach does provide the rectangles, but it is much more complicated.
It is based on the ‘AnnotationHighLevelAPI()’ function in the samples. It goes
something like this (still under development):

int num_annots = page.GetNumAnnots();
for (int i = 0; i < num_annots; ++i) {
Annot annot = page.GetAnnot(i);
if (!annot.IsValid()) continue;
if (annot.GetType() != Annot::e_Widget) continue;

cout << "Annot Type: " << annot.GetSDFObj().Get("Subtype").Value().GetName();
Obj obj = annot.GetSDFObj();
const char *someType = obj.Get("FT").Value().GetName();
if (strcmp(someType, "Btn") == 0) {
Obj subobj = obj.Get("Ff").Value();
if (!subobj) {
cout << "Check Mark" << endl;
}
else {
int number = obj.Get("Ff").Value().GetNumber();
cout << "Btn, but not a Check mark: " << number << endl;
}
}

Rect bbox = annot.GetRect();
cout << ", Position:" << " " << bbox.x1
<< ", " << bbox.y1
<< ", " << bbox.x2
<< ", " << bbox.y2
<< ", Type: " << someType << endl;
}

I would prefer to use the first, simpler approach but I need the rectangle coordinates.

Any comments or suggestions are most welcome…

-RFH

The first code snippet traverses all form fields in the document,
whereas the second one traverses all widget annotations on each page.
All widgets are always associated with form fields, whereas a form
field may not be associated with a widget.

As a result you should check that the annotation type is e_Widget when
casting a form field into a widget:

For example:

// In C++
FieldIterator itr = pdfdoc.GetFieldIterator();
for(; itr.HasNext(); itr.Next()) {
    Field field = itr.Current();
    cout << field.GetName() << endl;
    Annot annot(field.GetSDFObj());
    if (annot.GetType() != Annot::e_Widget) continue;
    Rect bbox = annot.GetRect();
    cout << bbox.x1 << "," << bbox.y1 << endl;
}

// In C#
FieldIterator itr = pdfdoc.GetFieldIterator();
for(; itr.HasNext(); itr.Next()) {
    Field field = itr.Current();
    Console.WriteLine("Field name: {0}", field.GetName());
    Annot annot = new Annot(field.GetSDFObj());
    if (annot.GetType() != Annot.Type.e_Widget) continue;
    Rect bbox = annot.GetRect();
    Console.WriteLine("BBox: "....);
}