Kyungjun Lee | 3fc77463 | 2024-05-03 22:33:00 | [diff] [blame] | 1 | // 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 | |
| 20 | namespace blink { |
| 21 | class WebAXObject; |
| 22 | } |
| 23 | |
| 24 | namespace ui { |
| 25 | struct AXNodeData; |
| 26 | } |
| 27 | |
| 28 | namespace pdf { |
| 29 | |
| 30 | class PdfAccessibilityTreeBuilder { |
| 31 | public: |
| 32 | PdfAccessibilityTreeBuilder( |
Nektarios Paisios | a3551e7 | 2025-01-13 07:17:29 | [diff] [blame^] | 33 | bool mark_headings_using_heuristic, |
Kyungjun Lee | 3fc77463 | 2024-05-03 22:33:00 | [diff] [blame] | 34 | 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 Paisios | a3551e7 | 2025-01-13 07:17:29 | [diff] [blame^] | 64 | ui::AXNodeData* CreateBlockLevelNode(const std::string& text_run_type, |
| 65 | float font_size); |
Ramin Halavati | 4cbf805 | 2024-10-16 06:47:59 | [diff] [blame] | 66 | ui::AXNodeData* CreateStaticTextNode(); |
Kyungjun Lee | 3fc77463 | 2024-05-03 22:33:00 | [diff] [blame] | 67 | 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 Halavati | 4cbf805 | 2024-10-16 06:47:59 | [diff] [blame] | 96 | ui::AXNodeData* CreateOcrWrapperNode(const gfx::PointF& position, bool start); |
Kyungjun Lee | 3fc77463 | 2024-05-03 22:33:00 | [diff] [blame] | 97 | 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 Halavati | 4cbf805 | 2024-10-16 06:47:59 | [diff] [blame] | 130 | void AddRemainingAnnotations(ui::AXNodeData* para_node, bool ocr_applied); |
Kyungjun Lee | 3fc77463 | 2024-05-03 22:33:00 | [diff] [blame] | 131 | |
Nektarios Paisios | a3551e7 | 2025-01-13 07:17:29 | [diff] [blame^] | 132 | const bool mark_headings_using_heuristic_; |
Kyungjun Lee | 3fc77463 | 2024-05-03 22:33:00 | [diff] [blame] | 133 | 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 | }; |
|
|