1 // Copyright 2014 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 "chrome/browser/chromeos/ui/accessibility_focus_ring.h" 6 7 #include "base/logging.h" 8 9 namespace chromeos { 10 11 // static 12 AccessibilityFocusRing AccessibilityFocusRing::CreateWithRect( 13 const gfx::Rect& bounds, int margin) { 14 // Compute the height of the top and bottom cap. 15 int cap_height = std::min(bounds.height() / 2, margin * 2); 16 17 gfx::Rect top(bounds.x(), bounds.y(), 18 bounds.width(), cap_height); 19 gfx::Rect bottom(bounds.x(), bounds.bottom() - cap_height, 20 bounds.width(), cap_height); 21 gfx::Rect body(bounds.x(), top.bottom(), 22 bounds.width(), bottom.y() - top.bottom()); 23 24 return CreateWithParagraphShape(top, body, bottom, margin); 25 } 26 27 // static 28 AccessibilityFocusRing AccessibilityFocusRing::Interpolate( 29 const AccessibilityFocusRing& r1, 30 const AccessibilityFocusRing& r2, 31 double fraction) { 32 AccessibilityFocusRing dst; 33 for (int i = 0; i < 36; ++i) { 34 dst.points[i] = gfx::Point( 35 r1.points[i].x() * (1 - fraction) + r2.points[i].x() * fraction, 36 r1.points[i].y() * (1 - fraction) + r2.points[i].y() * fraction); 37 } 38 return dst; 39 } 40 41 // static 42 AccessibilityFocusRing AccessibilityFocusRing::CreateWithParagraphShape( 43 const gfx::Rect& orig_top_line, 44 const gfx::Rect& orig_body, 45 const gfx::Rect& orig_bottom_line, 46 int margin) { 47 gfx::Rect top = orig_top_line; 48 gfx::Rect middle = orig_body; 49 gfx::Rect bottom = orig_bottom_line; 50 51 int min_height = std::min(top.height(), bottom.height()); 52 margin = std::min(margin, min_height / 2); 53 54 if (top.x() <= middle.x() + 2 * margin) { 55 top.set_width(top.width() + top.x() - middle.x()); 56 top.set_x(middle.x()); 57 } 58 if (top.right() >= middle.right() - 2 * margin) { 59 top.set_width(middle.right() - top.x()); 60 } 61 62 if (bottom.x() <= middle.x() + 2 * margin) { 63 bottom.set_width(bottom.width() + bottom.x() - middle.x()); 64 bottom.set_x(middle.x()); 65 } 66 if (bottom.right() >= middle.right() - 2 * margin) { 67 bottom.set_width(middle.right() - bottom.x()); 68 } 69 70 AccessibilityFocusRing ring; 71 ring.points[0] = gfx::Point(top.x(), top.bottom() - margin); 72 ring.points[1] = gfx::Point(top.x(), top.y() + margin); 73 ring.points[2] = gfx::Point(top.x(), top.y()); 74 ring.points[3] = gfx::Point(top.x() + margin, top.y()); 75 ring.points[4] = gfx::Point(top.right() - margin, top.y()); 76 ring.points[5] = gfx::Point(top.right(), top.y()); 77 ring.points[6] = gfx::Point(top.right(), top.y() + margin); 78 ring.points[7] = gfx::Point(top.right(), top.bottom() - margin); 79 ring.points[8] = gfx::Point(top.right(), top.bottom()); 80 if (top.right() < middle.right()) { 81 ring.points[9] = gfx::Point(top.right() + margin, middle.y()); 82 ring.points[10] = gfx::Point(middle.right() - margin, middle.y()); 83 } else { 84 ring.points[9] = gfx::Point(top.right(), middle.y()); 85 ring.points[10] = gfx::Point(middle.right(), middle.y()); 86 } 87 ring.points[11] = gfx::Point(middle.right(), middle.y()); 88 ring.points[12] = gfx::Point(middle.right(), middle.y() + margin); 89 ring.points[13] = gfx::Point(middle.right(), middle.bottom() - margin); 90 ring.points[14] = gfx::Point(middle.right(), middle.bottom()); 91 if (bottom.right() < middle.right()) { 92 ring.points[15] = gfx::Point(middle.right() - margin, bottom.y()); 93 ring.points[16] = gfx::Point(bottom.right() + margin, bottom.y()); 94 } else { 95 ring.points[15] = gfx::Point(middle.right(), bottom.y()); 96 ring.points[16] = gfx::Point(bottom.right(), bottom.y()); 97 } 98 ring.points[17] = gfx::Point(bottom.right(), bottom.y()); 99 ring.points[18] = gfx::Point(bottom.right(), bottom.y() + margin); 100 ring.points[19] = gfx::Point(bottom.right(), bottom.bottom() - margin); 101 ring.points[20] = gfx::Point(bottom.right(), bottom.bottom()); 102 ring.points[21] = gfx::Point(bottom.right() - margin, bottom.bottom()); 103 ring.points[22] = gfx::Point(bottom.x() + margin, bottom.bottom()); 104 ring.points[23] = gfx::Point(bottom.x(), bottom.bottom()); 105 ring.points[24] = gfx::Point(bottom.x(), bottom.bottom() - margin); 106 ring.points[25] = gfx::Point(bottom.x(), bottom.y() + margin); 107 ring.points[26] = gfx::Point(bottom.x(), bottom.y()); 108 if (bottom.x() > middle.x()) { 109 ring.points[27] = gfx::Point(bottom.x() - margin, bottom.y()); 110 ring.points[28] = gfx::Point(middle.x() + margin, middle.bottom()); 111 } else { 112 ring.points[27] = gfx::Point(bottom.x(), bottom.y()); 113 ring.points[28] = gfx::Point(middle.x(), middle.bottom()); 114 } 115 ring.points[29] = gfx::Point(middle.x(), middle.bottom()); 116 ring.points[30] = gfx::Point(middle.x(), middle.bottom() - margin); 117 ring.points[31] = gfx::Point(middle.x(), middle.y() + margin); 118 ring.points[32] = gfx::Point(middle.x(), middle.y()); 119 if (top.x() > middle.x()) { 120 ring.points[33] = gfx::Point(middle.x() + margin, middle.y()); 121 ring.points[34] = gfx::Point(top.x() - margin, top.bottom()); 122 } else { 123 ring.points[33] = gfx::Point(middle.x(), middle.y()); 124 ring.points[34] = gfx::Point(top.x(), top.bottom()); 125 } 126 ring.points[35] = gfx::Point(top.x(), top.bottom()); 127 128 return ring; 129 } 130 131 gfx::Rect AccessibilityFocusRing::GetBounds() const { 132 gfx::Point top_left = points[0]; 133 gfx::Point bottom_right = points[0]; 134 for (size_t i = 1; i < 36; ++i) { 135 top_left.SetToMin(points[i]); 136 bottom_right.SetToMax(points[i]); 137 } 138 return gfx::Rect(top_left, gfx::Size(bottom_right.x() - top_left.x(), 139 bottom_right.y() - top_left.y())); 140 } 141 142 } // namespace chromeos 143