| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
| 9 #include "base/strings/utf_string_conversion_utils.h" | 9 #include "base/strings/utf_string_conversion_utils.h" |
| 10 #include "components/pdf/renderer/pdf_accessibility_tree.h" | 10 #include "components/pdf/renderer/pdf_accessibility_tree.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 // page for that line spacing to be considered a paragraph break. | 35 // page for that line spacing to be considered a paragraph break. |
| 36 const double kParagraphLineSpacingRatio = 1.2; | 36 const double kParagraphLineSpacingRatio = 1.2; |
| 37 | 37 |
| 38 gfx::RectF ToGfxRectF(const PP_FloatRect& r) { | 38 gfx::RectF ToGfxRectF(const PP_FloatRect& r) { |
| 39 return gfx::RectF(r.point.x, r.point.y, r.size.width, r.size.height); | 39 return gfx::RectF(r.point.x, r.point.y, r.size.width, r.size.height); |
| 40 } | 40 } |
| 41 | 41 |
| 42 } | 42 } |
| 43 | 43 |
| 44 PdfAccessibilityTree::PdfAccessibilityTree( | 44 PdfAccessibilityTree::PdfAccessibilityTree( |
| 45 content::RenderView* render_view) | 45 content::RenderFrame* render_frame) |
| 46 : render_view_(render_view), | 46 : render_frame_(render_frame), |
| 47 render_accessibility_(nullptr), | |
| 48 zoom_(1.0) { | 47 zoom_(1.0) { |
| 49 content::RenderFrame* render_frame = render_view->GetMainRenderFrame(); | |
| 50 render_accessibility_ = render_frame->GetRenderAccessibility(); | |
| 51 } | 48 } |
| 52 | 49 |
| 53 PdfAccessibilityTree::~PdfAccessibilityTree() { | 50 PdfAccessibilityTree::~PdfAccessibilityTree() { |
| 54 } | 51 } |
| 55 | 52 |
| 56 void PdfAccessibilityTree::SetAccessibilityViewportInfo( | 53 void PdfAccessibilityTree::SetAccessibilityViewportInfo( |
| 57 const PP_PrivateAccessibilityViewportInfo& viewport_info) { | 54 const PP_PrivateAccessibilityViewportInfo& viewport_info) { |
| 58 zoom_ = viewport_info.zoom; | 55 zoom_ = viewport_info.zoom; |
| 59 CHECK_GT(zoom_, 0); | 56 CHECK_GT(zoom_, 0); |
| 60 scroll_ = ToVector2dF(viewport_info.scroll); | 57 scroll_ = ToVector2dF(viewport_info.scroll); |
| 61 scroll_.Scale(1.0 / zoom_); | 58 scroll_.Scale(1.0 / zoom_); |
| 62 offset_ = ToVector2dF(viewport_info.offset); | 59 offset_ = ToVector2dF(viewport_info.offset); |
| 63 offset_.Scale(1.0 / zoom_); | 60 offset_.Scale(1.0 / zoom_); |
| 64 } | 61 } |
| 65 | 62 |
| 66 void PdfAccessibilityTree::SetAccessibilityDocInfo( | 63 void PdfAccessibilityTree::SetAccessibilityDocInfo( |
| 67 const PP_PrivateAccessibilityDocInfo& doc_info) { | 64 const PP_PrivateAccessibilityDocInfo& doc_info) { |
| 68 doc_info_ = doc_info; | 65 doc_info_ = doc_info; |
| 69 doc_node_ = CreateNode(ui::AX_ROLE_GROUP); | 66 doc_node_ = CreateNode(ui::AX_ROLE_GROUP); |
| 70 } | 67 } |
| 71 | 68 |
| 72 void PdfAccessibilityTree::SetAccessibilityPageInfo( | 69 void PdfAccessibilityTree::SetAccessibilityPageInfo( |
| 73 const PP_PrivateAccessibilityPageInfo& page_info, | 70 const PP_PrivateAccessibilityPageInfo& page_info, |
| 74 const std::vector<PP_PrivateAccessibilityTextRunInfo>& text_runs, | 71 const std::vector<PP_PrivateAccessibilityTextRunInfo>& text_runs, |
| 75 const std::vector<PP_PrivateAccessibilityCharInfo>& chars) { | 72 const std::vector<PP_PrivateAccessibilityCharInfo>& chars) { |
| 73 content::RenderAccessibility* render_accessibility = |
| 74 render_frame_->GetRenderAccessibility(); |
| 75 if (!render_accessibility) |
| 76 return; |
| 77 |
| 76 uint32_t page_index = page_info.page_index; | 78 uint32_t page_index = page_info.page_index; |
| 77 CHECK_GE(page_index, 0U); | 79 CHECK_GE(page_index, 0U); |
| 78 CHECK_LT(page_index, doc_info_.page_count); | 80 CHECK_LT(page_index, doc_info_.page_count); |
| 79 | 81 |
| 80 ui::AXNodeData* page_node = CreateNode(ui::AX_ROLE_REGION); | 82 ui::AXNodeData* page_node = CreateNode(ui::AX_ROLE_REGION); |
| 81 page_node->AddStringAttribute( | 83 page_node->AddStringAttribute( |
| 82 ui::AX_ATTR_NAME, | 84 ui::AX_ATTR_NAME, |
| 83 l10n_util::GetPluralStringFUTF8( | 85 l10n_util::GetPluralStringFUTF8( |
| 84 IDS_PDF_PAGE_INDEX, page_index + 1)); | 86 IDS_PDF_PAGE_INDEX, page_index + 1)); |
| 85 | 87 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 112 | 114 |
| 113 // If we don't have a paragraph, create one. | 115 // If we don't have a paragraph, create one. |
| 114 if (!para_node) { | 116 if (!para_node) { |
| 115 para_node = CreateNode(ui::AX_ROLE_PARAGRAPH); | 117 para_node = CreateNode(ui::AX_ROLE_PARAGRAPH); |
| 116 page_node->child_ids.push_back(para_node->id); | 118 page_node->child_ids.push_back(para_node->id); |
| 117 | 119 |
| 118 if (heading_font_size_threshold > 0 && | 120 if (heading_font_size_threshold > 0 && |
| 119 text_run.font_size > heading_font_size_threshold) { | 121 text_run.font_size > heading_font_size_threshold) { |
| 120 para_node->role = ui::AX_ROLE_HEADING; | 122 para_node->role = ui::AX_ROLE_HEADING; |
| 121 para_node->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL, 2); | 123 para_node->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL, 2); |
| 124 para_node->AddStringAttribute(ui::AX_ATTR_HTML_TAG, "h2"); |
| 122 } | 125 } |
| 123 | 126 |
| 124 // This node is for the text inside the paragraph, it includes | 127 // This node is for the text inside the paragraph, it includes |
| 125 // the text of all of the text runs. | 128 // the text of all of the text runs. |
| 126 static_text_node = CreateNode(ui::AX_ROLE_STATIC_TEXT); | 129 static_text_node = CreateNode(ui::AX_ROLE_STATIC_TEXT); |
| 127 para_node->child_ids.push_back(static_text_node->id); | 130 para_node->child_ids.push_back(static_text_node->id); |
| 128 } | 131 } |
| 129 | 132 |
| 130 // Add this text run to the current static text node. | 133 // Add this text run to the current static text node. |
| 131 ui::AXNodeData* inline_text_box_node = CreateNode( | 134 ui::AXNodeData* inline_text_box_node = CreateNode( |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 Finish(); | 167 Finish(); |
| 165 } | 168 } |
| 166 | 169 |
| 167 void PdfAccessibilityTree::Finish() { | 170 void PdfAccessibilityTree::Finish() { |
| 168 ui::AXTreeUpdate update; | 171 ui::AXTreeUpdate update; |
| 169 update.root_id = doc_node_->id; | 172 update.root_id = doc_node_->id; |
| 170 for (const auto& node : nodes_) | 173 for (const auto& node : nodes_) |
| 171 update.nodes.push_back(*node); | 174 update.nodes.push_back(*node); |
| 172 | 175 |
| 173 CHECK(tree_.Unserialize(update)) << update.ToString() << tree_.error(); | 176 CHECK(tree_.Unserialize(update)) << update.ToString() << tree_.error(); |
| 174 render_accessibility_->SetPdfTreeSource(this); | 177 content::RenderAccessibility* render_accessibility = |
| 178 render_frame_->GetRenderAccessibility(); |
| 179 if (render_accessibility) |
| 180 render_accessibility->SetPdfTreeSource(this); |
| 175 } | 181 } |
| 176 | 182 |
| 177 void PdfAccessibilityTree::ComputeParagraphAndHeadingThresholds( | 183 void PdfAccessibilityTree::ComputeParagraphAndHeadingThresholds( |
| 178 const std::vector<PP_PrivateAccessibilityTextRunInfo>& text_runs, | 184 const std::vector<PP_PrivateAccessibilityTextRunInfo>& text_runs, |
| 179 double* out_heading_font_size_threshold, | 185 double* out_heading_font_size_threshold, |
| 180 double* out_line_spacing_threshold) { | 186 double* out_line_spacing_threshold) { |
| 181 // Scan over the font sizes and line spacing within this page and | 187 // Scan over the font sizes and line spacing within this page and |
| 182 // set heuristic thresholds so that text larger than the median font | 188 // set heuristic thresholds so that text larger than the median font |
| 183 // size can be marked as a heading, and spacing larger than the median | 189 // size can be marked as a heading, and spacing larger than the median |
| 184 // line spacing can be a paragraph break. | 190 // line spacing can be a paragraph break. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 | 244 |
| 239 gfx::Vector2dF PdfAccessibilityTree::ToVector2dF(const PP_Point& p) { | 245 gfx::Vector2dF PdfAccessibilityTree::ToVector2dF(const PP_Point& p) { |
| 240 return gfx::Vector2dF(p.x, p.y); | 246 return gfx::Vector2dF(p.x, p.y); |
| 241 } | 247 } |
| 242 | 248 |
| 243 gfx::RectF PdfAccessibilityTree::ToRectF(const PP_Rect& r) { | 249 gfx::RectF PdfAccessibilityTree::ToRectF(const PP_Rect& r) { |
| 244 return gfx::RectF(r.point.x, r.point.y, r.size.width, r.size.height); | 250 return gfx::RectF(r.point.x, r.point.y, r.size.width, r.size.height); |
| 245 } | 251 } |
| 246 | 252 |
| 247 ui::AXNodeData* PdfAccessibilityTree::CreateNode(ui::AXRole role) { | 253 ui::AXNodeData* PdfAccessibilityTree::CreateNode(ui::AXRole role) { |
| 254 content::RenderAccessibility* render_accessibility = |
| 255 render_frame_->GetRenderAccessibility(); |
| 256 |
| 248 ui::AXNodeData* node = new ui::AXNodeData(); | 257 ui::AXNodeData* node = new ui::AXNodeData(); |
| 249 node->id = render_accessibility_->GenerateAXID(); | 258 node->id = render_accessibility->GenerateAXID(); |
| 250 node->role = role; | 259 node->role = role; |
| 251 node->state = 1 << ui::AX_STATE_ENABLED | 1 << ui::AX_STATE_READ_ONLY; | 260 node->state = 1 << ui::AX_STATE_ENABLED | 1 << ui::AX_STATE_READ_ONLY; |
| 252 nodes_.push_back(base::WrapUnique(node)); | 261 nodes_.push_back(base::WrapUnique(node)); |
| 253 return node; | 262 return node; |
| 254 } | 263 } |
| 255 | 264 |
| 256 float PdfAccessibilityTree::GetDeviceScaleFactor() const { | 265 float PdfAccessibilityTree::GetDeviceScaleFactor() const { |
| 257 return render_view_->GetDeviceScaleFactor(); | 266 return render_frame_->GetRenderView()->GetDeviceScaleFactor(); |
| 258 } | 267 } |
| 259 | 268 |
| 260 // | 269 // |
| 261 // AXTreeSource implementation. | 270 // AXTreeSource implementation. |
| 262 // | 271 // |
| 263 | 272 |
| 264 bool PdfAccessibilityTree::GetTreeData(ui::AXTreeData* tree_data) const { | 273 bool PdfAccessibilityTree::GetTreeData(ui::AXTreeData* tree_data) const { |
| 265 return false; | 274 return false; |
| 266 } | 275 } |
| 267 | 276 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 const ui::AXNode* PdfAccessibilityTree::GetNull() const { | 309 const ui::AXNode* PdfAccessibilityTree::GetNull() const { |
| 301 return nullptr; | 310 return nullptr; |
| 302 } | 311 } |
| 303 | 312 |
| 304 void PdfAccessibilityTree::SerializeNode( | 313 void PdfAccessibilityTree::SerializeNode( |
| 305 const ui::AXNode* node, ui::AXNodeData* out_data) const { | 314 const ui::AXNode* node, ui::AXNodeData* out_data) const { |
| 306 *out_data = node->data(); | 315 *out_data = node->data(); |
| 307 } | 316 } |
| 308 | 317 |
| 309 } // namespace pdf | 318 } // namespace pdf |
| OLD | NEW |