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( ...@@ -141,6 +141,30 @@ void GetAccessibilityHighlightInfo(
CompareTextRuns<pp::PDF::PrivateAccessibilityHighlightInfo>); 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 } // namespace
bool GetAccessibilityInfo( bool GetAccessibilityInfo(
...@@ -229,7 +253,8 @@ bool GetAccessibilityInfo( ...@@ -229,7 +253,8 @@ bool GetAccessibilityInfo(
&page_objects->images); &page_objects->images);
GetAccessibilityHighlightInfo(engine, page_index, *text_runs, GetAccessibilityHighlightInfo(engine, page_index, *text_runs,
&page_objects->highlights); &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; return true;
} }
......
...@@ -283,6 +283,19 @@ class PDFEngine { ...@@ -283,6 +283,19 @@ class PDFEngine {
uint32_t color; 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. // Factory method to create an instance of the PDF Engine.
static std::unique_ptr<PDFEngine> Create(Client* client, static std::unique_ptr<PDFEngine> Create(Client* client,
bool enable_javascript); bool enable_javascript);
...@@ -391,6 +404,10 @@ class PDFEngine { ...@@ -391,6 +404,10 @@ class PDFEngine {
// ranges and bounding boxes. // ranges and bounding boxes.
virtual std::vector<AccessibilityHighlightInfo> GetHighlightInfo( virtual std::vector<AccessibilityHighlightInfo> GetHighlightInfo(
int page_index) = 0; 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 // Gets the PDF document's print scaling preference. True if the document can
// be scaled to fit. // be scaled to fit.
......
...@@ -523,6 +523,68 @@ TEST_F(AccessibilityTest, GetAccessibilityHighlightInfo) { ...@@ -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) { TEST_F(AccessibilityTest, TestSelectionActionHandling) {
struct Selection { struct Selection {
uint32_t start_page_index; uint32_t start_page_index;
......
...@@ -390,6 +390,13 @@ void ShutdownSDK() { ...@@ -390,6 +390,13 @@ void ShutdownSDK() {
TearDownV8(); 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, std::unique_ptr<PDFEngine> PDFEngine::Create(PDFEngine::Client* client,
bool enable_javascript) { bool enable_javascript) {
return std::make_unique<PDFiumEngine>(client, enable_javascript); return std::make_unique<PDFiumEngine>(client, enable_javascript);
...@@ -2332,6 +2339,12 @@ PDFiumEngine::GetHighlightInfo(int page_index) { ...@@ -2332,6 +2339,12 @@ PDFiumEngine::GetHighlightInfo(int page_index) {
return pages_[page_index]->GetHighlightInfo(); 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() { bool PDFiumEngine::GetPrintScaling() {
return !!FPDF_VIEWERREF_GetPrintScaling(doc()); return !!FPDF_VIEWERREF_GetPrintScaling(doc());
} }
......
...@@ -123,6 +123,8 @@ class PDFiumEngine : public PDFEngine, ...@@ -123,6 +123,8 @@ class PDFiumEngine : public PDFEngine,
std::vector<AccessibilityImageInfo> GetImageInfo(int page_index) override; std::vector<AccessibilityImageInfo> GetImageInfo(int page_index) override;
std::vector<AccessibilityHighlightInfo> GetHighlightInfo( std::vector<AccessibilityHighlightInfo> GetHighlightInfo(
int page_index) override; int page_index) override;
std::vector<AccessibilityTextFieldInfo> GetTextFieldInfo(
int page_index) override;
bool GetPrintScaling() override; bool GetPrintScaling() override;
int GetCopiesToPrint() override; int GetCopiesToPrint() override;
int GetDuplexType() override; int GetDuplexType() override;
......
...@@ -602,6 +602,30 @@ PDFiumPage::GetHighlightInfo() { ...@@ -602,6 +602,30 @@ PDFiumPage::GetHighlightInfo() {
return highlight_info; 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, PDFiumPage::Area PDFiumPage::GetLinkTargetAtIndex(int link_index,
LinkTarget* target) { LinkTarget* target) {
if (!available_ || link_index < 0) if (!available_ || link_index < 0)
......
...@@ -60,6 +60,9 @@ class PDFiumPage { ...@@ -60,6 +60,9 @@ class PDFiumPage {
// For all the highlights on the page, get their underlying text ranges and // For all the highlights on the page, get their underlying text ranges and
// bounding boxes. // bounding boxes.
std::vector<PDFEngine::AccessibilityHighlightInfo> GetHighlightInfo(); 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 { enum Area {
NONSELECTABLE_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