Upload upstream chromium 76.0.3809.146
[platform/framework/web/chromium-efl.git] / pdf / accessibility.cc
1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "pdf/accessibility.h"
6
7 #include "pdf/pdf_engine.h"
8 #include "ppapi/c/private/ppb_pdf.h"
9
10 namespace chrome_pdf {
11
12 bool GetAccessibilityInfo(
13     PDFEngine* engine,
14     int32_t page_index,
15     PP_PrivateAccessibilityPageInfo* page_info,
16     std::vector<PP_PrivateAccessibilityTextRunInfo>* text_runs,
17     std::vector<PP_PrivateAccessibilityCharInfo>* chars) {
18   int page_count = engine->GetNumberOfPages();
19   if (page_index < 0 || page_index >= page_count)
20     return false;
21
22   int char_count = engine->GetCharCount(page_index);
23
24   // Treat a char count of -1 (error) as 0 (an empty page), since
25   // other pages might have valid content.
26   if (char_count < 0)
27     char_count = 0;
28
29   page_info->page_index = page_index;
30   page_info->bounds = engine->GetPageBoundsRect(page_index);
31   page_info->char_count = char_count;
32
33   chars->resize(page_info->char_count);
34   for (uint32_t i = 0; i < page_info->char_count; ++i) {
35     (*chars)[i].unicode_character = engine->GetCharUnicode(page_index, i);
36   }
37
38   int char_index = 0;
39   while (char_index < char_count) {
40     PP_PrivateAccessibilityTextRunInfo text_run_info;
41     pp::FloatRect bounds;
42     engine->GetTextRunInfo(page_index, char_index, &text_run_info.len,
43                            &text_run_info.font_size, &bounds);
44     DCHECK_LE(char_index + text_run_info.len,
45               static_cast<uint32_t>(char_count));
46     text_run_info.direction = PP_PRIVATEDIRECTION_LTR;
47     text_run_info.bounds = bounds;
48     text_runs->push_back(text_run_info);
49
50     // We need to provide enough information to draw a bounding box
51     // around any arbitrary text range, but the bounding boxes of characters
52     // we get from PDFium don't necessarily "line up". Walk through the
53     // characters in each text run and let the width of each character be
54     // the difference between the x coordinate of one character and the
55     // x coordinate of the next. The rest of the bounds of each character
56     // can be computed from the bounds of the text run.
57     pp::FloatRect char_bounds = engine->GetCharBounds(page_index, char_index);
58     for (uint32_t i = 0; i < text_run_info.len - 1; i++) {
59       DCHECK_LT(char_index + i + 1, static_cast<uint32_t>(char_count));
60       pp::FloatRect next_char_bounds =
61           engine->GetCharBounds(page_index, char_index + i + 1);
62       (*chars)[char_index + i].char_width =
63           next_char_bounds.x() - char_bounds.x();
64       char_bounds = next_char_bounds;
65     }
66     (*chars)[char_index + text_run_info.len - 1].char_width =
67         char_bounds.width();
68
69     char_index += text_run_info.len;
70   }
71
72   page_info->text_run_count = text_runs->size();
73   return true;
74 }
75
76 }  // namespace chrome_pdf