1 /* 2 * Copyright (c) 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_BACKGROUND_MODIFIER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_BACKGROUND_MODIFIER_H 18 19 #include <functional> 20 #include <memory> 21 22 #include "render_service_client/core/modifier/rs_extended_modifier.h" 23 24 #include "core/components_ng/render/adapter/rosen_modifier_adapter.h" 25 26 namespace OHOS::Ace::NG { 27 class BackgroundModifier : public Rosen::RSBackgroundStyleModifier { 28 public: 29 BackgroundModifier() = default; 30 ~BackgroundModifier() override = default; 31 32 #ifndef USE_ROSEN_DRAWING Draw(Rosen::RSDrawingContext & context)33 void Draw(Rosen::RSDrawingContext& context) const override 34 { 35 auto host = host_.Upgrade(); 36 CHECK_NULL_VOID(host); 37 auto curSize = host->GetGeometryNode()->GetFrameSize(); 38 auto curWidth = curSize.Width(); 39 auto curHeight = curSize.Height(); 40 CHECK_NULL_VOID(pixelMap_); 41 std::shared_ptr<Media::PixelMap> mediaPixelMap = pixelMap_->GetPixelMapSharedPtr(); 42 CHECK_NULL_VOID(context.canvas); 43 std::shared_ptr<SkCanvas> skCanvas { context.canvas, [](SkCanvas* /* unused */) {} }; 44 auto* recordingCanvas = static_cast<Rosen::RSRecordingCanvas*>(skCanvas.get()); 45 SkSamplingOptions samplingOptions; 46 SkPaint paint; 47 48 SizeF desSize(initialNodeWidth_, initialNodeHeight_); 49 SizeF srcSize(mediaPixelMap->GetWidth(), mediaPixelMap->GetHeight()); 50 NG::OffsetF offset1 = Alignment::GetAlignPosition(srcSize, desSize, align_); 51 NG::OffsetF offset2 = Alignment::GetAlignPosition(desSize, srcSize, align_); 52 SkRect srcSKRect = SkRect::MakeXYWH(offset1.GetX(), offset1.GetY(), srcSize.Width(), srcSize.Height()); 53 SkRect desSKRect = SkRect::MakeXYWH(offset2.GetX() * curWidth / initialNodeWidth_, 54 offset2.GetY() * curHeight / initialNodeHeight_, srcSize.Width() * curWidth / initialNodeWidth_, 55 srcSize.Height() * curHeight / initialNodeHeight_); 56 if (srcSize.Width() > desSize.Width()) { 57 srcSKRect.fRight = offset1.GetX() + desSize.Width(); 58 desSKRect.fRight = curWidth; 59 } 60 if (srcSize.Height() > desSize.Height()) { 61 srcSKRect.fBottom = offset1.GetY() + desSize.Height(); 62 desSKRect.fBottom = curHeight; 63 } 64 recordingCanvas->DrawPixelMapRect(mediaPixelMap, srcSKRect, desSKRect, samplingOptions, &paint); 65 } 66 #else Draw(Rosen::RSDrawingContext & context)67 void Draw(Rosen::RSDrawingContext& context) const override 68 { 69 auto host = host_.Upgrade(); 70 CHECK_NULL_VOID(host); 71 auto curSize = host->GetGeometryNode()->GetFrameSize(); 72 auto curWidth = curSize.Width(); 73 auto curHeight = curSize.Height(); 74 CHECK_NULL_VOID(pixelMap_); 75 std::shared_ptr<Media::PixelMap> mediaPixelMap = pixelMap_->GetPixelMapSharedPtr(); 76 CHECK_NULL_VOID(context.canvas); 77 auto& recordingCanvas = static_cast<Rosen::ExtendRecordingCanvas&>(*context.canvas); 78 RSSamplingOptions samplingOptions; 79 RSBrush brush; 80 81 SizeF desSize(initialNodeWidth_, initialNodeHeight_); 82 SizeF srcSize(mediaPixelMap->GetWidth(), mediaPixelMap->GetHeight()); 83 NG::OffsetF offset1 = Alignment::GetAlignPosition(srcSize, desSize, align_); 84 NG::OffsetF offset2 = Alignment::GetAlignPosition(desSize, srcSize, align_); 85 RSRect srcRSRect = RSRect(offset1.GetX(), offset1.GetY(), srcSize.Width() + offset1.GetX(), 86 srcSize.Height() + offset1.GetY()); 87 RSRect desRSRect = RSRect(offset2.GetX() * curWidth / initialNodeWidth_, 88 offset2.GetY() * curHeight / initialNodeHeight_, 89 srcSize.Width() * curWidth / initialNodeWidth_ + offset2.GetX() * curWidth / initialNodeWidth_, 90 srcSize.Height() * curHeight / initialNodeHeight_ + 91 offset2.GetY() * curHeight / initialNodeHeight_); 92 if (srcSize.Width() > desSize.Width()) { 93 srcRSRect.SetRight(offset1.GetX() + desSize.Width()); 94 desRSRect.SetRight(curWidth); 95 } 96 if (srcSize.Height() > desSize.Height()) { 97 srcRSRect.SetBottom(offset1.GetY() + desSize.Height()); 98 desRSRect.SetBottom(curHeight); 99 } 100 recordingCanvas.AttachBrush(brush); 101 recordingCanvas.DrawPixelMapRect(mediaPixelMap, srcRSRect, desRSRect, samplingOptions); 102 recordingCanvas.DetachBrush(); 103 } 104 #endif 105 SetPixelMap(const RefPtr<PixelMap> & pixelMap)106 void SetPixelMap(const RefPtr<PixelMap>& pixelMap) 107 { 108 CHECK_NULL_VOID(pixelMap); 109 pixelMap_ = pixelMap; 110 } 111 SetAlign(const Alignment & align)112 void SetAlign(const Alignment& align) 113 { 114 align_ = align; 115 } 116 SetInitialNodeSize(const float width,const float height)117 void SetInitialNodeSize(const float width, const float height) 118 { 119 initialNodeWidth_ = width; 120 initialNodeHeight_ = height; 121 } 122 Modify()123 void Modify() 124 { 125 if (!flag_) { 126 flag_ = std::make_shared<Rosen::RSProperty<bool>>(0); 127 AttachProperty(flag_); 128 } else { 129 flag_->Set(!flag_->Get()); 130 } 131 } 132 SetHostNode(RefPtr<FrameNode> host)133 void SetHostNode(RefPtr<FrameNode> host) 134 { 135 host_ = host; 136 } 137 138 private: 139 RefPtr<PixelMap> pixelMap_; 140 Alignment align_; 141 float initialNodeWidth_ = 1.0f; 142 float initialNodeHeight_ = 1.0f; 143 std::shared_ptr<Rosen::RSProperty<bool>> flag_; 144 WeakPtr<FrameNode> host_; 145 }; 146 } // namespace OHOS::Ace::NG 147 148 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_BACKGROUND_MODIFIER_H 149