Commit cf548d4a authored by Ankit Kumar's avatar Ankit Kumar Committed by Commit Bot

Add text after overlapping annotations in accessibility tree

This CL fixes the issue where text runs after overlapping annotations
are not added to the accessibility tree. In the loop where text runs are
added to the accessibility tree, some text runs are skipped due to
incorrect normalization after overlapping annotations are added to the
tree.

Tests have been added to validate the scenario.

Fixed: 1066802
Change-Id: I6e7b3c72d9c25c45033a057d44261e888e9e7796
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2131808Reviewed-by: default avatarKevin Babbitt <kbabbitt@microsoft.com>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Commit-Queue: Ankit Kumar 🌪️ <ankk@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#755928}
parent b3e00d1a
...@@ -2564,6 +2564,12 @@ IN_PROC_BROWSER_TEST_F(PDFExtensionAccessibilityTextExtractionTest, ...@@ -2564,6 +2564,12 @@ IN_PROC_BROWSER_TEST_F(PDFExtensionAccessibilityTextExtractionTest,
RunTextExtractionTest(FILE_PATH_LITERAL("text-image-link.pdf")); RunTextExtractionTest(FILE_PATH_LITERAL("text-image-link.pdf"));
} }
// Test data of inline text boxes for PDF with overlapping annotations.
IN_PROC_BROWSER_TEST_F(PDFExtensionAccessibilityTextExtractionTest,
OverlappingAnnots) {
RunTextExtractionTest(FILE_PATH_LITERAL("overlapping-annots.pdf"));
}
class PDFExtensionAccessibilityTreeDumpTest class PDFExtensionAccessibilityTreeDumpTest
: public PDFExtensionTest, : public PDFExtensionTest,
public ::testing::WithParamInterface<size_t> { public ::testing::WithParamInterface<size_t> {
......
Overlapping link text,
link text,
some text after link texts.
\ No newline at end of file
{{header}}
{{object 1 0}} <<
/Type /Catalog
/Pages 2 0 R
>>
endobj
{{object 2 0}} <<
/Type /Pages
/MediaBox [0 0 612 792]
/CropBox [0 0 612 792]
/Count 1
/Kids [3 0 R]
/Resources <<
/Font <<
/F1 4 0 R
>>
>>
>>
endobj
{{object 3 0}} <<
/Type /Page
/Parent 2 0 R
/Contents 5 0 R
/Annots [6 0 R 7 0 R]
>>
endobj
{{object 4 0}} <<
/Type /Font
/Subtype /Type1
/BaseFont /Times-Roman
>>
endobj
{{object 5 0}} <<
{{streamlen}}
>>
stream
BT
70 700 Td
/F1 12 Tf
(Overlapping link text, some text after link texts.) Tj
ET
endstream
endobj
{{object 6 0}} <<
/Type /Annot
/Subtype /Link
/Rect [70 698 175 710]
/A <<
/Type /Action
/S /URI
/URI (https://www.bing.com)
>>
/F 4
>>
endobj
{{object 7 0}} <<
/Type /Annot
/Subtype /Link
/Rect [133 698 175 710]
/A <<
/Type /Action
/S /URI
/URI (https://www.adobe.com)
>>
/F 4
>>
endobj
{{xref}}
{{trailer}}
{{startxref}}
%%EOF
\ No newline at end of file
This diff was suppressed by a .gitattributes entry.
...@@ -282,6 +282,13 @@ bool IsObjectInTextRun(const std::vector<T>& objects, ...@@ -282,6 +282,13 @@ bool IsObjectInTextRun(const std::vector<T>& objects,
objects[object_index].text_run_index <= text_run_index); objects[object_index].text_run_index <= text_run_index);
} }
size_t NormalizeTextRunIndex(uint32_t object_end_text_run_index,
size_t current_text_run_index) {
return std::max<size_t>(
object_end_text_run_index,
current_text_run_index ? current_text_run_index - 1 : 0);
}
bool IsTextRenderModeFill(const PP_TextRenderingMode& mode) { bool IsTextRenderModeFill(const PP_TextRenderingMode& mode) {
switch (mode) { switch (mode) {
case PP_TEXTRENDERINGMODE_FILL: case PP_TEXTRENDERINGMODE_FILL:
...@@ -567,7 +574,7 @@ void PdfAccessibilityTree::AddPageContent( ...@@ -567,7 +574,7 @@ void PdfAccessibilityTree::AddPageContent(
link_node->relative_bounds.bounds); link_node->relative_bounds.bounds);
text_run_index = text_run_index =
std::max<size_t>(link_end_text_run_index, text_run_index); NormalizeTextRunIndex(link_end_text_run_index, text_run_index);
} else if (IsObjectInTextRun(images, current_image_index, text_run_index)) { } else if (IsObjectInTextRun(images, current_image_index, text_run_index)) {
FinishStaticNode(&static_text_node, &static_text); FinishStaticNode(&static_text_node, &static_text);
// If the |text_run_index| is less than or equal to the image's text run // If the |text_run_index| is less than or equal to the image's text run
...@@ -604,7 +611,7 @@ void PdfAccessibilityTree::AddPageContent( ...@@ -604,7 +611,7 @@ void PdfAccessibilityTree::AddPageContent(
highlight_node->relative_bounds.bounds); highlight_node->relative_bounds.bounds);
text_run_index = text_run_index =
std::max<size_t>(highlight_end_text_run_index, text_run_index); NormalizeTextRunIndex(highlight_end_text_run_index, text_run_index);
} else if (IsObjectInTextRun(text_fields, current_text_field_index, } else if (IsObjectInTextRun(text_fields, current_text_field_index,
text_run_index) && text_run_index) &&
base::FeatureList::IsEnabled( base::FeatureList::IsEnabled(
......
...@@ -348,6 +348,99 @@ TEST_F(PdfAccessibilityTreeTest, TestPdfAccessibilityTreeCreation) { ...@@ -348,6 +348,99 @@ TEST_F(PdfAccessibilityTreeTest, TestPdfAccessibilityTreeCreation) {
image_node->GetStringAttribute(ax::mojom::StringAttribute::kName)); image_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
} }
TEST_F(PdfAccessibilityTreeTest, TestOverlappingAnnots) {
text_runs_.emplace_back(kFirstRunMultiLine);
text_runs_.emplace_back(kSecondRunMultiLine);
text_runs_.emplace_back(kThirdRunMultiLine);
text_runs_.emplace_back(kFourthRunMultiLine);
chars_.insert(chars_.end(), std::begin(kDummyCharsData),
std::end(kDummyCharsData));
{
ppapi::PdfAccessibilityLinkInfo link;
link.bounds = PP_MakeFloatRectFromXYWH(1.0f, 1.0f, 5.0f, 6.0f);
link.url = kChromiumTestUrl;
link.text_run_index = 0;
link.text_run_count = 3;
page_objects_.links.push_back(std::move(link));
}
{
ppapi::PdfAccessibilityLinkInfo link;
link.bounds = PP_MakeFloatRectFromXYWH(1.0f, 2.0f, 5.0f, 6.0f);
link.url = kChromiumTestUrl;
link.text_run_index = 1;
link.text_run_count = 2;
page_objects_.links.push_back(std::move(link));
}
page_info_.text_run_count = text_runs_.size();
page_info_.char_count = chars_.size();
content::RenderFrame* render_frame = view_->GetMainRenderFrame();
ASSERT_TRUE(render_frame);
render_frame->SetAccessibilityModeForTest(ui::AXMode::kWebContents);
ASSERT_TRUE(render_frame->GetRenderAccessibility());
FakeRendererPpapiHost host(view_->GetMainRenderFrame());
PP_Instance instance = 0;
pdf::PdfAccessibilityTree pdf_accessibility_tree(&host, instance);
pdf_accessibility_tree.SetAccessibilityViewportInfo(viewport_info_);
pdf_accessibility_tree.SetAccessibilityDocInfo(doc_info_);
pdf_accessibility_tree.SetAccessibilityPageInfo(page_info_, text_runs_,
chars_, page_objects_);
/*
* Expected tree structure
* Document
* ++ Region
* ++++ Paragraph
* ++++++ Link
* ++++++ Link
* ++++++ Static Text
*/
ui::AXNode* root_node = pdf_accessibility_tree.GetRoot();
ASSERT_TRUE(root_node);
EXPECT_EQ(ax::mojom::Role::kDocument, root_node->data().role);
ASSERT_EQ(1u, root_node->children().size());
ui::AXNode* page_node = root_node->children()[0];
ASSERT_TRUE(page_node);
EXPECT_EQ(ax::mojom::Role::kRegion, page_node->data().role);
ASSERT_EQ(1u, page_node->children().size());
ui::AXNode* paragraph_node = page_node->children()[0];
ASSERT_TRUE(paragraph_node);
EXPECT_EQ(ax::mojom::Role::kParagraph, paragraph_node->data().role);
const std::vector<ui::AXNode*>& child_nodes = paragraph_node->children();
ASSERT_EQ(3u, child_nodes.size());
ui::AXNode* link_node = child_nodes[0];
ASSERT_TRUE(link_node);
EXPECT_EQ(kChromiumTestUrl,
link_node->GetStringAttribute(ax::mojom::StringAttribute::kUrl));
EXPECT_EQ(ax::mojom::Role::kLink, link_node->data().role);
EXPECT_EQ(gfx::RectF(1.0f, 1.0f, 5.0f, 6.0f),
link_node->data().relative_bounds.bounds);
ASSERT_EQ(1u, link_node->children().size());
link_node = child_nodes[1];
ASSERT_TRUE(link_node);
EXPECT_EQ(kChromiumTestUrl,
link_node->GetStringAttribute(ax::mojom::StringAttribute::kUrl));
EXPECT_EQ(ax::mojom::Role::kLink, link_node->data().role);
EXPECT_EQ(gfx::RectF(1.0f, 2.0f, 5.0f, 6.0f),
link_node->data().relative_bounds.bounds);
ASSERT_EQ(1u, link_node->children().size());
ui::AXNode* static_text_node = child_nodes[2];
ASSERT_TRUE(static_text_node);
EXPECT_EQ(ax::mojom::Role::kStaticText, static_text_node->data().role);
ASSERT_EQ(1u, static_text_node->children().size());
}
TEST_F(PdfAccessibilityTreeTest, TestHighlightCreation) { TEST_F(PdfAccessibilityTreeTest, TestHighlightCreation) {
// Enable feature flag // Enable feature flag
base::test::ScopedFeatureList scoped_feature_list; base::test::ScopedFeatureList scoped_feature_list;
......
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