Populate Choice Fields in PDFiumPage
This CL introduces a method PDFiumPage::PopulateChoiceFields() which reads choice form fields from the PDF document and stores relevant information in a vector within PDFiumPage. The CL also includes a new test file with sample choice fields and a unit test to validate the new method. Bug: 1030242 Change-Id: Ie8dc9da6c694747d8fef7721625f7690dda64124 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2249244 Reviewed-by: Lei Zhang <thestig@chromium.org> Reviewed-by: Ankit Kumar 🌪️ <ankk@microsoft.com> Commit-Queue: Mansi Awasthi <maawas@microsoft.com> Cr-Commit-Position: refs/heads/master@{#781102}
This commit is contained in:

committed by
Commit Bot

parent
9555d6555d
commit
b62d1d1c56
@@ -1240,12 +1240,45 @@ void PDFiumPage::PopulateTextField(FPDF_ANNOTATION annot) {
|
|||||||
text_fields_.push_back(std::move(text_field));
|
text_fields_.push_back(std::move(text_field));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFiumPage::PopulateChoiceField(FPDF_ANNOTATION annot) {
|
||||||
|
DCHECK(annot);
|
||||||
|
FPDF_FORMHANDLE form_handle = engine_->form();
|
||||||
|
int form_field_type = FPDFAnnot_GetFormFieldType(form_handle, annot);
|
||||||
|
DCHECK(form_field_type == FPDF_FORMFIELD_LISTBOX ||
|
||||||
|
form_field_type == FPDF_FORMFIELD_COMBOBOX);
|
||||||
|
|
||||||
|
ChoiceField choice_field;
|
||||||
|
if (!PopulateFormFieldProperties(annot, &choice_field))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int options_count = FPDFAnnot_GetOptionCount(form_handle, annot);
|
||||||
|
if (options_count < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
choice_field.options.resize(options_count);
|
||||||
|
for (int i = 0; i < options_count; ++i) {
|
||||||
|
choice_field.options[i].name =
|
||||||
|
base::UTF16ToUTF8(CallPDFiumWideStringBufferApi(
|
||||||
|
base::BindRepeating(&FPDFAnnot_GetOptionLabel, form_handle, annot,
|
||||||
|
i),
|
||||||
|
/*check_expected_size=*/true));
|
||||||
|
choice_field.options[i].is_selected =
|
||||||
|
FPDFAnnot_IsOptionSelected(form_handle, annot, i);
|
||||||
|
}
|
||||||
|
choice_fields_.push_back(std::move(choice_field));
|
||||||
|
}
|
||||||
|
|
||||||
void PDFiumPage::PopulateFormField(FPDF_ANNOTATION annot) {
|
void PDFiumPage::PopulateFormField(FPDF_ANNOTATION annot) {
|
||||||
DCHECK_EQ(FPDFAnnot_GetSubtype(annot), FPDF_ANNOT_WIDGET);
|
DCHECK_EQ(FPDFAnnot_GetSubtype(annot), FPDF_ANNOT_WIDGET);
|
||||||
int form_field_type = FPDFAnnot_GetFormFieldType(engine_->form(), annot);
|
int form_field_type = FPDFAnnot_GetFormFieldType(engine_->form(), annot);
|
||||||
|
|
||||||
// TODO(crbug.com/1030242): Populate other types of form fields too.
|
// TODO(crbug.com/1030242): Populate other types of form fields too.
|
||||||
switch (form_field_type) {
|
switch (form_field_type) {
|
||||||
|
case FPDF_FORMFIELD_COMBOBOX:
|
||||||
|
case FPDF_FORMFIELD_LISTBOX: {
|
||||||
|
PopulateChoiceField(annot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case FPDF_FORMFIELD_TEXTFIELD: {
|
case FPDF_FORMFIELD_TEXTFIELD: {
|
||||||
PopulateTextField(annot);
|
PopulateTextField(annot);
|
||||||
break;
|
break;
|
||||||
@@ -1415,6 +1448,19 @@ PDFiumPage::TextField::TextField(const TextField& that) = default;
|
|||||||
|
|
||||||
PDFiumPage::TextField::~TextField() = default;
|
PDFiumPage::TextField::~TextField() = default;
|
||||||
|
|
||||||
|
PDFiumPage::ChoiceFieldOption::ChoiceFieldOption() = default;
|
||||||
|
|
||||||
|
PDFiumPage::ChoiceFieldOption::ChoiceFieldOption(
|
||||||
|
const ChoiceFieldOption& that) = default;
|
||||||
|
|
||||||
|
PDFiumPage::ChoiceFieldOption::~ChoiceFieldOption() = default;
|
||||||
|
|
||||||
|
PDFiumPage::ChoiceField::ChoiceField() = default;
|
||||||
|
|
||||||
|
PDFiumPage::ChoiceField::ChoiceField(const ChoiceField& that) = default;
|
||||||
|
|
||||||
|
PDFiumPage::ChoiceField::~ChoiceField() = default;
|
||||||
|
|
||||||
// static
|
// static
|
||||||
uint32_t PDFiumPage::CountLinkHighlightOverlaps(
|
uint32_t PDFiumPage::CountLinkHighlightOverlaps(
|
||||||
const std::vector<Link>& links,
|
const std::vector<Link>& links,
|
||||||
|
@@ -178,6 +178,7 @@ class PDFiumPage {
|
|||||||
FRIEND_TEST_ALL_PREFIXES(PDFiumPageLinkTest, TestLinkGeneration);
|
FRIEND_TEST_ALL_PREFIXES(PDFiumPageLinkTest, TestLinkGeneration);
|
||||||
FRIEND_TEST_ALL_PREFIXES(PDFiumPageHighlightTest, TestPopulateHighlights);
|
FRIEND_TEST_ALL_PREFIXES(PDFiumPageHighlightTest, TestPopulateHighlights);
|
||||||
FRIEND_TEST_ALL_PREFIXES(PDFiumPageTextFieldTest, TestPopulateTextFields);
|
FRIEND_TEST_ALL_PREFIXES(PDFiumPageTextFieldTest, TestPopulateTextFields);
|
||||||
|
FRIEND_TEST_ALL_PREFIXES(PDFiumPageChoiceFieldTest, TestPopulateChoiceFields);
|
||||||
FRIEND_TEST_ALL_PREFIXES(PDFiumPageOverlappingTest, CountPartialOverlaps);
|
FRIEND_TEST_ALL_PREFIXES(PDFiumPageOverlappingTest, CountPartialOverlaps);
|
||||||
FRIEND_TEST_ALL_PREFIXES(PDFiumPageOverlappingTest, CountCompleteOverlaps);
|
FRIEND_TEST_ALL_PREFIXES(PDFiumPageOverlappingTest, CountCompleteOverlaps);
|
||||||
|
|
||||||
@@ -257,6 +258,25 @@ class PDFiumPage {
|
|||||||
std::string value;
|
std::string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Represents a choice field option.
|
||||||
|
struct ChoiceFieldOption {
|
||||||
|
ChoiceFieldOption();
|
||||||
|
ChoiceFieldOption(const ChoiceFieldOption& other);
|
||||||
|
~ChoiceFieldOption();
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
bool is_selected;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Represents a choice field within the page.
|
||||||
|
struct ChoiceField : FormField {
|
||||||
|
ChoiceField();
|
||||||
|
ChoiceField(const ChoiceField& other);
|
||||||
|
~ChoiceField();
|
||||||
|
|
||||||
|
std::vector<ChoiceFieldOption> options;
|
||||||
|
};
|
||||||
|
|
||||||
// Returns a link index if the given character index is over a link, or -1
|
// Returns a link index if the given character index is over a link, or -1
|
||||||
// otherwise.
|
// otherwise.
|
||||||
int GetLink(int char_index, LinkTarget* target);
|
int GetLink(int char_index, LinkTarget* target);
|
||||||
@@ -274,7 +294,9 @@ class PDFiumPage {
|
|||||||
void PopulateHighlight(FPDF_ANNOTATION annot);
|
void PopulateHighlight(FPDF_ANNOTATION annot);
|
||||||
// Populate |text_fields_| with |annot|.
|
// Populate |text_fields_| with |annot|.
|
||||||
void PopulateTextField(FPDF_ANNOTATION annot);
|
void PopulateTextField(FPDF_ANNOTATION annot);
|
||||||
// Populate form fields like text field on the page.
|
// Populate |choice_fields_| with |annot|.
|
||||||
|
void PopulateChoiceField(FPDF_ANNOTATION annot);
|
||||||
|
// Populate form fields like text field and choice field on the page.
|
||||||
void PopulateFormField(FPDF_ANNOTATION annot);
|
void PopulateFormField(FPDF_ANNOTATION annot);
|
||||||
// Returns link type and fills target associated with a destination. Returns
|
// Returns link type and fills target associated with a destination. Returns
|
||||||
// NONSELECTABLE_AREA if detection failed.
|
// NONSELECTABLE_AREA if detection failed.
|
||||||
@@ -331,6 +353,7 @@ class PDFiumPage {
|
|||||||
bool calculated_annotations_ = false;
|
bool calculated_annotations_ = false;
|
||||||
std::vector<Highlight> highlights_;
|
std::vector<Highlight> highlights_;
|
||||||
std::vector<TextField> text_fields_;
|
std::vector<TextField> text_fields_;
|
||||||
|
std::vector<ChoiceField> choice_fields_;
|
||||||
bool logged_overlapping_annotations_ = false;
|
bool logged_overlapping_annotations_ = false;
|
||||||
bool calculated_page_object_text_run_breaks_ = false;
|
bool calculated_page_object_text_run_breaks_ = false;
|
||||||
// The set of character indices on which text runs need to be broken for page
|
// The set of character indices on which text runs need to be broken for page
|
||||||
|
@@ -513,6 +513,94 @@ TEST_F(PDFiumPageTextFieldTest, TestPopulateTextFields) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using PDFiumPageChoiceFieldTest = PDFiumTestBase;
|
||||||
|
|
||||||
|
TEST_F(PDFiumPageChoiceFieldTest, TestPopulateChoiceFields) {
|
||||||
|
struct ExpectedChoiceFieldOption {
|
||||||
|
const char* name;
|
||||||
|
bool is_selected;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExpectedChoiceField {
|
||||||
|
const char* name;
|
||||||
|
std::vector<struct ExpectedChoiceFieldOption> options;
|
||||||
|
pp::Rect bounding_rect;
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ExpectedChoiceField kExpectedChoiceFields[] = {
|
||||||
|
{"Listbox_SingleSelect",
|
||||||
|
{{"Foo", false}, {"Bar", false}, {"Qux", false}},
|
||||||
|
{138, 296, 135, 41},
|
||||||
|
0},
|
||||||
|
{"Combo1",
|
||||||
|
{{"Apple", false}, {"Banana", true}, {"Cherry", false}},
|
||||||
|
{138, 230, 135, 41},
|
||||||
|
131072},
|
||||||
|
{"Listbox_ReadOnly",
|
||||||
|
{{"Dog", false}, {"Elephant", false}, {"Frog", false}},
|
||||||
|
{138, 96, 135, 41},
|
||||||
|
1},
|
||||||
|
{"Listbox_MultiSelectMultipleIndices",
|
||||||
|
{
|
||||||
|
{"Albania", false},
|
||||||
|
{"Belgium", true},
|
||||||
|
{"Croatia", false},
|
||||||
|
{"Denmark", true},
|
||||||
|
{"Estonia", false},
|
||||||
|
},
|
||||||
|
{138, 430, 135, 41},
|
||||||
|
2097152},
|
||||||
|
{"Listbox_MultiSelectMultipleValues",
|
||||||
|
{
|
||||||
|
{"Alpha", false},
|
||||||
|
{"Beta", false},
|
||||||
|
{"Gamma", true},
|
||||||
|
{"Delta", false},
|
||||||
|
{"Epsilon", true},
|
||||||
|
},
|
||||||
|
{138, 496, 135, 41},
|
||||||
|
2097152},
|
||||||
|
{"Listbox_MultiSelectMultipleMismatch",
|
||||||
|
{
|
||||||
|
{"Alligator", true},
|
||||||
|
{"Bear", false},
|
||||||
|
{"Cougar", true},
|
||||||
|
{"Deer", false},
|
||||||
|
{"Echidna", false},
|
||||||
|
},
|
||||||
|
{138, 563, 135, 41},
|
||||||
|
2097152}};
|
||||||
|
|
||||||
|
TestClient client;
|
||||||
|
std::unique_ptr<PDFiumEngine> engine =
|
||||||
|
InitializeEngine(&client, FILE_PATH_LITERAL("form_choice_fields.pdf"));
|
||||||
|
ASSERT_TRUE(engine);
|
||||||
|
ASSERT_EQ(1, engine->GetNumberOfPages());
|
||||||
|
|
||||||
|
PDFiumPage* page = GetPDFiumPageForTest(engine.get(), 0);
|
||||||
|
ASSERT_TRUE(page);
|
||||||
|
page->PopulateAnnotations();
|
||||||
|
size_t choice_fields_count = page->choice_fields_.size();
|
||||||
|
ASSERT_EQ(base::size(kExpectedChoiceFields), choice_fields_count);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < choice_fields_count; ++i) {
|
||||||
|
EXPECT_EQ(kExpectedChoiceFields[i].name, page->choice_fields_[i].name);
|
||||||
|
size_t choice_field_options_count = page->choice_fields_[i].options.size();
|
||||||
|
ASSERT_EQ(base::size(kExpectedChoiceFields[i].options),
|
||||||
|
choice_field_options_count);
|
||||||
|
for (size_t j = 0; j < choice_field_options_count; ++j) {
|
||||||
|
EXPECT_EQ(kExpectedChoiceFields[i].options[j].name,
|
||||||
|
page->choice_fields_[i].options[j].name);
|
||||||
|
EXPECT_EQ(kExpectedChoiceFields[i].options[j].is_selected,
|
||||||
|
page->choice_fields_[i].options[j].is_selected);
|
||||||
|
}
|
||||||
|
CompareRect(kExpectedChoiceFields[i].bounding_rect,
|
||||||
|
page->choice_fields_[i].bounding_rect);
|
||||||
|
EXPECT_EQ(kExpectedChoiceFields[i].flags, page->choice_fields_[i].flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
using PDFiumPageOverlappingTest = PDFiumTestBase;
|
using PDFiumPageOverlappingTest = PDFiumTestBase;
|
||||||
|
|
||||||
// The following scenarios are covered across both test cases:
|
// The following scenarios are covered across both test cases:
|
||||||
|
106
pdf/test/data/form_choice_fields.in
Normal file
106
pdf/test/data/form_choice_fields.in
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
{{header}}
|
||||||
|
{{object 1 0}} <<
|
||||||
|
/Type /Catalog
|
||||||
|
/Pages 2 0 R
|
||||||
|
/AcroForm <<
|
||||||
|
/Fields [4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R]
|
||||||
|
>>
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
{{object 2 0}} <<
|
||||||
|
/Type /Pages
|
||||||
|
/Count 1
|
||||||
|
/Kids [3 0 R]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
{{object 3 0}} <<
|
||||||
|
/Type /Page
|
||||||
|
/Parent 2 0 R
|
||||||
|
/Resources <<
|
||||||
|
/Font <<
|
||||||
|
/F1 <<
|
||||||
|
/Type /Font
|
||||||
|
/Subtype /Type1
|
||||||
|
/BaseFont /Helvetica
|
||||||
|
>>
|
||||||
|
>>
|
||||||
|
>>
|
||||||
|
/MediaBox [0 0 300 600]
|
||||||
|
/Annots [4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
{{object 4 0}} <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 0
|
||||||
|
/T (Listbox_SingleSelect)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 350 200 380]
|
||||||
|
/Opt [[(foo) (Foo)] [(bar) (Bar)] [(qux) (Qux)]]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
{{object 5 0}} <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 131072
|
||||||
|
/T (Combo1)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 400 200 430]
|
||||||
|
/Opt [(Apple) (Banana) (Cherry)]
|
||||||
|
/V (Banana)
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
{{object 6 0}} <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 1
|
||||||
|
/T (Listbox_ReadOnly)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 500 200 530]
|
||||||
|
/Opt [(Dog) (Elephant) (Frog)]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
{{object 7 0}} <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 2097152
|
||||||
|
/T (Listbox_MultiSelectMultipleIndices)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 250 200 280]
|
||||||
|
/Opt [(Albania) (Belgium) (Croatia) (Denmark) (Estonia)]
|
||||||
|
/I [1 3]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
{{object 8 0}} <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 2097152
|
||||||
|
/T (Listbox_MultiSelectMultipleValues)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 200 200 230]
|
||||||
|
/Opt [(Alpha) (Beta) (Gamma) (Delta) (Epsilon)]
|
||||||
|
/V [(Epsilon) (Gamma)]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
{{object 9 0}} <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 2097152
|
||||||
|
/T (Listbox_MultiSelectMultipleMismatch)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 150 200 180]
|
||||||
|
/Opt [(Alligator) (Bear) (Cougar) (Deer) (Echidna)]
|
||||||
|
/V [(Alligator) (Cougar)]
|
||||||
|
/I [1 3 4]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
{{xref}}
|
||||||
|
{{trailer}}
|
||||||
|
{{startxref}}
|
||||||
|
%%EOF
|
122
pdf/test/data/form_choice_fields.pdf
Normal file
122
pdf/test/data/form_choice_fields.pdf
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
%PDF-1.7
|
||||||
|
%<25><><EFBFBD><EFBFBD>
|
||||||
|
1 0 obj <<
|
||||||
|
/Type /Catalog
|
||||||
|
/Pages 2 0 R
|
||||||
|
/AcroForm <<
|
||||||
|
/Fields [4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R]
|
||||||
|
>>
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
2 0 obj <<
|
||||||
|
/Type /Pages
|
||||||
|
/Count 1
|
||||||
|
/Kids [3 0 R]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
3 0 obj <<
|
||||||
|
/Type /Page
|
||||||
|
/Parent 2 0 R
|
||||||
|
/Resources <<
|
||||||
|
/Font <<
|
||||||
|
/F1 <<
|
||||||
|
/Type /Font
|
||||||
|
/Subtype /Type1
|
||||||
|
/BaseFont /Helvetica
|
||||||
|
>>
|
||||||
|
>>
|
||||||
|
>>
|
||||||
|
/MediaBox [0 0 300 600]
|
||||||
|
/Annots [4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
4 0 obj <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 0
|
||||||
|
/T (Listbox_SingleSelect)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 350 200 380]
|
||||||
|
/Opt [[(foo) (Foo)] [(bar) (Bar)] [(qux) (Qux)]]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
5 0 obj <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 131072
|
||||||
|
/T (Combo1)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 400 200 430]
|
||||||
|
/Opt [(Apple) (Banana) (Cherry)]
|
||||||
|
/V (Banana)
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
6 0 obj <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 1
|
||||||
|
/T (Listbox_ReadOnly)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 500 200 530]
|
||||||
|
/Opt [(Dog) (Elephant) (Frog)]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
7 0 obj <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 2097152
|
||||||
|
/T (Listbox_MultiSelectMultipleIndices)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 250 200 280]
|
||||||
|
/Opt [(Albania) (Belgium) (Croatia) (Denmark) (Estonia)]
|
||||||
|
/I [1 3]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
8 0 obj <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 2097152
|
||||||
|
/T (Listbox_MultiSelectMultipleValues)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 200 200 230]
|
||||||
|
/Opt [(Alpha) (Beta) (Gamma) (Delta) (Epsilon)]
|
||||||
|
/V [(Epsilon) (Gamma)]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
9 0 obj <<
|
||||||
|
/Type /Annot
|
||||||
|
/Subtype /Widget
|
||||||
|
/FT /Ch
|
||||||
|
/Ff 2097152
|
||||||
|
/T (Listbox_MultiSelectMultipleMismatch)
|
||||||
|
/DA (0 0 0 rg /F1 12 Tf)
|
||||||
|
/Rect [100 150 200 180]
|
||||||
|
/Opt [(Alligator) (Bear) (Cougar) (Deer) (Echidna)]
|
||||||
|
/V [(Alligator) (Cougar)]
|
||||||
|
/I [1 3 4]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
xref
|
||||||
|
0 10
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000015 00000 n
|
||||||
|
0000000138 00000 n
|
||||||
|
0000000201 00000 n
|
||||||
|
0000000462 00000 n
|
||||||
|
0000000667 00000 n
|
||||||
|
0000000861 00000 n
|
||||||
|
0000001044 00000 n
|
||||||
|
0000001288 00000 n
|
||||||
|
0000001536 00000 n
|
||||||
|
trailer <<
|
||||||
|
/Root 1 0 R
|
||||||
|
/Size 10
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
1806
|
||||||
|
%%EOF
|
Reference in New Issue
Block a user