0

Pdf a11y: Populate AXNode with new text style info

This change fills the font-family, font-size, font-weight, italic, bold
and color attributes of the AXNode with exposed values from the PDFium
APIs.

I've also added a PDF accessibility tree dump test using the filter
properties to dump those attributes in the expected file. The test file
is "text-style.pdf".

Somehow, I added in a previous change text-format-expected-blink.txt.
This file should have never been committed. I removed it in this CL.

Bug: 985604
Change-Id: I70a4729269aea69e184e61710d7977425b431704
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1755412
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Bill Budge <bbudge@chromium.org>
Reviewed-by: Ian Prest <iapres@microsoft.com>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#711942}
This commit is contained in:
Benjamin Beaudry
2019-11-02 00:21:14 +00:00
committed by Commit Bot
parent 1452547a0a
commit cc4f1e5fe4
17 changed files with 351 additions and 21 deletions

@ -2622,3 +2622,7 @@ IN_PROC_BROWSER_TEST_P(PDFExtensionAccessibilityTreeDumpTest,
TextRunStyleHeuristic) {
RunPDFTest(FILE_PATH_LITERAL("text-run-style-heuristic.pdf"));
}
IN_PROC_BROWSER_TEST_P(PDFExtensionAccessibilityTreeDumpTest, TextStyle) {
RunPDFTest(FILE_PATH_LITERAL("text-style.pdf"));
}

@ -1,15 +0,0 @@
embeddedObject fontFamily='Roboto' color=-16777216 fontSize=13.00 fontWeight=400.00
++document fontFamily='Roboto' restriction=readOnly
++++region fontFamily='Roboto' name='Page 1' restriction=readOnly isPageBreakingObject=true
++++++paragraph fontFamily='Roboto' restriction=readOnly
++++++++staticText fontFamily='Roboto' name='Case 1<newline>' restriction=readOnly
++++++++++inlineTextBox fontFamily='Helvetica-Bold-Italic' name='Case 1<newline>' restriction=readOnly color=-65536 fontSize=38.00 fontWeight=600.00
++++++paragraph fontFamily='Roboto' restriction=readOnly
++++++++staticText fontFamily='Roboto' name='Case 2<newline>' restriction=readOnly
++++++++++inlineTextBox fontFamily='Helvetica-Bold-Italic' name='Case 2<newline>' restriction=readOnly color=-16711936 fontSize=38.00 fontWeight=600.00
++++++paragraph fontFamily='Roboto' restriction=readOnly
++++++++staticText fontFamily='Roboto' name='Case 3<newline>' restriction=readOnly
++++++++++inlineTextBox fontFamily='Helvetica-Bold-Italic' name='Case 3<newline>' restriction=readOnly color=-65536 fontSize=38.00 fontWeight=600.00
++++++paragraph fontFamily='Roboto' restriction=readOnly
++++++++staticText fontFamily='Roboto' name='Case 4' restriction=readOnly
++++++++++inlineTextBox fontFamily='Helvetica-Bold-Italic' name='Case 4' restriction=readOnly fontSize=38.00 fontWeight=600.00

@ -0,0 +1,11 @@
[embedded component]
++[document frame]
++++[landmark] name='Page 1'
++++++[paragraph]
++++++++[text] name='Case 1<newline>'
++++++[paragraph]
++++++++[text] name='Case 2<newline>'
++++++[paragraph]
++++++++[text] name='Case 3<newline>'
++++++[paragraph]
++++++++[text] name='Case 4'

@ -0,0 +1,15 @@
embeddedObject color=-16777216
++document restriction=readOnly
++++region name='Page 1' restriction=readOnly isPageBreakingObject=true
++++++paragraph restriction=readOnly
++++++++staticText name='Case 1<newline>' restriction=readOnly
++++++++++inlineTextBox fontFamily='Helvetica-Bold-Italic' name='Case 1<newline>' restriction=readOnly color=-65536 fontSize=38.00 fontWeight=800.00
++++++paragraph restriction=readOnly
++++++++staticText name='Case 2<newline>' restriction=readOnly
++++++++++inlineTextBox fontFamily='Helvetica-Bold-Italic' name='Case 2<newline>' restriction=readOnly color=-16711936 fontSize=38.00 fontWeight=800.00
++++++paragraph restriction=readOnly
++++++++staticText name='Case 3<newline>' restriction=readOnly
++++++++++inlineTextBox fontFamily='Helvetica-Bold-Italic' name='Case 3<newline>' restriction=readOnly color=-65536 fontSize=38.00 fontWeight=800.00
++++++paragraph restriction=readOnly
++++++++staticText name='Case 4' restriction=readOnly
++++++++++inlineTextBox fontFamily='Helvetica-Bold-Italic' name='Case 4' restriction=readOnly fontSize=38.00 fontWeight=800.00

@ -0,0 +1,11 @@
AXGroup AXDescription='Page 1'
++AXGroup
++++AXGroup AXDescription='Page 1'
++++++AXGroup
++++++++AXStaticText AXValue='Case 1<newline>'
++++++AXGroup
++++++++AXStaticText AXValue='Case 2<newline>'
++++++AXGroup
++++++++AXStaticText AXValue='Case 3<newline>'
++++++AXGroup
++++++++AXStaticText AXValue='Case 4'

@ -0,0 +1,11 @@
group
++document
++++region Name='Page 1'
++++++group
++++++++description Name='Case 1<newline>'
++++++group
++++++++description Name='Case 2<newline>'
++++++group
++++++++description Name='Case 3<newline>'
++++++group
++++++++description Name='Case 4'

@ -0,0 +1,11 @@
ROLE_SYSTEM_GROUPING FOCUSABLE
++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++++IA2_ROLE_LANDMARK name='Page 1' READONLY
++++++IA2_ROLE_PARAGRAPH READONLY
++++++++ROLE_SYSTEM_STATICTEXT name='Case 1<newline>' READONLY
++++++IA2_ROLE_PARAGRAPH READONLY
++++++++ROLE_SYSTEM_STATICTEXT name='Case 2<newline>' READONLY
++++++IA2_ROLE_PARAGRAPH READONLY
++++++++ROLE_SYSTEM_STATICTEXT name='Case 3<newline>' READONLY
++++++IA2_ROLE_PARAGRAPH READONLY
++++++++ROLE_SYSTEM_STATICTEXT name='Case 4' READONLY

@ -0,0 +1,92 @@
{{header}}
%@BLINK-ALLOW:fontFamily='Helvetica-Bold-Italic'
%@BLINK-ALLOW:fontSize=38.00
%@BLINK-ALLOW:fontWeight=800.00
%@BLINK-ALLOW:color=*
{{object 1 0}} <<
/Type /Catalog
/Pages 2 0 R
>>
endobj
{{object 2 0}} <<
/Type /Pages
/MediaBox [ 0 0 200 200 ]
/Count 1
/Kids [ 3 0 R ]
>>
endobj
{{object 3 0}} <<
/Type /Page
/Parent 2 0 R
/Resources <<
/Font <<
/F1 4 0 R
>>
>>
/Contents 6 0 R
>>
endobj
{{object 4 0}} <<
/Type /Font
/Subtype /Type1
/BaseFont /Helvetica-Bold-Italic
/FontDescriptor 5 0 R
>>
{{object 5 0}} <<
/Type /FontDescriptor
/FontName /Helvetica-Bold-Italic
/FontWeight 800
/StemV 165
/ItalicAngle 45
/Ascent 776
/Flags 64
/FontBBox [ -250 -236 2827 1000 ]
/CapHeight 763
/Descent -223
>>
endobj
{{object 6 0}} <<
{{streamlen}}
>>
stream
BT
20 150 Td
/F1 38 Tf
0 1 0 RG
1 0 0 rg
0 Tr
(Case 1) Tj
ET
BT
20 110 Td
/F1 38 Tf
0 1 0 RG
1 0 0 rg
1 Tr
(Case 2) Tj
ET
BT
20 70 Td
/F1 38 Tf
0 1 0 RG
1 0 0 rg
2 Tr
(Case 3) Tj
ET
BT
20 30 Td
/F1 38 Tf
0 1 0 RG
1 0 0 rg
3 Tr
(Case 4) Tj
ET
endstream
endobj
{{xref}}
{{trailer}}
{{startxref}}
%%EOF

@ -0,0 +1,105 @@
%PDF-1.7
%<25><><EFBFBD><EFBFBD>
%@BLINK-ALLOW:fontFamily='Helvetica-Bold-Italic'
%@BLINK-ALLOW:fontSize=38.00
%@BLINK-ALLOW:fontWeight=800.00
%@BLINK-ALLOW:color=*
1 0 obj <<
/Type /Catalog
/Pages 2 0 R
>>
endobj
2 0 obj <<
/Type /Pages
/MediaBox [ 0 0 200 200 ]
/Count 1
/Kids [ 3 0 R ]
>>
endobj
3 0 obj <<
/Type /Page
/Parent 2 0 R
/Resources <<
/Font <<
/F1 4 0 R
>>
>>
/Contents 6 0 R
>>
endobj
4 0 obj <<
/Type /Font
/Subtype /Type1
/BaseFont /Helvetica-Bold-Italic
/FontDescriptor 5 0 R
>>
5 0 obj <<
/Type /FontDescriptor
/FontName /Helvetica-Bold-Italic
/FontWeight 800
/StemV 165
/ItalicAngle 45
/Ascent 776
/Flags 64
/FontBBox [ -250 -236 2827 1000 ]
/CapHeight 763
/Descent -223
>>
endobj
6 0 obj <<
/Length 245
>>
stream
BT
20 150 Td
/F1 38 Tf
0 1 0 RG
1 0 0 rg
0 Tr
(Case 1) Tj
ET
BT
20 110 Td
/F1 38 Tf
0 1 0 RG
1 0 0 rg
1 Tr
(Case 2) Tj
ET
BT
20 70 Td
/F1 38 Tf
0 1 0 RG
1 0 0 rg
2 Tr
(Case 3) Tj
ET
BT
20 30 Td
/F1 38 Tf
0 1 0 RG
1 0 0 rg
3 Tr
(Case 4) Tj
ET
endstream
endobj
xref
0 7
0000000000 65535 f
0000000147 00000 n
0000000200 00000 n
0000000293 00000 n
0000000419 00000 n
0000000524 00000 n
0000000748 00000 n
trailer <<
/Root 1 0 R
/Size 7
>>
startxref
1045
%%EOF

@ -206,6 +206,30 @@ bool IsObjectInTextRun(const std::vector<T>& objects,
objects[object_index].text_run_index <= text_run_index);
}
bool IsTextRenderModeFill(const PP_TextRenderingMode& mode) {
switch (mode) {
case PP_TEXTRENDERINGMODE_FILL:
case PP_TEXTRENDERINGMODE_FILLSTROKE:
case PP_TEXTRENDERINGMODE_FILLCLIP:
case PP_TEXTRENDERINGMODE_FILLSTROKECLIP:
return true;
default:
return false;
}
}
bool IsTextRenderModeStroke(const PP_TextRenderingMode& mode) {
switch (mode) {
case PP_TEXTRENDERINGMODE_STROKE:
case PP_TEXTRENDERINGMODE_FILLSTROKE:
case PP_TEXTRENDERINGMODE_STROKECLIP:
case PP_TEXTRENDERINGMODE_FILLSTROKECLIP:
return true;
default:
return false;
}
}
} // namespace
PdfAccessibilityTree::PdfAccessibilityTree(content::RendererPpapiHost* host,
@ -699,6 +723,24 @@ ui::AXNodeData* PdfAccessibilityTree::CreateInlineTextBoxNode(
chars_utf8);
inline_text_box_node->AddIntAttribute(ax::mojom::IntAttribute::kTextDirection,
text_run.direction);
inline_text_box_node->AddStringAttribute(
ax::mojom::StringAttribute::kFontFamily, text_run.style.font_name);
inline_text_box_node->AddFloatAttribute(ax::mojom::FloatAttribute::kFontSize,
text_run.style.font_size);
inline_text_box_node->AddFloatAttribute(
ax::mojom::FloatAttribute::kFontWeight, text_run.style.font_weight);
if (text_run.style.is_italic)
inline_text_box_node->AddTextStyle(ax::mojom::TextStyle::kItalic);
if (text_run.style.is_bold)
inline_text_box_node->AddTextStyle(ax::mojom::TextStyle::kBold);
if (IsTextRenderModeFill(text_run.style.render_mode)) {
inline_text_box_node->AddIntAttribute(ax::mojom::IntAttribute::kColor,
text_run.style.fill_color);
} else if (IsTextRenderModeStroke(text_run.style.render_mode)) {
inline_text_box_node->AddIntAttribute(ax::mojom::IntAttribute::kColor,
text_run.style.stroke_color);
}
inline_text_box_node->relative_bounds.bounds =
ToGfxRectF(text_run.bounds) + page_bounds.OffsetFromOrigin();
std::vector<int32_t> char_offsets =

@ -10,6 +10,7 @@
#include "third_party/pdfium/public/fpdf_edit.h"
#include "third_party/pdfium/public/fpdf_fwlevent.h"
#include "third_party/pdfium/public/fpdf_sysfontinfo.h"
#include "third_party/pdfium/public/fpdfview.h"
#include "ui/events/keycodes/keyboard_codes.h"
#define STATIC_ASSERT_ENUM(a, b) \
@ -214,6 +215,20 @@ STATIC_ASSERT_ENUM(PP_PRIVATEDUPLEXMODE_SIMPLEX, Simplex);
STATIC_ASSERT_ENUM(PP_PRIVATEDUPLEXMODE_SHORT_EDGE, DuplexFlipShortEdge);
STATIC_ASSERT_ENUM(PP_PRIVATEDUPLEXMODE_LONG_EDGE, DuplexFlipLongEdge);
STATIC_ASSERT_ENUM(PP_TEXTRENDERINGMODE_FILL, FPDF_TEXTRENDERMODE_FILL);
STATIC_ASSERT_ENUM(PP_TEXTRENDERINGMODE_STROKE, FPDF_TEXTRENDERMODE_STROKE);
STATIC_ASSERT_ENUM(PP_TEXTRENDERINGMODE_FILLSTROKE,
FPDF_TEXTRENDERMODE_FILL_STROKE);
STATIC_ASSERT_ENUM(PP_TEXTRENDERINGMODE_INVISIBLE,
FPDF_TEXTRENDERMODE_INVISIBLE);
STATIC_ASSERT_ENUM(PP_TEXTRENDERINGMODE_FILLCLIP,
FPDF_TEXTRENDERMODE_FILL_CLIP);
STATIC_ASSERT_ENUM(PP_TEXTRENDERINGMODE_STROKECLIP,
FPDF_TEXTRENDERMODE_STROKE_CLIP);
STATIC_ASSERT_ENUM(PP_TEXTRENDERINGMODE_FILLSTROKECLIP,
FPDF_TEXTRENDERMODE_FILL_STROKE_CLIP);
STATIC_ASSERT_ENUM(PP_TEXTRENDERINGMODE_CLIP, FPDF_TEXTRENDERMODE_CLIP);
#if defined(OS_WIN)
STATIC_ASSERT_ENUM(chrome_pdf::kEmf, FPDF_PRINTMODE_EMF);
STATIC_ASSERT_ENUM(chrome_pdf::kTextOnly, FPDF_PRINTMODE_TEXTONLY);

@ -323,7 +323,12 @@ void PDFiumPage::CalculateTextRunStyleInfo(
style_info->stroke_color = MakeARGB(0xff, 0, 0, 0);
}
style_info->render_mode = FPDFText_GetTextRenderMode(text_page, char_index);
int render_mode = FPDFText_GetTextRenderMode(text_page, char_index);
if (render_mode < 0 || render_mode > PP_TEXTRENDERINGMODE_LAST) {
style_info->render_mode = PP_TEXTRENDERINGMODE_UNKNOWN;
} else {
style_info->render_mode = static_cast<PP_TextRenderingMode>(render_mode);
}
}
bool PDFiumPage::AreTextStyleEqual(

@ -207,9 +207,17 @@ TEST_F(PDFiumPageTextTest, GetTextRunInfo) {
int current_char_index = 0;
pp::PDF::PrivateAccessibilityTextStyleInfo expected_style_1 = {
"Times-Roman", 0, 0, 12, 0xff000000, 0xff000000, false, false};
"Times-Roman",
0,
PP_TEXTRENDERINGMODE_FILL,
12,
0xff000000,
0xff000000,
false,
false};
pp::PDF::PrivateAccessibilityTextStyleInfo expected_style_2 = {
"Helvetica", 0, 0, 16, 0xff000000, 0xff000000, false, false};
"Helvetica", 0, PP_TEXTRENDERINGMODE_FILL, 16, 0xff000000, 0xff000000,
false, false};
// The links span from [7, 22], [52, 66] and [92, 108] with 16, 15 and 17
// text run lengths respectively. There are text runs preceding and
// succeeding them.

@ -67,6 +67,20 @@ struct PP_PrivateAccessibilityPageInfo {
uint32_t image_count;
};
// See PDF Reference 1.7, page 402, table 5.3.
typedef enum {
PP_TEXTRENDERINGMODE_UNKNOWN = -1,
PP_TEXTRENDERINGMODE_FILL = 0,
PP_TEXTRENDERINGMODE_STROKE = 1,
PP_TEXTRENDERINGMODE_FILLSTROKE = 2,
PP_TEXTRENDERINGMODE_INVISIBLE = 3,
PP_TEXTRENDERINGMODE_FILLCLIP = 4,
PP_TEXTRENDERINGMODE_STROKECLIP = 5,
PP_TEXTRENDERINGMODE_FILLSTROKECLIP = 6,
PP_TEXTRENDERINGMODE_CLIP = 7,
PP_TEXTRENDERINGMODE_LAST = PP_TEXTRENDERINGMODE_CLIP
} PP_TextRenderingMode;
// This holds the text style information provided by the PDF and will be used
// in accessibility to provide the text style information. Needs to stay in
// sync with C++ version. (PrivateAccessibilityTextStyleInfo and
@ -75,7 +89,7 @@ struct PP_PrivateAccessibilityTextStyleInfo {
const char* font_name;
uint32_t font_name_length;
int font_weight;
int render_mode;
PP_TextRenderingMode render_mode;
double font_size;
// Colors are ARGB.
uint32_t fill_color;

@ -27,7 +27,7 @@ class PDF {
struct PrivateAccessibilityTextStyleInfo {
std::string font_name;
int font_weight;
int render_mode;
PP_TextRenderingMode render_mode;
double font_size;
// Colors are ARGB.
uint32_t fill_color;

@ -153,6 +153,7 @@ IPC_ENUM_TRAITS_MAX_VALUE(PP_HardwareAcceleration, PP_HARDWAREACCELERATION_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(PP_AudioProfile, PP_AUDIOPROFILE_MAX)
IPC_ENUM_TRAITS_MAX_VALUE(PP_VideoProfile, PP_VIDEOPROFILE_MAX)
IPC_ENUM_TRAITS_MAX_VALUE(PP_PrivateDirection, PP_PRIVATEDIRECTION_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(PP_TextRenderingMode, PP_TEXTRENDERINGMODE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(PP_PdfAccessibilityAction,
PP_PDF_ACCESSIBILITYACTION_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(PP_PdfAccessibilityScrollAlignment,

@ -25,7 +25,7 @@ struct PPAPI_SHARED_EXPORT PdfAccessibilityTextStyleInfo {
std::string font_name;
int font_weight;
int render_mode;
PP_TextRenderingMode render_mode;
double font_size;
// Colors are ARGB.
uint32_t fill_color;