1 /*
2 * Copyright (c) 2024 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 "hm_symbol_run.h"
17 #include "custom_symbol_config.h"
18 #include "default_symbol_config.h"
19 #include "draw/path.h"
20 #include "hm_symbol_node_build.h"
21 #include "include/pathops/SkPathOps.h"
22 #include "utils/text_log.h"
23 #include "utils/text_trace.h"
24
25 namespace OHOS {
26 namespace Rosen {
27 namespace SPText {
28 static const std::vector<RSEffectStrategy> COMMON_ANIMATION_TYPES = {
29 RSEffectStrategy::SCALE, RSEffectStrategy::APPEAR, RSEffectStrategy::DISAPPEAR,
30 RSEffectStrategy::BOUNCE, RSEffectStrategy::REPLACE_APPEAR, RSEffectStrategy::QUICK_REPLACE_APPEAR};
31
32 static const float SHADOW_EPSILON = 0.999f; // if blur radius less than 1, do noe need to draw
33
HMSymbolRun(uint64_t symbolId,const HMSymbolTxt & symbolTxt,const std::shared_ptr<RSTextBlob> & textBlob,std::function<bool (const std::shared_ptr<TextEngine::SymbolAnimationConfig> &)> & animationFunc)34 HMSymbolRun::HMSymbolRun(uint64_t symbolId,
35 const HMSymbolTxt& symbolTxt,
36 const std::shared_ptr<RSTextBlob>& textBlob,
37 std::function<bool(const std::shared_ptr<TextEngine::SymbolAnimationConfig>&)>& animationFunc)
38 : symbolTxt_(symbolTxt), symbolId_(symbolId)
39 {
40 if (textBlob) {
41 textBlob_ = textBlob;
42 } else {
43 TEXT_LOGD("Null text blob");
44 }
45 if (animationFunc) {
46 animationFunc_ = animationFunc;
47 } else {
48 TEXT_LOGD("Null animation func");
49 }
50 }
51
GetSymbolLayers(uint16_t glyphId,const HMSymbolTxt & symbolText)52 RSSymbolLayers HMSymbolRun::GetSymbolLayers(uint16_t glyphId, const HMSymbolTxt& symbolText)
53 {
54 RSSymbolLayers symbolInfo;
55 symbolInfo.symbolGlyphId = glyphId;
56 auto& symbolInfoOrign = symbolLayersGroups_;
57 if (symbolInfoOrign.renderModeGroups.empty() || symbolInfoOrign.symbolGlyphId == 0) {
58 TEXT_LOGD("Invalid symbol layer groups, glyph id %{public}hu.", glyphId);
59 return symbolInfo;
60 }
61
62 RSSymbolRenderingStrategy renderMode = symbolText.GetRenderMode();
63 if (symbolInfoOrign.renderModeGroups.find(renderMode) == symbolInfoOrign.renderModeGroups.end()) {
64 renderMode = RSSymbolRenderingStrategy::SINGLE;
65 }
66
67 symbolInfo.layers = symbolInfoOrign.layers;
68 if (symbolInfoOrign.renderModeGroups.find(renderMode) != symbolInfoOrign.renderModeGroups.end()) {
69 symbolInfo.renderGroups = symbolInfoOrign.renderModeGroups[renderMode];
70 symbolInfo.symbolGlyphId = symbolInfoOrign.symbolGlyphId;
71 }
72
73 switch (symbolText.GetSymbolColor().colorType) {
74 case SymbolColorType::GRADIENT_DEFAULT_COLOR:
75 SetGradientOrDefinedColor(symbolInfo);
76 break;
77 case SymbolColorType::GRADIENT_TYPE:
78 SetGradientColor(renderMode, symbolInfo);
79 if (gradients_.empty()) {
80 SetRenderColor(renderMode, symbolInfo);
81 }
82 break;
83 default:
84 SetRenderColor(renderMode, symbolInfo);
85 break;
86 }
87 return symbolInfo;
88 }
89
SetRenderColor(const RSSymbolRenderingStrategy & renderMode,RSSymbolLayers & symbolInfo)90 void HMSymbolRun::SetRenderColor(const RSSymbolRenderingStrategy& renderMode, RSSymbolLayers& symbolInfo)
91 {
92 std::vector<RSSColor> colorList = symbolTxt_.GetRenderColor();
93
94 if (!colorList.empty()) {
95 SetSymbolRenderColor(renderMode, colorList, symbolInfo);
96 }
97
98 std::vector<std::shared_ptr<SymbolGradient>> gradients;
99 for (const auto& group : symbolInfo.renderGroups) {
100 auto gradient = std::make_shared<SymbolGradient>();
101 std::vector<Drawing::ColorQuad> colorQuads;
102 Drawing::Color color;
103 color.SetRgb(group.color.r, group.color.g, group.color.b);
104 color.SetAlphaF(group.color.a);
105 colorQuads.push_back(color.CastToColorQuad());
106 gradient->SetColors(colorQuads);
107 gradients.push_back(gradient);
108 }
109 gradients_ = gradients;
110 }
111
SetGradientColor(const RSSymbolRenderingStrategy & renderMode,const RSSymbolLayers & symbolInfo)112 void HMSymbolRun::SetGradientColor(const RSSymbolRenderingStrategy& renderMode, const RSSymbolLayers& symbolInfo)
113 {
114 SymbolColor symbolColor = symbolTxt_.GetSymbolColor();
115 if (symbolColor.gradients.empty()) {
116 return;
117 }
118 std::vector<std::shared_ptr<SymbolGradient>> gradients;
119 if (renderMode == RSSymbolRenderingStrategy::SINGLE) {
120 gradients.push_back(symbolColor.gradients[0]);
121 gradients_ = gradients;
122 return;
123 }
124
125 size_t i = 0;
126 const size_t n = symbolColor.gradients.size() - 1;
127 for (size_t index = 0; index < symbolInfo.renderGroups.size(); index++) {
128 std::shared_ptr<SymbolGradient> gradient = nullptr;
129 if (i <= n) {
130 gradient = symbolColor.gradients[i];
131 i++;
132 } else {
133 gradient = SymbolNodeBuild::CreateGradient(symbolColor.gradients[n]);
134 }
135 if (gradient != nullptr) {
136 gradients.push_back(gradient);
137 }
138 }
139 gradients_ = std::move(gradients);
140 }
141
SetGradientOrDefinedColor(const RSSymbolLayers & symbolInfo)142 void HMSymbolRun::SetGradientOrDefinedColor(const RSSymbolLayers& symbolInfo)
143 {
144 auto symbolColor = symbolTxt_.GetSymbolColor();
145 const size_t n = symbolColor.gradients.size();
146 std::vector<std::shared_ptr<SymbolGradient>> gradients;
147 for (size_t i = 0; i < symbolInfo.renderGroups.size(); i++) {
148 if (i < n && symbolColor.gradients[i]) {
149 gradients.push_back(symbolColor.gradients[i]);
150 } else {
151 auto gradient = std::make_shared<SymbolGradient>();
152 Drawing::Color color;
153 const auto& group = symbolInfo.renderGroups[i];
154 color.SetRgb(group.color.r, group.color.g, group.color.b);
155 color.SetAlphaF(group.color.a);
156 std::vector<Drawing::ColorQuad> colorQuads;
157 colorQuads.push_back(color.CastToColorQuad());
158 gradient->SetColors(colorQuads);
159 gradients.push_back(gradient);
160 }
161 }
162 gradients_ = std::move(gradients);
163 }
164
SetSymbolRenderColor(const RSSymbolRenderingStrategy & renderMode,const std::vector<RSSColor> & colors,RSSymbolLayers & symbolInfo)165 void HMSymbolRun::SetSymbolRenderColor(const RSSymbolRenderingStrategy& renderMode,
166 const std::vector<RSSColor>& colors, RSSymbolLayers& symbolInfo)
167 {
168 if (colors.empty()) {
169 return;
170 }
171 switch (renderMode) {
172 // SINGLE and HIERARCHICAL: Supports single color setting
173 case RSSymbolRenderingStrategy::SINGLE:
174 for (size_t i = 0; i < symbolInfo.renderGroups.size(); ++i) {
175 symbolInfo.renderGroups[i].color = colors[0]; // the 0 indicates the the first color is used
176 }
177 break;
178 // MULTIPLE_OPACITY: Supports rgb replace and alphia overlay setting by the first color
179 case RSSymbolRenderingStrategy::MULTIPLE_OPACITY:
180 for (size_t i = 0; i < symbolInfo.renderGroups.size(); ++i) {
181 float colorAlphia = symbolInfo.renderGroups[i].color.a * colors[0].a;
182 symbolInfo.renderGroups[i].color.a = std::clamp(colorAlphia, 0.0f, 1.0f); // 0.0: min, 1.0: max
183 symbolInfo.renderGroups[i].color.r = colors[0].r; // the 0 indicates the the first color is used
184 symbolInfo.renderGroups[i].color.g = colors[0].g; // the 0 indicates the the first color is used
185 symbolInfo.renderGroups[i].color.b = colors[0].b; // the 0 indicates the the first color is used
186 }
187 break;
188 // MULTIPLE_COLOR: Supports mutiple color setting
189 case RSSymbolRenderingStrategy::MULTIPLE_COLOR:
190 for (size_t i = 0; i < symbolInfo.renderGroups.size() && i < colors.size(); ++i) {
191 symbolInfo.renderGroups[i].color = colors[i];
192 }
193 break;
194 default:
195 break;
196 }
197 }
198
UpdateSymbolLayersGroups(uint16_t glyphId)199 void HMSymbolRun::UpdateSymbolLayersGroups(uint16_t glyphId)
200 {
201 symbolLayersGroups_.symbolGlyphId = glyphId;
202 // Obtaining Symbol Preset LayerGroups Parameters
203 if (symbolTxt_.GetSymbolType() == SymbolType::SYSTEM) {
204 auto groups = OHOS::Rosen::Symbol::DefaultSymbolConfig::GetInstance()->GetSymbolLayersGroups(glyphId);
205 if (groups.renderModeGroups.empty()) {
206 TEXT_LOGD("Failed to get system symbol layer groups, glyph id %{public}hu", glyphId);
207 symbolLayersGroups_.renderModeGroups = {};
208 return;
209 }
210 symbolLayersGroups_ = groups;
211 } else {
212 auto groups = OHOS::Rosen::Symbol::CustomSymbolConfig::GetInstance()->GetSymbolLayersGroups(
213 symbolTxt_.familyName_, glyphId);
214 if (!groups.has_value()) {
215 TEXT_LOGD("Failed to get custom symbol layer groups, glyph id %{public}hu", glyphId);
216 symbolLayersGroups_.renderModeGroups = {};
217 return;
218 }
219 symbolLayersGroups_ = groups.value();
220 }
221 }
222
DrawSymbol(RSCanvas * canvas,const RSPoint & offset)223 void HMSymbolRun::DrawSymbol(RSCanvas* canvas, const RSPoint& offset)
224 {
225 TEXT_TRACE_FUNC();
226 if (!textBlob_) {
227 TEXT_LOGD("Null text blob");
228 return;
229 }
230
231 if (!canvas) {
232 TEXT_LOGD("Null canvas");
233 return;
234 }
235
236 std::vector<uint16_t> glyphIds;
237 RSTextBlob::GetDrawingGlyphIDforTextBlob(textBlob_.get(), glyphIds);
238 if (glyphIds.size() != 1) {
239 TEXT_LOGD("Glyph isn't unique");
240 canvas->DrawTextBlob(textBlob_.get(), offset.GetX(), offset.GetY());
241 return;
242 }
243 TEXT_LOGD("HmSymbol: DrawSymbol");
244 uint16_t glyphId = glyphIds[0];
245 OHOS::Rosen::Drawing::Path path = RSTextBlob::GetDrawingPathforTextBlob(glyphId, textBlob_.get());
246 RSHMSymbolData symbolData;
247
248 UpdateSymbolLayersGroups(glyphId);
249 symbolData.symbolInfo_ = GetSymbolLayers(glyphId, symbolTxt_);
250 if (symbolData.symbolInfo_.symbolGlyphId != glyphId) {
251 path = RSTextBlob::GetDrawingPathforTextBlob(symbolData.symbolInfo_.symbolGlyphId, textBlob_.get());
252 }
253 symbolData.path_ = path;
254 symbolData.symbolId = symbolId_; // symbolspan Id in paragraph
255 RSEffectStrategy symbolEffect = symbolTxt_.GetEffectStrategy();
256 std::pair<float, float> offsetXY(offset.GetX(), offset.GetY());
257 if (symbolEffect > 0 && symbolTxt_.GetAnimationStart()) { // 0 > has animation
258 if (SymbolAnimation(symbolData, offsetXY)) {
259 currentAnimationHasPlayed_ = true;
260 return;
261 }
262 }
263 ClearSymbolAnimation(symbolData, offsetXY);
264 OnDrawSymbol(canvas, symbolData, offset);
265 currentAnimationHasPlayed_ = false;
266 }
267
SetRenderColor(const std::vector<RSSColor> & colorList)268 void HMSymbolRun::SetRenderColor(const std::vector<RSSColor>& colorList)
269 {
270 symbolTxt_.SetRenderColor(colorList);
271 }
272
SetSymbolColor(const SymbolColor & symbolColor)273 void HMSymbolRun::SetSymbolColor(const SymbolColor& symbolColor)
274 {
275 symbolTxt_.SetSymbolColor(symbolColor);
276 }
277
SetRenderMode(RSSymbolRenderingStrategy renderMode)278 void HMSymbolRun::SetRenderMode(RSSymbolRenderingStrategy renderMode)
279 {
280 symbolTxt_.SetRenderMode(renderMode);
281 }
282
SetSymbolEffect(const RSEffectStrategy & effectStrategy)283 void HMSymbolRun::SetSymbolEffect(const RSEffectStrategy& effectStrategy)
284 {
285 symbolTxt_.SetSymbolEffect(effectStrategy);
286 currentAnimationHasPlayed_ = false;
287 }
288
SetAnimationMode(uint16_t animationMode)289 void HMSymbolRun::SetAnimationMode(uint16_t animationMode)
290 {
291 symbolTxt_.SetAnimationMode(animationMode);
292 currentAnimationHasPlayed_ = false;
293 }
294
SetAnimationStart(bool animationStart)295 void HMSymbolRun::SetAnimationStart(bool animationStart)
296 {
297 symbolTxt_.SetAnimationStart(animationStart);
298 currentAnimationHasPlayed_ = false;
299 }
300
SetCommonSubType(Drawing::DrawingCommonSubType commonSubType)301 void HMSymbolRun::SetCommonSubType(Drawing::DrawingCommonSubType commonSubType)
302 {
303 symbolTxt_.SetCommonSubType(commonSubType);
304 currentAnimationHasPlayed_ = false;
305 }
306
GetSymbolUid() const307 uint64_t HMSymbolRun::GetSymbolUid() const
308 {
309 return symbolTxt_.GetSymbolUid();
310 }
311
SetSymbolUid(uint64_t symbolUid)312 void HMSymbolRun::SetSymbolUid(uint64_t symbolUid)
313 {
314 symbolTxt_.SetSymbolUid(symbolUid);
315 symbolId_ = symbolUid;
316 }
317
SetSymbolTxt(const HMSymbolTxt & hmsymbolTxt)318 void HMSymbolRun::SetSymbolTxt(const HMSymbolTxt& hmsymbolTxt)
319 {
320 symbolTxt_ = hmsymbolTxt;
321 }
322
GetSymbolTxt()323 const HMSymbolTxt& HMSymbolRun::GetSymbolTxt()
324 {
325 return symbolTxt_;
326 }
327
SetSymbolShadow(const std::optional<SymbolShadow> & symbolShadow)328 void HMSymbolRun::SetSymbolShadow(const std::optional<SymbolShadow>& symbolShadow)
329 {
330 if (symbolTxt_.GetSymbolShadow().has_value() != symbolShadow.has_value()) {
331 currentAnimationHasPlayed_ = false;
332 }
333 symbolTxt_.SetSymbolShadow(symbolShadow);
334 }
335
SetAnimation(const std::function<bool (const std::shared_ptr<OHOS::Rosen::TextEngine::SymbolAnimationConfig> &)> & animationFunc)336 void HMSymbolRun::SetAnimation(
337 const std::function<bool(const std::shared_ptr<OHOS::Rosen::TextEngine::SymbolAnimationConfig>&)>&
338 animationFunc)
339 {
340 if (animationFunc) {
341 animationFunc_ = animationFunc;
342 }
343 }
344
SetTextBlob(const std::shared_ptr<RSTextBlob> & textBlob)345 void HMSymbolRun::SetTextBlob(const std::shared_ptr<RSTextBlob>& textBlob)
346 {
347 if (textBlob) {
348 std::vector<uint16_t> glyphId1;
349 std::vector<uint16_t> glyphId2;
350 RSTextBlob::GetDrawingGlyphIDforTextBlob(textBlob_.get(), glyphId1);
351 RSTextBlob::GetDrawingGlyphIDforTextBlob(textBlob.get(), glyphId2);
352 // 1 mean the textBlob has one symbol
353 if (!(glyphId1.size() == 1 && glyphId2.size() == 1 && glyphId1[0] == glyphId2[0])) {
354 currentAnimationHasPlayed_ = false;
355 }
356 textBlob_ = textBlob;
357 }
358 }
359
DrawPaths(RSCanvas * canvas,const std::vector<RSPath> & multPaths,const RSPath & path)360 void HMSymbolRun::DrawPaths(RSCanvas* canvas, const std::vector<RSPath>& multPaths,
361 const RSPath& path)
362 {
363 Drawing::Brush brush;
364 Drawing::Pen pen;
365 brush.SetAntiAlias(true);
366 pen.SetAntiAlias(true);
367
368 size_t n = gradients_.size();
369 bool isSingle = symbolTxt_.GetRenderMode() == RSSymbolRenderingStrategy::SINGLE && n > 0 &&
370 gradients_[0] != nullptr;
371 if (isSingle) { // if renderMode is SINGLE only set one color
372 gradients_[0]->Make(path.GetBounds());
373 brush = gradients_[0]->CreateGradientBrush();
374 pen = gradients_[0]->CreateGradientPen();
375 }
376
377 size_t i = 0;
378 for (const auto& multPath: multPaths) {
379 bool isValid = symbolTxt_.GetRenderMode() != RSSymbolRenderingStrategy::SINGLE && i < n &&
380 gradients_[i] != nullptr;
381 if (isValid) {
382 gradients_[i]->Make(multPath.GetBounds());
383 brush = gradients_[i]->CreateGradientBrush();
384 pen = gradients_[i]->CreateGradientPen();
385 i = i + 1 < n ? i + 1 : i;
386 }
387 canvas->AttachPen(pen);
388 canvas->AttachBrush(brush);
389 canvas->DrawPath(multPath);
390 canvas->DetachBrush();
391 canvas->DetachPen();
392 }
393 }
394
OnDrawSymbol(RSCanvas * canvas,const RSHMSymbolData & symbolData,RSPoint locate)395 void HMSymbolRun::OnDrawSymbol(RSCanvas* canvas, const RSHMSymbolData& symbolData, RSPoint locate)
396 {
397 TEXT_TRACE_FUNC();
398 RSPath path(symbolData.path_);
399
400 // 1.0 move path
401 path.Offset(locate.GetX(), locate.GetY());
402 if (symbolData.symbolInfo_.renderGroups.empty()) {
403 TEXT_LOGD("Empty render groups");
404 canvas->DrawPath(path);
405 return;
406 }
407
408 // 2.0 split path
409 std::vector<RSPath> paths;
410 RSHMSymbol::PathOutlineDecompose(path, paths);
411 std::vector<RSPath> pathLayers;
412 RSHMSymbol::MultilayerPath(symbolData.symbolInfo_.layers, paths, pathLayers);
413 // Stratification
414 std::vector<RSRenderGroup> groups = symbolData.symbolInfo_.renderGroups;
415 TEXT_LOGD("RenderGroup size %{public}zu", groups.size());
416 std::vector<RSPath> multPaths;
417 for (auto group : groups) {
418 RSPath multPath;
419 SymbolNodeBuild::MergeDrawingPath(multPath, group, pathLayers);
420 multPaths.push_back(multPath);
421 }
422
423 if (symbolTxt_.GetSymbolShadow().has_value() &&
424 symbolTxt_.GetSymbolShadow().value().blurRadius > SHADOW_EPSILON) {
425 DrawSymbolShadow(canvas, multPaths);
426 }
427
428 DrawPaths(canvas, multPaths, path);
429 }
430
DrawSymbolShadow(RSCanvas * canvas,const std::vector<RSPath> & multPaths)431 void HMSymbolRun::DrawSymbolShadow(RSCanvas* canvas, const std::vector<RSPath>& multPaths)
432 {
433 auto shadow = symbolTxt_.GetSymbolShadow().value();
434 Drawing::Filter filter;
435 filter.SetMaskFilter(Drawing::MaskFilter::CreateBlurMaskFilter(Drawing::BlurType::NORMAL,
436 shadow.blurRadius, false));
437 Drawing::Brush brush;
438 brush.SetAntiAlias(true);
439 brush.SetFilter(filter);
440
441 RSRecordingCanvas* recordingCanvas = nullptr;
442 if (canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
443 recordingCanvas = static_cast<RSRecordingCanvas*>(canvas);
444 }
445 if (recordingCanvas != nullptr) {
446 recordingCanvas->GetDrawCmdList()->SetHybridRenderType(RSHybridRenderType::NONE);
447 }
448
449 RSColor color;
450 for (size_t i = 0; i < multPaths.size(); i++) {
451 RSPath multPath = multPaths[i];
452 multPath.Offset(shadow.offset.GetX(), shadow.offset.GetY());
453 color = shadow.color;
454 bool isNeedSet = i < gradients_.size() && gradients_[i] && !gradients_[i]->GetColors().empty();
455 if (isNeedSet) {
456 auto colorQuad = gradients_[i]->GetColors()[0];
457 RSColor color1(colorQuad);
458 color.SetAlphaF(shadow.color.GetAlphaF() * color1.GetAlphaF());
459 }
460 brush.SetColor(color);
461 canvas->AttachBrush(brush);
462 canvas->DrawPath(multPath);
463 canvas->DetachBrush();
464 }
465 }
466
SymbolAnimation(const RSHMSymbolData & symbol,const std::pair<float,float> & offset)467 bool HMSymbolRun::SymbolAnimation(const RSHMSymbolData& symbol, const std::pair<float, float>& offset)
468 {
469 TEXT_TRACE_FUNC();
470 RSEffectStrategy effectMode = symbolTxt_.GetEffectStrategy();
471 uint16_t animationMode = symbolTxt_.GetAnimationMode();
472 if (effectMode == RSEffectStrategy::NONE) {
473 TEXT_LOGD("Invalid effect mode");
474 return false;
475 }
476 RSAnimationSetting animationSetting;
477 if (animationMode == 0 || effectMode == RSEffectStrategy::VARIABLE_COLOR) {
478 if (!GetAnimationGroups(effectMode, animationSetting)) {
479 TEXT_LOGD("Invalid animation setting");
480 return false;
481 }
482
483 if (std::find(COMMON_ANIMATION_TYPES.begin(), COMMON_ANIMATION_TYPES.end(), effectMode) !=
484 COMMON_ANIMATION_TYPES.end() && animationSetting.groupSettings.size() == 1) {
485 animationMode = 1; // the 1 is wholeSymbol effect
486 }
487 }
488 SymbolNodeBuild symbolNode = SymbolNodeBuild(animationSetting, symbol, effectMode, offset);
489 symbolNode.SetAnimation(animationFunc_);
490 symbolNode.SetSymbolId(symbolId_);
491 symbolNode.SetAnimationMode(animationMode);
492 symbolNode.SetRepeatCount(symbolTxt_.GetRepeatCount());
493 symbolNode.SetAnimationStart(symbolTxt_.GetAnimationStart());
494 symbolNode.SetCommonSubType(symbolTxt_.GetCommonSubType());
495 symbolNode.SetCurrentAnimationHasPlayed(currentAnimationHasPlayed_);
496 symbolNode.SetRenderMode(symbolTxt_.GetRenderMode());
497 symbolNode.SetGradients(gradients_);
498 symbolNode.SetSymbolShadow(symbolTxt_.GetSymbolShadow());
499 symbolNode.SetSlope(animationSetting.slope);
500 if (effectMode == RSEffectStrategy::DISABLE) {
501 symbolNode.SetCommonSubType(animationSetting.commonSubType);
502 }
503 bool isNeed = (symbolTxt_.GetRenderMode() != RSSymbolRenderingStrategy::SINGLE &&
504 gradients_.size() < symbolTxt_.GetGradients().size());
505 if (isNeed) {
506 auto gradients = symbolTxt_.GetGradients();
507 symbolNode.SetDisableSlashColor(gradients[gradients_.size()]);
508 }
509 return symbolNode.DecomposeSymbolAndDraw();
510 }
511
ClearSymbolAnimation(const RSHMSymbolData & symbol,const std::pair<float,float> & offset)512 void HMSymbolRun::ClearSymbolAnimation(const RSHMSymbolData& symbol, const std::pair<float, float>& offset)
513 {
514 auto effectMode = RSEffectStrategy::NONE;
515 RSAnimationSetting animationSetting;
516
517 SymbolNodeBuild symbolNode = SymbolNodeBuild(animationSetting, symbol, effectMode, offset);
518 symbolNode.SetAnimation(animationFunc_);
519 symbolNode.SetSymbolId(symbolId_);
520 symbolNode.ClearAnimation();
521 }
522
GetAnimationGroups(const RSEffectStrategy effectStrategy,RSAnimationSetting & animationOut)523 bool HMSymbolRun::GetAnimationGroups(const RSEffectStrategy effectStrategy,
524 RSAnimationSetting& animationOut)
525 {
526 RSAnimationType animationType = static_cast<RSAnimationType>(effectStrategy);
527
528 for (const auto& animationSetting : symbolLayersGroups_.animationSettings) {
529 if (std::find(animationSetting.animationTypes.begin(), animationSetting.animationTypes.end(),
530 animationType) == animationSetting.animationTypes.end()) {
531 continue;
532 }
533 if (!animationSetting.groupSettings.empty()) {
534 animationOut = animationSetting;
535 return true;
536 }
537 }
538 return false;
539 }
540 }
541 }
542 }