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