• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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/overlay/sheet_wrapper_paint_method.h"
17 
18 #include "base/geometry/ng/offset_t.h"
19 #include "base/utils/utils.h"
20 #include "core/components/common/properties/shadow_config.h"
21 #include "core/components_ng/pattern/overlay/sheet_presentation_pattern.h"
22 #include "core/components_ng/pattern/overlay/sheet_style.h"
23 #include "core/components_ng/pattern/overlay/sheet_wrapper_pattern.h"
24 #include "core/components_ng/render/drawing.h"
25 #include "core/components_ng/render/drawing_prop_convertor.h"
26 #include "core/components_ng/render/paint_wrapper.h"
27 #include "core/pipeline_ng/pipeline_context.h"
28 
29 namespace OHOS::Ace::NG {
30 namespace {
31 constexpr Dimension ARROW_VERTICAL_P1_OFFSET_X = 8.0_vp;
32 constexpr Dimension ARROW_VERTICAL_P2_OFFSET_X = 1.5_vp;
33 constexpr Dimension ARROW_VERTICAL_P2_OFFSET_Y = 7.32_vp;
34 constexpr Dimension ARROW_VERTICAL_P4_OFFSET_X = 1.5_vp;
35 constexpr Dimension ARROW_VERTICAL_P4_OFFSET_Y = 7.32_vp;
36 constexpr Dimension ARROW_VERTICAL_P5_OFFSET_X = 8.0_vp;
37 constexpr Dimension ARROW_CORNER_P2_OFFSET_X = 12.8_vp;
38 constexpr Dimension ARROW_CORNER_P2_OFFSET_Y = 7.6_vp;
39 constexpr Dimension ARROW_CORNER_P4_OFFSET_Y = 6.0_vp;
40 constexpr Dimension ARROW_RADIUS = 2.0_vp;
41 constexpr float BLUR_MASK_FILTER = 0.55f;
42 constexpr float HALF = 0.5f;
43 } // namespace
44 
PaintOuterBorder(RSCanvas & canvas,PaintWrapper * paintWrapper)45 void SheetWrapperPaintMethod::PaintOuterBorder(RSCanvas& canvas, PaintWrapper* paintWrapper)
46 {
47     CHECK_NULL_VOID(paintWrapper);
48     CHECK_EQUAL_VOID(IsDrawBorder(paintWrapper), false);
49     auto sheetNode = GetSheetNode(paintWrapper);
50     CHECK_NULL_VOID(sheetNode);
51     auto pipeline = sheetNode->GetContext();
52     CHECK_NULL_VOID(pipeline);
53     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
54     CHECK_NULL_VOID(sheetTheme);
55     RSPath path;
56     auto outerBorderWidth = sheetTheme->GetSheetOuterBorderWidth().ConvertToPx();
57     auto sheetPattern = DynamicCast<SheetPresentationPattern>(sheetNode->GetPattern());
58     CHECK_NULL_VOID(sheetPattern);
59     BorderRadiusProperty sheetRadius(sheetTheme->GetSheetRadius());
60     sheetPattern->CalculateSheetRadius(sheetRadius);
61     GetBorderDrawPath(path, sheetNode, sheetTheme, outerBorderWidth, sheetRadius);
62     RSPen pen;
63     SetBorderPenStyle(pen, sheetTheme->GetSheetOuterBorderWidth(), sheetTheme->GetSheetOuterBorderColor());
64     canvas.Save();
65     canvas.AttachPen(pen);
66     canvas.DrawPath(path);
67     canvas.DetachPen();
68     canvas.Restore();
69     path.Close();
70 }
71 
GetSheetNode(PaintWrapper * paintWrapper)72 RefPtr<FrameNode> SheetWrapperPaintMethod::GetSheetNode(PaintWrapper* paintWrapper)
73 {
74     CHECK_NULL_RETURN(paintWrapper, nullptr);
75     auto renderContext = paintWrapper->GetRenderContext();
76     CHECK_NULL_RETURN(renderContext, nullptr);
77     auto host = renderContext->GetHost();
78     CHECK_NULL_RETURN(host, nullptr);
79     auto sheetNode = DynamicCast<FrameNode>(host->GetFirstChild());
80     CHECK_NULL_RETURN(sheetNode, nullptr);
81     return sheetNode;
82 }
83 
GetBorderDrawPath(RSPath & path,const RefPtr<FrameNode> sheetNode,const RefPtr<SheetTheme> & sheetTheme,float borderWidth,const BorderRadiusProperty & sheetRadius)84 void SheetWrapperPaintMethod::GetBorderDrawPath(RSPath& path, const RefPtr<FrameNode> sheetNode,
85     const RefPtr<SheetTheme>& sheetTheme, float borderWidth, const BorderRadiusProperty& sheetRadius)
86 {
87     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
88         GetBorderDrawPathNew(path, sheetNode, borderWidth, sheetRadius);
89         return;
90     }
91     auto sheetPattern = DynamicCast<SheetPresentationPattern>(sheetNode->GetPattern());
92     CHECK_NULL_VOID(sheetPattern);
93     auto geometryNode = sheetNode->GetGeometryNode();
94     CHECK_NULL_VOID(geometryNode);
95     auto sheetSize = geometryNode->GetFrameSize();
96     auto radiusTopLeft = sheetRadius.radiusTopLeft->ConvertToPx();
97     auto radiusTopRight = sheetRadius.radiusTopRight->ConvertToPx();
98     auto radiusBottomRight = sheetRadius.radiusBottomRight->ConvertToPx();
99     auto radiusBottomLeft = sheetRadius.radiusBottomLeft->ConvertToPx();
100     auto borderOffset = borderWidth * HALF;
101     auto arrowOffset = sheetPattern->GetSheetArrowOffset().GetX();
102     auto targetOffsetX = sheetNode->GetPositionToParentWithTransform().GetX();
103     auto targetOffsetY = sheetNode->GetPositionToParentWithTransform().GetY();
104     auto arrowHeight = SHEET_ARROW_HEIGHT.ConvertToPx();
105     path.Reset();
106     path.MoveTo(targetOffsetX - borderOffset, arrowHeight + radiusTopLeft + targetOffsetY);
107     if (LessNotEqual(radiusTopLeft, sheetSize.Width() * HALF - ARROW_VERTICAL_P1_OFFSET_X.ConvertToPx())) {
108         // When radius is less than half the page width, draw radius and P1
109         path.ArcTo(radiusTopLeft + borderOffset, radiusTopLeft + borderOffset, 0.0f, RSPathDirection::CW_DIRECTION,
110             radiusTopLeft + targetOffsetX, arrowHeight + targetOffsetY - borderOffset);
111         path.LineTo(arrowOffset - ARROW_VERTICAL_P1_OFFSET_X.ConvertToPx() + targetOffsetX,
112             arrowHeight + targetOffsetY - borderOffset); // P1
113     } else {
114         // Change the end point of radius, skip P1 and draw P2 to P3 directly
115         path.ArcTo(radiusTopLeft + borderOffset, radiusTopLeft + borderOffset, 0.0f, RSPathDirection::CW_DIRECTION,
116             sheetSize.Width() * HALF - ARROW_VERTICAL_P1_OFFSET_X.ConvertToPx() + targetOffsetX,
117             arrowHeight + targetOffsetY - borderOffset);
118     }
119     path.LineTo(arrowOffset - ARROW_VERTICAL_P2_OFFSET_X.ConvertToPx() + targetOffsetX - borderOffset,
120         arrowHeight - ARROW_VERTICAL_P2_OFFSET_Y.ConvertToPx() + targetOffsetY); // P2
121     path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.0f,
122         RSPathDirection::CW_DIRECTION,
123         arrowOffset + ARROW_VERTICAL_P4_OFFSET_X.ConvertToPx() + targetOffsetX + borderOffset,
124         arrowHeight - ARROW_VERTICAL_P4_OFFSET_Y.ConvertToPx() + targetOffsetY); // P4
125     path.LineTo(arrowOffset + ARROW_VERTICAL_P5_OFFSET_X.ConvertToPx() + targetOffsetX,
126         arrowHeight + targetOffsetY - borderOffset); // P5
127     if (LessNotEqual(radiusTopRight, sheetSize.Width() * HALF - ARROW_VERTICAL_P5_OFFSET_X.ConvertToPx())) {
128         // When radius is less than half the page width, draw P5
129         path.LineTo(sheetSize.Width() - radiusTopRight + targetOffsetX, arrowHeight + targetOffsetY - borderOffset);
130     }
131     path.ArcTo(radiusTopRight + borderOffset, radiusTopRight + borderOffset, 0.0f, RSPathDirection::CW_DIRECTION,
132         sheetSize.Width() + targetOffsetX + borderOffset, arrowHeight + radiusTopRight + targetOffsetY);
133     path.LineTo(
134         sheetSize.Width() + targetOffsetX + borderOffset, sheetSize.Height() - radiusBottomRight + targetOffsetY);
135     path.ArcTo(radiusBottomRight + borderOffset, radiusBottomRight + borderOffset, 0.0f, RSPathDirection::CW_DIRECTION,
136         sheetSize.Width() - radiusBottomRight + targetOffsetX, sheetSize.Height() + targetOffsetY + borderOffset);
137     path.LineTo(radiusBottomLeft + targetOffsetX, sheetSize.Height() + targetOffsetY + borderOffset);
138     path.ArcTo(radiusBottomLeft + borderOffset, radiusBottomLeft + borderOffset, 0.0f, RSPathDirection::CW_DIRECTION,
139         targetOffsetX - borderOffset, sheetSize.Height() - radiusBottomLeft + targetOffsetY);
140     path.LineTo(targetOffsetX - borderOffset, arrowHeight + radiusTopLeft + targetOffsetY);
141 }
142 
PaintInnerBorder(RSCanvas & canvas,PaintWrapper * paintWrapper)143 void SheetWrapperPaintMethod::PaintInnerBorder(RSCanvas& canvas, PaintWrapper* paintWrapper)
144 {
145     CHECK_NULL_VOID(paintWrapper);
146     CHECK_EQUAL_VOID(IsDrawBorder(paintWrapper), false);
147     auto sheetNode = GetSheetNode(paintWrapper);
148     CHECK_NULL_VOID(sheetNode);
149     auto pipeline = sheetNode->GetContext();
150     CHECK_NULL_VOID(pipeline);
151     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
152     CHECK_NULL_VOID(sheetTheme);
153     RSPath path;
154     auto innerBorderWidth = -(sheetTheme->GetSheetInnerBorderWidth().ConvertToPx());
155     auto sheetPattern = DynamicCast<SheetPresentationPattern>(sheetNode->GetPattern());
156     CHECK_NULL_VOID(sheetPattern);
157     BorderRadiusProperty sheetRadius(sheetTheme->GetSheetRadius());
158     sheetPattern->CalculateSheetRadius(sheetRadius);
159     GetBorderDrawPath(path, sheetNode, sheetTheme, innerBorderWidth, sheetRadius);
160     RSPen pen;
161     SetBorderPenStyle(pen, sheetTheme->GetSheetInnerBorderWidth(), sheetTheme->GetSheetInnerBorderColor());
162     canvas.Save();
163     canvas.AttachPen(pen);
164     canvas.DrawPath(path);
165     canvas.DetachPen();
166     canvas.Restore();
167     path.Close();
168 }
169 
SetBorderPenStyle(RSPen & pen,const Dimension & borderWidth,const Color & borderColor)170 void SheetWrapperPaintMethod::SetBorderPenStyle(RSPen& pen, const Dimension& borderWidth, const Color& borderColor)
171 {
172     RSFilter filter;
173     filter.SetMaskFilter(RSMaskFilter::CreateBlurMaskFilter(RSBlurType::SOLID, BLUR_MASK_FILTER));
174     pen.SetFilter(filter);
175     pen.SetAntiAlias(true);
176     pen.SetWidth(borderWidth.ConvertToPx());
177     pen.SetColor(borderColor.GetValue());
178 }
179 
IsDrawBorder(PaintWrapper * paintWrapper)180 bool SheetWrapperPaintMethod::IsDrawBorder(PaintWrapper* paintWrapper)
181 {
182     auto sheetNode = GetSheetNode(paintWrapper);
183     CHECK_NULL_RETURN(sheetNode, false);
184     auto sheetPattern = DynamicCast<SheetPresentationPattern>(sheetNode->GetPattern());
185     CHECK_NULL_RETURN(sheetPattern, false);
186     auto sheetType = sheetPattern->GetSheetTypeNoProcess();
187     auto pipeline = sheetNode->GetContext();
188     CHECK_NULL_RETURN(pipeline, false);
189     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
190     CHECK_NULL_RETURN(sheetTheme, false);
191     auto layoutProperty = sheetNode->GetLayoutProperty<SheetPresentationProperty>();
192     CHECK_NULL_RETURN(layoutProperty, false);
193     auto sheetStyle = layoutProperty->GetSheetStyleValue();
194     if (sheetTheme->IsOuterBorderEnable() && sheetType == SheetType::SHEET_POPUP &&
195         !sheetStyle.borderWidth.has_value()) {
196         return true;
197     }
198     return false;
199 }
200 
GetBorderDrawPathNew(RSPath & path,const RefPtr<FrameNode> sheetNode,float borderWidth,const BorderRadiusProperty & sheetRadius)201 void SheetWrapperPaintMethod::GetBorderDrawPathNew(RSPath& path, const RefPtr<FrameNode> sheetNode,
202     float borderWidth, const BorderRadiusProperty& sheetRadius)
203 {
204     auto sheetPattern = DynamicCast<SheetPresentationPattern>(sheetNode->GetPattern());
205     CHECK_NULL_VOID(sheetPattern);
206     auto sheetPopupInfo = sheetPattern->GetSheetPopupInfo();
207     if (!sheetPopupInfo.showArrow) {
208         DrawClipPathWithoutArrow(path, sheetNode, sheetRadius, borderWidth);
209         return;
210     }
211     switch (sheetPopupInfo.finalPlacement) {
212         case Placement::BOTTOM_LEFT:
213             [[fallthrough]];
214         case Placement::BOTTOM_RIGHT:
215             [[fallthrough]];
216         case Placement::BOTTOM: {
217             DrawClipPathBottom(path, sheetNode, sheetRadius, borderWidth, sheetPopupInfo);
218             break;
219         }
220         case Placement::TOP_LEFT:
221             [[fallthrough]];
222         case Placement::TOP_RIGHT:
223             [[fallthrough]];
224         case Placement::TOP: {
225             DrawClipPathTop(path, sheetNode, sheetRadius, borderWidth, sheetPopupInfo);
226             break;
227         }
228         case Placement::RIGHT_TOP:
229             [[fallthrough]];
230         case Placement::RIGHT_BOTTOM:
231             [[fallthrough]];
232         case Placement::RIGHT: {
233             DrawClipPathRight(path, sheetNode, sheetRadius, borderWidth, sheetPopupInfo);
234             break;
235         }
236         case Placement::LEFT_TOP:
237             [[fallthrough]];
238         case Placement::LEFT_BOTTOM:
239             [[fallthrough]];
240         case Placement::LEFT: {
241             DrawClipPathLeft(path, sheetNode, sheetRadius, borderWidth, sheetPopupInfo);
242             break;
243         }
244         default:
245             break;
246     }
247 }
248 
DrawClipPathBottom(RSPath & path,const RefPtr<FrameNode> sheetNode,const BorderRadiusProperty & sheetRadius,float borderWidth,const SheetPopupInfo & sheetPopupInfo)249 void SheetWrapperPaintMethod::DrawClipPathBottom(RSPath& path, const RefPtr<FrameNode> sheetNode,
250     const BorderRadiusProperty& sheetRadius, float borderWidth, const SheetPopupInfo& sheetPopupInfo)
251 {
252     auto geometryNode = sheetNode->GetGeometryNode();
253     CHECK_NULL_VOID(geometryNode);
254     auto sheetSize = geometryNode->GetFrameSize();
255     auto radiusTopLeft = sheetRadius.radiusTopLeft->ConvertToPx();
256     auto radiusTopRight = sheetRadius.radiusTopRight->ConvertToPx();
257     auto radiusBottomRight = sheetRadius.radiusBottomRight->ConvertToPx();
258     auto radiusBottomLeft = sheetRadius.radiusBottomLeft->ConvertToPx();
259     auto borderOffset = borderWidth * HALF;
260     auto targetOffsetX = sheetNode->GetPositionToParentWithTransform().GetX();
261     auto targetOffsetY = sheetNode->GetPositionToParentWithTransform().GetY();
262     OffsetF arrowOffset(sheetPopupInfo.arrowOffsetX, sheetPopupInfo.arrowOffsetY);
263     auto arrowPosition = sheetPopupInfo.arrowPosition;
264     // clip path start from TopLeft, and draw Right-angled arrow first if needed
265     path.Reset();
266     if (arrowPosition == SheetArrowPosition::BOTTOM_LEFT) {
267         path.MoveTo(targetOffsetX - borderOffset, targetOffsetY + SHEET_ARROW_HEIGHT.ConvertToPx());  // P5
268         path.LineTo(targetOffsetX - borderOffset,
269             targetOffsetY + (SHEET_ARROW_HEIGHT - ARROW_CORNER_P4_OFFSET_Y).ConvertToPx()); // P4
270         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset,
271             0.f, RSPathDirection::CW_DIRECTION,
272             (SHEET_ARROW_WIDTH - ARROW_CORNER_P2_OFFSET_X).ConvertToPx() + targetOffsetX + borderOffset,
273             (SHEET_ARROW_HEIGHT - ARROW_CORNER_P2_OFFSET_Y).ConvertToPx() + targetOffsetY); // P2
274         path.LineTo(SHEET_ARROW_WIDTH.ConvertToPx() + targetOffsetX,
275             SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY - borderOffset);  // P1
276     } else {
277         path.MoveTo(targetOffsetX - borderOffset, SHEET_ARROW_HEIGHT.ConvertToPx() + radiusTopLeft + targetOffsetY);
278         path.ArcTo(radiusTopLeft + borderOffset, radiusTopLeft + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
279             radiusTopLeft + targetOffsetX, SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY - borderOffset);
280     }
281     if (arrowPosition == SheetArrowPosition::NONE) {
282         path.LineTo(arrowOffset.GetX() - ARROW_VERTICAL_P1_OFFSET_X.ConvertToPx() + targetOffsetX,
283             SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY - borderOffset);  // P1
284         path.LineTo(arrowOffset.GetX() - ARROW_VERTICAL_P2_OFFSET_X.ConvertToPx() + targetOffsetX - borderOffset,
285             (SHEET_ARROW_HEIGHT - ARROW_VERTICAL_P2_OFFSET_Y).ConvertToPx() + targetOffsetY);   // P2
286         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset,
287             0.f, RSPathDirection::CW_DIRECTION,
288             arrowOffset.GetX() + ARROW_VERTICAL_P4_OFFSET_X.ConvertToPx() + targetOffsetX + borderOffset,
289             (SHEET_ARROW_HEIGHT - ARROW_VERTICAL_P4_OFFSET_Y).ConvertToPx() + targetOffsetY);   // P4
290         path.LineTo(arrowOffset.GetX() + ARROW_VERTICAL_P5_OFFSET_X.ConvertToPx() + targetOffsetX,
291             SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY - borderOffset);  // P5
292     }
293     if (arrowPosition == SheetArrowPosition::BOTTOM_RIGHT) {
294         path.LineTo(sheetSize.Width() - SHEET_ARROW_WIDTH.ConvertToPx() + targetOffsetX,
295             SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY - borderOffset);  // P1
296         path.LineTo(sheetSize.Width() - (SHEET_ARROW_WIDTH - ARROW_CORNER_P2_OFFSET_X).ConvertToPx() +
297             targetOffsetX - borderOffset,
298             (SHEET_ARROW_HEIGHT - ARROW_CORNER_P2_OFFSET_Y).ConvertToPx() + targetOffsetY); // P2
299         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.0f,
300             RSPathDirection::CW_DIRECTION, sheetSize.Width() + targetOffsetX + borderOffset,
301             (SHEET_ARROW_HEIGHT - ARROW_CORNER_P4_OFFSET_Y).ConvertToPx() + targetOffsetY);  // P4
302         path.LineTo(sheetSize.Width() + targetOffsetX + borderOffset,
303             SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY);    // P5
304     } else {
305         path.LineTo(sheetSize.Width() - radiusTopRight + targetOffsetX,
306             SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY - borderOffset);
307         path.ArcTo(radiusTopRight + borderOffset, radiusTopRight + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
308             sheetSize.Width() + targetOffsetX + borderOffset,
309             SHEET_ARROW_HEIGHT.ConvertToPx() + radiusTopRight + targetOffsetY);
310     }
311     path.LineTo(sheetSize.Width() + targetOffsetX + borderOffset,
312         sheetSize.Height() - radiusBottomRight + targetOffsetY);
313     path.ArcTo(radiusBottomRight + borderOffset, radiusBottomRight + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
314         sheetSize.Width() - radiusBottomRight + targetOffsetX, sheetSize.Height() + targetOffsetY + borderOffset);
315     path.LineTo(radiusBottomLeft + targetOffsetX, sheetSize.Height() + targetOffsetY + borderOffset);
316     path.ArcTo(radiusBottomLeft + borderOffset, radiusBottomLeft + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
317         targetOffsetX + borderOffset, sheetSize.Height() - radiusBottomLeft + targetOffsetY);
318     if (arrowPosition == SheetArrowPosition::BOTTOM_LEFT) {
319         path.LineTo(targetOffsetX - borderOffset, targetOffsetY + SHEET_ARROW_HEIGHT.ConvertToPx());
320     } else {
321         path.LineTo(targetOffsetX - borderOffset, SHEET_ARROW_HEIGHT.ConvertToPx() + radiusTopLeft + targetOffsetY);
322     }
323 }
324 
DrawClipPathTop(RSPath & path,const RefPtr<FrameNode> sheetNode,const BorderRadiusProperty & sheetRadius,float borderWidth,const SheetPopupInfo & sheetPopupInfo)325 void SheetWrapperPaintMethod::DrawClipPathTop(RSPath& path, const RefPtr<FrameNode> sheetNode,
326     const BorderRadiusProperty& sheetRadius, float borderWidth, const SheetPopupInfo& sheetPopupInfo)
327 {
328     auto geometryNode = sheetNode->GetGeometryNode();
329     CHECK_NULL_VOID(geometryNode);
330     auto sheetSize = geometryNode->GetFrameSize();
331     auto radiusTopLeft = sheetRadius.radiusTopLeft->ConvertToPx();
332     auto radiusTopRight = sheetRadius.radiusTopRight->ConvertToPx();
333     auto radiusBottomRight = sheetRadius.radiusBottomRight->ConvertToPx();
334     auto radiusBottomLeft = sheetRadius.radiusBottomLeft->ConvertToPx();
335     auto borderOffset = borderWidth * HALF;
336     auto targetOffsetX = sheetNode->GetPositionToParentWithTransform().GetX();
337     auto targetOffsetY = sheetNode->GetPositionToParentWithTransform().GetY();
338     OffsetF arrowOffset(sheetPopupInfo.arrowOffsetX, sheetPopupInfo.arrowOffsetY);
339     auto arrowPosition = sheetPopupInfo.arrowPosition;
340     // clip path start from TopLeft, and draw sheet radius first
341     path.Reset();
342     path.MoveTo(targetOffsetX - borderOffset, radiusTopLeft + targetOffsetY);
343     path.ArcTo(radiusTopLeft + borderOffset, radiusTopLeft + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
344         radiusTopLeft + targetOffsetX, targetOffsetY - borderOffset);
345     path.LineTo(sheetSize.Width() - radiusTopRight + targetOffsetX, targetOffsetY - borderOffset);
346     path.ArcTo(radiusTopRight + borderOffset, radiusTopRight + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
347         sheetSize.Width() + targetOffsetX + borderOffset, radiusTopRight + targetOffsetY);
348     if (arrowPosition == SheetArrowPosition::TOP_RIGHT) {
349         path.LineTo(sheetSize.Width() + targetOffsetX + borderOffset, sheetSize.Height() -
350             (SHEET_ARROW_HEIGHT - ARROW_CORNER_P4_OFFSET_Y).ConvertToPx() + targetOffsetY);    // P4
351         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.f,
352             RSPathDirection::CW_DIRECTION,
353             sheetSize.Width() - (SHEET_ARROW_WIDTH - ARROW_CORNER_P2_OFFSET_X).ConvertToPx() + targetOffsetX -
354             borderOffset, sheetSize.Height() - (SHEET_ARROW_HEIGHT - ARROW_CORNER_P2_OFFSET_Y).ConvertToPx() +
355             targetOffsetY);    // P2
356         path.LineTo(sheetSize.Width() - SHEET_ARROW_WIDTH.ConvertToPx() + targetOffsetX,
357             sheetSize.Height() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY + borderOffset); // P1
358     } else {
359         path.LineTo(sheetSize.Width() + targetOffsetX + borderOffset,
360             sheetSize.Height() - radiusBottomRight - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY);
361         path.ArcTo(radiusBottomRight + borderOffset, radiusBottomRight + borderOffset, 0.f,
362             RSPathDirection::CW_DIRECTION, sheetSize.Width() - radiusBottomRight + targetOffsetX,
363             sheetSize.Height() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY + borderOffset);
364     }
365     if (arrowPosition == SheetArrowPosition::NONE) {
366         path.LineTo(arrowOffset.GetX() + ARROW_VERTICAL_P1_OFFSET_X.ConvertToPx() + targetOffsetX,
367             sheetSize.Height() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY + borderOffset); // P1
368         path.LineTo(arrowOffset.GetX() + ARROW_VERTICAL_P2_OFFSET_X.ConvertToPx() + targetOffsetX - borderOffset,
369             sheetSize.Height() - (SHEET_ARROW_HEIGHT - ARROW_VERTICAL_P2_OFFSET_Y).ConvertToPx() +
370             targetOffsetY);  // P2
371         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.f,
372             RSPathDirection::CW_DIRECTION,
373             arrowOffset.GetX() - ARROW_VERTICAL_P4_OFFSET_X.ConvertToPx() + targetOffsetX - borderOffset,
374             sheetSize.Height() - (SHEET_ARROW_HEIGHT - ARROW_VERTICAL_P4_OFFSET_Y).ConvertToPx() +
375             targetOffsetY);  // P4
376         path.LineTo(arrowOffset.GetX() - ARROW_VERTICAL_P5_OFFSET_X.ConvertToPx() + targetOffsetX,
377             sheetSize.Height() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY + borderOffset); // P5
378     }
379     if (arrowPosition == SheetArrowPosition::TOP_LEFT) {
380         path.LineTo(SHEET_ARROW_WIDTH.ConvertToPx() + targetOffsetX,
381             sheetSize.Height() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY + borderOffset); // P1
382         path.LineTo((SHEET_ARROW_WIDTH - ARROW_CORNER_P2_OFFSET_X).ConvertToPx() + targetOffsetX + borderOffset,
383             sheetSize.Height() - (SHEET_ARROW_HEIGHT - ARROW_CORNER_P2_OFFSET_Y).ConvertToPx() + targetOffsetY);  // P2
384         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.f,
385             RSPathDirection::CW_DIRECTION, targetOffsetX - borderOffset,
386             sheetSize.Height() - (SHEET_ARROW_HEIGHT - ARROW_CORNER_P4_OFFSET_Y).ConvertToPx() + targetOffsetY);  // P4
387         path.LineTo(targetOffsetX - borderOffset,
388             sheetSize.Height() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY); // P5
389     } else {
390         path.LineTo(radiusBottomLeft + targetOffsetX,
391             sheetSize.Height() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY + borderOffset);
392         path.ArcTo(radiusBottomLeft + borderOffset, radiusBottomLeft + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
393             targetOffsetX - borderOffset,
394             sheetSize.Height() - radiusBottomLeft - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetY);
395     }
396     path.LineTo(targetOffsetX - borderOffset, radiusTopLeft + targetOffsetY);
397 }
398 
DrawClipPathLeft(RSPath & path,const RefPtr<FrameNode> sheetNode,const BorderRadiusProperty & sheetRadius,float borderWidth,const SheetPopupInfo & sheetPopupInfo)399 void SheetWrapperPaintMethod::DrawClipPathLeft(RSPath& path, const RefPtr<FrameNode> sheetNode,
400     const BorderRadiusProperty& sheetRadius, float borderWidth, const SheetPopupInfo& sheetPopupInfo)
401 {
402     auto geometryNode = sheetNode->GetGeometryNode();
403     CHECK_NULL_VOID(geometryNode);
404     auto sheetSize = geometryNode->GetFrameSize();
405     auto radiusTopLeft = sheetRadius.radiusTopLeft->ConvertToPx();
406     auto radiusTopRight = sheetRadius.radiusTopRight->ConvertToPx();
407     auto radiusBottomRight = sheetRadius.radiusBottomRight->ConvertToPx();
408     auto radiusBottomLeft = sheetRadius.radiusBottomLeft->ConvertToPx();
409     auto borderOffset = borderWidth * HALF;
410     auto targetOffsetX = sheetNode->GetPositionToParentWithTransform().GetX();
411     auto targetOffsetY = sheetNode->GetPositionToParentWithTransform().GetY();
412     OffsetF arrowOffset(sheetPopupInfo.arrowOffsetX, sheetPopupInfo.arrowOffsetY);
413     auto arrowPosition = sheetPopupInfo.arrowPosition;
414     // clip path start from TopLeft, and draw sheet radius first
415     path.Reset();
416     path.MoveTo(targetOffsetX - borderOffset, radiusTopLeft + targetOffsetY);
417     path.ArcTo(radiusTopLeft + borderOffset, radiusTopLeft + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
418         radiusTopLeft + targetOffsetX, targetOffsetY - borderOffset);
419     if (arrowPosition == SheetArrowPosition::LEFT_TOP) {
420         path.LineTo(sheetSize.Width() - (SHEET_ARROW_HEIGHT - ARROW_CORNER_P4_OFFSET_Y).ConvertToPx() + targetOffsetX,
421             targetOffsetY - borderOffset); // P4
422         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.f,
423             RSPathDirection::CW_DIRECTION,
424             sheetSize.Width() - (SHEET_ARROW_HEIGHT - ARROW_CORNER_P2_OFFSET_Y).ConvertToPx() + targetOffsetX,
425             (SHEET_ARROW_WIDTH - ARROW_CORNER_P2_OFFSET_X).ConvertToPx() + targetOffsetY + borderOffset);  // P2
426         path.LineTo(sheetSize.Width() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX + borderOffset,
427             SHEET_ARROW_WIDTH.ConvertToPx() + targetOffsetY);  // P1
428     } else {
429         path.LineTo(sheetSize.Width() - radiusTopRight - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX,
430             targetOffsetY - borderOffset);
431         path.ArcTo(radiusTopRight + borderOffset, radiusTopRight + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
432             sheetSize.Width() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX + borderOffset,
433             radiusTopRight + targetOffsetY);
434     }
435     if (arrowPosition == SheetArrowPosition::NONE) {
436         path.LineTo(sheetSize.Width() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX + borderOffset,
437             arrowOffset.GetY() - ARROW_VERTICAL_P1_OFFSET_X.ConvertToPx() + targetOffsetY);    // P1
438         path.LineTo(sheetSize.Width() - (SHEET_ARROW_HEIGHT - ARROW_VERTICAL_P2_OFFSET_Y).ConvertToPx() +
439             targetOffsetX,
440             arrowOffset.GetY() - ARROW_VERTICAL_P2_OFFSET_X.ConvertToPx() + targetOffsetY - borderOffset);    // P2
441         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.f,
442             RSPathDirection::CW_DIRECTION,
443             sheetSize.Width() - (SHEET_ARROW_HEIGHT - ARROW_VERTICAL_P4_OFFSET_Y).ConvertToPx() + targetOffsetX,
444             arrowOffset.GetY() + ARROW_VERTICAL_P4_OFFSET_X.ConvertToPx() + targetOffsetY + borderOffset);    // P4
445         path.LineTo(sheetSize.Width() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX + borderOffset,
446             arrowOffset.GetY() + ARROW_VERTICAL_P5_OFFSET_X.ConvertToPx() + targetOffsetY);    // P5
447     }
448     if (arrowPosition == SheetArrowPosition::LEFT_BOTTOM) {
449         path.LineTo(sheetSize.Width() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX + borderOffset,
450             sheetSize.Height() - SHEET_ARROW_WIDTH.ConvertToPx() + targetOffsetY);  // P1
451         path.LineTo(sheetSize.Width() - (SHEET_ARROW_HEIGHT - ARROW_CORNER_P2_OFFSET_Y).ConvertToPx() + targetOffsetX,
452             sheetSize.Height() - (SHEET_ARROW_WIDTH - ARROW_CORNER_P2_OFFSET_X).ConvertToPx() +
453             targetOffsetY - borderOffset); // P2
454         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.f,
455             RSPathDirection::CW_DIRECTION,
456             sheetSize.Width() - (SHEET_ARROW_HEIGHT - ARROW_CORNER_P4_OFFSET_Y).ConvertToPx() + targetOffsetX,
457             sheetSize.Height() + targetOffsetY + borderOffset); // P4
458         path.LineTo(sheetSize.Width() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX,
459             sheetSize.Height() + targetOffsetY + borderOffset);   // P5
460     } else {
461         path.LineTo(sheetSize.Width() - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX + borderOffset,
462             sheetSize.Height() - radiusBottomRight + targetOffsetY);
463         path.ArcTo(radiusBottomRight + borderOffset, radiusBottomRight + borderOffset, 0.f,
464             RSPathDirection::CW_DIRECTION,
465             sheetSize.Width() - radiusBottomRight - SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX,
466             sheetSize.Height() + targetOffsetY + borderOffset);
467     }
468     path.LineTo(radiusBottomLeft + targetOffsetX, sheetSize.Height() + targetOffsetY + borderOffset);
469     path.ArcTo(radiusBottomLeft + borderOffset, radiusBottomLeft + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
470         targetOffsetX - borderOffset, sheetSize.Height() - radiusBottomLeft + targetOffsetY);
471     path.LineTo(targetOffsetX - borderOffset, radiusTopLeft + targetOffsetY);
472 }
473 
DrawClipPathRight(RSPath & path,const RefPtr<FrameNode> sheetNode,const BorderRadiusProperty & sheetRadius,float borderWidth,const SheetPopupInfo & sheetPopupInfo)474 void SheetWrapperPaintMethod::DrawClipPathRight(RSPath& path, const RefPtr<FrameNode> sheetNode,
475     const BorderRadiusProperty& sheetRadius, float borderWidth, const SheetPopupInfo& sheetPopupInfo)
476 {
477     auto geometryNode = sheetNode->GetGeometryNode();
478     CHECK_NULL_VOID(geometryNode);
479     auto sheetSize = geometryNode->GetFrameSize();
480     auto radiusTopLeft = sheetRadius.radiusTopLeft->ConvertToPx();
481     auto radiusTopRight = sheetRadius.radiusTopRight->ConvertToPx();
482     auto radiusBottomRight = sheetRadius.radiusBottomRight->ConvertToPx();
483     auto radiusBottomLeft = sheetRadius.radiusBottomLeft->ConvertToPx();
484     auto borderOffset = borderWidth * HALF;
485     auto targetOffsetX = sheetNode->GetPositionToParentWithTransform().GetX();
486     auto targetOffsetY = sheetNode->GetPositionToParentWithTransform().GetY();
487     OffsetF arrowOffset(sheetPopupInfo.arrowOffsetX, sheetPopupInfo.arrowOffsetY);
488     auto arrowPosition = sheetPopupInfo.arrowPosition;
489     // clip path start from TopLeft, and if left side need draw left top Right-angled arrow, draw it first
490     path.Reset();
491     if (arrowPosition == SheetArrowPosition::RIGHT_TOP) {
492         path.MoveTo(SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX - borderOffset,
493             SHEET_ARROW_WIDTH.ConvertToPx() + targetOffsetY);  // P1
494         path.LineTo((SHEET_ARROW_HEIGHT - ARROW_CORNER_P2_OFFSET_Y).ConvertToPx() + targetOffsetX,
495             (SHEET_ARROW_WIDTH - ARROW_CORNER_P2_OFFSET_X).ConvertToPx() + targetOffsetY + borderOffset);  // P2
496         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.f,
497             RSPathDirection::CW_DIRECTION,
498             (SHEET_ARROW_HEIGHT - ARROW_CORNER_P4_OFFSET_Y).ConvertToPx() + targetOffsetX,
499             targetOffsetY - borderOffset);    // P4
500         path.LineTo(SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX, targetOffsetY - borderOffset);  // P5
501     } else {
502         path.MoveTo(SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX - borderOffset, radiusTopLeft + targetOffsetY);
503         path.ArcTo(radiusTopLeft + borderOffset, radiusTopLeft + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
504             radiusTopLeft + SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX, targetOffsetY - borderOffset);
505     }
506     path.LineTo(sheetSize.Width() - radiusTopRight + targetOffsetX, targetOffsetY - borderOffset);
507     path.ArcTo(radiusTopRight + borderOffset, radiusTopRight + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
508         sheetSize.Width() + targetOffsetX + borderOffset, radiusTopRight + targetOffsetY);
509     path.LineTo(sheetSize.Width() + targetOffsetX + borderOffset,
510         sheetSize.Height() - radiusBottomRight + targetOffsetY);
511     path.ArcTo(radiusBottomRight + borderOffset, radiusBottomRight + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
512         sheetSize.Width() - radiusBottomRight + targetOffsetX,
513         sheetSize.Height() + targetOffsetY + borderOffset);
514     if (arrowPosition == SheetArrowPosition::RIGHT_BOTTOM) {
515         path.LineTo(SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX,
516             sheetSize.Height() + targetOffsetY + borderOffset);   // P5
517         path.LineTo((SHEET_ARROW_HEIGHT - ARROW_CORNER_P4_OFFSET_Y).ConvertToPx() + targetOffsetX,
518             sheetSize.Height() + targetOffsetY + borderOffset);  // P4
519         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.f,
520             RSPathDirection::CW_DIRECTION,
521             (SHEET_ARROW_HEIGHT - ARROW_CORNER_P2_OFFSET_Y).ConvertToPx() + targetOffsetX,
522             sheetSize.Height() - (SHEET_ARROW_WIDTH - ARROW_CORNER_P2_OFFSET_X).ConvertToPx() +
523             targetOffsetY - borderOffset); // P2
524         path.LineTo(SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX - borderOffset,
525             sheetSize.Height() - SHEET_ARROW_WIDTH.ConvertToPx() + targetOffsetY); // P1
526     } else {
527         path.LineTo(radiusBottomLeft + SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX,
528             sheetSize.Height() + targetOffsetY + borderOffset);
529         path.ArcTo(radiusBottomLeft + borderOffset, radiusBottomLeft + borderOffset, 0.f,
530             RSPathDirection::CW_DIRECTION, SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX - borderOffset,
531             sheetSize.Height() - radiusBottomLeft + targetOffsetY);
532     }
533     if (arrowPosition == SheetArrowPosition::NONE) {
534         path.LineTo(SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX - borderOffset,
535             arrowOffset.GetY() + ARROW_VERTICAL_P1_OFFSET_X.ConvertToPx() + targetOffsetY);    // P1
536         path.LineTo((SHEET_ARROW_HEIGHT - ARROW_VERTICAL_P2_OFFSET_Y).ConvertToPx() + targetOffsetX,
537             arrowOffset.GetY() + ARROW_VERTICAL_P2_OFFSET_X.ConvertToPx() + targetOffsetY + borderOffset);    // P2
538         path.ArcTo(ARROW_RADIUS.ConvertToPx() + borderOffset, ARROW_RADIUS.ConvertToPx() + borderOffset, 0.f,
539             RSPathDirection::CW_DIRECTION,
540             (SHEET_ARROW_HEIGHT - ARROW_VERTICAL_P4_OFFSET_Y).ConvertToPx() + targetOffsetX,
541             arrowOffset.GetY() - ARROW_VERTICAL_P4_OFFSET_X.ConvertToPx() + targetOffsetY - borderOffset);    // P4
542         path.LineTo(SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX - borderOffset,
543             arrowOffset.GetY() - ARROW_VERTICAL_P5_OFFSET_X.ConvertToPx() + targetOffsetY);    // P5
544     }
545     if (arrowPosition == SheetArrowPosition::RIGHT_TOP) {
546         path.LineTo(SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX - borderOffset,
547             SHEET_ARROW_WIDTH.ConvertToPx() + targetOffsetY);
548     } else {
549         path.LineTo(SHEET_ARROW_HEIGHT.ConvertToPx() + targetOffsetX - borderOffset, radiusTopLeft + targetOffsetY);
550     }
551 }
552 
DrawClipPathWithoutArrow(RSPath & path,const RefPtr<FrameNode> sheetNode,const BorderRadiusProperty & sheetRadius,float borderWidth)553 void SheetWrapperPaintMethod::DrawClipPathWithoutArrow(RSPath& path, const RefPtr<FrameNode> sheetNode,
554     const BorderRadiusProperty& sheetRadius, float borderWidth)
555 {
556     auto geometryNode = sheetNode->GetGeometryNode();
557     CHECK_NULL_VOID(geometryNode);
558     auto sheetSize = geometryNode->GetFrameSize();
559     auto radiusTopLeft = sheetRadius.radiusTopLeft->ConvertToPx();
560     auto radiusTopRight = sheetRadius.radiusTopRight->ConvertToPx();
561     auto radiusBottomRight = sheetRadius.radiusBottomRight->ConvertToPx();
562     auto radiusBottomLeft = sheetRadius.radiusBottomLeft->ConvertToPx();
563     auto borderOffset = borderWidth * HALF;
564     auto targetOffsetX = sheetNode->GetPositionToParentWithTransform().GetX();
565     auto targetOffsetY = sheetNode->GetPositionToParentWithTransform().GetY();
566     path.Reset();
567     path.MoveTo(targetOffsetX - borderOffset, radiusTopLeft + targetOffsetY);
568     path.ArcTo(radiusTopLeft + borderOffset, radiusTopLeft + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
569         radiusTopLeft + targetOffsetX, targetOffsetY - borderOffset);
570     path.LineTo(sheetSize.Width() - radiusTopRight + targetOffsetX, targetOffsetY - borderOffset);
571     path.ArcTo(radiusTopRight + borderOffset, radiusTopRight + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
572         sheetSize.Width() + targetOffsetX + borderOffset, radiusTopRight + targetOffsetY);
573     path.LineTo(sheetSize.Width() + targetOffsetX + borderOffset,
574         sheetSize.Height() - radiusBottomRight + targetOffsetY);
575     path.ArcTo(radiusBottomRight + borderOffset, radiusBottomRight + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
576         sheetSize.Width() - radiusBottomRight + targetOffsetX, sheetSize.Height() + targetOffsetY + borderOffset);
577     path.LineTo(radiusBottomLeft + targetOffsetX, sheetSize.Height() + targetOffsetY + borderOffset);
578     path.ArcTo(radiusBottomLeft + borderOffset, radiusBottomLeft + borderOffset, 0.f, RSPathDirection::CW_DIRECTION,
579         targetOffsetX - borderOffset, sheetSize.Height() - radiusBottomLeft + targetOffsetY);
580     path.LineTo(targetOffsetX - borderOffset, radiusTopLeft + targetOffsetY);
581 }
582 } // namespace OHOS::Ace::NG
583