• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 #include "core/components_ng/pattern/checkbox/checkbox_paint_method.h"
16 #include "ui/base/utils/utils.h"
17 
18 #include "core/components_ng/base/frame_node.h"
19 #include "core/components_ng/pattern/checkbox/checkbox_paint_property.h"
20 #include "core/components_ng/render/drawing_prop_convertor.h"
21 #include "core/pipeline_ng/pipeline_context.h"
22 
23 namespace OHOS::Ace::NG {
24 namespace {
25 constexpr uint8_t ENABLED_ALPHA = 255;
26 constexpr uint8_t DISABLED_ALPHA = 102;
27 constexpr float CHECK_MARK_START_X_POSITION = 0.25f;
28 constexpr float CHECK_MARK_START_Y_POSITION = 0.49f;
29 constexpr float CHECK_MARK_MIDDLE_X_POSITION = 0.44f;
30 constexpr float CHECK_MARK_MIDDLE_Y_POSITION = 0.68f;
31 constexpr float CHECK_MARK_END_X_POSITION = 0.76f;
32 constexpr float CHECK_MARK_END_Y_POSITION = 0.33f;
33 constexpr float CHECKBOX_DOUBLE_RATIO = 2.0f;
34 constexpr float CHECKBOX_LENGTH_ZERO = 0.0f;
35 } // namespace
36 
GetContentModifier(PaintWrapper * paintWrapper)37 RefPtr<Modifier> CheckBoxPaintMethod::GetContentModifier(PaintWrapper* paintWrapper)
38 {
39     if (!checkboxModifier_) {
40         auto size = paintWrapper->GetContentSize();
41         auto offset = paintWrapper->GetContentOffset();
42         auto pipeline = PipelineBase::GetCurrentContextSafely();
43         CHECK_NULL_RETURN(pipeline, nullptr);
44         auto host = paintWrapper->GetRenderContext() ? paintWrapper->GetRenderContext()->GetHost() : nullptr;
45         CHECK_NULL_RETURN(host, nullptr);
46         auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>(host->GetThemeScopeId());
47         CHECK_NULL_RETURN(checkBoxTheme, nullptr);
48         auto paintProperty = DynamicCast<CheckBoxPaintProperty>(paintWrapper->GetPaintProperty());
49         CHECK_NULL_RETURN(paintProperty, nullptr);
50         auto isSelect = paintProperty->GetCheckBoxSelectValue(false);
51         auto boardColor = isSelect ? paintProperty->GetCheckBoxSelectedColorValue(checkBoxTheme->GetActiveColor())
52                                    : checkBoxTheme->GetInactivePointColor();
53         auto checkColor = isSelect ? paintProperty->GetCheckBoxCheckMarkColorValue(checkBoxTheme->GetPointColor())
54                                    : Color::TRANSPARENT;
55         auto borderColor = isSelect ? Color::TRANSPARENT
56                                     : paintProperty->GetCheckBoxUnSelectedColorValue(checkBoxTheme->GetInactiveColor());
57         auto shadowColor = isSelect ? checkBoxTheme->GetShadowColor() : Color::TRANSPARENT;
58         float strokePaintSize = size.Width();
59         auto checkStroke = static_cast<float>(checkBoxTheme->GetCheckStroke().ConvertToPx());
60         if (paintProperty->HasCheckBoxCheckMarkWidth()) {
61             checkStroke = static_cast<float>(paintProperty->GetCheckBoxCheckMarkWidthValue().ConvertToPx());
62             auto strokeLimitByMarkSize = strokePaintSize * CHECKBOX_MARK_STROKEWIDTH_LIMIT_RATIO;
63             if (checkStroke > strokeLimitByMarkSize) {
64                 checkStroke = strokeLimitByMarkSize;
65             }
66         }
67         auto strokeSize = size.Width();
68         if (paintProperty->HasCheckBoxCheckMarkSize()) {
69             if (paintProperty->GetCheckBoxCheckMarkSizeValue().ConvertToPx() >= 0) {
70                 strokePaintSize = paintProperty->GetCheckBoxCheckMarkSizeValue().ConvertToPx();
71             }
72             if (strokePaintSize > size.Width()) {
73                 strokePaintSize = size.Width();
74             }
75         }
76         checkboxModifier_ = AceType::MakeRefPtr<CheckBoxModifier>(
77             isSelect, boardColor, checkColor, borderColor, shadowColor, size, offset, checkStroke, strokeSize);
78     }
79     return checkboxModifier_;
80 }
81 
UpdateCheckboxColors(const RefPtr<CheckBoxPaintProperty> & paintProperty)82 void CheckBoxPaintMethod::UpdateCheckboxColors(const RefPtr<CheckBoxPaintProperty>& paintProperty)
83 {
84     if (paintProperty->HasCheckBoxSelectedColor()) {
85         checkboxModifier_->SetUserActiveColor(paintProperty->GetCheckBoxSelectedColorValue());
86     }
87     if (paintProperty->HasCheckBoxSelectedStyle()) {
88         checkboxModifier_->SetCheckboxStyle(paintProperty->GetCheckBoxSelectedStyleValue());
89     }
90     if (paintProperty->HasCheckBoxUnSelectedColor()) {
91         checkboxModifier_->SetInActiveColor(paintProperty->GetCheckBoxUnSelectedColorValue());
92     }
93     if (paintProperty->HasCheckBoxCheckMarkColor()) {
94         checkboxModifier_->SetPointColor(paintProperty->GetCheckBoxCheckMarkColorValue());
95     }
96 }
97 
UpdateContentModifier(PaintWrapper * paintWrapper)98 void CheckBoxPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
99 {
100     CHECK_NULL_VOID(checkboxModifier_);
101     CHECK_NULL_VOID(paintWrapper);
102     auto host = paintWrapper->GetRenderContext() ? paintWrapper->GetRenderContext()->GetHost() : nullptr;
103     CHECK_NULL_VOID(host);
104     checkboxModifier_->InitializeParam(host->GetThemeScopeId());
105     auto size = paintWrapper->GetContentSize();
106     float strokePaintSize = size.Width();
107     auto paintProperty = DynamicCast<CheckBoxPaintProperty>(paintWrapper->GetPaintProperty());
108     CHECK_NULL_VOID(paintProperty);
109     if (paintProperty->GetCheckBoxSelect().has_value()) {
110         checkboxModifier_->SetIsSelect(paintProperty->GetCheckBoxSelectValue());
111     }
112     UpdateCheckboxColors(paintProperty);
113     if (paintProperty->HasCheckBoxCheckMarkSize()) {
114         if (paintProperty->GetCheckBoxCheckMarkSizeValue().ConvertToPx() >= 0) {
115             strokePaintSize = paintProperty->GetCheckBoxCheckMarkSizeValue().ConvertToPx();
116         }
117         if (strokePaintSize > size.Width()) {
118             strokePaintSize = size.Width();
119         }
120     }
121     checkboxModifier_->SetStrokeSize(strokePaintSize);
122     if (paintProperty->HasCheckBoxCheckMarkWidth()) {
123         auto strokeWidth = paintProperty->GetCheckBoxCheckMarkWidthValue().ConvertToPx();
124         auto strokeLimitByMarkSize = strokePaintSize * CHECKBOX_MARK_STROKEWIDTH_LIMIT_RATIO;
125         if (strokeWidth > strokeLimitByMarkSize) {
126             strokeWidth = strokeLimitByMarkSize;
127         }
128         checkboxModifier_->SetStrokeWidth(strokeWidth);
129     }
130     checkboxModifier_->SetSize(size);
131     auto offset = paintWrapper->GetContentOffset();
132     checkboxModifier_->SetOffset(offset);
133     checkboxModifier_->SetEnabled(enabled_);
134     checkboxModifier_->SetTouchHoverAnimationType(touchHoverType_);
135     checkboxModifier_->UpdateAnimatableProperty(needAnimation_, host->GetContextRefPtr());
136     auto context = host->GetContext();
137     CHECK_NULL_VOID(context);
138     auto checkBoxTheme = context->GetTheme<CheckboxTheme>(host->GetThemeScopeId());
139     if (paintProperty->HasCheckBoxUnSelectedColor()) {
140         CHECK_NULL_VOID(checkBoxTheme);
141         checkboxModifier_->SetHasUnselectedColor(
142             paintProperty->GetCheckBoxUnSelectedColorValue() != checkBoxTheme->GetInactiveColor());
143     } else {
144         checkboxModifier_->SetHasUnselectedColor(false);
145     }
146     SetHoverEffectType(paintProperty);
147     SetModifierBoundsRect(checkBoxTheme, size, offset, paintWrapper);
148 }
149 
SetModifierBoundsRect(const RefPtr<CheckboxTheme> & theme,const SizeF & size,const OffsetF & offset,PaintWrapper * paintWrapper)150 void CheckBoxPaintMethod::SetModifierBoundsRect(
151     const RefPtr<CheckboxTheme>& theme, const SizeF& size, const OffsetF& offset, PaintWrapper* paintWrapper)
152 {
153     CHECK_NULL_VOID(theme);
154     auto horizontalPadding = theme->GetHotZoneHorizontalPadding().ConvertToPx();
155     auto verticalPadding = theme->GetHotZoneVerticalPadding().ConvertToPx();
156     float boundsRectOriginX = offset.GetX() - horizontalPadding;
157     float boundsRectOriginY = offset.GetY() - verticalPadding;
158     float boundsRectWidth = size.Width() + 2 * horizontalPadding;
159     float boundsRectHeight = size.Height() + 2 * verticalPadding;
160     RectF boundsRect(boundsRectOriginX, boundsRectOriginY, boundsRectWidth, boundsRectHeight);
161     CHECK_NULL_VOID(checkboxModifier_);
162     auto origin = checkboxModifier_->GetBoundsRect();
163     CHECK_EQUAL_VOID(origin, boundsRect);
164     checkboxModifier_->SetBoundsRect(boundsRect);
165     paintWrapper->FlushContentModifier();
166 }
167 
SetHoverEffectType(const RefPtr<CheckBoxPaintProperty> & checkBoxPaintProperty)168 void CheckBoxPaintMethod::SetHoverEffectType(const RefPtr<CheckBoxPaintProperty>& checkBoxPaintProperty)
169 {
170     auto host = checkBoxPaintProperty->GetHost();
171     CHECK_NULL_VOID(host);
172     auto eventHub = host->GetOrCreateEventHub<EventHub>();
173     CHECK_NULL_VOID(eventHub);
174     auto inputEventHub = eventHub->GetInputEventHub();
175     HoverEffectType hoverEffectType = HoverEffectType::AUTO;
176     if (inputEventHub) {
177         hoverEffectType = inputEventHub->GetHoverEffect();
178         if (HoverEffectType::UNKNOWN == hoverEffectType || HoverEffectType::OPACITY == hoverEffectType) {
179             hoverEffectType = HoverEffectType::AUTO;
180         }
181         if (checkboxModifier_) {
182             checkboxModifier_->SetHoverEffectType(hoverEffectType);
183         }
184     }
185 }
186 
CheckBoxModifier(bool isSelect,const Color & boardColor,const Color & checkColor,const Color & borderColor,const Color & shadowColor,const SizeF & size,const OffsetF & offset,float checkStroke,float strokeSize)187 CheckBoxModifier::CheckBoxModifier(bool isSelect, const Color& boardColor, const Color& checkColor,
188     const Color& borderColor, const Color& shadowColor, const SizeF& size, const OffsetF& offset, float checkStroke,
189     float strokeSize)
190 {
191     animatableBoardColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(boardColor));
192     animatableCheckColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(checkColor));
193     animatableBorderColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(borderColor));
194     animatableShadowColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(shadowColor));
195     checkStroke_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(checkStroke);
196     strokeSize_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(strokeSize);
197     offset_ = AceType::MakeRefPtr<AnimatablePropertyOffsetF>(offset);
198     size_ = AceType::MakeRefPtr<AnimatablePropertySizeF>(size);
199     animateTouchHoverColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(Color::TRANSPARENT));
200 
201     isSelect_ = AceType::MakeRefPtr<PropertyBool>(isSelect);
202     isFocused_ = AceType::MakeRefPtr<PropertyBool>(false);
203     enabled_ = AceType::MakeRefPtr<PropertyBool>(true);
204     hasBuilder_ = AceType::MakeRefPtr<PropertyBool>(false);
205     useContentModifier_ = AceType::MakeRefPtr<PropertyBool>(false);
206     checkBoxShape_ = AceType::MakeRefPtr<PropertyInt>(static_cast<int32_t>(CheckBoxStyle::CIRCULAR_STYLE));
207 
208     AttachProperty(animatableBoardColor_);
209     AttachProperty(animatableCheckColor_);
210     AttachProperty(animatableBorderColor_);
211     AttachProperty(animatableShadowColor_);
212     AttachProperty(animateTouchHoverColor_);
213     AttachProperty(checkStroke_);
214     AttachProperty(strokeSize_);
215     AttachProperty(isSelect_);
216     AttachProperty(isFocused_);
217     AttachProperty(offset_);
218     AttachProperty(size_);
219     AttachProperty(enabled_);
220     AttachProperty(hasBuilder_);
221     AttachProperty(checkBoxShape_);
222 }
223 
InitializeParam(TokenThemeScopeId themeScopeId)224 void CheckBoxModifier::InitializeParam(TokenThemeScopeId themeScopeId)
225 {
226     auto pipeline = PipelineBase::GetCurrentContext();
227     CHECK_NULL_VOID(pipeline);
228     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>(themeScopeId);
229     CHECK_NULL_VOID(checkBoxTheme);
230     borderWidth_ = checkBoxTheme->GetBorderWidth().ConvertToPx();
231     borderRadius_ = checkBoxTheme->GetBorderRadius().ConvertToPx();
232     whiteBorderRadius_ = checkBoxTheme->GetWhiteBorderRadius().ConvertToPx();
233     pointColor_ = checkBoxTheme->GetPointColor();
234     activeColor_ = checkBoxTheme->GetActiveColor();
235     inactiveColor_ = checkBoxTheme->GetInactiveColor();
236     inactivePointColor_ = checkBoxTheme->GetInactivePointColor();
237     shadowColor_ = checkBoxTheme->GetShadowColor();
238     clickEffectColor_ = checkBoxTheme->GetClickEffectColor();
239     hoverColor_ = checkBoxTheme->GetHoverColor();
240     hoverRadius_ = checkBoxTheme->GetHoverRadius();
241     hotZoneHorizontalPadding_ = checkBoxTheme->GetHotZoneHorizontalPadding();
242     hotZoneVerticalPadding_ = checkBoxTheme->GetHotZoneVerticalPadding();
243     defaultPaddingSize_ = checkBoxTheme->GetDefaultPaddingSize();
244     defaultRoundPaddingSize_ = checkBoxTheme->GetDefaultRoundPaddingSize();
245     hoverPaddingSize_ = checkBoxTheme->GetHoverPaddingSize();
246     shadowWidth_ = checkBoxTheme->GetShadowWidth();
247     userActiveColor_ = activeColor_;
248     hoverDuration_ = checkBoxTheme->GetHoverDuration();
249     hoverToTouchDuration_ = checkBoxTheme->GetHoverToTouchDuration();
250     touchDuration_ = checkBoxTheme->GetTouchDuration();
251     colorAnimationDuration_ = checkBoxTheme->GetColorAnimationDuration();
252     focusBoardColor_ = checkBoxTheme->GetFocusBoardColor();
253     focusBoardSize_ = checkBoxTheme->GetFocusBoardSize();
254     roundFocusBoardSize_ = checkBoxTheme->GetRoundFocusBoardSize();
255     borderFocusedColor_ = checkBoxTheme->GetBorderFocusedColor();
256     focusedBGColorUnselected_ = checkBoxTheme->GetFocusedBGColorUnselected();
257     showCircleDial_ = checkBoxTheme->IsCircleDial();
258 }
259 
PaintCheckBox(RSCanvas & canvas,const OffsetF & paintOffset,const SizeF & contentSize) const260 void CheckBoxModifier::PaintCheckBox(RSCanvas& canvas, const OffsetF& paintOffset, const SizeF& contentSize) const
261 {
262     DrawFocusBoard(canvas, contentSize, paintOffset);
263     DrawTouchAndHoverBoard(canvas, contentSize, paintOffset);
264     RSPen pen;
265     pen.SetWidth(borderWidth_);
266     pen.SetAntiAlias(true);
267     RSPen shadowPen = RSPen(pen);
268     RSBrush brush;
269     brush.SetColor(ToRSColor(animatableBoardColor_->Get()));
270     brush.SetAntiAlias(true);
271     if (!enabled_->Get()) {
272         brush.SetColor(
273             ToRSColor(animatableBoardColor_->Get().BlendOpacity(static_cast<float>(DISABLED_ALPHA) / ENABLED_ALPHA)));
274     }
275     if (isFocused_->Get() && !isSelect_->Get()) {
276         brush.SetColor(ToRSColor(focusedBGColorUnselected_));
277     }
278     DrawBackboard(canvas, paintOffset, brush, contentSize);
279     pen.SetColor(ToRSColor(animatableBorderColor_->Get()));
280     if (!enabled_->Get()) {
281         pen.SetColor(
282             ToRSColor(animatableBorderColor_->Get().BlendOpacity(static_cast<float>(DISABLED_ALPHA) / ENABLED_ALPHA)));
283     }
284     if (!isSelect_->Get() && isFocused_->Get() && !hasUnselectedColor_) {
285         pen.SetColor(ToRSColor(borderFocusedColor_));
286     }
287     if (enabled_->Get() || !isSelect_->Get()) {
288         DrawBorder(canvas, paintOffset, pen, contentSize);
289     }
290     pen.SetColor(ToRSColor(animatableCheckColor_->Get()));
291     shadowPen.SetColor(ToRSColor(animatableShadowColor_->Get()));
292     if (!hasBuilder_->Get()) {
293         DrawCheck(canvas, paintOffset, pen, shadowPen, contentSize);
294     }
295 }
296 
DrawFocusBoard(RSCanvas & canvas,const SizeF & size,const OffsetF & offset) const297 void CheckBoxModifier::DrawFocusBoard(RSCanvas& canvas, const SizeF& size, const OffsetF& offset) const
298 {
299     RSBrush brush;
300     if (isFocused_->Get()) {
301         brush.SetColor(ToRSColor(focusBoardColor_));
302     } else {
303         brush.SetColor(ToRSColor(Color::TRANSPARENT));
304     }
305     brush.SetAntiAlias(true);
306     auto bgSizeOffset = (checkBoxShape_->Get() == static_cast<int32_t>(CheckBoxStyle::SQUARE_STYLE)) ?
307         focusBoardSize_.ConvertToPx() : roundFocusBoardSize_.ConvertToPx();
308     float originX = offset.GetX() - bgSizeOffset;
309     float originY = offset.GetY() - bgSizeOffset;
310     float endX = offset.GetX() + bgSizeOffset + size.Width();
311     float endY = offset.GetY() + bgSizeOffset + size.Height();
312     float useFocusBoardRadoius = whiteBorderRadius_ + bgSizeOffset;
313     auto rrect = RSRoundRect({ originX, originY, endX, endY }, useFocusBoardRadoius, useFocusBoardRadoius);
314 
315     canvas.AttachBrush(brush);
316     DrawRectOrCircle(canvas, rrect);
317     canvas.DetachBrush();
318 }
319 
DrawTouchAndHoverBoard(RSCanvas & canvas,const SizeF & size,const OffsetF & offset) const320 void CheckBoxModifier::DrawTouchAndHoverBoard(RSCanvas& canvas, const SizeF& size, const OffsetF& offset) const
321 {
322     if (HoverEffectType::NONE == hoverEffectType_) {
323         return;
324     }
325     RSBrush brush;
326     brush.SetColor(ToRSColor(animateTouchHoverColor_->Get()));
327     brush.SetAntiAlias(true);
328     float originX;
329     float originY;
330     float endX;
331     float endY;
332     auto defaultPadding = (checkBoxShape_->Get() == static_cast<int32_t>(CheckBoxStyle::SQUARE_STYLE)) ?
333         defaultPaddingSize_.ConvertToPx() : defaultRoundPaddingSize_.ConvertToPx();
334     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
335         if (showCircleDial_) {
336             defaultPadding = hoverPaddingSize_.ConvertToPx();
337         }
338         originX = offset.GetX() - defaultPadding;
339         originY = offset.GetY() - defaultPadding;
340         endX = size.Width() + originX + CHECKBOX_DOUBLE_RATIO * defaultPadding;
341         endY = size.Height() + originY + CHECKBOX_DOUBLE_RATIO * defaultPadding;
342     } else {
343         originX = offset.GetX() - hotZoneHorizontalPadding_.ConvertToPx();
344         originY = offset.GetY() - hotZoneVerticalPadding_.ConvertToPx();
345         endX = size.Width() + originX + CHECKBOX_DOUBLE_RATIO * hotZoneHorizontalPadding_.ConvertToPx();
346         endY = size.Height() + originY + CHECKBOX_DOUBLE_RATIO * hotZoneVerticalPadding_.ConvertToPx();
347     }
348     auto rrect = RSRoundRect({ originX, originY, endX, endY }, hoverRadius_.ConvertToPx(), hoverRadius_.ConvertToPx());
349     canvas.AttachBrush(brush);
350     DrawRectOrCircle(canvas, rrect);
351     canvas.DetachBrush();
352 }
353 
DrawBorder(RSCanvas & canvas,const OffsetF & origin,RSPen & pen,const SizeF & paintSize) const354 void CheckBoxModifier::DrawBorder(RSCanvas& canvas, const OffsetF& origin, RSPen& pen, const SizeF& paintSize) const
355 {
356     float originX = origin.GetX() + borderWidth_ / CHECKBOX_DOUBLE_RATIO;
357     float originY = origin.GetY() + borderWidth_ / CHECKBOX_DOUBLE_RATIO;
358     float endX = originX + paintSize.Width() - borderWidth_;
359     float endY = originY + paintSize.Height() - borderWidth_;
360     auto rrect = RSRoundRect({ originX, originY, endX, endY }, borderRadius_, borderRadius_);
361     canvas.AttachPen(pen);
362     DrawRectOrCircle(canvas, rrect);
363     canvas.DetachPen();
364 }
365 
DrawBackboard(RSCanvas & canvas,const OffsetF & origin,RSBrush & brush,const SizeF & paintSize) const366 void CheckBoxModifier::DrawBackboard(
367     RSCanvas& canvas, const OffsetF& origin, RSBrush& brush, const SizeF& paintSize) const
368 {
369     float originX = origin.GetX();
370     float originY = origin.GetY();
371     float endX = originX + paintSize.Width();
372     float endY = originY + paintSize.Height();
373     auto rrect = RSRoundRect({ originX, originY, endX, endY }, borderRadius_, borderRadius_);
374     canvas.AttachBrush(brush);
375     DrawRectOrCircle(canvas, rrect);
376     canvas.DetachBrush();
377 }
378 
DrawCheck(RSCanvas & canvas,const OffsetF & origin,RSPen & pen,RSPen & shadowPen,const SizeF & paintSize) const379 void CheckBoxModifier::DrawCheck(
380     RSCanvas& canvas, const OffsetF& origin, RSPen& pen, RSPen& shadowPen, const SizeF& paintSize) const
381 {
382     if (strokeSize_->Get() == CHECKBOX_LENGTH_ZERO || checkStroke_->Get() == CHECKBOX_LENGTH_ZERO) {
383         TAG_LOGD(AceLogTag::ACE_SELECT_COMPONENT, "checkbox draw check zero %{public}f %{public}f", strokeSize_->Get(),
384             checkStroke_->Get());
385         return;
386     }
387 #ifndef USE_ROSEN_DRAWING
388     RSPath path;
389 #else
390     RSRecordingPath path;
391 #endif
392     float originX = origin.GetX();
393     float originY = origin.GetY();
394     float strokeSize = strokeSize_->Get();
395     const Offset start = Offset(strokeSize * CHECK_MARK_START_X_POSITION, strokeSize * CHECK_MARK_START_Y_POSITION);
396     const Offset middle = Offset(strokeSize * CHECK_MARK_MIDDLE_X_POSITION, strokeSize * CHECK_MARK_MIDDLE_Y_POSITION);
397     const Offset end = Offset(strokeSize * CHECK_MARK_END_X_POSITION, strokeSize * CHECK_MARK_END_Y_POSITION);
398     path.MoveTo(originX + start.GetX() + (paintSize.Width() - strokeSize) / CHECKBOX_DOUBLE_RATIO,
399         originY + start.GetY() + (paintSize.Height() - strokeSize) / CHECKBOX_DOUBLE_RATIO);
400     path.LineTo(originX + middle.GetX() + (paintSize.Width() - strokeSize) / CHECKBOX_DOUBLE_RATIO,
401         originY + middle.GetY() + (paintSize.Height() - strokeSize) / CHECKBOX_DOUBLE_RATIO);
402     path.MoveTo(originX + middle.GetX() + (paintSize.Width() - strokeSize) / CHECKBOX_DOUBLE_RATIO,
403         originY + middle.GetY() + (paintSize.Height() - strokeSize) / CHECKBOX_DOUBLE_RATIO);
404     path.LineTo(originX + end.GetX() + (paintSize.Width() - strokeSize) / CHECKBOX_DOUBLE_RATIO,
405         originY + end.GetY() + (paintSize.Height() - strokeSize) / CHECKBOX_DOUBLE_RATIO);
406     shadowPen.SetCapStyle(RSPen::CapStyle::ROUND_CAP);
407     shadowPen.SetWidth(checkStroke_->Get() + shadowWidth_.ConvertToPx() * CHECKBOX_DOUBLE_RATIO);
408     pen.SetWidth(checkStroke_->Get());
409     pen.SetCapStyle(RSPen::CapStyle::ROUND_CAP);
410     canvas.AttachPen(shadowPen);
411     canvas.DrawPath(path);
412     canvas.DetachPen();
413     canvas.AttachPen(pen);
414     canvas.DrawPath(path);
415     canvas.DetachPen();
416 }
417 
DrawRectOrCircle(RSCanvas & canvas,const RSRoundRect & rrect) const418 void CheckBoxModifier::DrawRectOrCircle(RSCanvas& canvas, const RSRoundRect& rrect) const
419 {
420     if (CheckBoxStyle::SQUARE_STYLE == checkBoxStyle_) {
421         canvas.DrawRoundRect(rrect);
422     } else {
423         RSScalar halfDenominator = 2.0f;
424         RSRect rect = rrect.GetRect();
425         RSScalar x = (rect.GetLeft() + rect.GetRight()) / halfDenominator;
426         RSScalar y = (rect.GetTop() + rect.GetBottom()) / halfDenominator;
427         RSPoint centerPt(x, y);
428         RSScalar radius = std::min(rect.GetWidth(), rect.GetHeight()) / halfDenominator;
429         canvas.DrawCircle(centerPt, radius);
430     }
431 }
432 
433 } // namespace OHOS::Ace::NG
434