1 // Copyright 2020 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.
5 #include "pdf/accessibility_helper.h"
11 #include "base/numerics/safe_math.h"
12 #include "pdf/accessibility_structs.h"
13 #include "third_party/abseil-cpp/absl/types/optional.h"
15 namespace chrome_pdf {
17 bool IsCharWithinTextRun(const AccessibilityTextRunInfo& text_run,
18 uint32_t text_run_start_char_index,
19 uint32_t char_index) {
20 return char_index >= text_run_start_char_index &&
21 char_index - text_run_start_char_index < text_run.len;
24 // If a valid text run range is not found for the char range then return the
26 AccessibilityTextRunRangeInfo GetEnclosingTextRunRangeForCharRange(
27 const std::vector<AccessibilityTextRunInfo>& text_runs,
30 // Initialize with fallback value.
31 AccessibilityTextRunRangeInfo text_range = {text_runs.size(), 0};
32 if (start_char_index < 0 || char_count <= 0)
35 base::CheckedNumeric<uint32_t> checked_end_char_index = char_count - 1;
36 checked_end_char_index += start_char_index;
37 if (!checked_end_char_index.IsValid())
39 uint32_t end_char_index = checked_end_char_index.ValueOrDie();
40 uint32_t current_char_index = 0;
41 absl::optional<size_t> start_text_run;
42 for (size_t i = 0; i < text_runs.size(); ++i) {
43 if (!start_text_run.has_value() &&
44 IsCharWithinTextRun(text_runs[i], current_char_index,
49 if (start_text_run.has_value() &&
50 IsCharWithinTextRun(text_runs[i], current_char_index, end_char_index)) {
51 text_range.index = start_text_run.value();
52 text_range.count = i - text_range.index + 1;
55 current_char_index += text_runs[i].len;
60 } // namespace chrome_pdf