chromium/components/pdf/renderer/pdf_accessibility_tree_builder.cc

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#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 {

// Don't try to apply font size thresholds to automatically identify headings
// if the median font size is not at least this many points.
const float kMinimumFontSize =;

// Don't try to apply paragraph break thresholds to automatically identify
// paragraph breaks if the median line break is not at least this many points.
const float kMinimumLineSpacing =;

// Ratio between the font size of one text run and the median on the page
// for that text run to be considered to be a heading instead of normal text.
const float kHeadingFontSizeRatio =;

// Ratio between the line spacing between two lines and the median on the
// page for that line spacing to be considered a paragraph break.
const float kParagraphLineSpacingRatio =;

// This class is used as part of our heuristic to determine which text runs live
// on the same "line".  As we process runs, we keep a weighted average of the
// top and bottom coordinates of the line, and if a new run falls within that
// range (within a threshold) it is considered part of the line.
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

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  // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
    )
    :{}

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) {}

}  // namespace pdf