1 /*
2  * Copyright (c) 2021-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 
16 #include "core/components/toggle/rosen_render_toggle.h"
17 
18 #ifndef USE_ROSEN_DRAWING
19 #include "include/core/SkRRect.h"
20 #endif
21 
22 #include "core/pipeline/base/rosen_render_context.h"
23 #ifdef OHOS_PLATFORM
24 #include "core/components/common/painter/rosen_svg_painter.h"
25 #else
26 #ifdef USE_ROSEN_DRAWING
27 #include "core/components_ng/render/drawing.h"
28 #endif
29 #endif
30 #include "render_service_client/core/ui/rs_node.h"
31 
32 namespace OHOS::Ace {
33 
PerformLayout()34 void RosenRenderToggle::PerformLayout()
35 {
36     RenderToggle::PerformLayout();
37     UpdateLayer();
38 }
39 
UpdateLayer()40 void RosenRenderToggle::UpdateLayer()
41 {
42     float translateX = GetLayoutSize().Width() / 2.0 * (1.0 - scale_);
43     float translateY = GetLayoutSize().Height() / 2.0 * (1.0 - scale_);
44     Matrix4 translateMatrix = Matrix4::CreateTranslate(translateX, translateY, 0.0);
45     Matrix4 scaleMatrix = Matrix4::CreateScale(scale_, scale_, 1.0);
46     Matrix4 transformMatrix = translateMatrix * scaleMatrix;
47     transformLayer_ = transformMatrix;
48 }
49 
Paint(RenderContext & context,const Offset & offset)50 void RosenRenderToggle::Paint(RenderContext& context, const Offset& offset)
51 {
52     auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
53     if (canvas == nullptr) {
54         LOGE("Paint canvas is null");
55         return;
56     }
57     UpdateLayer();
58 #ifdef OHOS_PLATFORM
59 #ifndef USE_ROSEN_DRAWING
60     auto recordingCanvas = static_cast<Rosen::RSRecordingCanvas*>(canvas);
61     recordingCanvas->concat(RosenSvgPainter::ToSkMatrix(transformLayer_));
62 #else
63     auto recordingCanvas = static_cast<RSRecordingCanvas*>(canvas);
64     recordingCanvas->ConcatMatrix(RosenSvgPainter::ToDrawingMatrix(transformLayer_));
65 #endif
66 #endif
67     DrawToggle(canvas, offset);
68     RenderNode::Paint(context, offset);
69 }
70 
Measure()71 Size RosenRenderToggle::Measure()
72 {
73     toggleSize_ = GetLayoutParam().GetMaxSize();
74     if (NearEqual(GetLayoutParam().GetMaxSize().Width(), Size::INFINITE_SIZE) || (!widthDefined_)) {
75         toggleSize_.SetWidth(0.0);
76     }
77     return toggleSize_;
78 }
79 
80 #ifndef USE_ROSEN_DRAWING
DrawToggle(SkCanvas * canvas,const Offset & offset) const81 void RosenRenderToggle::DrawToggle(SkCanvas* canvas, const Offset& offset) const
82 {
83     SkPaint paint;
84     paint.setColor(GetStatusColor().GetValue());
85     paint.setStyle(SkPaint::Style::kFill_Style);
86     paint.setAntiAlias(true);
87 
88     SkRRect rRect;
89     double radius = toggleSize_.Height() / 2;
90     rRect.setRectXY(SkRect::MakeIWH(toggleSize_.Width(), toggleSize_.Height()), radius, radius);
91     rRect.offset(offset.GetX(), offset.GetY());
92     canvas->drawRRect(rRect, paint);
93 }
94 #else
DrawToggle(RSCanvas * canvas,const Offset & offset) const95 void RosenRenderToggle::DrawToggle(RSCanvas* canvas, const Offset& offset) const
96 {
97     RSBrush brush;
98     brush.SetColor(GetStatusColor().GetValue());
99     brush.SetAntiAlias(true);
100 
101     double radius = toggleSize_.Height() / 2;
102     RSRoundRect rRect(
103         RSRect(0, 0, static_cast<RSScalar>(toggleSize_.Width()),
104             static_cast<RSScalar>(toggleSize_.Height())),
105         radius, radius);
106     rRect.Offset(offset.GetX(), offset.GetY());
107     canvas->AttachBrush(brush);
108     canvas->DrawRoundRect(rRect);
109     canvas->DetachBrush();
110 }
111 #endif
112 
GetStatusColor() const113 Color RosenRenderToggle::GetStatusColor() const
114 {
115     auto checkColor = toggleComponent_->GetCheckedColor();
116     auto pressedColor = toggleComponent_->GetPressedBlendColor();
117     auto backgroundColor = toggleComponent_->GetBackgroundColor();
118     if (toggleComponent_->GetCheckedState()) {
119         if (isPressed_) {
120             return checkColor.BlendColor(pressedColor);
121         }
122         return checkColor;
123     }
124     if (isPressed_) {
125         return backgroundColor.BlendColor(pressedColor);
126     }
127     return backgroundColor;
128 }
129 
HasEffectiveTransform() const130 bool RosenRenderToggle::HasEffectiveTransform() const
131 {
132     return scale_ == 1;
133 }
134 
135 } // namespace OHOS::Ace
136