1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
pdf / accessibility_helper.cc [blame]
// Copyright 2020 The Chromium Authors
// 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 <optional>
#include <vector>
#include "base/numerics/safe_math.h"
#include "pdf/accessibility_structs.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;
std::optional<size_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