1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.. All rights reserved.
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 "text_animation_config.h"
17 #include "draw/path.h"
18 #include "hm_symbol_node_build.h"
19 #include "utils/text_log.h"
20 #include "utils/text_trace.h"
21
22 namespace OHOS::Rosen::SPText {
23
SetUniqueId(uint64_t uniqueId)24 void TextAnimationConfig::SetUniqueId(uint64_t uniqueId)
25 {
26 uniqueId_ = uniqueId;
27 }
28
SetAnimation(const std::function<bool (const std::shared_ptr<OHOS::Rosen::TextEngine::SymbolAnimationConfig> &)> & animationFunc)29 void TextAnimationConfig::SetAnimation(
30 const std::function<bool(const std::shared_ptr<OHOS::Rosen::TextEngine::SymbolAnimationConfig>&)>&
31 animationFunc)
32 {
33 if (animationFunc) {
34 animationFunc_ = animationFunc;
35 }
36 }
37
SetEffectConfig(const std::vector<std::vector<Drawing::DrawingPiecewiseParameter>> & parameters)38 void TextAnimationConfig::SetEffectConfig(
39 const std::vector<std::vector<Drawing::DrawingPiecewiseParameter>>& parameters)
40 {
41 parameters_ = parameters;
42 currentAnimationHasPlayed_ = false;
43 }
44
SetColor(const RSColor & color)45 void TextAnimationConfig::SetColor(const RSColor& color)
46 {
47 color_ = color.CastToColorQuad();
48 }
49
SetAnimationStart(bool animationStart)50 void TextAnimationConfig::SetAnimationStart(bool animationStart)
51 {
52 animationStart_ = animationStart;
53 }
54
SetEffectStrategy(RSEffectStrategy effectStrategy)55 void TextAnimationConfig::SetEffectStrategy(RSEffectStrategy effectStrategy)
56 {
57 effectStrategy_ = effectStrategy;
58 currentAnimationHasPlayed_ = false;
59 }
60
DrawTextEffect(RSCanvas * canvas,const std::vector<TextEngine::TextEffectElement> & effectElements)61 bool TextAnimationConfig::DrawTextEffect(RSCanvas* canvas,
62 const std::vector<TextEngine::TextEffectElement>& effectElements)
63 {
64 TEXT_TRACE_FUNC();
65 if (canvas == nullptr) {
66 TEXT_LOGE("Invalid input, canvas is nullptr.");
67 return false;
68 }
69
70 if (effectElements.empty()) {
71 TEXT_LOGE("Invalid input, effectElements is empty.");
72 return false;
73 }
74
75 if (animationStart_) {
76 if (TextAnimationRun(effectElements)) {
77 currentAnimationHasPlayed_ = true;
78 return true;
79 }
80 }
81 currentAnimationHasPlayed_ = false;
82 OnDrawTextEffect(canvas, effectElements);
83 return false;
84 }
85
TextAnimationRun(const std::vector<TextEngine::TextEffectElement> & effectElements)86 bool TextAnimationConfig::TextAnimationRun(const std::vector<TextEngine::TextEffectElement>& effectElements)
87 {
88 TEXT_TRACE_FUNC();
89 if (animationFunc_ == nullptr) {
90 return false;
91 }
92 auto symbolAnimationConfig = std::make_shared<TextEngine::SymbolAnimationConfig>();
93 symbolAnimationConfig->effectStrategy = effectStrategy_;
94 symbolAnimationConfig->animationStart = animationStart_;
95 symbolAnimationConfig->currentAnimationHasPlayed = currentAnimationHasPlayed_;
96 symbolAnimationConfig->parameters = parameters_;
97 symbolAnimationConfig->color = color_.CastToColorQuad();
98 for (const auto& element: effectElements) {
99 symbolAnimationConfig->effectElement = element;
100 symbolAnimationConfig->symbolSpanId = element.uniqueId;
101 if (!animationFunc_(symbolAnimationConfig)) {
102 return false;
103 }
104 }
105
106 return true;
107 }
108
OnDrawTextEffect(RSCanvas * canvas,const std::vector<TextEngine::TextEffectElement> & effectElements)109 void TextAnimationConfig::OnDrawTextEffect(RSCanvas* canvas,
110 const std::vector<TextEngine::TextEffectElement>& effectElements)
111 {
112 TEXT_TRACE_FUNC();
113 Drawing::Brush brush;
114 brush.SetAntiAlias(true);
115 brush.SetColor(color_.CastToColorQuad());
116 canvas->AttachBrush(brush);
117 for (const auto& effectElement : effectElements) {
118 ClearTextAnimation(effectElement.uniqueId);
119 auto path = effectElement.path;
120 path.Offset(effectElement.offset.GetX(), effectElement.offset.GetY());
121 canvas->DrawPath(path);
122 }
123 canvas->DetachBrush();
124 }
125
ClearTextAnimation(uint64_t uniqueId)126 void TextAnimationConfig::ClearTextAnimation(uint64_t uniqueId)
127 {
128 if (animationFunc_ == nullptr) {
129 return;
130 }
131 auto symbolAnimationConfig = std::make_shared<TextEngine::SymbolAnimationConfig>();
132 symbolAnimationConfig->effectStrategy = Drawing::DrawingEffectStrategy::NONE;
133 symbolAnimationConfig->symbolSpanId = uniqueId;
134 animationFunc_(symbolAnimationConfig);
135 }
136
AnimationUnchange(bool isUnchange)137 void TextAnimationConfig::AnimationUnchange(bool isUnchange)
138 {
139 currentAnimationHasPlayed_ = isUnchange;
140 }
141
ClearAllTextAnimation()142 void TextAnimationConfig::ClearAllTextAnimation()
143 {
144 TEXT_TRACE_FUNC();
145 if (animationFunc_ == nullptr) {
146 return;
147 }
148 auto symbolAnimationConfig = std::make_shared<TextEngine::SymbolAnimationConfig>();
149 symbolAnimationConfig->effectStrategy = Drawing::DrawingEffectStrategy::TEXT_FLIP;
150 symbolAnimationConfig->animationStart = false;
151 animationFunc_(symbolAnimationConfig);
152 }
153 }