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