Commit 3297cfbe authored by Mansi Awasthi's avatar Mansi Awasthi Committed by Commit Bot

Fetch text field information from PDFiumEngine for accessibility

This CL adds GetAccessibilityTextFieldInfo() for fetching text field
information from PDFiumEngine using AccessibilityTextFieldInfo struct.
GetAccessibilityTextFieldInfo() is called from within
GetAccessibilityInfo() to populate PrivateAccessibilityTextFieldInfo.
The CL also includes corresponding unit test.

Bug: 1030242
Change-Id: Iafab8645f42c3720482f7e180d94587380f58de9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2084671
Commit-Queue: Mansi Awasthi <maawas@microsoft.com>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarKevin Babbitt <kbabbitt@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#751055}
parent b61dc6ac
......@@ -141,6 +141,30 @@ void GetAccessibilityHighlightInfo(
CompareTextRuns<pp::PDF::PrivateAccessibilityHighlightInfo>);
}
void GetAccessibilityTextFieldInfo(
PDFEngine* engine,
int32_t page_index,
uint32_t text_run_count,
std::vector<pp::PDF::PrivateAccessibilityTextFieldInfo>* text_fields) {
std::vector<PDFEngine::AccessibilityTextFieldInfo> engine_text_field_info =
engine->GetTextFieldInfo(page_index);
for (size_t i = 0; i < engine_text_field_info.size(); ++i) {
auto& cur_text_field_info = engine_text_field_info[i];
pp::PDF::PrivateAccessibilityTextFieldInfo text_field_info;
text_field_info.name = std::move(cur_text_field_info.name);
text_field_info.value = std::move(cur_text_field_info.value);
text_field_info.index_in_page = i;
text_field_info.is_read_only = cur_text_field_info.is_read_only;
text_field_info.is_required = cur_text_field_info.is_required;
text_field_info.is_password = cur_text_field_info.is_password;
// TODO(crbug.com/1030242): Update text run index to nearest text run to
// text field bounds.
text_field_info.text_run_index = text_run_count;
text_field_info.bounds = std::move(cur_text_field_info.bounds);
text_fields->push_back(std::move(text_field_info));
}
}
} // namespace
bool GetAccessibilityInfo(
......@@ -229,7 +253,8 @@ bool GetAccessibilityInfo(
&page_objects->images);
GetAccessibilityHighlightInfo(engine, page_index, *text_runs,
&page_objects->highlights);
// TODO(crbug.com/1030242): Populate text fields.
GetAccessibilityTextFieldInfo(engine, page_index, page_info->text_run_count,
&page_objects->text_fields);
return true;
}
......
......@@ -283,6 +283,19 @@ class PDFEngine {
uint32_t color;
};
struct AccessibilityTextFieldInfo {
AccessibilityTextFieldInfo();
AccessibilityTextFieldInfo(const AccessibilityTextFieldInfo& that);
~AccessibilityTextFieldInfo();
std::string name;
std::string value;
bool is_read_only;
bool is_required;
bool is_password;
pp::FloatRect bounds;
};
// Factory method to create an instance of the PDF Engine.
static std::unique_ptr<PDFEngine> Create(Client* client,
bool enable_javascript);
......@@ -391,6 +404,10 @@ class PDFEngine {
// ranges and bounding boxes.
virtual std::vector<AccessibilityHighlightInfo> GetHighlightInfo(
int page_index) = 0;
// For all the text fields in page |page_index|, get their properties like
// name, value, bounding boxes etc.
virtual std::vector<AccessibilityTextFieldInfo> GetTextFieldInfo(
int page_index) = 0;
// Gets the PDF document's print scaling preference. True if the document can
// be scaled to fit.
......
......@@ -523,6 +523,68 @@ TEST_F(AccessibilityTest, GetAccessibilityHighlightInfo) {
}
}
TEST_F(AccessibilityTest, GetAccessibilityTextFieldInfo) {
static const pp::PDF::PrivateAccessibilityTextFieldInfo
kExpectedTextFieldInfo[] = {
{"Text Box", "Text", false, false, false, 0, 5, {138, 230, 135, 41}},
{"ReadOnly",
"Elephant",
true,
false,
false,
1,
5,
{138, 163, 135, 41}},
{"Required",
"Required Field",
false,
true,
false,
2,
5,
{138, 303, 135, 34}},
{"Password", "", false, false, true, 3, 5, {138, 356, 135, 35}}};
static const pp::Rect kExpectedPageRect = {{5, 3}, {400, 400}};
TestClient client;
std::unique_ptr<PDFiumEngine> engine =
InitializeEngine(&client, FILE_PATH_LITERAL("form_text_fields.pdf"));
ASSERT_TRUE(engine);
ASSERT_EQ(1, engine->GetNumberOfPages());
PP_PrivateAccessibilityPageInfo page_info;
std::vector<pp::PDF::PrivateAccessibilityTextRunInfo> text_runs;
std::vector<PP_PrivateAccessibilityCharInfo> chars;
pp::PDF::PrivateAccessibilityPageObjects page_objects;
ASSERT_TRUE(GetAccessibilityInfo(engine.get(), 0, &page_info, &text_runs,
&chars, &page_objects));
EXPECT_EQ(0u, page_info.page_index);
CompareRect(kExpectedPageRect, page_info.bounds);
EXPECT_EQ(text_runs.size(), page_info.text_run_count);
EXPECT_EQ(chars.size(), page_info.char_count);
ASSERT_EQ(page_objects.text_fields.size(),
base::size(kExpectedTextFieldInfo));
for (size_t i = 0; i < page_objects.text_fields.size(); ++i) {
const pp::PDF::PrivateAccessibilityTextFieldInfo& text_field_info =
page_objects.text_fields[i];
EXPECT_EQ(kExpectedTextFieldInfo[i].name, text_field_info.name);
EXPECT_EQ(kExpectedTextFieldInfo[i].value, text_field_info.value);
EXPECT_EQ(kExpectedTextFieldInfo[i].is_read_only,
text_field_info.is_read_only);
EXPECT_EQ(kExpectedTextFieldInfo[i].is_required,
text_field_info.is_required);
EXPECT_EQ(kExpectedTextFieldInfo[i].is_password,
text_field_info.is_password);
EXPECT_EQ(kExpectedTextFieldInfo[i].index_in_page,
text_field_info.index_in_page);
EXPECT_EQ(kExpectedTextFieldInfo[i].text_run_index,
text_field_info.text_run_index);
CompareRect(kExpectedTextFieldInfo[i].bounds, text_field_info.bounds);
}
}
TEST_F(AccessibilityTest, TestSelectionActionHandling) {
struct Selection {
uint32_t start_page_index;
......
......@@ -390,6 +390,13 @@ void ShutdownSDK() {
TearDownV8();
}
PDFEngine::AccessibilityTextFieldInfo::AccessibilityTextFieldInfo() = default;
PDFEngine::AccessibilityTextFieldInfo::AccessibilityTextFieldInfo(
const AccessibilityTextFieldInfo& that) = default;
PDFEngine::AccessibilityTextFieldInfo::~AccessibilityTextFieldInfo() = default;
std::unique_ptr<PDFEngine> PDFEngine::Create(PDFEngine::Client* client,
bool enable_javascript) {
return std::make_unique<PDFiumEngine>(client, enable_javascript);
......@@ -2332,6 +2339,12 @@ PDFiumEngine::GetHighlightInfo(int page_index) {
return pages_[page_index]->GetHighlightInfo();
}
std::vector<PDFEngine::AccessibilityTextFieldInfo>
PDFiumEngine::GetTextFieldInfo(int page_index) {
DCHECK(PageIndexInBounds(page_index));
return pages_[page_index]->GetTextFieldInfo();
}
bool PDFiumEngine::GetPrintScaling() {
return !!FPDF_VIEWERREF_GetPrintScaling(doc());
}
......
......@@ -123,6 +123,8 @@ class PDFiumEngine : public PDFEngine,
std::vector<AccessibilityImageInfo> GetImageInfo(int page_index) override;
std::vector<AccessibilityHighlightInfo> GetHighlightInfo(
int page_index) override;
std::vector<AccessibilityTextFieldInfo> GetTextFieldInfo(
int page_index) override;
bool GetPrintScaling() override;
int GetCopiesToPrint() override;
int GetDuplexType() override;
......
......@@ -602,6 +602,30 @@ PDFiumPage::GetHighlightInfo() {
return highlight_info;
}
std::vector<PDFEngine::AccessibilityTextFieldInfo>
PDFiumPage::GetTextFieldInfo() {
std::vector<PDFEngine::AccessibilityTextFieldInfo> text_field_info;
if (!available_)
return text_field_info;
PopulateAnnotations();
text_field_info.reserve(text_fields_.size());
for (const TextField& text_field : text_fields_) {
PDFEngine::AccessibilityTextFieldInfo cur_info;
cur_info.name = text_field.name;
cur_info.value = text_field.value;
cur_info.is_read_only = !!(text_field.flags & FPDF_FORMFLAG_READONLY);
cur_info.is_required = !!(text_field.flags & FPDF_FORMFLAG_REQUIRED);
cur_info.is_password = !!(text_field.flags & FPDF_FORMFLAG_TEXT_PASSWORD);
cur_info.bounds = pp::FloatRect(
text_field.bounding_rect.x(), text_field.bounding_rect.y(),
text_field.bounding_rect.width(), text_field.bounding_rect.height());
text_field_info.push_back(std::move(cur_info));
}
return text_field_info;
}
PDFiumPage::Area PDFiumPage::GetLinkTargetAtIndex(int link_index,
LinkTarget* target) {
if (!available_ || link_index < 0)
......
......@@ -60,6 +60,9 @@ class PDFiumPage {
// For all the highlights on the page, get their underlying text ranges and
// bounding boxes.
std::vector<PDFEngine::AccessibilityHighlightInfo> GetHighlightInfo();
// For all the text fields on the page, get their properties like name,
// value, bounding boxes, etc.
std::vector<PDFEngine::AccessibilityTextFieldInfo> GetTextFieldInfo();
enum Area {
NONSELECTABLE_AREA,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment