blob: 1822badd3890d8b23a7af6a557109945573b07df [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "pdf/accessibility_helper.h"
#include <stdint.h>
#include <vector>
#include "base/numerics/safe_math.h"
#include "pdf/accessibility_structs.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace chrome_pdf {
bool IsCharWithinTextRun(const AccessibilityTextRunInfo& text_run,
uint32_t text_run_start_char_index,
uint32_t char_index) {
return char_index >= text_run_start_char_index &&
char_index - text_run_start_char_index < text_run.len;
}
// If a valid text run range is not found for the char range then return the
// fallback value.
AccessibilityTextRunRangeInfo GetEnclosingTextRunRangeForCharRange(
const std::vector<AccessibilityTextRunInfo>& text_runs,
int start_char_index,
int char_count) {
// Initialize with fallback value.
AccessibilityTextRunRangeInfo text_range = {text_runs.size(), 0};
if (start_char_index < 0 || char_count <= 0)
return text_range;
base::CheckedNumeric<uint32_t> checked_end_char_index = char_count - 1;
checked_end_char_index += start_char_index;
if (!checked_end_char_index.IsValid())
return text_range;
uint32_t end_char_index = checked_end_char_index.ValueOrDie();
uint32_t current_char_index = 0;
absl::optional<uint32_t> start_text_run;
for (size_t i = 0; i < text_runs.size(); ++i) {
if (!start_text_run.has_value() &&
IsCharWithinTextRun(text_runs[i], current_char_index,
start_char_index)) {
start_text_run = i;
}
if (start_text_run.has_value() &&
IsCharWithinTextRun(text_runs[i], current_char_index, end_char_index)) {
text_range.index = start_text_run.value();
text_range.count = i - text_range.index + 1;
break;
}
current_char_index += text_runs[i].len;
}
return text_range;
}
} // namespace chrome_pdf