Chromium Code Reviews| Index: pdf/out_of_process_instance.cc |
| diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc |
| index 869fdf24958af20bbff24f64720e0cae4f5bd3f5..440c6497f141c58a697b6a4b2313b6d370d6c37e 100644 |
| --- a/pdf/out_of_process_instance.cc |
| +++ b/pdf/out_of_process_instance.cc |
| @@ -153,6 +153,10 @@ const char kJSFieldFocus[] = "focused"; |
| const int kFindResultCooldownMs = 100; |
| +// A delay to wait between each accessibility page to keep the system |
| +// responsive. |
| +const int kAccessibilityPageDelayMs = 100; |
| + |
| const double kMinZoom = 0.01; |
| namespace { |
| @@ -206,10 +210,20 @@ PP_Bool GetPrintPresetOptionsFromDocument( |
| return PP_TRUE; |
| } |
| +void EnableAccessibility(PP_Instance instance) { |
| + void* object = pp::Instance::GetPerInstanceObject(instance, kPPPPdfInterface); |
| + if (object) { |
| + OutOfProcessInstance* obj_instance = |
| + static_cast<OutOfProcessInstance*>(object); |
| + return obj_instance->EnableAccessibility(); |
| + } |
| +} |
| + |
| const PPP_Pdf ppp_private = { |
| &GetLinkAtPosition, |
| &Transform, |
| - &GetPrintPresetOptionsFromDocument |
| + &GetPrintPresetOptionsFromDocument, |
| + &EnableAccessibility, |
| }; |
| int ExtractPrintPreviewPageIndex(const std::string& src_url) { |
| @@ -288,7 +302,8 @@ OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance) |
| did_call_start_loading_(false), |
| stop_scrolling_(false), |
| background_color_(0), |
| - top_toolbar_height_(0) { |
| + top_toolbar_height_(0), |
| + accessibility_enabled_(false) { |
| loader_factory_.Initialize(this); |
| timer_factory_.Initialize(this); |
| form_factory_.Initialize(this); |
| @@ -614,6 +629,85 @@ void OutOfProcessInstance::GetPrintPresetOptionsFromDocument( |
| options->uniform_page_size = uniform_page_size; |
| } |
| +void OutOfProcessInstance::EnableAccessibility() { |
| + if (accessibility_enabled_) |
| + return; |
| + |
| + accessibility_enabled_ = true; |
| + |
| + PP_PrivateAccessibilityDocInfo doc_info; |
| + doc_info.page_count = engine_->GetNumberOfPages(); |
| + doc_info.text_accessible = PP_FromBool( |
| + engine_->HasPermission(PDFEngine::PERMISSION_COPY_ACCESSIBLE)); |
| + doc_info.text_copyable = PP_FromBool( |
| + engine_->HasPermission(PDFEngine::PERMISSION_COPY)); |
| + pp::PDF::SetAccessibilityDocInfo(GetPluginInstance(), &doc_info); |
| + |
| + // If the document contents isn't accessible, don't send anything more. |
| + if (!(engine_->HasPermission(PDFEngine::PERMISSION_COPY) || |
| + engine_->HasPermission(PDFEngine::PERMISSION_COPY_ACCESSIBLE))) { |
| + return; |
| + } |
| + |
| + PP_PrivateAccessibilityViewportInfo viewport_info; |
| + viewport_info.scroll.x = 0; |
| + viewport_info.scroll.y = -top_toolbar_height_ * device_scale_; |
| + viewport_info.offset = available_area_.point(); |
| + viewport_info.zoom = zoom_; |
| + pp::PDF::SetAccessibilityViewportInfo(GetPluginInstance(), &viewport_info); |
| + |
| + // Schedule loading the first page. |
| + pp::CompletionCallback callback = |
| + timer_factory_.NewCallback( |
| + &OutOfProcessInstance::SendNextAccessibilityPage); |
| + pp::Module::Get()->core()->CallOnMainThread(kAccessibilityPageDelayMs, |
| + callback, 0); |
| +} |
| + |
| +void OutOfProcessInstance::SendNextAccessibilityPage(int32_t page_index) { |
| + int page_count = engine_->GetNumberOfPages(); |
| + if (page_index < 0 || page_index >= page_count) |
| + return; |
| + |
| + PP_PrivateAccessibilityPageInfo page_info; |
| + page_info.page_index = page_index; |
| + page_info.bounds = engine_->GetPageBoundsRect(page_index); |
| + page_info.char_count = engine_->GetCharCount(page_index); |
| + |
| + std::vector<PP_PrivateAccessibilityCharInfo> chars(page_info.char_count); |
| + for (uint32_t i = 0; i < page_info.char_count; ++i) { |
| + chars[i].unicode_character = engine_->GetCharUnicode(page_index, i); |
| + chars[i].char_width = engine_->GetCharWidth(page_index, i); |
| + } |
| + |
| + std::vector<PP_PrivateAccessibilityTextRunInfo> text_runs; |
| + uint32_t char_index = 0; |
|
raymes
2016/05/30 04:17:37
int (that's what the argument type is anyhow)?
dmazzoni
2016/05/31 21:45:01
Done.
|
| + int text_run_index = 0; |
| + while (char_index < page_info.char_count) { |
| + PP_PrivateAccessibilityTextRunInfo text_run_info; |
| + pp::FloatRect bounds; |
| + engine_->GetTextRunInfo( |
| + page_index, char_index, &text_run_info.len, |
| + &text_run_info.font_size, &bounds); |
| + text_run_info.direction = PP_PRIVATEDIRECTION_LTR; |
| + text_run_info.bounds = bounds; |
| + text_runs.push_back(text_run_info); |
| + text_run_index++; |
| + char_index += text_run_info.len; |
| + } |
| + |
| + page_info.text_run_count = text_runs.size(); |
| + pp::PDF::SetAccessibilityPageInfo( |
| + GetPluginInstance(), &page_info, text_runs.data(), chars.data()); |
| + |
| + // Schedule loading the next page. |
| + pp::CompletionCallback callback = |
| + timer_factory_.NewCallback( |
| + &OutOfProcessInstance::SendNextAccessibilityPage); |
| + pp::Module::Get()->core()->CallOnMainThread(kAccessibilityPageDelayMs, |
| + callback, page_index + 1); |
| +} |
| + |
| pp::Var OutOfProcessInstance::GetLinkAtPosition( |
| const pp::Point& point) { |
| pp::Point offset_point(point); |