• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "property/rs_properties.h"
17 
18 #include <algorithm>
19 #include <securec.h>
20 
21 #include "common/rs_common_def.h"
22 #include "common/rs_obj_abs_geometry.h"
23 #include "common/rs_vector4.h"
24 #include "pipeline/rs_uni_render_judgement.h"
25 #include "platform/common/rs_log.h"
26 #include "platform/common/rs_system_properties.h"
27 #include "render/rs_filter.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 namespace {
32 constexpr int32_t INDEX_2 = 2;
33 constexpr int32_t INDEX_4 = 4;
34 constexpr int32_t INDEX_5 = 5;
35 constexpr int32_t INDEX_6 = 6;
36 constexpr int32_t INDEX_7 = 7;
37 constexpr int32_t INDEX_9 = 9;
38 constexpr int32_t INDEX_10 = 10;
39 constexpr int32_t INDEX_11 = 11;
40 constexpr int32_t INDEX_12 = 12;
41 constexpr int32_t INDEX_14 = 14;
42 constexpr int32_t INDEX_18 = 18;
43 
44 const Vector4f Vector4fZero { 0.f, 0.f, 0.f, 0.f };
45 
46 using ResetPropertyFunc = void (*)(RSProperties* prop);
47 const std::unordered_map<RSModifierType, ResetPropertyFunc> g_funcLUT = {
__anon72ed1c210202() 48     { RSModifierType::BOUNDS, [](RSProperties* prop) {} },
__anon72ed1c210302() 49     { RSModifierType::FRAME, [](RSProperties* prop) {} },
__anon72ed1c210402() 50     { RSModifierType::SANDBOX, [](RSProperties* prop) { prop->ResetSandBox(); } },
__anon72ed1c210502() 51     { RSModifierType::POSITION_Z, [](RSProperties* prop) { prop->SetPositionZ(0.f); } },
__anon72ed1c210602() 52     { RSModifierType::PIVOT, [](RSProperties* prop) { prop->SetPivot(Vector2f(0.5f, 0.5f)); } },
__anon72ed1c210702() 53     { RSModifierType::PIVOT_Z, [](RSProperties* prop) { prop->SetPivotZ(0.f); } },
__anon72ed1c210802() 54     { RSModifierType::QUATERNION, [](RSProperties* prop) { prop->SetQuaternion(Quaternion()); } },
__anon72ed1c210902() 55     { RSModifierType::ROTATION, [](RSProperties* prop) { prop->SetRotation(0.f); } },
__anon72ed1c210a02() 56     { RSModifierType::ROTATION_X, [](RSProperties* prop) { prop->SetRotationX(0.f); } },
__anon72ed1c210b02() 57     { RSModifierType::ROTATION_Y, [](RSProperties* prop) { prop->SetRotationY(0.f); } },
__anon72ed1c210c02() 58     { RSModifierType::CAMERA_DISTANCE, [](RSProperties* prop) { prop->SetCameraDistance(0.f); } },
__anon72ed1c210d02() 59     { RSModifierType::SCALE, [](RSProperties* prop) { prop->SetScale(Vector2f(1.f, 1.f)); } },
__anon72ed1c210e02() 60     { RSModifierType::TRANSLATE, [](RSProperties* prop) { prop->SetTranslate(Vector2f(0.f, 0.f)); } },
__anon72ed1c210f02() 61     { RSModifierType::TRANSLATE_Z, [](RSProperties* prop) { prop->SetTranslateZ(0.f); } },
__anon72ed1c211002() 62     { RSModifierType::CORNER_RADIUS, [](RSProperties* prop) { prop->SetCornerRadius(0.f); } },
__anon72ed1c211102() 63     { RSModifierType::ALPHA, [](RSProperties* prop) { prop->SetAlpha(1.f); } },
__anon72ed1c211202() 64     { RSModifierType::ALPHA_OFFSCREEN, [](RSProperties* prop) { prop->SetAlphaOffscreen(false); } },
__anon72ed1c211302() 65     { RSModifierType::FOREGROUND_COLOR, [](RSProperties* prop) { prop->SetForegroundColor(RSColor()); } },
__anon72ed1c211402() 66     { RSModifierType::BACKGROUND_COLOR, [](RSProperties* prop) { prop->SetBackgroundColor(RSColor()); } },
__anon72ed1c211502() 67     { RSModifierType::BACKGROUND_SHADER, [](RSProperties* prop) { prop->SetBackgroundShader(nullptr); } },
__anon72ed1c211602() 68     { RSModifierType::BG_IMAGE, [](RSProperties* prop) { prop->SetBgImage(nullptr); } },
__anon72ed1c211702() 69     { RSModifierType::BG_IMAGE_WIDTH, [](RSProperties* prop) { prop->SetBgImageWidth(0.f); } },
__anon72ed1c211802() 70     { RSModifierType::BG_IMAGE_HEIGHT, [](RSProperties* prop) { prop->SetBgImageHeight(0.f); } },
__anon72ed1c211902() 71     { RSModifierType::BG_IMAGE_POSITION_X, [](RSProperties* prop) { prop->SetBgImagePositionX(0.f); } },
__anon72ed1c211a02() 72     { RSModifierType::BG_IMAGE_POSITION_Y, [](RSProperties* prop) { prop->SetBgImagePositionY(0.f); } },
__anon72ed1c211b02() 73     { RSModifierType::BORDER_COLOR, [](RSProperties* prop) { prop->SetBorderColor(RSColor()); } },
__anon72ed1c211c02() 74     { RSModifierType::BORDER_WIDTH, [](RSProperties* prop) { prop->SetBorderWidth(0.f); } },
__anon72ed1c211d02() 75     { RSModifierType::BORDER_STYLE, [](RSProperties* prop) { prop->SetBorderStyle((uint32_t)BorderStyle::NONE); } },
__anon72ed1c211e02() 76     { RSModifierType::FILTER, [](RSProperties* prop) { prop->SetFilter(nullptr); } },
__anon72ed1c211f02() 77     { RSModifierType::BACKGROUND_FILTER, [](RSProperties* prop) { prop->SetBackgroundFilter(nullptr); } },
__anon72ed1c212002() 78     { RSModifierType::LINEAR_GRADIENT_BLUR_PARA, [](RSProperties* prop) { prop->SetLinearGradientBlurPara(nullptr); } },
__anon72ed1c212102() 79     { RSModifierType::DYNAMIC_LIGHT_UP_RATE, [](RSProperties* prop) { prop->SetDynamicLightUpRate(std::nullopt); } },
80     { RSModifierType::DYNAMIC_LIGHT_UP_DEGREE,
__anon72ed1c212202() 81         [](RSProperties* prop) { prop->SetDynamicLightUpDegree(std::nullopt); } },
__anon72ed1c212302() 82     { RSModifierType::FRAME_GRAVITY, [](RSProperties* prop) { prop->SetFrameGravity(Gravity::DEFAULT); } },
__anon72ed1c212402() 83     { RSModifierType::CLIP_RRECT, [](RSProperties* prop) { prop->SetClipRRect(RRect()); } },
__anon72ed1c212502() 84     { RSModifierType::CLIP_BOUNDS, [](RSProperties* prop) { prop->SetClipBounds(nullptr); } },
__anon72ed1c212602() 85     { RSModifierType::CLIP_TO_BOUNDS, [](RSProperties* prop) { prop->SetClipToBounds(false); } },
__anon72ed1c212702() 86     { RSModifierType::CLIP_TO_FRAME, [](RSProperties* prop) { prop->SetClipToFrame(false); } },
__anon72ed1c212802() 87     { RSModifierType::VISIBLE, [](RSProperties* prop) { prop->SetVisible(true); } },
__anon72ed1c212902() 88     { RSModifierType::SHADOW_COLOR, [](RSProperties* prop) { prop->SetShadowColor(RgbPalette::Transparent()); } },
__anon72ed1c212a02() 89     { RSModifierType::SHADOW_OFFSET_X, [](RSProperties* prop) { prop->SetShadowOffsetX(0.f); } },
__anon72ed1c212b02() 90     { RSModifierType::SHADOW_OFFSET_Y, [](RSProperties* prop) { prop->SetShadowOffsetY(0.f); } },
__anon72ed1c212c02() 91     { RSModifierType::SHADOW_ALPHA, [](RSProperties* prop) { prop->SetShadowAlpha(0.f); } },
__anon72ed1c212d02() 92     { RSModifierType::SHADOW_ELEVATION, [](RSProperties* prop) { prop->SetShadowElevation(0.f); } },
__anon72ed1c212e02() 93     { RSModifierType::SHADOW_RADIUS, [](RSProperties* prop) { prop->SetShadowRadius(0.f); } },
__anon72ed1c212f02() 94     { RSModifierType::SHADOW_PATH, [](RSProperties* prop) { prop->SetShadowPath(nullptr); } },
__anon72ed1c213002() 95     { RSModifierType::SHADOW_MASK, [](RSProperties* prop) { prop->SetShadowMask(false); } },
__anon72ed1c213102() 96     { RSModifierType::MASK, [](RSProperties* prop) { prop->SetMask(nullptr); } },
__anon72ed1c213202() 97     { RSModifierType::SPHERIZE, [](RSProperties* prop) { prop->SetSpherize(0.f); } },
__anon72ed1c213302() 98     { RSModifierType::LIGHT_UP_EFFECT, [](RSProperties* prop) { prop->SetLightUpEffect(1.f); } },
__anon72ed1c213402() 99     { RSModifierType::PIXEL_STRETCH, [](RSProperties* prop) { prop->SetPixelStretch(std::nullopt); } },
__anon72ed1c213502() 100     { RSModifierType::PIXEL_STRETCH_PERCENT, [](RSProperties* prop) { prop->SetPixelStretchPercent(std::nullopt); } },
__anon72ed1c213602() 101     { RSModifierType::GRAY_SCALE, [](RSProperties* prop) { prop->SetGrayScale(std::nullopt); } },
__anon72ed1c213702() 102     { RSModifierType::BRIGHTNESS, [](RSProperties* prop) { prop->SetBrightness(std::nullopt); } },
__anon72ed1c213802() 103     { RSModifierType::CONTRAST, [](RSProperties* prop) { prop->SetContrast(std::nullopt); } },
__anon72ed1c213902() 104     { RSModifierType::SATURATE, [](RSProperties* prop) { prop->SetSaturate(std::nullopt); } },
__anon72ed1c213a02() 105     { RSModifierType::SEPIA, [](RSProperties* prop) { prop->SetSepia(std::nullopt); } },
__anon72ed1c213b02() 106     { RSModifierType::INVERT, [](RSProperties* prop) { prop->SetInvert(std::nullopt); } },
__anon72ed1c213c02() 107     { RSModifierType::HUE_ROTATE, [](RSProperties* prop) { prop->SetHueRotate(std::nullopt); } },
__anon72ed1c213d02() 108     { RSModifierType::COLOR_BLEND, [](RSProperties* prop) { prop->SetColorBlend(std::nullopt); } },
__anon72ed1c213e02() 109     { RSModifierType::USE_EFFECT, [](RSProperties* prop) { prop->SetUseEffect(false); } },
110 };
111 } // namespace
112 
113 // Only enable filter cache when uni-render is enabled and filter cache is enabled
114 const bool RSProperties::FilterCacheEnabled =
115     RSSystemProperties::GetFilterCacheEnabled() && RSUniRenderJudgement::IsUniRender();
RSProperties()116 RSProperties::RSProperties()
117 {
118     boundsGeo_ = std::make_shared<RSObjAbsGeometry>();
119     frameGeo_ = std::make_shared<RSObjGeometry>();
120 }
121 
122 RSProperties::~RSProperties() = default;
123 
ResetProperty(const std::unordered_set<RSModifierType> & dirtyTypes)124 void RSProperties::ResetProperty(const std::unordered_set<RSModifierType>& dirtyTypes)
125 {
126     for (const auto& type : dirtyTypes) {
127         auto it = g_funcLUT.find(type);
128         if (it != g_funcLUT.end()) {
129             it->second(this);
130         }
131     }
132 }
133 
SetBounds(Vector4f bounds)134 void RSProperties::SetBounds(Vector4f bounds)
135 {
136     if (bounds.z_ != boundsGeo_->GetWidth() || bounds.w_ != boundsGeo_->GetHeight()) {
137         contentDirty_ = true;
138     }
139     boundsGeo_->SetRect(bounds.x_, bounds.y_, bounds.z_, bounds.w_);
140     hasBounds_ = true;
141     geoDirty_ = true;
142     SetDirty();
143 }
144 
SetBoundsSize(Vector2f size)145 void RSProperties::SetBoundsSize(Vector2f size)
146 {
147     boundsGeo_->SetSize(size.x_, size.y_);
148     hasBounds_ = true;
149     geoDirty_ = true;
150     contentDirty_ = true;
151     SetDirty();
152 }
153 
SetBoundsWidth(float width)154 void RSProperties::SetBoundsWidth(float width)
155 {
156     boundsGeo_->SetWidth(width);
157     hasBounds_ = true;
158     geoDirty_ = true;
159     contentDirty_ = true;
160     SetDirty();
161 }
162 
SetBoundsHeight(float height)163 void RSProperties::SetBoundsHeight(float height)
164 {
165     boundsGeo_->SetHeight(height);
166     hasBounds_ = true;
167     geoDirty_ = true;
168     contentDirty_ = true;
169     SetDirty();
170 }
171 
SetBoundsPosition(Vector2f position)172 void RSProperties::SetBoundsPosition(Vector2f position)
173 {
174     boundsGeo_->SetPosition(position.x_, position.y_);
175     geoDirty_ = true;
176     SetDirty();
177 }
178 
SetBoundsPositionX(float positionX)179 void RSProperties::SetBoundsPositionX(float positionX)
180 {
181     boundsGeo_->SetX(positionX);
182     geoDirty_ = true;
183     SetDirty();
184 }
185 
SetBoundsPositionY(float positionY)186 void RSProperties::SetBoundsPositionY(float positionY)
187 {
188     boundsGeo_->SetY(positionY);
189     geoDirty_ = true;
190     SetDirty();
191 }
192 
GetBounds() const193 Vector4f RSProperties::GetBounds() const
194 {
195     return { boundsGeo_->GetX(), boundsGeo_->GetY(), boundsGeo_->GetWidth(), boundsGeo_->GetHeight() };
196 }
197 
GetBoundsSize() const198 Vector2f RSProperties::GetBoundsSize() const
199 {
200     return { boundsGeo_->GetWidth(), boundsGeo_->GetHeight() };
201 }
202 
GetBoundsWidth() const203 float RSProperties::GetBoundsWidth() const
204 {
205     return boundsGeo_->GetWidth();
206 }
207 
GetBoundsHeight() const208 float RSProperties::GetBoundsHeight() const
209 {
210     return boundsGeo_->GetHeight();
211 }
212 
GetBoundsPositionX() const213 float RSProperties::GetBoundsPositionX() const
214 {
215     return boundsGeo_->GetX();
216 }
217 
GetBoundsPositionY() const218 float RSProperties::GetBoundsPositionY() const
219 {
220     return boundsGeo_->GetY();
221 }
222 
GetBoundsPosition() const223 Vector2f RSProperties::GetBoundsPosition() const
224 {
225     return { GetBoundsPositionX(), GetBoundsPositionY() };
226 }
227 
SetFrame(Vector4f frame)228 void RSProperties::SetFrame(Vector4f frame)
229 {
230     if (frame.z_ != frameGeo_->GetWidth() || frame.w_ != frameGeo_->GetHeight()) {
231         contentDirty_ = true;
232     }
233     frameGeo_->SetRect(frame.x_, frame.y_, frame.z_, frame.w_);
234     geoDirty_ = true;
235     SetDirty();
236 }
237 
SetFrameSize(Vector2f size)238 void RSProperties::SetFrameSize(Vector2f size)
239 {
240     frameGeo_->SetSize(size.x_, size.y_);
241     geoDirty_ = true;
242     contentDirty_ = true;
243     SetDirty();
244 }
245 
SetFrameWidth(float width)246 void RSProperties::SetFrameWidth(float width)
247 {
248     frameGeo_->SetWidth(width);
249     geoDirty_ = true;
250     contentDirty_ = true;
251     SetDirty();
252 }
253 
SetFrameHeight(float height)254 void RSProperties::SetFrameHeight(float height)
255 {
256     frameGeo_->SetHeight(height);
257     geoDirty_ = true;
258     contentDirty_ = true;
259     SetDirty();
260 }
261 
SetFramePosition(Vector2f position)262 void RSProperties::SetFramePosition(Vector2f position)
263 {
264     frameGeo_->SetPosition(position.x_, position.y_);
265     geoDirty_ = true;
266     SetDirty();
267 }
268 
SetFramePositionX(float positionX)269 void RSProperties::SetFramePositionX(float positionX)
270 {
271     frameGeo_->SetX(positionX);
272     geoDirty_ = true;
273     SetDirty();
274 }
275 
SetFramePositionY(float positionY)276 void RSProperties::SetFramePositionY(float positionY)
277 {
278     frameGeo_->SetY(positionY);
279     geoDirty_ = true;
280     SetDirty();
281 }
282 
GetFrame() const283 Vector4f RSProperties::GetFrame() const
284 {
285     return { frameGeo_->GetX(), frameGeo_->GetY(), frameGeo_->GetWidth(), frameGeo_->GetHeight() };
286 }
287 
GetFrameSize() const288 Vector2f RSProperties::GetFrameSize() const
289 {
290     return { frameGeo_->GetWidth(), frameGeo_->GetHeight() };
291 }
292 
GetFrameWidth() const293 float RSProperties::GetFrameWidth() const
294 {
295     return frameGeo_->GetWidth();
296 }
297 
GetFrameHeight() const298 float RSProperties::GetFrameHeight() const
299 {
300     return frameGeo_->GetHeight();
301 }
302 
GetFramePositionX() const303 float RSProperties::GetFramePositionX() const
304 {
305     return frameGeo_->GetX();
306 }
307 
GetFramePositionY() const308 float RSProperties::GetFramePositionY() const
309 {
310     return frameGeo_->GetY();
311 }
312 
GetFramePosition() const313 Vector2f RSProperties::GetFramePosition() const
314 {
315     return { GetFramePositionX(), GetFramePositionY() };
316 }
317 
GetFrameOffsetX() const318 float RSProperties::GetFrameOffsetX() const
319 {
320     return frameOffsetX_;
321 }
322 
GetFrameOffsetY() const323 float RSProperties::GetFrameOffsetY() const
324 {
325     return frameOffsetY_;
326 }
327 
GetBoundsGeometry() const328 const std::shared_ptr<RSObjAbsGeometry>& RSProperties::GetBoundsGeometry() const
329 {
330     return boundsGeo_;
331 }
332 
GetFrameGeometry() const333 const std::shared_ptr<RSObjGeometry>& RSProperties::GetFrameGeometry() const
334 {
335     return frameGeo_;
336 }
337 
338 #ifndef USE_ROSEN_DRAWING
UpdateGeometry(const RSProperties * parent,bool dirtyFlag,const std::optional<SkPoint> & offset,const std::optional<SkRect> & clipRect)339 bool RSProperties::UpdateGeometry(const RSProperties* parent, bool dirtyFlag, const std::optional<SkPoint>& offset,
340     const std::optional<SkRect>& clipRect)
341 #else
342 bool RSProperties::UpdateGeometry(const RSProperties* parent, bool dirtyFlag,
343     const std::optional<Drawing::Point>& offset, const std::optional<Drawing::Rect>& clipRect)
344 #endif
345 {
346     if (boundsGeo_ == nullptr) {
347         return false;
348     }
349     auto boundsGeoPtr = (boundsGeo_);
350 
351     if (!dirtyFlag && !geoDirty_) {
352         return false;
353     }
354     auto parentGeo = parent == nullptr ? nullptr : (parent->boundsGeo_);
355     if (parentGeo && sandbox_ && sandbox_->matrix_) {
356         parentGeo = std::make_shared<RSObjAbsGeometry>();
357         parentGeo->ConcatMatrix(*(sandbox_->matrix_));
358     }
359     CheckEmptyBounds();
360     boundsGeoPtr->UpdateMatrix(parentGeo, offset, clipRect);
361     if (RSSystemProperties::GetSkipGeometryNotChangeEnabled()) {
362         auto rect = boundsGeoPtr->GetAbsRect();
363         if (!lastRect_.has_value()) {
364             lastRect_ = rect;
365             return true;
366         }
367         dirtyFlag = dirtyFlag || rect != lastRect_.value();
368         lastRect_ = rect;
369         return dirtyFlag;
370     } else {
371         return true;
372     }
373 }
374 
SetSandBox(const std::optional<Vector2f> & parentPosition)375 void RSProperties::SetSandBox(const std::optional<Vector2f>& parentPosition)
376 {
377     if (!sandbox_) {
378         sandbox_ = std::make_unique<Sandbox>();
379     }
380     sandbox_->position_ = parentPosition;
381     geoDirty_ = true;
382     SetDirty();
383 }
384 
GetSandBox() const385 std::optional<Vector2f> RSProperties::GetSandBox() const
386 {
387     return sandbox_ ? sandbox_->position_ : std::nullopt;
388 }
389 
ResetSandBox()390 void RSProperties::ResetSandBox()
391 {
392     sandbox_ = nullptr;
393 }
394 
395 #ifndef USE_ROSEN_DRAWING
UpdateSandBoxMatrix(const std::optional<SkMatrix> & rootMatrix)396 void RSProperties::UpdateSandBoxMatrix(const std::optional<SkMatrix>& rootMatrix)
397 #else
398 void RSProperties::UpdateSandBoxMatrix(const std::optional<Drawing::Matrix>& rootMatrix)
399 #endif
400 {
401     if (!sandbox_ || !rootMatrix || !sandbox_->position_) {
402         return;
403     }
404 #ifndef USE_ROSEN_DRAWING
405     auto matrix = rootMatrix.value();
406     sandbox_->matrix_ = matrix.preTranslate(sandbox_->position_->x_, sandbox_->position_->y_);
407 #else
408     auto matrix = Drawing::Matrix();
409     for (int i = 0; i < Drawing::Matrix::MATRIX_SIZE; i++) {
410         matrix.Set(static_cast<Drawing::Matrix::Index>(i), rootMatrix.value().Get(i));
411     }
412     matrix.PreTranslate(sandbox_->position_->x_, sandbox_->position_->y_);
413     sandbox_->matrix_ = matrix;
414 #endif
415 }
416 
417 #ifndef USE_ROSEN_DRAWING
GetSandBoxMatrix() const418 std::optional<SkMatrix> RSProperties::GetSandBoxMatrix() const
419 #else
420 std::optional<Drawing::Matrix> RSProperties::GetSandBoxMatrix() const
421 #endif
422 {
423     return sandbox_ ? sandbox_->matrix_ : std::nullopt;
424 }
425 
SetPositionZ(float positionZ)426 void RSProperties::SetPositionZ(float positionZ)
427 {
428     boundsGeo_->SetZ(positionZ);
429     frameGeo_->SetZ(positionZ);
430     geoDirty_ = true;
431     SetDirty();
432 }
433 
GetPositionZ() const434 float RSProperties::GetPositionZ() const
435 {
436     return boundsGeo_->GetZ();
437 }
438 
SetPivot(Vector2f pivot)439 void RSProperties::SetPivot(Vector2f pivot)
440 {
441     boundsGeo_->SetPivot(pivot.x_, pivot.y_);
442     geoDirty_ = true;
443     SetDirty();
444 }
445 
SetPivotX(float pivotX)446 void RSProperties::SetPivotX(float pivotX)
447 {
448     boundsGeo_->SetPivotX(pivotX);
449     geoDirty_ = true;
450     SetDirty();
451 }
452 
SetPivotY(float pivotY)453 void RSProperties::SetPivotY(float pivotY)
454 {
455     boundsGeo_->SetPivotY(pivotY);
456     geoDirty_ = true;
457     SetDirty();
458 }
459 
SetPivotZ(float pivotZ)460 void RSProperties::SetPivotZ(float pivotZ)
461 {
462     boundsGeo_->SetPivotZ(pivotZ);
463     geoDirty_ = true;
464     SetDirty();
465 }
466 
GetPivot() const467 Vector2f RSProperties::GetPivot() const
468 {
469     return { boundsGeo_->GetPivotX(), boundsGeo_->GetPivotY() };
470 }
471 
GetPivotX() const472 float RSProperties::GetPivotX() const
473 {
474     return boundsGeo_->GetPivotX();
475 }
476 
GetPivotY() const477 float RSProperties::GetPivotY() const
478 {
479     return boundsGeo_->GetPivotY();
480 }
481 
GetPivotZ() const482 float RSProperties::GetPivotZ() const
483 {
484     return boundsGeo_->GetPivotZ();
485 }
486 
SetCornerRadius(Vector4f cornerRadius)487 void RSProperties::SetCornerRadius(Vector4f cornerRadius)
488 {
489     cornerRadius_ = cornerRadius;
490     SetDirty();
491 }
492 
GetCornerRadius() const493 Vector4f RSProperties::GetCornerRadius() const
494 {
495     return cornerRadius_.value_or(Vector4fZero);
496 }
497 
SetQuaternion(Quaternion quaternion)498 void RSProperties::SetQuaternion(Quaternion quaternion)
499 {
500     boundsGeo_->SetQuaternion(quaternion);
501     geoDirty_ = true;
502     SetDirty();
503 }
504 
SetRotation(float degree)505 void RSProperties::SetRotation(float degree)
506 {
507     boundsGeo_->SetRotation(degree);
508     geoDirty_ = true;
509     SetDirty();
510 }
511 
SetRotationX(float degree)512 void RSProperties::SetRotationX(float degree)
513 {
514     boundsGeo_->SetRotationX(degree);
515     geoDirty_ = true;
516     SetDirty();
517 }
518 
SetRotationY(float degree)519 void RSProperties::SetRotationY(float degree)
520 {
521     boundsGeo_->SetRotationY(degree);
522     geoDirty_ = true;
523     SetDirty();
524 }
525 
SetCameraDistance(float cameraDistance)526 void RSProperties::SetCameraDistance(float cameraDistance)
527 {
528     boundsGeo_->SetCameraDistance(cameraDistance);
529     geoDirty_ = true;
530     SetDirty();
531 }
532 
SetScale(Vector2f scale)533 void RSProperties::SetScale(Vector2f scale)
534 {
535     boundsGeo_->SetScale(scale.x_, scale.y_);
536     geoDirty_ = true;
537     SetDirty();
538 }
539 
SetScaleX(float sx)540 void RSProperties::SetScaleX(float sx)
541 {
542     boundsGeo_->SetScaleX(sx);
543     geoDirty_ = true;
544     SetDirty();
545 }
546 
SetScaleY(float sy)547 void RSProperties::SetScaleY(float sy)
548 {
549     boundsGeo_->SetScaleY(sy);
550     geoDirty_ = true;
551     SetDirty();
552 }
553 
SetTranslate(Vector2f translate)554 void RSProperties::SetTranslate(Vector2f translate)
555 {
556     boundsGeo_->SetTranslateX(translate[0]);
557     boundsGeo_->SetTranslateY(translate[1]);
558     geoDirty_ = true;
559     SetDirty();
560 }
561 
SetTranslateX(float translate)562 void RSProperties::SetTranslateX(float translate)
563 {
564     boundsGeo_->SetTranslateX(translate);
565     geoDirty_ = true;
566     SetDirty();
567 }
568 
SetTranslateY(float translate)569 void RSProperties::SetTranslateY(float translate)
570 {
571     boundsGeo_->SetTranslateY(translate);
572     geoDirty_ = true;
573     SetDirty();
574 }
575 
SetTranslateZ(float translate)576 void RSProperties::SetTranslateZ(float translate)
577 {
578     boundsGeo_->SetTranslateZ(translate);
579     geoDirty_ = true;
580     SetDirty();
581 }
582 
GetQuaternion() const583 Quaternion RSProperties::GetQuaternion() const
584 {
585     return boundsGeo_->GetQuaternion();
586 }
587 
GetRotation() const588 float RSProperties::GetRotation() const
589 {
590     return boundsGeo_->GetRotation();
591 }
592 
GetRotationX() const593 float RSProperties::GetRotationX() const
594 {
595     return boundsGeo_->GetRotationX();
596 }
597 
GetRotationY() const598 float RSProperties::GetRotationY() const
599 {
600     return boundsGeo_->GetRotationY();
601 }
602 
GetCameraDistance() const603 float RSProperties::GetCameraDistance() const
604 {
605     return boundsGeo_->GetCameraDistance();
606 }
607 
GetScaleX() const608 float RSProperties::GetScaleX() const
609 {
610     return boundsGeo_->GetScaleX();
611 }
612 
GetScaleY() const613 float RSProperties::GetScaleY() const
614 {
615     return boundsGeo_->GetScaleY();
616 }
617 
GetScale() const618 Vector2f RSProperties::GetScale() const
619 {
620     return { boundsGeo_->GetScaleX(), boundsGeo_->GetScaleY() };
621 }
622 
GetTranslate() const623 Vector2f RSProperties::GetTranslate() const
624 {
625     return Vector2f(GetTranslateX(), GetTranslateY());
626 }
627 
GetTranslateX() const628 float RSProperties::GetTranslateX() const
629 {
630     return boundsGeo_->GetTranslateX();
631 }
632 
GetTranslateY() const633 float RSProperties::GetTranslateY() const
634 {
635     return boundsGeo_->GetTranslateY();
636 }
637 
GetTranslateZ() const638 float RSProperties::GetTranslateZ() const
639 {
640     return boundsGeo_->GetTranslateZ();
641 }
642 
SetParticles(const RSRenderParticleVector & particles)643 void RSProperties::SetParticles(const RSRenderParticleVector& particles)
644 {
645     particles_ = particles;
646     if (particles_.GetParticleSize() > 0) {
647         isDrawn_ = true;
648     }
649     SetDirty();
650     contentDirty_ = true;
651 }
652 
GetParticles() const653 RSRenderParticleVector RSProperties::GetParticles() const
654 {
655     return particles_;
656 }
657 
SetAlpha(float alpha)658 void RSProperties::SetAlpha(float alpha)
659 {
660     alpha_ = alpha;
661     if (alpha_ < 1.) {
662         isDrawn_ = true;
663     }
664     SetDirty();
665     contentDirty_ = true;
666 }
667 
GetAlpha() const668 float RSProperties::GetAlpha() const
669 {
670     return alpha_;
671 }
SetAlphaOffscreen(bool alphaOffscreen)672 void RSProperties::SetAlphaOffscreen(bool alphaOffscreen)
673 {
674     alphaOffscreen_ = alphaOffscreen;
675     if (alpha_ < 1.) {
676         isDrawn_ = true;
677     }
678     SetDirty();
679     contentDirty_ = true;
680 }
681 
GetAlphaOffscreen() const682 bool RSProperties::GetAlphaOffscreen() const
683 {
684     return alphaOffscreen_;
685 }
686 
SetSublayerTransform(const std::optional<Matrix3f> & sublayerTransform)687 void RSProperties::SetSublayerTransform(const std::optional<Matrix3f>& sublayerTransform)
688 {
689     sublayerTransform_ = sublayerTransform;
690     SetDirty();
691 }
692 
GetSublayerTransform() const693 const std::optional<Matrix3f>& RSProperties::GetSublayerTransform() const
694 {
695     return sublayerTransform_;
696 }
697 
698 // foreground properties
SetForegroundColor(Color color)699 void RSProperties::SetForegroundColor(Color color)
700 {
701     if (!decoration_) {
702         decoration_ = std::make_optional<Decoration>();
703     }
704     decoration_->foregroundColor_ = color;
705     SetDirty();
706     contentDirty_ = true;
707 }
708 
GetForegroundColor() const709 Color RSProperties::GetForegroundColor() const
710 {
711     return decoration_ ? decoration_->foregroundColor_ : RgbPalette::Transparent();
712 }
713 
714 // background properties
SetBackgroundColor(Color color)715 void RSProperties::SetBackgroundColor(Color color)
716 {
717     if (!decoration_) {
718         decoration_ = std::make_optional<Decoration>();
719     }
720     if (color.GetAlpha() > 0) {
721         isDrawn_ = true;
722     }
723     decoration_->backgroundColor_ = color;
724     SetDirty();
725     contentDirty_ = true;
726 }
727 
GetBackgroundColor() const728 Color RSProperties::GetBackgroundColor() const
729 {
730     return decoration_ ? decoration_->backgroundColor_ : RgbPalette::Transparent();
731 }
732 
SetBackgroundShader(std::shared_ptr<RSShader> shader)733 void RSProperties::SetBackgroundShader(std::shared_ptr<RSShader> shader)
734 {
735     if (!decoration_) {
736         decoration_ = std::make_optional<Decoration>();
737     }
738     if (shader) {
739         isDrawn_ = true;
740     }
741     decoration_->bgShader_ = shader;
742     SetDirty();
743     contentDirty_ = true;
744 }
745 
GetBackgroundShader() const746 std::shared_ptr<RSShader> RSProperties::GetBackgroundShader() const
747 {
748     return decoration_ ? decoration_->bgShader_ : nullptr;
749 }
750 
SetBgImage(std::shared_ptr<RSImage> image)751 void RSProperties::SetBgImage(std::shared_ptr<RSImage> image)
752 {
753     if (!decoration_) {
754         decoration_ = std::make_optional<Decoration>();
755     }
756     if (image) {
757         isDrawn_ = true;
758     }
759     decoration_->bgImage_ = image;
760     SetDirty();
761     contentDirty_ = true;
762 }
763 
GetBgImage() const764 std::shared_ptr<RSImage> RSProperties::GetBgImage() const
765 {
766     return decoration_ ? decoration_->bgImage_ : nullptr;
767 }
768 
SetBgImageWidth(float width)769 void RSProperties::SetBgImageWidth(float width)
770 {
771     if (!decoration_) {
772         decoration_ = std::make_optional<Decoration>();
773     }
774     decoration_->bgImageRect_.width_ = width;
775     SetDirty();
776     contentDirty_ = true;
777 }
778 
SetBgImageHeight(float height)779 void RSProperties::SetBgImageHeight(float height)
780 {
781     if (!decoration_) {
782         decoration_ = std::make_optional<Decoration>();
783     }
784     decoration_->bgImageRect_.height_ = height;
785     SetDirty();
786     contentDirty_ = true;
787 }
788 
SetBgImagePositionX(float positionX)789 void RSProperties::SetBgImagePositionX(float positionX)
790 {
791     if (!decoration_) {
792         decoration_ = std::make_optional<Decoration>();
793     }
794     decoration_->bgImageRect_.left_ = positionX;
795     SetDirty();
796     contentDirty_ = true;
797 }
798 
SetBgImagePositionY(float positionY)799 void RSProperties::SetBgImagePositionY(float positionY)
800 {
801     if (!decoration_) {
802         decoration_ = std::make_optional<Decoration>();
803     }
804     decoration_->bgImageRect_.top_ = positionY;
805     SetDirty();
806     contentDirty_ = true;
807 }
808 
GetBgImageWidth() const809 float RSProperties::GetBgImageWidth() const
810 {
811     return decoration_ ? decoration_->bgImageRect_.width_ : 0.f;
812 }
813 
GetBgImageHeight() const814 float RSProperties::GetBgImageHeight() const
815 {
816     return decoration_ ? decoration_->bgImageRect_.height_ : 0.f;
817 }
818 
GetBgImagePositionX() const819 float RSProperties::GetBgImagePositionX() const
820 {
821     return decoration_ ? decoration_->bgImageRect_.left_ : 0.f;
822 }
823 
GetBgImagePositionY() const824 float RSProperties::GetBgImagePositionY() const
825 {
826     return decoration_ ? decoration_->bgImageRect_.top_ : 0.f;
827 }
828 
829 // border properties
SetBorderColor(Vector4<Color> color)830 void RSProperties::SetBorderColor(Vector4<Color> color)
831 {
832     if (!border_) {
833         border_ = std::make_shared<RSBorder>();
834     }
835     border_->SetColorFour(color);
836     if (border_->GetColor().GetAlpha() > 0) {
837         isDrawn_ = true;
838     }
839     SetDirty();
840     contentDirty_ = true;
841 }
842 
SetBorderWidth(Vector4f width)843 void RSProperties::SetBorderWidth(Vector4f width)
844 {
845     if (!border_) {
846         border_ = std::make_shared<RSBorder>();
847     }
848     border_->SetWidthFour(width);
849     isDrawn_ = true;
850     SetDirty();
851     contentDirty_ = true;
852 }
853 
SetBorderStyle(Vector4<uint32_t> style)854 void RSProperties::SetBorderStyle(Vector4<uint32_t> style)
855 {
856     if (!border_) {
857         border_ = std::make_shared<RSBorder>();
858     }
859     border_->SetStyleFour(style);
860     isDrawn_ = true;
861     SetDirty();
862     contentDirty_ = true;
863 }
864 
GetBorderColor() const865 Vector4<Color> RSProperties::GetBorderColor() const
866 {
867     return border_ ? border_->GetColorFour() : Vector4<Color>(RgbPalette::Transparent());
868 }
869 
GetBorderWidth() const870 Vector4f RSProperties::GetBorderWidth() const
871 {
872     return border_ ? border_->GetWidthFour() : Vector4f(0.f);
873 }
874 
GetBorderStyle() const875 Vector4<uint32_t> RSProperties::GetBorderStyle() const
876 {
877     return border_ ? border_->GetStyleFour() : Vector4<uint32_t>(static_cast<uint32_t>(BorderStyle::NONE));
878 }
879 
GetBorder() const880 const std::shared_ptr<RSBorder>& RSProperties::GetBorder() const
881 {
882     return border_;
883 }
884 
SetBackgroundFilter(std::shared_ptr<RSFilter> backgroundFilter)885 void RSProperties::SetBackgroundFilter(std::shared_ptr<RSFilter> backgroundFilter)
886 {
887     backgroundFilter_ = backgroundFilter;
888     if (backgroundFilter_) {
889         isDrawn_ = true;
890     }
891     SetDirty();
892     filterManagerNeedUpdate_ = true;
893     contentDirty_ = true;
894 }
895 
SetLinearGradientBlurPara(std::shared_ptr<RSLinearGradientBlurPara> para)896 void RSProperties::SetLinearGradientBlurPara(std::shared_ptr<RSLinearGradientBlurPara> para)
897 {
898     linearGradientBlurPara_ = para;
899     if (para && para->blurRadius_ > 0.) {
900         isDrawn_ = true;
901     }
902     SetDirty();
903     contentDirty_ = true;
904 }
905 
SetDynamicLightUpRate(const std::optional<float> & rate)906 void RSProperties::SetDynamicLightUpRate(const std::optional<float>& rate)
907 {
908     dynamicLightUpRate_ = rate;
909     if (rate.has_value()) {
910         isDrawn_ = true;
911     }
912     SetDirty();
913     contentDirty_ = true;
914 }
915 
SetDynamicLightUpDegree(const std::optional<float> & lightUpDegree)916 void RSProperties::SetDynamicLightUpDegree(const std::optional<float>& lightUpDegree)
917 {
918     dynamicLightUpDegree_ = lightUpDegree;
919     if (lightUpDegree.has_value()) {
920         isDrawn_ = true;
921     }
922     SetDirty();
923     contentDirty_ = true;
924 }
925 
SetFilter(std::shared_ptr<RSFilter> filter)926 void RSProperties::SetFilter(std::shared_ptr<RSFilter> filter)
927 {
928     filter_ = filter;
929     if (filter) {
930         isDrawn_ = true;
931     }
932     SetDirty();
933     filterManagerNeedUpdate_ = true;
934     contentDirty_ = true;
935 }
936 
GetBackgroundFilter() const937 const std::shared_ptr<RSFilter>& RSProperties::GetBackgroundFilter() const
938 {
939     return backgroundFilter_;
940 }
941 
GetLinearGradientBlurPara() const942 const std::shared_ptr<RSLinearGradientBlurPara>& RSProperties::GetLinearGradientBlurPara() const
943 {
944     return linearGradientBlurPara_;
945 }
946 
GetDynamicLightUpRate() const947 const std::optional<float>& RSProperties::GetDynamicLightUpRate() const
948 {
949     return dynamicLightUpRate_;
950 }
951 
GetDynamicLightUpDegree() const952 const std::optional<float>& RSProperties::GetDynamicLightUpDegree() const
953 {
954     return dynamicLightUpDegree_;
955 }
956 
GetFilter() const957 const std::shared_ptr<RSFilter>& RSProperties::GetFilter() const
958 {
959     return filter_;
960 }
961 
IsDynamicLightUpValid() const962 bool RSProperties::IsDynamicLightUpValid() const
963 {
964     return dynamicLightUpRate_.has_value() && dynamicLightUpDegree_.has_value() &&
965            ROSEN_GNE(*dynamicLightUpRate_, 0.0) && ROSEN_GE(*dynamicLightUpDegree_, 0.0) &&
966            ROSEN_LE(*dynamicLightUpDegree_, 1.0);
967 }
968 
969 // shadow properties
SetShadowColor(Color color)970 void RSProperties::SetShadowColor(Color color)
971 {
972     if (!shadow_.has_value()) {
973         shadow_ = std::make_optional<RSShadow>();
974     }
975     shadow_->SetColor(color);
976     SetDirty();
977     // [planning] if shadow stores as texture and out of node
978     // node content would not be affected
979     contentDirty_ = true;
980 }
981 
SetShadowOffsetX(float offsetX)982 void RSProperties::SetShadowOffsetX(float offsetX)
983 {
984     if (!shadow_.has_value()) {
985         shadow_ = std::make_optional<RSShadow>();
986     }
987     shadow_->SetOffsetX(offsetX);
988     SetDirty();
989     // [planning] if shadow stores as texture and out of node
990     // node content would not be affected
991     contentDirty_ = true;
992 }
993 
SetShadowOffsetY(float offsetY)994 void RSProperties::SetShadowOffsetY(float offsetY)
995 {
996     if (!shadow_.has_value()) {
997         shadow_ = std::make_optional<RSShadow>();
998     }
999     shadow_->SetOffsetY(offsetY);
1000     SetDirty();
1001     // [planning] if shadow stores as texture and out of node
1002     // node content would not be affected
1003     contentDirty_ = true;
1004 }
1005 
SetShadowAlpha(float alpha)1006 void RSProperties::SetShadowAlpha(float alpha)
1007 {
1008     if (!shadow_.has_value()) {
1009         shadow_ = std::make_optional<RSShadow>();
1010     }
1011     shadow_->SetAlpha(alpha);
1012     if (shadow_->IsValid()) {
1013         isDrawn_ = true;
1014     }
1015     SetDirty();
1016     // [planning] if shadow stores as texture and out of node
1017     // node content would not be affected
1018     contentDirty_ = true;
1019 }
1020 
SetShadowElevation(float elevation)1021 void RSProperties::SetShadowElevation(float elevation)
1022 {
1023     if (!shadow_.has_value()) {
1024         shadow_ = std::make_optional<RSShadow>();
1025     }
1026     shadow_->SetElevation(elevation);
1027     if (shadow_->IsValid()) {
1028         isDrawn_ = true;
1029     }
1030     SetDirty();
1031     // [planning] if shadow stores as texture and out of node
1032     // node content would not be affected
1033     contentDirty_ = true;
1034 }
1035 
SetShadowRadius(float radius)1036 void RSProperties::SetShadowRadius(float radius)
1037 {
1038     if (!shadow_.has_value()) {
1039         shadow_ = std::make_optional<RSShadow>();
1040     }
1041     shadow_->SetRadius(radius);
1042     if (shadow_->IsValid()) {
1043         isDrawn_ = true;
1044     }
1045     SetDirty();
1046     // [planning] if shadow stores as texture and out of node
1047     // node content would not be affected
1048     contentDirty_ = true;
1049 }
1050 
SetShadowPath(std::shared_ptr<RSPath> shadowPath)1051 void RSProperties::SetShadowPath(std::shared_ptr<RSPath> shadowPath)
1052 {
1053     if (!shadow_.has_value()) {
1054         shadow_ = std::make_optional<RSShadow>();
1055     }
1056     shadow_->SetPath(shadowPath);
1057     SetDirty();
1058     // [planning] if shadow stores as texture and out of node
1059     // node content would not be affected
1060     contentDirty_ = true;
1061 }
1062 
SetShadowMask(bool shadowMask)1063 void RSProperties::SetShadowMask(bool shadowMask)
1064 {
1065     if (!shadow_.has_value()) {
1066         shadow_ = std::make_optional<RSShadow>();
1067     }
1068     shadow_->SetMask(shadowMask);
1069     SetDirty();
1070     // [planning] if shadow stores as texture and out of node
1071     // node content would not be affected
1072     contentDirty_ = true;
1073 }
1074 
GetShadowColor() const1075 Color RSProperties::GetShadowColor() const
1076 {
1077     return shadow_ ? shadow_->GetColor() : Color::FromArgbInt(DEFAULT_SPOT_COLOR);
1078 }
1079 
GetShadowOffsetX() const1080 float RSProperties::GetShadowOffsetX() const
1081 {
1082     return shadow_ ? shadow_->GetOffsetX() : DEFAULT_SHADOW_OFFSET_X;
1083 }
1084 
GetShadowOffsetY() const1085 float RSProperties::GetShadowOffsetY() const
1086 {
1087     return shadow_ ? shadow_->GetOffsetY() : DEFAULT_SHADOW_OFFSET_Y;
1088 }
1089 
GetShadowAlpha() const1090 float RSProperties::GetShadowAlpha() const
1091 {
1092     return shadow_ ? shadow_->GetAlpha() : 0.f;
1093 }
1094 
GetShadowElevation() const1095 float RSProperties::GetShadowElevation() const
1096 {
1097     return shadow_ ? shadow_->GetElevation() : 0.f;
1098 }
1099 
GetShadowRadius() const1100 float RSProperties::GetShadowRadius() const
1101 {
1102     return shadow_ ? shadow_->GetRadius() : DEFAULT_SHADOW_RADIUS;
1103 }
1104 
GetShadowPath() const1105 std::shared_ptr<RSPath> RSProperties::GetShadowPath() const
1106 {
1107     return shadow_ ? shadow_->GetPath() : nullptr;
1108 }
1109 
GetShadowMask() const1110 bool RSProperties::GetShadowMask() const
1111 {
1112     return shadow_ ? shadow_->GetMask() : false;
1113 }
1114 
IsShadowValid() const1115 bool RSProperties::IsShadowValid() const
1116 {
1117     return shadow_ && shadow_->IsValid();
1118 }
1119 
SetFrameGravity(Gravity gravity)1120 void RSProperties::SetFrameGravity(Gravity gravity)
1121 {
1122     if (frameGravity_ != gravity) {
1123         frameGravity_ = gravity;
1124         SetDirty();
1125         contentDirty_ = true;
1126     }
1127 }
1128 
GetFrameGravity() const1129 Gravity RSProperties::GetFrameGravity() const
1130 {
1131     return frameGravity_;
1132 }
1133 
SetDrawRegion(std::shared_ptr<RectF> rect)1134 void RSProperties::SetDrawRegion(std::shared_ptr<RectF> rect)
1135 {
1136     drawRegion_ = rect;
1137     SetDirty();
1138     geoDirty_ = true;  // since drawRegion affect dirtyRegion, mark it as geoDirty
1139 }
1140 
GetDrawRegion() const1141 std::shared_ptr<RectF> RSProperties::GetDrawRegion() const
1142 {
1143     return drawRegion_;
1144 }
1145 
SetClipRRect(RRect clipRRect)1146 void RSProperties::SetClipRRect(RRect clipRRect)
1147 {
1148     clipRRect_ = clipRRect;
1149     if (GetClipToRRect()) {
1150         isDrawn_ = true;
1151     }
1152     SetDirty();
1153     geoDirty_ = true;  // [planning] all clip ops should be checked
1154 }
1155 
GetClipRRect() const1156 RRect RSProperties::GetClipRRect() const
1157 {
1158     return clipRRect_ ? *clipRRect_ : RRect();
1159 }
1160 
GetClipToRRect() const1161 bool RSProperties::GetClipToRRect() const
1162 {
1163     return clipRRect_.has_value();
1164 }
1165 
SetClipBounds(std::shared_ptr<RSPath> path)1166 void RSProperties::SetClipBounds(std::shared_ptr<RSPath> path)
1167 {
1168     if (path) {
1169         isDrawn_ = true;
1170     }
1171     if (clipPath_ != path) {
1172         clipPath_ = path;
1173         SetDirty();
1174         geoDirty_ = true;  // [planning] all clip ops should be checked
1175     }
1176 }
1177 
GetClipBounds() const1178 std::shared_ptr<RSPath> RSProperties::GetClipBounds() const
1179 {
1180     return clipPath_;
1181 }
1182 
SetClipToBounds(bool clipToBounds)1183 void RSProperties::SetClipToBounds(bool clipToBounds)
1184 {
1185     if (clipToBounds) {
1186         isDrawn_ = true;
1187     }
1188     if (clipToBounds_ != clipToBounds) {
1189         clipToBounds_ = clipToBounds;
1190         SetDirty();
1191         geoDirty_ = true;  // [planning] all clip ops should be checked
1192     }
1193 }
1194 
GetClipToBounds() const1195 bool RSProperties::GetClipToBounds() const
1196 {
1197     return clipToBounds_;
1198 }
1199 
SetClipToFrame(bool clipToFrame)1200 void RSProperties::SetClipToFrame(bool clipToFrame)
1201 {
1202     if (clipToFrame) {
1203         isDrawn_ = true;
1204     }
1205     if (clipToFrame_ != clipToFrame) {
1206         clipToFrame_ = clipToFrame;
1207         SetDirty();
1208         geoDirty_ = true;  // [planning] all clip ops should be checked
1209     }
1210 }
1211 
GetClipToFrame() const1212 bool RSProperties::GetClipToFrame() const
1213 {
1214     return clipToFrame_;
1215 }
1216 
GetBoundsRect() const1217 RectF RSProperties::GetBoundsRect() const
1218 {
1219     if (boundsGeo_->IsEmpty()) {
1220         return RectF(0, 0, GetFrameWidth(), GetFrameHeight());
1221     } else {
1222         return RectF(0, 0, GetBoundsWidth(), GetBoundsHeight());
1223     }
1224 }
1225 
GetFrameRect() const1226 RectF RSProperties::GetFrameRect() const
1227 {
1228     return RectF(0, 0, GetFrameWidth(), GetFrameHeight());
1229 }
1230 
GetBgImageRect() const1231 RectF RSProperties::GetBgImageRect() const
1232 {
1233     return decoration_ ? decoration_->bgImageRect_ : RectF();
1234 }
1235 
SetVisible(bool visible)1236 void RSProperties::SetVisible(bool visible)
1237 {
1238     if (visible_ != visible) {
1239         visible_ = visible;
1240         SetDirty();
1241         contentDirty_ = true;
1242     }
1243 }
1244 
GetVisible() const1245 bool RSProperties::GetVisible() const
1246 {
1247     return visible_;
1248 }
1249 
GetRRect() const1250 RRect RSProperties::GetRRect() const
1251 {
1252     RectF rect = GetBoundsRect();
1253     RRect rrect = RRect(rect, GetCornerRadius());
1254     return rrect;
1255 }
1256 
GetInnerRRect() const1257 RRect RSProperties::GetInnerRRect() const
1258 {
1259     auto rect = GetBoundsRect();
1260     Vector4f cornerRadius = GetCornerRadius();
1261     if (border_) {
1262         rect.left_ += border_->GetWidth(RSBorder::LEFT);
1263         rect.top_ += border_->GetWidth(RSBorder::TOP);
1264         rect.width_ -= border_->GetWidth(RSBorder::LEFT) + border_->GetWidth(RSBorder::RIGHT);
1265         rect.height_ -= border_->GetWidth(RSBorder::TOP) + border_->GetWidth(RSBorder::BOTTOM);
1266         cornerRadius = cornerRadius - GetBorderWidth();
1267     }
1268     RRect rrect = RRect(rect, cornerRadius);
1269     return rrect;
1270 }
1271 
NeedFilter() const1272 bool RSProperties::NeedFilter() const
1273 {
1274     return (backgroundFilter_ != nullptr && backgroundFilter_->IsValid()) ||
1275         (filter_ != nullptr && filter_->IsValid()) || IsLightUpEffectValid() || IsDynamicLightUpValid();
1276 }
1277 
NeedClip() const1278 bool RSProperties::NeedClip() const
1279 {
1280     return clipToBounds_ || clipToFrame_;
1281 }
1282 
SetDirty()1283 void RSProperties::SetDirty()
1284 {
1285     isDirty_ = true;
1286 }
1287 
ResetDirty()1288 void RSProperties::ResetDirty()
1289 {
1290     isDirty_ = false;
1291     geoDirty_ = false;
1292     contentDirty_ = false;
1293 }
1294 
IsDirty() const1295 bool RSProperties::IsDirty() const
1296 {
1297     return isDirty_;
1298 }
1299 
IsGeoDirty() const1300 bool RSProperties::IsGeoDirty() const
1301 {
1302     return geoDirty_;
1303 }
1304 
IsContentDirty() const1305 bool RSProperties::IsContentDirty() const
1306 {
1307     return contentDirty_;
1308 }
1309 
GetDirtyRect() const1310 RectI RSProperties::GetDirtyRect() const
1311 {
1312     RectI dirtyRect;
1313     auto boundsGeometry = (boundsGeo_);
1314     if (clipToBounds_ || std::isinf(GetFrameWidth()) || std::isinf(GetFrameHeight())) {
1315         dirtyRect = boundsGeometry->GetAbsRect();
1316     } else {
1317         auto frameRect =
1318             boundsGeometry->MapAbsRect(RectF(GetFrameOffsetX(), GetFrameOffsetY(), GetFrameWidth(), GetFrameHeight()));
1319         dirtyRect = boundsGeometry->GetAbsRect().JoinRect(frameRect);
1320     }
1321     if (drawRegion_ == nullptr || drawRegion_->IsEmpty()) {
1322         return dirtyRect;
1323     } else {
1324         auto drawRegion = boundsGeometry->MapAbsRect(*drawRegion_);
1325         // this is used to fix the scene with drawRegion problem, which is need to be optimized
1326         drawRegion.SetRight(drawRegion.GetRight() + 1);
1327         drawRegion.SetBottom(drawRegion.GetBottom() + 1);
1328         drawRegion.SetAll(drawRegion.left_ - 1, drawRegion.top_ - 1,
1329             drawRegion.width_ + 1, drawRegion.height_ + 1);
1330         return dirtyRect.JoinRect(drawRegion);
1331     }
1332 }
1333 
GetDirtyRect(RectI & drawRegion) const1334 RectI RSProperties::GetDirtyRect(RectI& drawRegion) const
1335 {
1336     RectI dirtyRect;
1337     auto boundsGeometry = (boundsGeo_);
1338     if (clipToBounds_ || std::isinf(GetFrameWidth()) || std::isinf(GetFrameHeight())) {
1339         dirtyRect = boundsGeometry->GetAbsRect();
1340     } else {
1341         auto frameRect =
1342             boundsGeometry->MapAbsRect(RectF(GetFrameOffsetX(), GetFrameOffsetY(), GetFrameWidth(), GetFrameHeight()));
1343         dirtyRect = boundsGeometry->GetAbsRect().JoinRect(frameRect);
1344     }
1345     if (drawRegion_ == nullptr || drawRegion_->IsEmpty()) {
1346         drawRegion = RectI();
1347         return dirtyRect;
1348     } else {
1349         drawRegion = boundsGeometry->MapAbsRect(*drawRegion_);
1350         // this is used to fix the scene with drawRegion problem, which is need to be optimized
1351         drawRegion.SetRight(drawRegion.GetRight() + 1);
1352         drawRegion.SetBottom(drawRegion.GetBottom() + 1);
1353         drawRegion.SetAll(drawRegion.left_ - 1, drawRegion.top_ - 1,
1354             drawRegion.width_ + 1, drawRegion.height_ + 1);
1355         return dirtyRect.JoinRect(drawRegion);
1356     }
1357 }
1358 
CheckEmptyBounds()1359 void RSProperties::CheckEmptyBounds()
1360 {
1361     // [planning] remove this func and fallback to framerect after surfacenode using frame
1362     if (!hasBounds_) {
1363         boundsGeo_->SetRect(frameGeo_->GetX(), frameGeo_->GetY(), frameGeo_->GetWidth(), frameGeo_->GetHeight());
1364     }
1365 }
1366 
1367 // mask properties
SetMask(std::shared_ptr<RSMask> mask)1368 void RSProperties::SetMask(std::shared_ptr<RSMask> mask)
1369 {
1370     mask_ = mask;
1371     if (mask_) {
1372         isDrawn_ = true;
1373     }
1374     SetDirty();
1375     contentDirty_ = true;
1376 }
1377 
GetMask() const1378 std::shared_ptr<RSMask> RSProperties::GetMask() const
1379 {
1380     return mask_;
1381 }
1382 
SetSpherize(float spherizeDegree)1383 void RSProperties::SetSpherize(float spherizeDegree)
1384 {
1385     spherizeDegree_ = spherizeDegree;
1386     SetDirty();
1387     contentDirty_ = true;
1388 }
1389 
GetSpherize() const1390 float RSProperties::GetSpherize() const
1391 {
1392     return spherizeDegree_;
1393 }
1394 
IsSpherizeValid() const1395 bool RSProperties::IsSpherizeValid() const
1396 {
1397     constexpr float epsilon = 0.001f;
1398     return GetSpherize() - 0.0 > epsilon;
1399 }
1400 
SetLightUpEffect(float lightUpEffectDegree)1401 void RSProperties::SetLightUpEffect(float lightUpEffectDegree)
1402 {
1403     lightUpEffectDegree_ = lightUpEffectDegree;
1404     if (IsLightUpEffectValid()) {
1405         isDrawn_ = true;
1406     }
1407     SetDirty();
1408     contentDirty_ = true;
1409 }
1410 
GetLightUpEffect() const1411 float RSProperties::GetLightUpEffect() const
1412 {
1413     return lightUpEffectDegree_;
1414 }
1415 
IsLightUpEffectValid() const1416 bool RSProperties::IsLightUpEffectValid() const
1417 {
1418     return ROSEN_GE(GetLightUpEffect(), 0.0) && ROSEN_LNE(GetLightUpEffect(), 1.0);
1419 }
1420 
SetUseEffect(bool useEffect)1421 void RSProperties::SetUseEffect(bool useEffect)
1422 {
1423     useEffect_ = useEffect;
1424     if (GetUseEffect()) {
1425         isDrawn_ = true;
1426     }
1427     SetDirty();
1428 }
1429 
GetUseEffect() const1430 bool RSProperties::GetUseEffect() const
1431 {
1432     return useEffect_;
1433 }
1434 
SetPixelStretch(const std::optional<Vector4f> & stretchSize)1435 void RSProperties::SetPixelStretch(const std::optional<Vector4f>& stretchSize)
1436 {
1437     pixelStretch_ = stretchSize;
1438     SetDirty();
1439     pixelStretchNeedUpdate_ = true;
1440     contentDirty_ = true;
1441 }
1442 
GetPixelStretch() const1443 const std::optional<Vector4f>& RSProperties::GetPixelStretch() const
1444 {
1445     return pixelStretch_;
1446 }
1447 
GetPixelStretchDirtyRect() const1448 RectI RSProperties::GetPixelStretchDirtyRect() const
1449 {
1450     auto dirtyRect = GetDirtyRect();
1451 
1452     auto scaledBounds = RectF(dirtyRect.left_ - pixelStretch_->x_, dirtyRect.top_ - pixelStretch_->y_,
1453         dirtyRect.width_ + pixelStretch_->x_ + pixelStretch_->z_,
1454         dirtyRect.height_ + pixelStretch_->y_ + pixelStretch_->w_);
1455 
1456     auto scaledIBounds = RectI(std::floor(scaledBounds.left_), std::floor(scaledBounds.top_),
1457         std::ceil(scaledBounds.width_) + 1, std::ceil(scaledBounds.height_) + 1);
1458     return dirtyRect.JoinRect(scaledIBounds);
1459 }
1460 
SetPixelStretchPercent(const std::optional<Vector4f> & stretchPercent)1461 void RSProperties::SetPixelStretchPercent(const std::optional<Vector4f>& stretchPercent)
1462 {
1463     pixelStretchPercent_ = stretchPercent;
1464     SetDirty();
1465     pixelStretchNeedUpdate_ = true;
1466     contentDirty_ = true;
1467 }
1468 
GetPixelStretchPercent() const1469 const std::optional<Vector4f>& RSProperties::GetPixelStretchPercent() const
1470 {
1471     return pixelStretchPercent_;
1472 }
1473 
1474 // Image effect properties
SetGrayScale(const std::optional<float> & grayScale)1475 void RSProperties::SetGrayScale(const std::optional<float>& grayScale)
1476 {
1477     grayScale_ = grayScale;
1478     colorFilterNeedUpdate_ = true;
1479     SetDirty();
1480     contentDirty_ = true;
1481 }
1482 
GetGrayScale() const1483 const std::optional<float>& RSProperties::GetGrayScale() const
1484 {
1485     return grayScale_;
1486 }
1487 
SetBrightness(const std::optional<float> & brightness)1488 void RSProperties::SetBrightness(const std::optional<float>& brightness)
1489 {
1490     brightness_ = brightness;
1491     colorFilterNeedUpdate_ = true;
1492     SetDirty();
1493     contentDirty_ = true;
1494 }
1495 
GetBrightness() const1496 const std::optional<float>& RSProperties::GetBrightness() const
1497 {
1498     return brightness_;
1499 }
1500 
SetContrast(const std::optional<float> & contrast)1501 void RSProperties::SetContrast(const std::optional<float>& contrast)
1502 {
1503     contrast_ = contrast;
1504     colorFilterNeedUpdate_ = true;
1505     SetDirty();
1506     contentDirty_ = true;
1507 }
1508 
GetContrast() const1509 const std::optional<float>& RSProperties::GetContrast() const
1510 {
1511     return contrast_;
1512 }
1513 
SetSaturate(const std::optional<float> & saturate)1514 void RSProperties::SetSaturate(const std::optional<float>& saturate)
1515 {
1516     saturate_ = saturate;
1517     colorFilterNeedUpdate_ = true;
1518     SetDirty();
1519     contentDirty_ = true;
1520 }
1521 
GetSaturate() const1522 const std::optional<float>& RSProperties::GetSaturate() const
1523 {
1524     return saturate_;
1525 }
1526 
SetSepia(const std::optional<float> & sepia)1527 void RSProperties::SetSepia(const std::optional<float>& sepia)
1528 {
1529     sepia_ = sepia;
1530     colorFilterNeedUpdate_ = true;
1531     SetDirty();
1532     contentDirty_ = true;
1533 }
1534 
GetSepia() const1535 const std::optional<float>& RSProperties::GetSepia() const
1536 {
1537     return sepia_;
1538 }
1539 
SetInvert(const std::optional<float> & invert)1540 void RSProperties::SetInvert(const std::optional<float>& invert)
1541 {
1542     invert_ = invert;
1543     colorFilterNeedUpdate_ = true;
1544     SetDirty();
1545     contentDirty_ = true;
1546 }
1547 
GetInvert() const1548 const std::optional<float>& RSProperties::GetInvert() const
1549 {
1550     return invert_;
1551 }
1552 
SetHueRotate(const std::optional<float> & hueRotate)1553 void RSProperties::SetHueRotate(const std::optional<float>& hueRotate)
1554 {
1555     hueRotate_ = hueRotate;
1556     colorFilterNeedUpdate_ = true;
1557     SetDirty();
1558     contentDirty_ = true;
1559 }
1560 
GetHueRotate() const1561 const std::optional<float>& RSProperties::GetHueRotate() const
1562 {
1563     return hueRotate_;
1564 }
1565 
SetColorBlend(const std::optional<Color> & colorBlend)1566 void RSProperties::SetColorBlend(const std::optional<Color>& colorBlend)
1567 {
1568     colorBlend_ = colorBlend;
1569     colorFilterNeedUpdate_ = true;
1570     SetDirty();
1571     contentDirty_ = true;
1572 }
1573 
GetColorBlend() const1574 const std::optional<Color>& RSProperties::GetColorBlend() const
1575 {
1576     return colorBlend_;
1577 }
1578 
GreatNotEqual(double left,double right)1579 static bool GreatNotEqual(double left, double right)
1580 {
1581     constexpr double epsilon = 0.001f;
1582     return (left - right) > epsilon;
1583 }
1584 
NearEqual(const double left,const double right)1585 static bool NearEqual(const double left, const double right)
1586 {
1587     constexpr double epsilon = 0.001f;
1588     return (std::abs(left - right) <= epsilon);
1589 }
1590 
GreatOrEqual(double left,double right)1591 static bool GreatOrEqual(double left, double right)
1592 {
1593     constexpr double epsilon = -0.001f;
1594     return (left - right) > epsilon;
1595 }
1596 
1597 #ifndef USE_ROSEN_DRAWING
GetColorFilter() const1598 const sk_sp<SkColorFilter>& RSProperties::GetColorFilter() const
1599 #else
1600 const std::shared_ptr<Drawing::ColorFilter>& RSProperties::GetColorFilter() const
1601 #endif
1602 {
1603     return colorFilter_;
1604 }
1605 
GenerateColorFilter()1606 void RSProperties::GenerateColorFilter()
1607 {
1608     // No update needed if color filter is valid
1609     if (!colorFilterNeedUpdate_) {
1610         return;
1611     }
1612 
1613     colorFilterNeedUpdate_ = false;
1614     colorFilter_ = nullptr;
1615     if (!grayScale_ && !brightness_ && !contrast_ && !saturate_ && !sepia_ && !invert_ && !hueRotate_ && !colorBlend_) {
1616         return;
1617     }
1618 
1619 #ifndef USE_ROSEN_DRAWING
1620     sk_sp<SkColorFilter> filter = nullptr;
1621 #else
1622     std::shared_ptr<Drawing::ColorFilter> filter = nullptr;
1623 #endif
1624 
1625     if (grayScale_.has_value() && GreatNotEqual(*grayScale_, 0.f)) {
1626         auto grayScale = grayScale_.value();
1627         float matrix[20] = { 0.0f }; // 20 : matrix size
1628         matrix[0] = matrix[INDEX_5] = matrix[INDEX_10] = 0.2126f * grayScale; // 0.2126 : gray scale coefficient
1629         matrix[1] = matrix[INDEX_6] = matrix[INDEX_11] = 0.7152f * grayScale; // 0.7152 : gray scale coefficient
1630         matrix[INDEX_2] = matrix[INDEX_7] = matrix[INDEX_12] = 0.0722f * grayScale; // 0.0722 : gray scale coefficient
1631         matrix[INDEX_18] = 1.0 * grayScale;
1632 #ifndef USE_ROSEN_DRAWING
1633         filter = SkColorFilters::Matrix(matrix);
1634         colorFilter_ = filter->makeComposed(colorFilter_);
1635 #else
1636         Drawing::ColorMatrix colorMatrix;
1637         colorMatrix.SetArray(matrix);
1638         filter = Drawing::ColorFilter::CreateMatrixColorFilter(colorMatrix);
1639         if (colorFilter_) {
1640             filter->Compose(*colorFilter_);
1641         }
1642         colorFilter_ = filter;
1643 #endif
1644     }
1645     if (brightness_.has_value() && !NearEqual(*brightness_, 1.0)) {
1646         auto brightness = brightness_.value();
1647         float matrix[20] = { 0.0f }; // 20 : matrix size
1648         // shift brightness to (-1, 1)
1649         brightness = brightness - 1;
1650         matrix[0] = matrix[INDEX_6] = matrix[INDEX_12] = matrix[INDEX_18] = 1.0f;
1651         matrix[INDEX_4] = matrix[INDEX_9] = matrix[INDEX_14] = brightness;
1652 #ifndef USE_ROSEN_DRAWING
1653         filter = SkColorFilters::Matrix(matrix);
1654         colorFilter_ = filter->makeComposed(colorFilter_);
1655 #else
1656         Drawing::ColorMatrix colorMatrix;
1657         colorMatrix.SetArray(matrix);
1658         filter = Drawing::ColorFilter::CreateMatrixColorFilter(colorMatrix);
1659         if (colorFilter_) {
1660             filter->Compose(*colorFilter_);
1661         }
1662         colorFilter_ = filter;
1663 #endif
1664     }
1665     if (contrast_.has_value() && !NearEqual(*contrast_, 1.0)) {
1666         auto contrast = contrast_.value();
1667         uint32_t contrastValue128 = 128;
1668         uint32_t contrastValue255 = 255;
1669         float matrix[20] = { 0.0f }; // 20 : matrix size
1670         matrix[0] = matrix[INDEX_6] = matrix[INDEX_12] = contrast;
1671         matrix[INDEX_4] = matrix[INDEX_9] = matrix[INDEX_14] = contrastValue128 * (1 - contrast) / contrastValue255;
1672         matrix[INDEX_18] = 1.0f;
1673 #ifndef USE_ROSEN_DRAWING
1674         filter = SkColorFilters::Matrix(matrix);
1675         colorFilter_ = filter->makeComposed(colorFilter_);
1676 #else
1677         Drawing::ColorMatrix colorMatrix;
1678         colorMatrix.SetArray(matrix);
1679         filter = Drawing::ColorFilter::CreateMatrixColorFilter(colorMatrix);
1680         if (colorFilter_) {
1681             filter->Compose(*colorFilter_);
1682         }
1683         colorFilter_ = filter;
1684 #endif
1685     }
1686     if (saturate_.has_value() && !NearEqual(*saturate_, 1.0) && GreatOrEqual(*saturate_, 0.0)) {
1687         auto saturate = saturate_.value();
1688         float matrix[20] = { 0.0f }; // 20 : matrix size
1689         matrix[0] = 0.3086f * (1 - saturate) + saturate; // 0.3086 : saturate coefficient
1690         matrix[1] = matrix[INDEX_11] = 0.6094f * (1 - saturate); // 0.6094 : saturate coefficient
1691         matrix[INDEX_2] = matrix[INDEX_7] = 0.0820f * (1 - saturate); // 0.0820 : saturate coefficient
1692         matrix[INDEX_5] = matrix[INDEX_10] = 0.3086f * (1 - saturate); // 0.3086 : saturate coefficient
1693         matrix[INDEX_6] = 0.6094f * (1 - saturate) + saturate; // 0.6094 : saturate coefficient
1694         matrix[INDEX_12] = 0.0820f * (1 - saturate) + saturate; // 0.0820 : saturate coefficient
1695         matrix[INDEX_18] = 1.0f;
1696 #ifndef USE_ROSEN_DRAWING
1697         filter = SkColorFilters::Matrix(matrix);
1698         colorFilter_ = filter->makeComposed(colorFilter_);
1699 #else
1700         Drawing::ColorMatrix colorMatrix;
1701         colorMatrix.SetArray(matrix);
1702         filter = Drawing::ColorFilter::CreateMatrixColorFilter(colorMatrix);
1703         if (colorFilter_) {
1704             filter->Compose(*colorFilter_);
1705         }
1706         colorFilter_ = filter;
1707 #endif
1708     }
1709     if (sepia_.has_value() && GreatNotEqual(*sepia_, 0.0)) {
1710         auto sepia = sepia_.value();
1711         float matrix[20] = { 0.0f }; // 20 : matrix size
1712         matrix[0] = 0.393f * sepia;
1713         matrix[1] = 0.769f * sepia;
1714         matrix[INDEX_2] = 0.189f * sepia;
1715 
1716         matrix[INDEX_5] = 0.349f * sepia;
1717         matrix[INDEX_6] = 0.686f * sepia;
1718         matrix[INDEX_7] = 0.168f * sepia;
1719 
1720         matrix[INDEX_10] = 0.272f * sepia;
1721         matrix[INDEX_11] = 0.534f * sepia;
1722         matrix[INDEX_12] = 0.131f * sepia;
1723         matrix[INDEX_18] = 1.0f * sepia;
1724 #ifndef USE_ROSEN_DRAWING
1725         filter = SkColorFilters::Matrix(matrix);
1726         colorFilter_ = filter->makeComposed(colorFilter_);
1727 #else
1728         Drawing::ColorMatrix colorMatrix;
1729         colorMatrix.SetArray(matrix);
1730         filter = Drawing::ColorFilter::CreateMatrixColorFilter(colorMatrix);
1731         if (colorFilter_) {
1732             filter->Compose(*colorFilter_);
1733         }
1734         colorFilter_ = filter;
1735 #endif
1736     }
1737     if (invert_.has_value() && GreatNotEqual(*invert_, 0.0)) {
1738         auto invert = invert_.value();
1739         float matrix[20] = { 0.0f }; // 20 : matrix size
1740         if (invert > 1.0) {
1741             invert = 1.0;
1742         }
1743         // complete color invert when dstRGB = 1 - srcRGB
1744         // map (0, 1) to (1, -1)
1745         matrix[0] = matrix[INDEX_6] = matrix[INDEX_12] = 1.0 - 2.0 * invert; // 2.0: invert
1746         matrix[INDEX_18] = 1.0f;
1747         // invert = 0.5 -> RGB = (0.5, 0.5, 0.5) -> image completely gray
1748         matrix[INDEX_4] = matrix[INDEX_9] = matrix[INDEX_14] = invert;
1749 #ifndef USE_ROSEN_DRAWING
1750         filter = SkColorFilters::Matrix(matrix);
1751         colorFilter_ = filter->makeComposed(colorFilter_);
1752 #else
1753         Drawing::ColorMatrix colorMatrix;
1754         colorMatrix.SetArray(matrix);
1755         filter = Drawing::ColorFilter::CreateMatrixColorFilter(colorMatrix);
1756         if (colorFilter_) {
1757             filter->Compose(*colorFilter_);
1758         }
1759         colorFilter_ = filter;
1760 #endif
1761     }
1762     if (hueRotate_.has_value() && GreatNotEqual(*hueRotate_, 0.0)) {
1763         auto hueRotate = hueRotate_.value();
1764         while (GreatOrEqual(hueRotate, 360)) { // 360 : degree
1765             hueRotate -= 360; // 360 : degree
1766         }
1767         float matrix[20] = { 0.0f }; // 20 : matrix size
1768         int32_t type = hueRotate / 120; // 120 : degree
1769         float N = (hueRotate - 120 * type) / 120; // 120 : degree
1770         switch (type) {
1771             case 0:
1772                 // color change = R->G, G->B, B->R
1773                 matrix[INDEX_2] = matrix[INDEX_5] = matrix[INDEX_11] = N;
1774                 matrix[0] = matrix[INDEX_6] = matrix[INDEX_12] = 1 - N;
1775                 matrix[INDEX_18] = 1.0f;
1776                 break;
1777             case 1:
1778                 // compare to original: R->B, G->R, B->G
1779                 matrix[1] = matrix[INDEX_7] = matrix[INDEX_10] = N;
1780                 matrix[INDEX_2] = matrix[INDEX_5] = matrix[INDEX_11] = 1 - N;
1781                 matrix[INDEX_18] = 1.0f;
1782                 break;
1783             case 2: // 2: back to normal color
1784                 matrix[0] = matrix[INDEX_6] = matrix[INDEX_12] = N;
1785                 matrix[1] = matrix[INDEX_7] = matrix[INDEX_10] = 1 - N;
1786                 matrix[INDEX_18] = 1.0f;
1787                 break;
1788             default:
1789                 break;
1790         }
1791 #ifndef USE_ROSEN_DRAWING
1792         filter = SkColorFilters::Matrix(matrix);
1793         colorFilter_ = filter->makeComposed(colorFilter_);
1794 #else
1795         Drawing::ColorMatrix colorMatrix;
1796         colorMatrix.SetArray(matrix);
1797         filter = Drawing::ColorFilter::CreateMatrixColorFilter(colorMatrix);
1798         if (colorFilter_) {
1799             filter->Compose(*colorFilter_);
1800         }
1801         colorFilter_ = filter;
1802 #endif
1803     }
1804     if (colorBlend_.has_value() && *colorBlend_ != RgbPalette::Transparent()) {
1805         auto colorBlend = colorBlend_.value();
1806 #ifndef USE_ROSEN_DRAWING
1807         filter = SkColorFilters::Blend(
1808             SkColorSetARGB(colorBlend.GetAlpha(), colorBlend.GetRed(), colorBlend.GetGreen(), colorBlend.GetBlue()),
1809             SkBlendMode::kPlus);
1810         colorFilter_ = filter->makeComposed(colorFilter_);
1811 #else
1812         filter = Drawing::ColorFilter::CreateBlendModeColorFilter(Drawing::Color::ColorQuadSetARGB(
1813             colorBlend.GetRed(), colorBlend.GetGreen(), colorBlend.GetBlue(), colorBlend.GetAlpha()),
1814             Drawing::BlendMode::PLUS);
1815         if (colorFilter_) {
1816             filter->Compose(*colorFilter_);
1817         }
1818         colorFilter_ = filter;
1819 #endif
1820     }
1821     isDrawn_ = true;
1822 }
1823 
Dump() const1824 std::string RSProperties::Dump() const
1825 {
1826     std::string dumpInfo;
1827     char buffer[UINT8_MAX] = { 0 };
1828     if (sprintf_s(buffer, UINT8_MAX, "Bounds[%.1f %.1f %.1f %.1f] Frame[%.1f %.1f %.1f %.1f]",
1829         GetBoundsPositionX(), GetBoundsPositionY(), GetBoundsWidth(), GetBoundsHeight(),
1830         GetFramePositionX(), GetFramePositionY(), GetFrameWidth(), GetFrameHeight()) != -1) {
1831         dumpInfo.append(buffer);
1832     }
1833 
1834     // PositionZ
1835     auto ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1836     if (ret != EOK) {
1837         return "Failed to memset_s for PositionZ, ret=" + std::to_string(ret);
1838     }
1839     if (!ROSEN_EQ(GetPositionZ(), 0.f) &&
1840         sprintf_s(buffer, UINT8_MAX, ", PositionZ[%.1f]", GetPositionZ()) != -1) {
1841         dumpInfo.append(buffer);
1842     }
1843 
1844     // Pivot
1845     std::unique_ptr<Transform> defaultTrans = std::make_unique<Transform>();
1846     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1847     if (ret != EOK) {
1848         return "Failed to memset_s for Pivot, ret=" + std::to_string(ret);
1849     }
1850     Vector2f pivot = GetPivot();
1851     if ((!ROSEN_EQ(pivot[0], defaultTrans->pivotX_) || !ROSEN_EQ(pivot[1], defaultTrans->pivotY_)) &&
1852         sprintf_s(buffer, UINT8_MAX, ", Pivot[%.1f,%.1f]", pivot[0], pivot[1]) != -1) {
1853         dumpInfo.append(buffer);
1854     }
1855 
1856     // CornerRadius
1857     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1858     if (ret != EOK) {
1859         return "Failed to memset_s for CornerRadius, ret=" + std::to_string(ret);
1860     }
1861     if (!GetCornerRadius().IsZero() &&
1862         sprintf_s(buffer, UINT8_MAX, ", CornerRadius[%.1f %.1f %.1f %.1f]",
1863             GetCornerRadius().x_, GetCornerRadius().y_, GetCornerRadius().z_, GetCornerRadius().w_) != -1) {
1864         dumpInfo.append(buffer);
1865     }
1866 
1867     // Rotation
1868     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1869     if (ret != EOK) {
1870         return "Failed to memset_s for Rotation, ret=" + std::to_string(ret);
1871     }
1872     if (!ROSEN_EQ(GetRotation(), defaultTrans->rotation_) &&
1873         sprintf_s(buffer, UINT8_MAX, ", Rotation[%.1f]", GetRotation()) != -1) {
1874         dumpInfo.append(buffer);
1875     }
1876     // RotationX
1877     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1878     if (ret != EOK) {
1879         return "Failed to memset_s for RotationX, ret=" + std::to_string(ret);
1880     }
1881     if (!ROSEN_EQ(GetRotationX(), defaultTrans->rotationX_) &&
1882         sprintf_s(buffer, UINT8_MAX, ", RotationX[%.1f]", GetRotationX()) != -1) {
1883         dumpInfo.append(buffer);
1884     }
1885     // RotationY
1886     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1887     if (ret != EOK) {
1888         return "Failed to memset_s for RotationY, ret=" + std::to_string(ret);
1889     }
1890     if (!ROSEN_EQ(GetRotationY(), defaultTrans->rotationY_) &&
1891         sprintf_s(buffer, UINT8_MAX, ", RotationY[%.1f]", GetRotationY()) != -1) {
1892         dumpInfo.append(buffer);
1893     }
1894 
1895     // TranslateX
1896     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1897     if (ret != EOK) {
1898         return "Failed to memset_s for TranslateX, ret=" + std::to_string(ret);
1899     }
1900     if (!ROSEN_EQ(GetTranslateX(), defaultTrans->translateX_) &&
1901         sprintf_s(buffer, UINT8_MAX, ", TranslateX[%.1f]", GetTranslateX()) != -1) {
1902         dumpInfo.append(buffer);
1903     }
1904 
1905     // TranslateY
1906     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1907     if (ret != EOK) {
1908         return "Failed to memset_s for TranslateY, ret=" + std::to_string(ret);
1909     }
1910     if (!ROSEN_EQ(GetTranslateY(), defaultTrans->translateY_) &&
1911         sprintf_s(buffer, UINT8_MAX, ", TranslateY[%.1f]", GetTranslateY()) != -1) {
1912         dumpInfo.append(buffer);
1913     }
1914 
1915     // TranslateZ
1916     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1917     if (ret != EOK) {
1918         return "Failed to memset_s for TranslateZ, ret=" + std::to_string(ret);
1919     }
1920     if (!ROSEN_EQ(GetTranslateZ(), defaultTrans->translateZ_) &&
1921         sprintf_s(buffer, UINT8_MAX, ", TranslateZ[%.1f]", GetTranslateZ()) != -1) {
1922         dumpInfo.append(buffer);
1923     }
1924 
1925     // ScaleX
1926     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1927     if (ret != EOK) {
1928         return "Failed to memset_s for ScaleX, ret=" + std::to_string(ret);
1929     }
1930     if (!ROSEN_EQ(GetScaleX(), defaultTrans->scaleX_) &&
1931         sprintf_s(buffer, UINT8_MAX, ", ScaleX[%.1f]", GetScaleX()) != -1) {
1932         dumpInfo.append(buffer);
1933     }
1934 
1935     // ScaleY
1936     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1937     if (ret != EOK) {
1938         return "Failed to memset_s for ScaleY, ret=" + std::to_string(ret);
1939     }
1940     if (!ROSEN_EQ(GetScaleY(), defaultTrans->scaleY_) &&
1941         sprintf_s(buffer, UINT8_MAX, ", ScaleY[%.1f]", GetScaleY()) != -1) {
1942         dumpInfo.append(buffer);
1943     }
1944 
1945     // Alpha
1946     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1947     if (ret != EOK) {
1948         return "Failed to memset_s for Alpha, ret=" + std::to_string(ret);
1949     }
1950     if (!ROSEN_EQ(GetAlpha(), 1.f) &&
1951         sprintf_s(buffer, UINT8_MAX, ", Alpha[%.1f]", GetAlpha()) != -1) {
1952         dumpInfo.append(buffer);
1953     }
1954 
1955     // ForegroundColor
1956     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1957     if (ret != EOK) {
1958         return "Failed to memset_s for ForegroundColor, ret=" + std::to_string(ret);
1959     }
1960     if (!ROSEN_EQ(GetForegroundColor(), RgbPalette::Transparent()) &&
1961         sprintf_s(buffer, UINT8_MAX, ", ForegroundColor[#%08X]", GetForegroundColor().AsArgbInt()) != -1) {
1962         dumpInfo.append(buffer);
1963     }
1964 
1965     // BackgroundColor
1966     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1967     if (ret != EOK) {
1968         return "Failed to memset_s for BackgroundColor, ret=" + std::to_string(ret);
1969     }
1970     if (!ROSEN_EQ(GetBackgroundColor(), RgbPalette::Transparent()) &&
1971         sprintf_s(buffer, UINT8_MAX, ", BackgroundColor[#%08X]", GetBackgroundColor().AsArgbInt()) != -1) {
1972         dumpInfo.append(buffer);
1973     }
1974 
1975     // BgImage
1976     std::unique_ptr<Decoration> defaultDecoration = std::make_unique<Decoration>();
1977     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1978     if (ret != EOK) {
1979         return "Failed to memset_s for BgImage, ret=" + std::to_string(ret);
1980     }
1981     if ((!ROSEN_EQ(GetBgImagePositionX(), defaultDecoration->bgImageRect_.left_) ||
1982         !ROSEN_EQ(GetBgImagePositionY(), defaultDecoration->bgImageRect_.top_) ||
1983         !ROSEN_EQ(GetBgImageWidth(), defaultDecoration->bgImageRect_.width_) ||
1984         !ROSEN_EQ(GetBgImageHeight(), defaultDecoration->bgImageRect_.height_)) &&
1985         sprintf_s(buffer, UINT8_MAX, ", BgImage[%.1f %.1f %.1f %.1f]", GetBgImagePositionX(),
1986             GetBgImagePositionY(), GetBgImageWidth(), GetBgImageHeight()) != -1) {
1987         dumpInfo.append(buffer);
1988     }
1989 
1990     // Border
1991     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
1992     if (ret != EOK) {
1993         return "Failed to memset_s for Border, ret=" + std::to_string(ret);
1994     }
1995     if (border_ && border_->HasBorder() &&
1996         sprintf_s(buffer, UINT8_MAX, ", Border[%s]", border_->ToString().c_str()) != -1) {
1997         dumpInfo.append(buffer);
1998     }
1999 
2000     // ShadowColor
2001     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2002     if (ret != EOK) {
2003         return "Failed to memset_s for ShadowColor, ret=" + std::to_string(ret);
2004     }
2005     if (!ROSEN_EQ(GetShadowColor(), Color(DEFAULT_SPOT_COLOR)) &&
2006         sprintf_s(buffer, UINT8_MAX, ", ShadowColor[#%08X]", GetShadowColor().AsArgbInt()) != -1) {
2007         dumpInfo.append(buffer);
2008     }
2009 
2010     // ShadowOffsetX
2011     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2012     if (ret != EOK) {
2013         return "Failed to memset_s for ShadowOffsetX, ret=" + std::to_string(ret);
2014     }
2015     if (!ROSEN_EQ(GetShadowOffsetX(), DEFAULT_SHADOW_OFFSET_X) &&
2016         sprintf_s(buffer, UINT8_MAX, ", ShadowOffsetX[%.1f]", GetShadowOffsetX()) != -1) {
2017         dumpInfo.append(buffer);
2018     }
2019 
2020     // ShadowOffsetY
2021     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2022     if (ret != EOK) {
2023         return "Failed to memset_s for ShadowOffsetY, ret=" + std::to_string(ret);
2024     }
2025     if (!ROSEN_EQ(GetShadowOffsetY(), DEFAULT_SHADOW_OFFSET_Y) &&
2026         sprintf_s(buffer, UINT8_MAX, ", ShadowOffsetY[%.1f]", GetShadowOffsetY()) != -1) {
2027         dumpInfo.append(buffer);
2028     }
2029 
2030     // ShadowAlpha
2031     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2032     if (ret != EOK) {
2033         return "Failed to memset_s for ShadowAlpha, ret=" + std::to_string(ret);
2034     }
2035     if (!ROSEN_EQ(GetShadowAlpha(), 0.f) &&
2036         sprintf_s(buffer, UINT8_MAX, ", ShadowAlpha[%.1f]", GetShadowAlpha()) != -1) {
2037         dumpInfo.append(buffer);
2038     }
2039 
2040     // ShadowElevation
2041     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2042     if (ret != EOK) {
2043         return "Failed to memset_s for ShadowElevation, ret=" + std::to_string(ret);
2044     }
2045     if (!ROSEN_EQ(GetShadowElevation(), 0.f) &&
2046         sprintf_s(buffer, UINT8_MAX, ", ShadowElevation[%.1f]", GetShadowElevation()) != -1) {
2047         dumpInfo.append(buffer);
2048     }
2049 
2050     // ShadowRadius
2051     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2052     if (ret != EOK) {
2053         return "Failed to memset_s for ShadowRadius, ret=" + std::to_string(ret);
2054     }
2055     if (!ROSEN_EQ(GetShadowRadius(), 0.f) &&
2056         sprintf_s(buffer, UINT8_MAX, ", ShadowRadius[%.1f]", GetShadowRadius()) != -1) {
2057         dumpInfo.append(buffer);
2058     }
2059 
2060     // FrameGravity
2061     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2062     if (ret != EOK) {
2063         return "Failed to memset_s for FrameGravity, ret=" + std::to_string(ret);
2064     }
2065     if (!ROSEN_EQ(GetFrameGravity(), Gravity::DEFAULT) &&
2066         sprintf_s(buffer, UINT8_MAX, ", FrameGravity[%d]", GetFrameGravity()) != -1) {
2067         dumpInfo.append(buffer);
2068     }
2069 
2070     // IsVisible
2071     if (!GetVisible()) {
2072         dumpInfo.append(", IsVisible[false]");
2073     }
2074 
2075     // Gray Scale
2076     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2077     if (ret != EOK) {
2078         return "Failed to memset_s for GrayScale, ret=" + std::to_string(ret);
2079     }
2080     auto grayScale = GetGrayScale();
2081     if (grayScale.has_value() && !ROSEN_EQ(*grayScale, 0.f) &&
2082         sprintf_s(buffer, UINT8_MAX, ", GrayScale[%.1f]", *grayScale) != -1) {
2083         dumpInfo.append(buffer);
2084     }
2085 
2086     // Brightness
2087     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2088     if (ret != EOK) {
2089         return "Failed to memset_s for Brightness, ret=" + std::to_string(ret);
2090     }
2091     auto brightness = GetBrightness();
2092     if (brightness.has_value() && !ROSEN_EQ(*brightness, 1.f) &&
2093         sprintf_s(buffer, UINT8_MAX, ", Brightness[%.1f]", *brightness) != -1) {
2094         dumpInfo.append(buffer);
2095     }
2096 
2097     // Contrast
2098     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2099     if (ret != EOK) {
2100         return "Failed to memset_s for Contrast, ret=" + std::to_string(ret);
2101     }
2102     auto contrast = GetContrast();
2103     if (contrast.has_value() && !ROSEN_EQ(*contrast, 1.f) &&
2104         sprintf_s(buffer, UINT8_MAX, ", Contrast[%.1f]", *contrast) != -1) {
2105         dumpInfo.append(buffer);
2106     }
2107 
2108     // Saturate
2109     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2110     if (ret != EOK) {
2111         return "Failed to memset_s for Saturate, ret=" + std::to_string(ret);
2112     }
2113     auto saturate = GetSaturate();
2114     if (saturate.has_value() && !ROSEN_EQ(*saturate, 1.f) &&
2115         sprintf_s(buffer, UINT8_MAX, ", Saturate[%.1f]", *saturate) != -1) {
2116         dumpInfo.append(buffer);
2117     }
2118 
2119     // Sepia
2120     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2121     if (ret != EOK) {
2122         return "Failed to memset_s for Sepia, ret=" + std::to_string(ret);
2123     }
2124     auto sepia = GetSepia();
2125     if (sepia.has_value() && !ROSEN_EQ(*sepia, 0.f) &&
2126         sprintf_s(buffer, UINT8_MAX, ", Sepia[%.1f]", *sepia) != -1) {
2127         dumpInfo.append(buffer);
2128     }
2129 
2130     // Invert
2131     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2132     if (ret != EOK) {
2133         return "Failed to memset_s for Invert, ret=" + std::to_string(ret);
2134     }
2135     auto invert = GetInvert();
2136     if (invert.has_value() && !ROSEN_EQ(*invert, 0.f) &&
2137         sprintf_s(buffer, UINT8_MAX, ", Invert[%.1f]", *invert) != -1) {
2138         dumpInfo.append(buffer);
2139     }
2140 
2141     // Hue Rotate
2142     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2143     if (ret != EOK) {
2144         return "Failed to memset_s for HueRotate, ret=" + std::to_string(ret);
2145     }
2146     auto hueRotate = GetHueRotate();
2147     if (hueRotate.has_value() && !ROSEN_EQ(*hueRotate, 0.f) &&
2148         sprintf_s(buffer, UINT8_MAX, ", HueRotate[%.1f]", *hueRotate) != -1) {
2149         dumpInfo.append(buffer);
2150     }
2151 
2152     // Color Blend
2153     ret = memset_s(buffer, UINT8_MAX, 0, UINT8_MAX);
2154     if (ret != EOK) {
2155         return "Failed to memset_s for ColorBlend, ret=" + std::to_string(ret);
2156     }
2157     auto colorBlend = GetColorBlend();
2158     if (colorBlend.has_value() && !ROSEN_EQ(*colorBlend, RgbPalette::Transparent()) &&
2159         sprintf_s(buffer, UINT8_MAX, ", ColorBlend[#%08X]", colorBlend->AsArgbInt()) != -1) {
2160         dumpInfo.append(buffer);
2161     }
2162 
2163     return dumpInfo;
2164 }
2165 
2166 #ifndef USE_ROSEN_DRAWING
CreateFilterCacheManagerIfNeed()2167 void RSProperties::CreateFilterCacheManagerIfNeed()
2168 {
2169     filterManagerNeedUpdate_ = false;
2170     if (!FilterCacheEnabled) {
2171         return;
2172     }
2173     if (auto& filter = GetBackgroundFilter(); filter != nullptr && filter->IsValid()) {
2174         auto& cacheManager = backgroundFilterCacheManager_;
2175         if (cacheManager == nullptr) {
2176             cacheManager = std::make_unique<RSFilterCacheManager>();
2177         }
2178         cacheManager->UpdateCacheStateWithFilterHash(filter->Hash());
2179     } else {
2180         backgroundFilterCacheManager_.reset();
2181     }
2182     if (auto& filter = GetFilter(); filter != nullptr && filter->IsValid()) {
2183         auto& cacheManager = foregroundFilterCacheManager_;
2184         if (cacheManager == nullptr) {
2185             cacheManager = std::make_unique<RSFilterCacheManager>();
2186         }
2187         cacheManager->UpdateCacheStateWithFilterHash(filter->Hash());
2188     } else {
2189         foregroundFilterCacheManager_.reset();
2190     }
2191 }
2192 
GetFilterCacheManager(bool isForeground) const2193 const std::unique_ptr<RSFilterCacheManager>& RSProperties::GetFilterCacheManager(bool isForeground) const
2194 {
2195     return isForeground ? foregroundFilterCacheManager_ : backgroundFilterCacheManager_;
2196 }
2197 #endif
2198 
OnApplyModifiers()2199 void RSProperties::OnApplyModifiers()
2200 {
2201     if (geoDirty_) {
2202         if (!hasBounds_) {
2203             CheckEmptyBounds();
2204         } else {
2205             CalculateFrameOffset();
2206         }
2207     }
2208     if (colorFilterNeedUpdate_) {
2209         GenerateColorFilter();
2210     }
2211     if (pixelStretchNeedUpdate_ || geoDirty_) {
2212         CalculatePixelStretch();
2213     }
2214 #ifndef USE_ROSEN_DRAWING
2215     if (filterManagerNeedUpdate_) {
2216         CreateFilterCacheManagerIfNeed();
2217     }
2218 #endif
2219 }
2220 
SignBit(float x)2221 inline static int SignBit(float x)
2222 {
2223     constexpr static float eps = 1e-5f;
2224     if (x <= -eps) {
2225         return -1;
2226     } else if (x >= eps) {
2227         return 1;
2228     } else {
2229         return 0;
2230     }
2231 }
2232 
CalculatePixelStretch()2233 void RSProperties::CalculatePixelStretch()
2234 {
2235     pixelStretchNeedUpdate_ = false;
2236     // no pixel stretch
2237     if (!pixelStretch_.has_value() && !pixelStretchPercent_.has_value()) {
2238         return;
2239     }
2240     // convert pixel stretch percent to pixel stretch
2241     if (pixelStretchPercent_) {
2242         auto width = GetBoundsWidth();
2243         auto height = GetBoundsHeight();
2244         if (isinf(width) || isinf(height)) {
2245             return;
2246         }
2247         pixelStretch_ = *pixelStretchPercent_ * Vector4f(width, height, width, height);
2248     }
2249     // parameter check: same sign
2250     const auto sign = SignBit(pixelStretch_->x_);
2251     if (sign == 0 || SignBit(pixelStretch_->y_) != sign || SignBit(pixelStretch_->z_) != sign ||
2252         SignBit(pixelStretch_->w_) != sign) {
2253         pixelStretch_ = std::nullopt;
2254         return;
2255     }
2256     isDrawn_ = true;
2257 }
2258 
CalculateFrameOffset()2259 void RSProperties::CalculateFrameOffset()
2260 {
2261     frameOffsetX_ = frameGeo_->GetX() - boundsGeo_->GetX();
2262     frameOffsetY_ = frameGeo_->GetY() - boundsGeo_->GetY();
2263     if (isinf(frameOffsetX_)) {
2264         frameOffsetX_ = 0.;
2265     }
2266     if (isinf(frameOffsetY_)) {
2267         frameOffsetY_ = 0.;
2268     }
2269     if (frameOffsetX_ != 0. || frameOffsetY_ != 0.) {
2270         isDrawn_ = true;
2271     }
2272 }
2273 } // namespace Rosen
2274 } // namespace OHOS
2275