blob: bde59316db7aadee5f06a8ef033c18d2214f667b [file] [log] [blame]
Kyungjun Lee3fc774632024-05-03 22:33:001// Copyright 2024 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef COMPONENTS_PDF_RENDERER_PDF_ACCESSIBILITY_TREE_BUILDER_H_
6#define COMPONENTS_PDF_RENDERER_PDF_ACCESSIBILITY_TREE_BUILDER_H_
7
8#include <map>
9#include <vector>
10
11#include "base/memory/raw_ptr.h"
12#include "base/memory/raw_ref.h"
13#include "base/memory/weak_ptr.h"
14#include "components/pdf/renderer/pdf_accessibility_tree.h"
15#include "pdf/accessibility_structs.h"
16#include "services/screen_ai/buildflags/buildflags.h"
17#include "third_party/blink/public/web/web_ax_object.h"
18#include "ui/accessibility/ax_enums.mojom-shared.h"
19
20namespace blink {
21class WebAXObject;
22}
23
24namespace ui {
25struct AXNodeData;
26}
27
28namespace pdf {
29
30class PdfAccessibilityTreeBuilder {
31 public:
32 PdfAccessibilityTreeBuilder(
Nektarios Paisiosa3551e72025-01-13 07:17:2933 bool mark_headings_using_heuristic,
Kyungjun Lee3fc774632024-05-03 22:33:0034 const std::vector<chrome_pdf::AccessibilityTextRunInfo>& text_runs,
35 const std::vector<chrome_pdf::AccessibilityCharInfo>& chars,
36 const chrome_pdf::AccessibilityPageObjects& page_objects,
37 const chrome_pdf::AccessibilityPageInfo& page_info,
38 uint32_t page_index,
39 ui::AXNodeData* root_node,
40 blink::WebAXObject* container_obj,
41 std::vector<std::unique_ptr<ui::AXNodeData>>* nodes,
42 std::map<int32_t, chrome_pdf::PageCharacterIndex>*
43 node_id_to_page_char_index,
44 std::map<int32_t, PdfAccessibilityTree::AnnotationInfo>*
45 node_id_to_annotation_info
46#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
47 ,
48 PdfOcrHelper* ocr_helper,
49 bool has_accessible_text
50#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
51 );
52
53 PdfAccessibilityTreeBuilder(const PdfAccessibilityTreeBuilder&) = delete;
54 PdfAccessibilityTreeBuilder& operator=(const PdfAccessibilityTreeBuilder&) =
55 delete;
56 ~PdfAccessibilityTreeBuilder();
57
58 void BuildPageTree();
59
60 private:
61 void AddWordStartsAndEnds(ui::AXNodeData* inline_text_box);
62 ui::AXNodeData* CreateAndAppendNode(ax::mojom::Role role,
63 ax::mojom::Restriction restriction);
Nektarios Paisiosa3551e72025-01-13 07:17:2964 ui::AXNodeData* CreateBlockLevelNode(const std::string& text_run_type,
65 float font_size);
Ramin Halavati4cbf8052024-10-16 06:47:5966 ui::AXNodeData* CreateStaticTextNode();
Kyungjun Lee3fc774632024-05-03 22:33:0067 ui::AXNodeData* CreateStaticTextNode(
68 const chrome_pdf::PageCharacterIndex& page_char_index);
69 ui::AXNodeData* CreateInlineTextBoxNode(
70 const chrome_pdf::AccessibilityTextRunInfo& text_run,
71 const chrome_pdf::PageCharacterIndex& page_char_index);
72 ui::AXNodeData* CreateLinkNode(const chrome_pdf::AccessibilityLinkInfo& link);
73 ui::AXNodeData* CreateImageNode(
74 const chrome_pdf::AccessibilityImageInfo& image);
75 ui::AXNodeData* CreateHighlightNode(
76 const chrome_pdf::AccessibilityHighlightInfo& highlight);
77 ui::AXNodeData* CreatePopupNoteNode(
78 const chrome_pdf::AccessibilityHighlightInfo& highlight);
79 ui::AXNodeData* CreateTextFieldNode(
80 const chrome_pdf::AccessibilityTextFieldInfo& text_field);
81 ui::AXNodeData* CreateButtonNode(
82 const chrome_pdf::AccessibilityButtonInfo& button);
83 ui::AXNodeData* CreateListboxOptionNode(
84 const chrome_pdf::AccessibilityChoiceFieldOptionInfo& choice_field_option,
85 ax::mojom::Restriction restriction);
86 ui::AXNodeData* CreateListboxNode(
87 const chrome_pdf::AccessibilityChoiceFieldInfo& choice_field,
88 ui::AXNodeData* control_node);
89 ui::AXNodeData* CreateComboboxInputNode(
90 const chrome_pdf::AccessibilityChoiceFieldInfo& choice_field,
91 ax::mojom::Restriction restriction);
92 ui::AXNodeData* CreateComboboxNode(
93 const chrome_pdf::AccessibilityChoiceFieldInfo& choice_field);
94 ui::AXNodeData* CreateChoiceFieldNode(
95 const chrome_pdf::AccessibilityChoiceFieldInfo& choice_field);
Ramin Halavati4cbf8052024-10-16 06:47:5996 ui::AXNodeData* CreateOcrWrapperNode(const gfx::PointF& position, bool start);
Kyungjun Lee3fc774632024-05-03 22:33:0097 void AddTextToAXNode(size_t start_text_run_index,
98 uint32_t end_text_run_index,
99 ui::AXNodeData* ax_node,
100 ui::AXNodeData** previous_on_line_node);
101 void AddTextToObjectNode(size_t object_text_run_index,
102 uint32_t object_text_run_count,
103 ui::AXNodeData* object_node,
104 ui::AXNodeData* para_node,
105 ui::AXNodeData** previous_on_line_node,
106 size_t* text_run_index);
107 void AddLinkToParaNode(const chrome_pdf::AccessibilityLinkInfo& link,
108 ui::AXNodeData* para_node,
109 ui::AXNodeData** previous_on_line_node,
110 size_t* text_run_index);
111 void AddImageToParaNode(const chrome_pdf::AccessibilityImageInfo& image,
112 ui::AXNodeData* para_node,
113 size_t* text_run_index);
114 void AddHighlightToParaNode(
115 const chrome_pdf::AccessibilityHighlightInfo& highlight,
116 ui::AXNodeData* para_node,
117 ui::AXNodeData** previous_on_line_node,
118 size_t* text_run_index);
119 void AddTextFieldToParaNode(
120 const chrome_pdf::AccessibilityTextFieldInfo& text_field,
121 ui::AXNodeData* para_node,
122 size_t* text_run_index);
123 void AddButtonToParaNode(const chrome_pdf::AccessibilityButtonInfo& button,
124 ui::AXNodeData* para_node,
125 size_t* text_run_index);
126 void AddChoiceFieldToParaNode(
127 const chrome_pdf::AccessibilityChoiceFieldInfo& choice_field,
128 ui::AXNodeData* para_node,
129 size_t* text_run_index);
Ramin Halavati4cbf8052024-10-16 06:47:59130 void AddRemainingAnnotations(ui::AXNodeData* para_node, bool ocr_applied);
Kyungjun Lee3fc774632024-05-03 22:33:00131
Nektarios Paisiosa3551e72025-01-13 07:17:29132 const bool mark_headings_using_heuristic_;
Kyungjun Lee3fc774632024-05-03 22:33:00133 std::vector<uint32_t> text_run_start_indices_;
134 const raw_ref<const std::vector<chrome_pdf::AccessibilityTextRunInfo>>
135 text_runs_;
136 const raw_ref<const std::vector<chrome_pdf::AccessibilityCharInfo>> chars_;
137 const raw_ref<const std::vector<chrome_pdf::AccessibilityLinkInfo>> links_;
138 uint32_t current_link_index_ = 0;
139 const raw_ref<const std::vector<chrome_pdf::AccessibilityImageInfo>> images_;
140 uint32_t current_image_index_ = 0;
141 const raw_ref<const std::vector<chrome_pdf::AccessibilityHighlightInfo>>
142 highlights_;
143 uint32_t current_highlight_index_ = 0;
144 const raw_ref<const std::vector<chrome_pdf::AccessibilityTextFieldInfo>>
145 text_fields_;
146 uint32_t current_text_field_index_ = 0;
147 const raw_ref<const std::vector<chrome_pdf::AccessibilityButtonInfo>>
148 buttons_;
149 uint32_t current_button_index_ = 0;
150 const raw_ref<const std::vector<chrome_pdf::AccessibilityChoiceFieldInfo>>
151 choice_fields_;
152 uint32_t current_choice_field_index_ = 0;
153 uint32_t page_index_;
154 raw_ptr<ui::AXNodeData> root_node_;
155 raw_ptr<ui::AXNodeData> page_node_;
156 raw_ptr<blink::WebAXObject> container_obj_;
157 raw_ptr<std::vector<std::unique_ptr<ui::AXNodeData>>> nodes_;
158 raw_ptr<std::map<int32_t, chrome_pdf::PageCharacterIndex>>
159 node_id_to_page_char_index_;
160 raw_ptr<std::map<int32_t, PdfAccessibilityTree::AnnotationInfo>>
161 node_id_to_annotation_info_;
162 float heading_font_size_threshold_ = 0;
163 float paragraph_spacing_threshold_ = 0;
164
165#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
166 raw_ptr<PdfOcrHelper> ocr_helper_ = nullptr;
167 const bool has_accessible_text_;
168#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
169};