#include "components/pdf/renderer/pdf_accessibility_tree_builder.h"
#include <queue>
#include <string>
#include "base/i18n/break_iterator.h"
#include "base/strings/utf_string_conversion_utils.h"
#include "components/pdf/renderer/pdf_ocr_helper.h"
#include "components/strings/grit/components_strings.h"
#include "pdf/accessibility_structs.h"
#include "pdf/pdf_features.h"
#include "third_party/blink/public/web/web_ax_object.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/strings/grit/auto_image_annotation_strings.h"
namespace {
const float kMinimumFontSize = …;
const float kMinimumLineSpacing = …;
const float kHeadingFontSizeRatio = …;
const float kParagraphLineSpacingRatio = …;
class LineHelper { … };
bool BreakParagraph(
const std::vector<chrome_pdf::AccessibilityTextRunInfo>& text_runs,
uint32_t text_run_index,
float paragraph_spacing_threshold) { … }
void BuildStaticNode(ui::AXNodeData** static_text_node,
std::string* static_text) { … }
void ComputeParagraphAndHeadingThresholds(
const std::vector<chrome_pdf::AccessibilityTextRunInfo>& text_runs,
float* out_heading_font_size_threshold,
float* out_paragraph_spacing_threshold) { … }
void ConnectPreviousAndNextOnLine(ui::AXNodeData* previous_on_line_node,
ui::AXNodeData* next_on_line_node) { … }
ax::mojom::Role GetRoleForButtonType(chrome_pdf::ButtonType button_type) { … }
std::string GetTextRunCharsAsUTF8(
const chrome_pdf::AccessibilityTextRunInfo& text_run,
const std::vector<chrome_pdf::AccessibilityCharInfo>& chars,
int char_index) { … }
std::vector<int32_t> GetTextRunCharOffsets(
const chrome_pdf::AccessibilityTextRunInfo& text_run,
const std::vector<chrome_pdf::AccessibilityCharInfo>& chars,
int char_index) { … }
template <typename T>
bool IsObjectInTextRun(const std::vector<T>& objects,
uint32_t object_index,
size_t text_run_index) { … }
template <typename T>
bool IsObjectWithRangeInTextRun(const std::vector<T>& objects,
uint32_t object_index,
size_t text_run_index) { … }
bool IsTextRenderModeFill(const chrome_pdf::AccessibilityTextRenderMode& mode) { … }
bool IsTextRenderModeStroke(
const chrome_pdf::AccessibilityTextRenderMode& mode) { … }
size_t NormalizeTextRunIndex(uint32_t object_end_text_run_index,
size_t current_text_run_index) { … }
}
namespace pdf {
PdfAccessibilityTreeBuilder::PdfAccessibilityTreeBuilder(
base::WeakPtr<PdfAccessibilityTree> pdf_accessibility_tree,
const std::vector<chrome_pdf::AccessibilityTextRunInfo>& text_runs,
const std::vector<chrome_pdf::AccessibilityCharInfo>& chars,
const chrome_pdf::AccessibilityPageObjects& page_objects,
const chrome_pdf::AccessibilityPageInfo& page_info,
uint32_t page_index,
ui::AXNodeData* root_node,
blink::WebAXObject* container_obj,
std::vector<std::unique_ptr<ui::AXNodeData>>* nodes,
std::map<int32_t, chrome_pdf::PageCharacterIndex>*
node_id_to_page_char_index,
std::map<int32_t, PdfAccessibilityTree::AnnotationInfo>*
node_id_to_annotation_info
#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
,
PdfOcrHelper* ocr_helper,
bool has_accessible_text
#endif
)
: … { … }
PdfAccessibilityTreeBuilder::~PdfAccessibilityTreeBuilder() = default;
void PdfAccessibilityTreeBuilder::BuildPageTree() { … }
void PdfAccessibilityTreeBuilder::AddWordStartsAndEnds(
ui::AXNodeData* inline_text_box) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateAndAppendNode(
ax::mojom::Role role,
ax::mojom::Restriction restriction) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateParagraphNode(
float font_size) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateStaticTextNode(
const chrome_pdf::PageCharacterIndex& page_char_index) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateInlineTextBoxNode(
const chrome_pdf::AccessibilityTextRunInfo& text_run,
const chrome_pdf::PageCharacterIndex& page_char_index) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateLinkNode(
const chrome_pdf::AccessibilityLinkInfo& link) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateImageNode(
const chrome_pdf::AccessibilityImageInfo& image) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateHighlightNode(
const chrome_pdf::AccessibilityHighlightInfo& highlight) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreatePopupNoteNode(
const chrome_pdf::AccessibilityHighlightInfo& highlight) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateTextFieldNode(
const chrome_pdf::AccessibilityTextFieldInfo& text_field) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateButtonNode(
const chrome_pdf::AccessibilityButtonInfo& button) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateListboxOptionNode(
const chrome_pdf::AccessibilityChoiceFieldOptionInfo& choice_field_option,
ax::mojom::Restriction restriction) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateListboxNode(
const chrome_pdf::AccessibilityChoiceFieldInfo& choice_field,
ui::AXNodeData* control_node) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateComboboxInputNode(
const chrome_pdf::AccessibilityChoiceFieldInfo& choice_field,
ax::mojom::Restriction restriction) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateComboboxNode(
const chrome_pdf::AccessibilityChoiceFieldInfo& choice_field) { … }
ui::AXNodeData* PdfAccessibilityTreeBuilder::CreateChoiceFieldNode(
const chrome_pdf::AccessibilityChoiceFieldInfo& choice_field) { … }
void PdfAccessibilityTreeBuilder::AddTextToAXNode(
size_t start_text_run_index,
uint32_t end_text_run_index,
ui::AXNodeData* ax_node,
ui::AXNodeData** previous_on_line_node) { … }
void PdfAccessibilityTreeBuilder::AddTextToObjectNode(
size_t object_text_run_index,
uint32_t object_text_run_count,
ui::AXNodeData* object_node,
ui::AXNodeData* para_node,
ui::AXNodeData** previous_on_line_node,
size_t* text_run_index) { … }
void PdfAccessibilityTreeBuilder::AddLinkToParaNode(
const chrome_pdf::AccessibilityLinkInfo& link,
ui::AXNodeData* para_node,
ui::AXNodeData** previous_on_line_node,
size_t* text_run_index) { … }
void PdfAccessibilityTreeBuilder::AddImageToParaNode(
const chrome_pdf::AccessibilityImageInfo& image,
ui::AXNodeData* para_node,
size_t* text_run_index) { … }
void PdfAccessibilityTreeBuilder::AddHighlightToParaNode(
const chrome_pdf::AccessibilityHighlightInfo& highlight,
ui::AXNodeData* para_node,
ui::AXNodeData** previous_on_line_node,
size_t* text_run_index) { … }
void PdfAccessibilityTreeBuilder::AddTextFieldToParaNode(
const chrome_pdf::AccessibilityTextFieldInfo& text_field,
ui::AXNodeData* para_node,
size_t* text_run_index) { … }
void PdfAccessibilityTreeBuilder::AddButtonToParaNode(
const chrome_pdf::AccessibilityButtonInfo& button,
ui::AXNodeData* para_node,
size_t* text_run_index) { … }
void PdfAccessibilityTreeBuilder::AddChoiceFieldToParaNode(
const chrome_pdf::AccessibilityChoiceFieldInfo& choice_field,
ui::AXNodeData* para_node,
size_t* text_run_index) { … }
void PdfAccessibilityTreeBuilder::AddRemainingAnnotations(
ui::AXNodeData* para_node) { … }
}