• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/accessibility/accessibility_utils.h"
17 
18 namespace OHOS::Ace {
19 
20 const char ACCESSIBILITY_TAG_DIV[] = "div";
21 const char ACCESSIBILITY_TAG_CALENDAR[] = "calendar";
22 const char ACCESSIBILITY_TAG_TEXT[] = "text";
23 const char ACCESSIBILITY_TAG_PICKER[] = "picker";
24 const char ACCESSIBILITY_TAG_OPTION[] = "option";
25 const char ACCESSIBILITY_TAG_POPUP[] = "popup";
26 const char ACCESSIBILITY_TAG_PROGRESS[] = "progress";
27 const char ACCESSIBILITY_TAG_SELECT[] = "select";
28 const char ACCESSIBILITY_TAG_MENU[] = "menu";
29 const char ACCESSIBILITY_TAG_SLIDER[] = "slider";
30 const char ACCESSIBILITY_TAG_SPAN[] = "span";
31 const char ACCESSIBILITY_TAG_STACK[] = "stack";
32 const char ACCESSIBILITY_TAG_SWIPER[] = "swiper";
33 const char ACCESSIBILITY_TAG_SWITCH[] = "switch";
34 const char ACCESSIBILITY_TAG_TABS[] = "tabs";
35 const char ACCESSIBILITY_TAG_TAB_BAR[] = "tab-bar";
36 const char ACCESSIBILITY_TAG_TAB_CONTENT[] = "tab-content";
37 const char ACCESSIBILITY_TAG_REFRESH[] = "refresh";
38 const char ACCESSIBILITY_TAG_IMAGE[] = "image";
39 const char ACCESSIBILITY_TAG_LIST[] = "list";
40 const char ACCESSIBILITY_TAG_LIST_ITEM[] = "list-item";
41 const char ACCESSIBILITY_TAG_LIST_ITEM_GROUP[] = "list-item-group";
42 const char ACCESSIBILITY_TAG_VIDEO[] = "video";
43 const char ACCESSIBILITY_TAG_RATING[] = "rating";
44 const char ACCESSIBILITY_TAG_MARQUEE[] = "marquee";
45 const char ACCESSIBILITY_TAG_NAVIGATION_BAR[] = "navigation-bar";
46 const char ACCESSIBILITY_TAG_NAVIGATION_MENU[] = "navigation-menu";
47 const char ACCESSIBILITY_TAG_TEXTAREA[] = "textarea";
48 const char ACCESSIBILITY_TAG_INPUT[] = "input";
49 const char ACCESSIBILITY_TAG_LABEL[] = "label";
50 const char ACCESSIBILITY_TAG_DIVIDER[] = "divider";
51 const char ACCESSIBILITY_TAG_CANVAS[] = "canvas";
52 const char ACCESSIBILITY_TAG_BUTTON[] = "button";
53 const char ACCESSIBILITY_TAG_CHART[] = "chart";
54 const char ACCESSIBILITY_TAG_CLOCK[] = "clock";
55 const char ACCESSIBILITY_TAG_DIALOG[] = "dialog";
56 const char ACCESSIBILITY_TAG_SEARCH[] = "search";
57 
58 const int32_t WEIGHTED_VALUE = 13;
59 const int32_t FOCUS_DIRECTION_UP = 1;
60 const int32_t FOCUS_DIRECTION_DOWN = 1 << 1;
61 const int32_t FOCUS_DIRECTION_LEFT = 1 << 2;
62 const int32_t FOCUS_DIRECTION_RIGHT = 1 << 3;
63 const int32_t FOCUS_DIRECTION_FORWARD = 1 << 4;
64 const int32_t FOCUS_DIRECTION_BACKWARD = 1 << 5;
65 
CheckRectBeam(const Rect & nodeRect,const Rect & itemRect,const int direction)66 static bool CheckRectBeam(const Rect& nodeRect, const Rect& itemRect, const int direction)
67 {
68     switch (direction) {
69         case FOCUS_DIRECTION_LEFT:
70         case FOCUS_DIRECTION_RIGHT:
71             return nodeRect.Top() < itemRect.Bottom() && itemRect.Top() < nodeRect.Bottom();
72         case FOCUS_DIRECTION_UP:
73         case FOCUS_DIRECTION_DOWN:
74             return nodeRect.Left() < itemRect.Right() && itemRect.Left() < nodeRect.Right();
75         default:
76             break;
77     }
78     return false;
79 }
80 
IsToDirectionOf(const Rect & nodeRect,const Rect & itemRect,const int direction)81 static bool IsToDirectionOf(const Rect& nodeRect, const Rect& itemRect, const int direction)
82 {
83     switch (direction) {
84         case FOCUS_DIRECTION_LEFT:
85             return nodeRect.Left() >= itemRect.Right();
86         case FOCUS_DIRECTION_RIGHT:
87             return nodeRect.Right() <= itemRect.Left();
88         case FOCUS_DIRECTION_UP:
89             return nodeRect.Top() >= itemRect.Bottom();
90         case FOCUS_DIRECTION_DOWN:
91             return nodeRect.Bottom() <= itemRect.Top();
92         default:
93             break;
94     }
95     return false;
96 }
97 
MajorAxisDistanceToFarEdge(const Rect & nodeRect,const Rect & itemRect,const int direction)98 static double MajorAxisDistanceToFarEdge(const Rect& nodeRect, const Rect& itemRect, const int direction)
99 {
100     double distance = 0.0;
101     switch (direction) {
102         case FOCUS_DIRECTION_LEFT:
103             distance = nodeRect.Left() - itemRect.Left();
104             break;
105         case FOCUS_DIRECTION_RIGHT:
106             distance = nodeRect.Right() - itemRect.Right();
107             break;
108         case FOCUS_DIRECTION_UP:
109             distance = nodeRect.Top() - itemRect.Top();
110             break;
111         case FOCUS_DIRECTION_DOWN:
112             distance = nodeRect.Bottom() - itemRect.Bottom();
113             break;
114         default:
115             break;
116     }
117 
118     return distance > 1.0 ? distance : 1.0;
119 }
120 
MajorAxisDistance(const Rect & nodeRect,const Rect & itemRect,const int direction)121 static double MajorAxisDistance(const Rect& nodeRect, const Rect& itemRect, const int direction)
122 {
123     double distance = 0.0;
124     switch (direction) {
125         case FOCUS_DIRECTION_LEFT:
126             distance = nodeRect.Left() - itemRect.Right();
127             break;
128         case FOCUS_DIRECTION_RIGHT:
129             distance = nodeRect.Right() - itemRect.Left();
130             break;
131         case FOCUS_DIRECTION_UP:
132             distance = nodeRect.Top() - itemRect.Bottom();
133             break;
134         case FOCUS_DIRECTION_DOWN:
135             distance = nodeRect.Bottom() - itemRect.Top();
136             break;
137         default:
138             break;
139     }
140 
141     return distance > 0.0 ? distance : 0.0;
142 }
143 
MinorAxisDistance(const Rect & nodeRect,const Rect & itemRect,const int direction)144 static double MinorAxisDistance(const Rect& nodeRect, const Rect& itemRect, const int direction)
145 {
146     double distance = 0.0;
147     switch (direction) {
148         case FOCUS_DIRECTION_LEFT:
149         case FOCUS_DIRECTION_RIGHT:
150             distance = (nodeRect.Top() + nodeRect.Bottom()) / 2 - (itemRect.Top() + itemRect.Bottom()) / 2;
151             break;
152         case FOCUS_DIRECTION_UP:
153         case FOCUS_DIRECTION_DOWN:
154             distance = (nodeRect.Left() + nodeRect.Right()) / 2 - (itemRect.Left() + itemRect.Right()) / 2;
155             break;
156         default:
157             break;
158     }
159 
160     return distance > 0.0 ? distance : -distance;
161 }
162 
GetWeightedDistanceFor(double majorAxisDistance,double minorAxisDistance)163 static double GetWeightedDistanceFor(double majorAxisDistance, double minorAxisDistance)
164 {
165     return WEIGHTED_VALUE * majorAxisDistance * majorAxisDistance + minorAxisDistance * minorAxisDistance;
166 }
167 
IsCandidateRect(const Rect & nodeRect,const Rect & itemRect,const int direction)168 static bool IsCandidateRect(const Rect& nodeRect, const Rect& itemRect, const int direction)
169 {
170     switch (direction) {
171         case FOCUS_DIRECTION_LEFT:
172             return nodeRect.Left() > itemRect.Left() && nodeRect.Right() > itemRect.Right();
173         case FOCUS_DIRECTION_RIGHT:
174             return nodeRect.Left() < itemRect.Left() && nodeRect.Right() < itemRect.Right();
175         case FOCUS_DIRECTION_UP:
176             return nodeRect.Top() > itemRect.Top() && nodeRect.Bottom() > itemRect.Bottom();
177         case FOCUS_DIRECTION_DOWN:
178             return nodeRect.Top() < itemRect.Top() && nodeRect.Bottom() < itemRect.Bottom();
179         default:
180             break;
181     }
182     return false;
183 }
184 
185 // Check whether rect1 is outright better than rect2.
OutrightBetter(const Rect & nodeRect,const int direction,const Rect & Rect1,const Rect & Rect2)186 static bool OutrightBetter(const Rect& nodeRect, const int direction, const Rect& Rect1, const Rect& Rect2)
187 {
188     bool rect1InSrcBeam = CheckRectBeam(nodeRect, Rect1, direction);
189     bool rect2InSrcBeam = CheckRectBeam(nodeRect, Rect2, direction);
190     if (rect2InSrcBeam || !rect1InSrcBeam) {
191         return false;
192     }
193 
194     if (!IsToDirectionOf(nodeRect, Rect2, direction)) {
195         return true;
196     }
197 
198     // for direction left or right
199     if (direction == FOCUS_DIRECTION_LEFT || direction == FOCUS_DIRECTION_RIGHT) {
200         return true;
201     }
202 
203     return (MajorAxisDistance(nodeRect, Rect1, direction) < MajorAxisDistanceToFarEdge(nodeRect, Rect2, direction));
204 }
205 
CheckBetterRect(const Rect & nodeRect,const int direction,const Rect & itemRect,const Rect & tempBest)206 bool CheckBetterRect(const Rect& nodeRect, const int direction, const Rect& itemRect, const Rect& tempBest)
207 {
208     if (!IsCandidateRect(nodeRect, itemRect, direction)) {
209         return false;
210     }
211 
212     if (!IsCandidateRect(nodeRect, tempBest, direction)) {
213         return true;
214     }
215 
216     // now both of item and tempBest are all at the direction of node.
217     if (OutrightBetter(nodeRect, direction, itemRect, tempBest)) {
218         return true;
219     }
220 
221     if (OutrightBetter(nodeRect, direction, tempBest, itemRect)) {
222         return false;
223     }
224 
225     // otherwise, do fudge-tastic comparison of the major and minor axis
226     return (GetWeightedDistanceFor(
227                 MajorAxisDistance(nodeRect, itemRect, direction), MinorAxisDistance(nodeRect, itemRect, direction)) <
228             GetWeightedDistanceFor(
229                 MajorAxisDistance(nodeRect, tempBest, direction), MinorAxisDistance(nodeRect, tempBest, direction)));
230 }
231 
232 }  // namespace OHOS::Ace