1 /* 2 * Copyright (c) 2025 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_TRANSITION_MODIFIER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_TRANSITION_MODIFIER_H 18 19 #include <functional> 20 #include <memory> 21 22 #include "render_service_client/core/modifier_ng/custom/rs_transition_style_modifier.h" 23 24 #include "core/components_ng/render/adapter/rosen_modifier_adapter.h" 25 #include "core/components_ng/render/drawing_prop_convertor.h" 26 #include "core/components_ng/render/render_context.h" 27 28 namespace OHOS::Ace::NG { 29 using RSTransitionStyleModifier = Rosen::ModifierNG::RSTransitionStyleModifier; 30 class TransitionModifier : public RSTransitionStyleModifier { 31 public: 32 TransitionModifier() = default; 33 ~TransitionModifier() override = default; 34 Draw(RSDrawingContext & context)35 void Draw(RSDrawingContext& context) const override 36 { 37 if (isBuilderBackground_) { 38 DrawWithPixelMap(context); 39 } else { 40 DrawWithBackgroundColor(context); 41 } 42 } 43 SetPixelMap(const RefPtr<PixelMap> & pixelMap)44 void SetPixelMap(const RefPtr<PixelMap>& pixelMap) 45 { 46 pixelMap_ = pixelMap; 47 } 48 SetAlign(const Alignment & align)49 void SetAlign(const Alignment& align) 50 { 51 align_ = align; 52 } 53 Modify()54 void Modify() 55 { 56 if (!flag_) { 57 flag_ = std::make_shared<Rosen::RSProperty<bool>>(0); 58 AttachProperty(flag_); 59 } else { 60 flag_->Set(!flag_->Get()); 61 } 62 } 63 SetHostNode(RefPtr<FrameNode> host)64 void SetHostNode(RefPtr<FrameNode> host) 65 { 66 host_ = host; 67 } 68 SetBackgroundColor(const Color & color)69 void SetBackgroundColor(const Color& color) 70 { 71 backgroundColor_ = color; 72 } 73 SetDrawRegionUpdateFunc(std::function<void (const std::shared_ptr<Rosen::RectF> & rect)> && func)74 void SetDrawRegionUpdateFunc(std::function<void(const std::shared_ptr<Rosen::RectF>& rect)>&& func) 75 { 76 updateDrawRegionFunc_ = std::move(func); 77 } 78 SetIsBuilderBackground(bool isBuilderBackground)79 void SetIsBuilderBackground(bool isBuilderBackground) 80 { 81 isBuilderBackground_ = isBuilderBackground; 82 } 83 SetInitialBackgroundRegion(const RectF & region)84 void SetInitialBackgroundRegion(const RectF& region) 85 { 86 initialBackgroundRegion_ = region; 87 } 88 89 private: DrawWithPixelMap(RSDrawingContext & context)90 void DrawWithPixelMap(RSDrawingContext& context) const 91 { 92 CHECK_NULL_VOID(pixelMap_); 93 RSRect backgroundRegion = GetBackgroundRegion(); 94 auto backgroundRegionWidth = backgroundRegion.GetWidth(); 95 auto backgroundRegionHeight = backgroundRegion.GetHeight(); 96 std::shared_ptr<Media::PixelMap> mediaPixelMap = pixelMap_->GetPixelMapSharedPtr(); 97 CHECK_NULL_VOID(mediaPixelMap); 98 CHECK_NULL_VOID(context.canvas); 99 auto& recordingCanvas = static_cast<Rosen::ExtendRecordingCanvas&>(*context.canvas); 100 RSSamplingOptions samplingOptions; 101 RSBrush brush; 102 SizeF desSize(initialBackgroundRegion_.Width(), initialBackgroundRegion_.Height()); 103 SizeF srcSize(mediaPixelMap->GetWidth(), mediaPixelMap->GetHeight()); 104 NG::OffsetF offset1 = Alignment::GetAlignPosition(srcSize, desSize, align_); 105 NG::OffsetF offset2 = Alignment::GetAlignPosition(desSize, srcSize, align_); 106 RSRect srcRSRect = 107 RSRect(offset1.GetX(), offset1.GetY(), srcSize.Width() + offset1.GetX(), srcSize.Height() + offset1.GetY()); 108 float widthScale = backgroundRegionWidth / initialBackgroundRegion_.Width(); 109 float heightScale = backgroundRegionHeight / initialBackgroundRegion_.Height(); 110 RSRect desRSRect = RSRect(backgroundRegion.GetLeft() + offset2.GetX() * widthScale, 111 backgroundRegion.GetTop() + offset2.GetY() * heightScale, 112 backgroundRegion.GetLeft() + (srcSize.Width() + offset2.GetX()) * widthScale, 113 backgroundRegion.GetTop() + (srcSize.Height() + offset2.GetY()) * heightScale); 114 if (srcSize.Width() > desSize.Width()) { 115 srcRSRect.SetRight(offset1.GetX() + desSize.Width()); 116 desRSRect.SetRight(backgroundRegion.GetLeft() + backgroundRegionWidth); 117 } 118 if (srcSize.Height() > desSize.Height()) { 119 srcRSRect.SetBottom(offset1.GetY() + desSize.Height()); 120 desRSRect.SetBottom(backgroundRegion.GetTop() + backgroundRegionHeight); 121 } 122 std::shared_ptr<Rosen::RectF> drawRegion = std::make_shared<Rosen::RectF>( 123 desRSRect.GetLeft(), desRSRect.GetTop(), desRSRect.GetWidth(), desRSRect.GetHeight()); 124 CHECK_NULL_VOID(updateDrawRegionFunc_); 125 updateDrawRegionFunc_(drawRegion); 126 recordingCanvas.AttachBrush(brush); 127 recordingCanvas.DrawPixelMapRect(mediaPixelMap, srcRSRect, desRSRect, samplingOptions); 128 recordingCanvas.DetachBrush(); 129 } 130 DrawWithBackgroundColor(RSDrawingContext & context)131 void DrawWithBackgroundColor(RSDrawingContext& context) const 132 { 133 RSRect backgroundRegion = GetBackgroundRegion(); 134 std::shared_ptr<Rosen::RectF> drawRect = std::make_shared<Rosen::RectF>(backgroundRegion.GetLeft(), 135 backgroundRegion.GetTop(), backgroundRegion.GetWidth(), backgroundRegion.GetHeight()); 136 CHECK_NULL_VOID(updateDrawRegionFunc_); 137 updateDrawRegionFunc_(drawRect); 138 CHECK_NULL_VOID(context.canvas); 139 auto& recordingCanvas = static_cast<Rosen::ExtendRecordingCanvas&>(*context.canvas); 140 RSBrush brush; 141 brush.SetColor(ToRSColor(backgroundColor_)); 142 recordingCanvas.AttachBrush(brush); 143 recordingCanvas.DrawRect(backgroundRegion); 144 recordingCanvas.DetachBrush(); 145 } 146 GetBackgroundRegion()147 RSRect GetBackgroundRegion() const 148 { 149 RSRect rect; 150 RefPtr<FrameNode> host = host_.Upgrade(); 151 CHECK_NULL_RETURN(host, rect); 152 rect = ToRSRect(host->GetBackGroundAccumulatedSafeAreaExpand()); 153 return rect; 154 } 155 156 RefPtr<PixelMap> pixelMap_; 157 Alignment align_; 158 Color backgroundColor_; 159 std::shared_ptr<Rosen::RSProperty<bool>> flag_; 160 WeakPtr<FrameNode> host_; 161 bool isBuilderBackground_ = false; 162 RectF initialBackgroundRegion_ = { 0.0f, 0.0f, 1.0f, 1.0f }; 163 std::function<void(const std::shared_ptr<Rosen::RectF>& rect)> updateDrawRegionFunc_; 164 }; 165 } // namespace OHOS::Ace::NG 166 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_TRANSITION_MODIFIER_H