0

Pass highlight information to mimehandler process for accessibility

This CL adds support for passing text highlight information from
PDFiumEngine to mimehandler process using appropriate
AccessibilityHighlightInfo structs. Add
GetAccessibilityHighlightInfo() which works similar to
GetAccessibilityLinkInfo() called from within GetAccessibilityInfo() in
pdf/accessibility.cc. Also includes corresponding unit test.

Bug: 1008775
Change-Id: I7916177fef5e864f0e3b4b0a0b8c1693bf09f19c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1871492
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Kalpak Tapas <katapas@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#720886}
This commit is contained in:
Kalpak Tapas
2019-12-03 09:12:43 +00:00
committed by Commit Bot
parent 8d310c790d
commit d99d676686
7 changed files with 119 additions and 1 deletions

@ -56,6 +56,11 @@ bool GetEnclosingTextRunRangeForCharRange(
return false;
}
template <typename T>
bool CompareTextRuns(const T& a, const T& b) {
return a.text_run_index < b.text_run_index;
}
void GetAccessibilityLinkInfo(
PDFEngine* engine,
int32_t page_index,
@ -105,6 +110,36 @@ void GetAccessibilityImageInfo(
}
}
void GetAccessibilityHighlightInfo(
PDFEngine* engine,
int32_t page_index,
const std::vector<pp::PDF::PrivateAccessibilityTextRunInfo>& text_runs,
std::vector<pp::PDF::PrivateAccessibilityHighlightInfo>* highlights) {
std::vector<PDFEngine::AccessibilityHighlightInfo> engine_highlight_info =
engine->GetHighlightInfo(page_index);
for (size_t i = 0; i < engine_highlight_info.size(); ++i) {
auto& cur_highlight_info = engine_highlight_info[i];
pp::PDF::PrivateAccessibilityHighlightInfo highlight_info;
highlight_info.index_in_page = i;
highlight_info.bounds = std::move(cur_highlight_info.bounds);
if (!GetEnclosingTextRunRangeForCharRange(
text_runs, cur_highlight_info.start_char_index,
cur_highlight_info.char_count, &highlight_info.text_run_index,
&highlight_info.text_run_count)) {
// If a valid text run range is not found for the highlight, set the
// fallback values of |text_run_index| and |text_run_count| for
// |highlight_info|.
highlight_info.text_run_index = text_runs.size();
highlight_info.text_run_count = 0;
}
highlights->push_back(std::move(highlight_info));
}
std::sort(highlights->begin(), highlights->end(),
CompareTextRuns<pp::PDF::PrivateAccessibilityHighlightInfo>);
}
} // namespace
bool GetAccessibilityInfo(
@ -191,7 +226,8 @@ bool GetAccessibilityInfo(
&page_objects->links);
GetAccessibilityImageInfo(engine, page_index, page_info->text_run_count,
&page_objects->images);
// TODO(crbug.com/1008775): Populate highlights
GetAccessibilityHighlightInfo(engine, page_index, *text_runs,
&page_objects->highlights);
return true;
}

@ -296,6 +296,12 @@ class PDFEngine {
pp::FloatRect bounds;
};
struct AccessibilityHighlightInfo {
int start_char_index = -1;
int char_count;
pp::FloatRect bounds;
};
// Factory method to create an instance of the PDF Engine.
static std::unique_ptr<PDFEngine> Create(Client* client,
bool enable_javascript);
@ -399,6 +405,11 @@ class PDFEngine {
// For all the images in page |page_index|, get their alt texts and bounding
// boxes.
virtual std::vector<AccessibilityImageInfo> GetImageInfo(int page_index) = 0;
// For all the highlights in page |page_index|, get their underlying text
// ranges and bounding boxes.
virtual std::vector<AccessibilityHighlightInfo> GetHighlightInfo(
int page_index) = 0;
// Gets the PDF document's print scaling preference. True if the document can
// be scaled to fit.
virtual bool GetPrintScaling() = 0;

@ -455,4 +455,43 @@ TEST_F(AccessibilityTest, GetAccessibilityLinkInfo) {
}
}
TEST_F(AccessibilityTest, GetAccessibilityHighlightInfo) {
static const pp::PDF::PrivateAccessibilityHighlightInfo
kExpectedHighlightInfo[] = {{"", 0, 0, 1, {{5, 196}, {49, 26}}},
{"", 1, 2, 1, {{110, 196}, {77, 26}}},
{"", 2, 3, 1, {{192, 196}, {13, 26}}}};
static const pp::Rect kExpectedPageRect = {{5, 3}, {533, 266}};
TestClient client;
std::unique_ptr<PDFiumEngine> engine =
InitializeEngine(&client, FILE_PATH_LITERAL("highlights.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.highlights.size(), base::size(kExpectedHighlightInfo));
for (size_t i = 0; i < page_objects.highlights.size(); ++i) {
const pp::PDF::PrivateAccessibilityHighlightInfo& highlight_info =
page_objects.highlights[i];
EXPECT_EQ(highlight_info.index_in_page,
kExpectedHighlightInfo[i].index_in_page);
CompareRect(kExpectedHighlightInfo[i].bounds, highlight_info.bounds);
EXPECT_EQ(highlight_info.text_run_index,
kExpectedHighlightInfo[i].text_run_index);
EXPECT_EQ(highlight_info.text_run_count,
kExpectedHighlightInfo[i].text_run_count);
}
}
} // namespace chrome_pdf

@ -2301,6 +2301,12 @@ std::vector<PDFEngine::AccessibilityImageInfo> PDFiumEngine::GetImageInfo(
return pages_[page_index]->GetImageInfo();
}
std::vector<PDFEngine::AccessibilityHighlightInfo>
PDFiumEngine::GetHighlightInfo(int page_index) {
DCHECK(PageIndexInBounds(page_index));
return pages_[page_index]->GetHighlightInfo();
}
bool PDFiumEngine::GetPrintScaling() {
return !!FPDF_VIEWERREF_GetPrintScaling(doc());
}

@ -119,6 +119,8 @@ class PDFiumEngine : public PDFEngine,
int start_char_index) override;
std::vector<AccessibilityLinkInfo> GetLinkInfo(int page_index) override;
std::vector<AccessibilityImageInfo> GetImageInfo(int page_index) override;
std::vector<AccessibilityHighlightInfo> GetHighlightInfo(
int page_index) override;
bool GetPrintScaling() override;
int GetCopiesToPrint() override;
int GetDuplexType() override;

@ -570,6 +570,27 @@ std::vector<PDFEngine::AccessibilityImageInfo> PDFiumPage::GetImageInfo() {
return image_info;
}
std::vector<PDFEngine::AccessibilityHighlightInfo>
PDFiumPage::GetHighlightInfo() {
std::vector<PDFEngine::AccessibilityHighlightInfo> highlight_info;
if (!available_)
return highlight_info;
PopulateHighlights();
highlight_info.reserve(highlights_.size());
for (const Highlight& highlight : highlights_) {
PDFEngine::AccessibilityHighlightInfo cur_info;
cur_info.start_char_index = highlight.start_char_index;
cur_info.char_count = highlight.char_count;
cur_info.bounds = pp::FloatRect(
highlight.bounding_rect.x(), highlight.bounding_rect.y(),
highlight.bounding_rect.width(), highlight.bounding_rect.height());
highlight_info.push_back(std::move(cur_info));
}
return highlight_info;
}
PDFiumPage::Area PDFiumPage::GetLinkTargetAtIndex(int link_index,
LinkTarget* target) {
if (!available_ || link_index < 0)

@ -57,6 +57,9 @@ class PDFiumPage {
std::vector<PDFEngine::AccessibilityLinkInfo> GetLinkInfo();
// For all the images on the page, get their alt texts and bounding boxes.
std::vector<PDFEngine::AccessibilityImageInfo> GetImageInfo();
// For all the highlights on the page, get their underlying text ranges and
// bounding boxes.
std::vector<PDFEngine::AccessibilityHighlightInfo> GetHighlightInfo();
enum Area {
NONSELECTABLE_AREA,