1 /*
2 * Copyright (c) 2025 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/components_ng/pattern/xcomponent/xcomponent_utils.h"
17
18 #include "core/components/xcomponent/native_interface_xcomponent_impl.h"
19
20 namespace OHOS::Ace::NG {
RoundValueToPixelGrid(float value,bool isRound,bool forceCeil,bool forceFloor)21 float XComponentUtils::RoundValueToPixelGrid(float value, bool isRound, bool forceCeil, bool forceFloor)
22 {
23 float fractials = fmod(value, 1.0f);
24 if (fractials < 0.0f) {
25 ++fractials;
26 }
27 if (forceCeil) {
28 return (value - fractials + 1.0f);
29 } else if (forceFloor) {
30 return (value - fractials);
31 } else if (isRound) {
32 if (NearEqual(fractials, 1.0f) || GreatOrEqual(fractials, 0.50f)) {
33 return (value - fractials + 1.0f);
34 } else {
35 return (value - fractials);
36 }
37 }
38 return value;
39 }
40
AdjustPaintRect(float positionX,float positionY,float width,float height,bool isRound)41 RectF XComponentUtils::AdjustPaintRect(float positionX, float positionY, float width, float height, bool isRound)
42 {
43 RectF rect;
44 float relativeLeft = positionX;
45 float relativeTop = positionY;
46 float nodeWidth = width;
47 float nodeHeight = height;
48 float absoluteRight = relativeLeft + nodeWidth;
49 float absoluteBottom = relativeTop + nodeHeight;
50 float roundToPixelErrorX = 0;
51 float roundToPixelErrorY = 0;
52
53 float nodeLeftI = RoundValueToPixelGrid(relativeLeft, isRound, false, false);
54 float nodeTopI = RoundValueToPixelGrid(relativeTop, isRound, false, false);
55 roundToPixelErrorX += nodeLeftI - relativeLeft;
56 roundToPixelErrorY += nodeTopI - relativeTop;
57 rect.SetLeft(nodeLeftI);
58 rect.SetTop(nodeTopI);
59
60 float nodeWidthI = RoundValueToPixelGrid(absoluteRight, isRound, false, false) - nodeLeftI;
61 float nodeWidthTemp = RoundValueToPixelGrid(nodeWidth, isRound, false, false);
62 roundToPixelErrorX += nodeWidthI - nodeWidth;
63 if (roundToPixelErrorX > 0.5f) {
64 nodeWidthI -= 1.0f;
65 roundToPixelErrorX -= 1.0f;
66 }
67 if (roundToPixelErrorX < -0.5f) {
68 nodeWidthI += 1.0f;
69 roundToPixelErrorX += 1.0f;
70 }
71 if (nodeWidthI < nodeWidthTemp) {
72 roundToPixelErrorX += nodeWidthTemp - nodeWidthI;
73 nodeWidthI = nodeWidthTemp;
74 }
75
76 float nodeHeightI = RoundValueToPixelGrid(absoluteBottom, isRound, false, false) - nodeTopI;
77 float nodeHeightTemp = RoundValueToPixelGrid(nodeHeight, isRound, false, false);
78 roundToPixelErrorY += nodeHeightI - nodeHeight;
79 if (roundToPixelErrorY > 0.5f) {
80 nodeHeightI -= 1.0f;
81 roundToPixelErrorY -= 1.0f;
82 }
83 if (roundToPixelErrorY < -0.5f) {
84 nodeHeightI += 1.0f;
85 roundToPixelErrorY += 1.0f;
86 }
87 if (nodeHeightI < nodeHeightTemp) {
88 roundToPixelErrorY += nodeHeightTemp - nodeHeightI;
89 nodeHeightI = nodeHeightTemp;
90 }
91
92 rect.SetWidth(nodeWidthI);
93 rect.SetHeight(nodeHeightI);
94 return rect;
95 }
96
XComponentRenderFitToString(RenderFit renderFit)97 std::string XComponentUtils::XComponentRenderFitToString(RenderFit renderFit)
98 {
99 static const std::string renderFitStyles[] = { "RenderFit.CENTER", "RenderFit.TOP", "RenderFit.BOTTOM",
100 "RenderFit.LEFT", "RenderFit.RIGHT", "RenderFit.TOP_LEFT", "RenderFit.TOP_RIGHT", "RenderFit.BOTTOM_LEFT",
101 "RenderFit.BOTTOM_RIGHT", "RenderFit.RESIZE_FILL", "RenderFit.RESIZE_CONTAIN",
102 "RenderFit.RESIZE_CONTAIN_TOP_LEFT", "RenderFit.RESIZE_CONTAIN_BOTTOM_RIGHT", "RenderFit.RESIZE_COVER",
103 "RenderFit.RESIZE_COVER_TOP_LEFT", "RenderFit.RESIZE_COVER_BOTTOM_RIGHT" };
104 return renderFitStyles[static_cast<int>(renderFit)];
105 }
106
ConvertNativeXComponentMouseEventAction(MouseAction mouseAction)107 OH_NativeXComponent_MouseEventAction XComponentUtils::ConvertNativeXComponentMouseEventAction(MouseAction mouseAction)
108 {
109 switch (mouseAction) {
110 case MouseAction::PRESS:
111 return OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_PRESS;
112 case MouseAction::RELEASE:
113 return OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_RELEASE;
114 case MouseAction::MOVE:
115 return OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_MOVE;
116 case MouseAction::CANCEL:
117 return OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_CANCEL;
118 default:
119 return OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_MOUSE_NONE;
120 }
121 }
122
ConvertNativeXComponentMouseEventButton(MouseButton mouseButton)123 OH_NativeXComponent_MouseEventButton XComponentUtils::ConvertNativeXComponentMouseEventButton(MouseButton mouseButton)
124 {
125 switch (mouseButton) {
126 case MouseButton::LEFT_BUTTON:
127 return OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_LEFT_BUTTON;
128 case MouseButton::RIGHT_BUTTON:
129 return OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_RIGHT_BUTTON;
130 case MouseButton::MIDDLE_BUTTON:
131 return OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_MIDDLE_BUTTON;
132 case MouseButton::BACK_BUTTON:
133 return OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_BACK_BUTTON;
134 case MouseButton::FORWARD_BUTTON:
135 return OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_FORWARD_BUTTON;
136 default:
137 return OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_NONE_BUTTON;
138 }
139 }
140
ConvertNativeXComponentTouchEvent(const TouchType & touchType)141 OH_NativeXComponent_TouchEventType XComponentUtils::ConvertNativeXComponentTouchEvent(const TouchType& touchType)
142 {
143 switch (touchType) {
144 case TouchType::DOWN:
145 return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_DOWN;
146 case TouchType::UP:
147 return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UP;
148 case TouchType::MOVE:
149 return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_MOVE;
150 case TouchType::CANCEL:
151 return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_CANCEL;
152 default:
153 return OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UNKNOWN;
154 }
155 }
156
ConvertNativeXComponentTouchToolType(const SourceTool & toolType)157 OH_NativeXComponent_TouchPointToolType XComponentUtils::ConvertNativeXComponentTouchToolType(const SourceTool& toolType)
158 {
159 switch (toolType) {
160 case SourceTool::FINGER:
161 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_FINGER;
162 case SourceTool::PEN:
163 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_PEN;
164 case SourceTool::RUBBER:
165 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_RUBBER;
166 case SourceTool::BRUSH:
167 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_BRUSH;
168 case SourceTool::PENCIL:
169 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_PENCIL;
170 case SourceTool::AIRBRUSH:
171 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_AIRBRUSH;
172 case SourceTool::MOUSE:
173 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_MOUSE;
174 case SourceTool::LENS:
175 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_LENS;
176 default:
177 return OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN;
178 }
179 }
180
ConvertNativeXComponentKeyAction(const KeyAction & keyAction)181 OH_NativeXComponent_KeyAction XComponentUtils::ConvertNativeXComponentKeyAction(const KeyAction& keyAction)
182 {
183 switch (keyAction) {
184 case KeyAction::DOWN:
185 return OH_NativeXComponent_KeyAction::OH_NATIVEXCOMPONENT_KEY_ACTION_DOWN;
186 case KeyAction::UP:
187 return OH_NativeXComponent_KeyAction::OH_NATIVEXCOMPONENT_KEY_ACTION_UP;
188 default:
189 return OH_NativeXComponent_KeyAction::OH_NATIVEXCOMPONENT_KEY_ACTION_UNKNOWN;
190 }
191 }
192
ConvertNativeXComponentEventSourceType(const SourceType & sourceType)193 OH_NativeXComponent_EventSourceType XComponentUtils::ConvertNativeXComponentEventSourceType(
194 const SourceType& sourceType)
195 {
196 switch (sourceType) {
197 case SourceType::MOUSE:
198 return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_MOUSE;
199 case SourceType::TOUCH:
200 return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_TOUCHSCREEN;
201 case SourceType::TOUCH_PAD:
202 return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_TOUCHPAD;
203 case SourceType::KEYBOARD:
204 return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_KEYBOARD;
205 default:
206 return OH_NativeXComponent_EventSourceType::OH_NATIVEXCOMPONENT_SOURCE_TYPE_UNKNOWN;
207 }
208 }
209
ConvertNativeXComponentKeyEvent(const KeyEvent & event)210 OH_NativeXComponent_KeyEvent XComponentUtils::ConvertNativeXComponentKeyEvent(const KeyEvent& event)
211 {
212 OH_NativeXComponent_KeyEvent nativeKeyEvent;
213 nativeKeyEvent.action = ConvertNativeXComponentKeyAction(event.action);
214 nativeKeyEvent.code = static_cast<OH_NativeXComponent_KeyCode>(event.code);
215 nativeKeyEvent.sourceType = ConvertNativeXComponentEventSourceType(event.sourceType);
216 nativeKeyEvent.deviceId = event.deviceId;
217 nativeKeyEvent.timestamp = event.timeStamp.time_since_epoch().count();
218 nativeKeyEvent.modifierKeyStates = CalculateModifierKeyState(event.pressedCodes);
219 nativeKeyEvent.isNumLockOn = event.numLock;
220 nativeKeyEvent.isCapsLockOn = event.enableCapsLock;
221 nativeKeyEvent.isScrollLockOn = event.scrollLock;
222 return nativeKeyEvent;
223 }
224
ConvertNativeXComponentAnalyzerStatus(const ImageAnalyzerState state)225 ArkUI_XComponent_ImageAnalyzerState XComponentUtils::ConvertNativeXComponentAnalyzerStatus(
226 const ImageAnalyzerState state)
227 {
228 switch (state) {
229 case ImageAnalyzerState::UNSUPPORTED:
230 return ArkUI_XComponent_ImageAnalyzerState::ARKUI_XCOMPONENT_AI_ANALYSIS_UNSUPPORTED;
231 case ImageAnalyzerState::ONGOING:
232 return ArkUI_XComponent_ImageAnalyzerState::ARKUI_XCOMPONENT_AI_ANALYSIS_ONGOING;
233 case ImageAnalyzerState::STOPPED:
234 return ArkUI_XComponent_ImageAnalyzerState::ARKUI_XCOMPONENT_AI_ANALYSIS_STOPPED;
235 case ImageAnalyzerState::FINISHED:
236 return ArkUI_XComponent_ImageAnalyzerState::ARKUI_XCOMPONENT_AI_ANALYSIS_FINISHED;
237 default:
238 return ArkUI_XComponent_ImageAnalyzerState::ARKUI_XCOMPONENT_AI_ANALYSIS_DISABLED;
239 }
240 }
241 } // namespace OHOS::Ace::NG
242