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 #ifndef RENDER_SERVICE_CLIENT_CORE_RENDER_RS_IMAGE_H
17 #define RENDER_SERVICE_CLIENT_CORE_RENDER_RS_IMAGE_H
18 
19 #include "draw/canvas.h"
20 #include "effect/color_filter.h"
21 #include "image/image.h"
22 #include "render/rs_image_base.h"
23 
24 namespace OHOS {
25 namespace Media {
26 class PixelMap;
27 }
28 namespace Rosen {
29 namespace Drawing {
30 struct AdaptiveImageInfo {
31     int32_t fitNum = 0;
32     int32_t repeatNum = 0;
33     Point radius[4];
34     double scale = 0.0;
35     uint32_t uniqueId = 0;
36     int32_t width = 0;
37     int32_t height = 0;
38     uint32_t dynamicRangeMode = 0;
39     int32_t rotateDegree = 0;
40     Rect frameRect;
41 };
42 }
43 
44 class RsImageInfo final {
45 public:
RsImageInfo(int fitNum,int repeatNum,const Drawing::Point * radius,double scale,uint32_t id,int w,int h)46     RsImageInfo(int fitNum, int repeatNum, const Drawing::Point* radius, double scale, uint32_t id, int w, int h)
47         : fitNum_(fitNum), repeatNum_(repeatNum), radius_(radius), scale_(scale),
48           uniqueId_(id), width_(w), height_(h) {};
~RsImageInfo()49     ~RsImageInfo() {}
50     int fitNum_ = 0;
51     int repeatNum_ = 0;
52     const Drawing::Point* radius_;
53     double scale_ = 0.0;
54     uint32_t uniqueId_ = 0;
55     int width_ = 0;
56     int height_ = 0;
57 };
58 
59 enum class ImageRepeat {
60     NO_REPEAT = 0,
61     REPEAT_X,
62     REPEAT_Y,
63     REPEAT,
64 };
65 
66 enum class ImageFit {
67     FILL,
68     CONTAIN,
69     COVER,
70     FIT_WIDTH,
71     FIT_HEIGHT,
72     NONE,
73     SCALE_DOWN,
74     TOP_LEFT,
75     TOP,
76     TOP_RIGHT,
77     LEFT,
78     CENTER,
79     RIGHT,
80     BOTTOM_LEFT,
81     BOTTOM,
82     BOTTOM_RIGHT,
83     COVER_TOP_LEFT,
84 };
85 
86 class RSB_EXPORT RSImage : public RSImageBase {
87 public:
88     RSImage() = default;
89     ~RSImage();
90 
91     bool IsEqual(const RSImage& other) const;
92     void CanvasDrawImage(Drawing::Canvas& canvas, const Drawing::Rect& rect,
93         const Drawing::SamplingOptions& samplingOptions, bool isBackground = false);
94     void SetImageFit(int fitNum);
95     void SetImageRepeat(int repeatNum);
96     void SetImageRotateDegree(int32_t degree);
97     void SetRadius(const std::vector<Drawing::Point>& radius);
98     void SetScale(double scale);
SetInnerRect(const std::optional<Drawing::RectI> & innerRect)99     void SetInnerRect(const std::optional<Drawing::RectI>& innerRect) { innerRect_ = innerRect;}
100 
101     void SetCompressData(const std::shared_ptr<Drawing::Data> data, uint32_t id, int width, int height);
102     void SetCompressData(const std::shared_ptr<Drawing::Data> compressData);
103 
104     bool HDRConvert(const Drawing::SamplingOptions& sampling, Drawing::Canvas& canvas);
105     void SetPaint(Drawing::Paint paint);
106     void SetDynamicRangeMode(uint32_t dynamicRangeMode);
107 
108     void SetNodeId(NodeId nodeId);
109 
110     void ApplyImageFit();
111     ImageFit GetImageFit();
112     Drawing::AdaptiveImageInfo GetAdaptiveImageInfoWithCustomizedFrameRect(const Drawing::Rect& frameRect) const;
113     RectF GetDstRect();
114     void SetFrameRect(RectF frameRect);
115 #ifdef ROSEN_OHOS
116     bool Marshalling(Parcel& parcel) const override;
117     [[nodiscard]] static RSImage* Unmarshalling(Parcel& parcel);
118 #endif
dump(std::string & desc,int depth)119     void dump(std::string &desc, int depth) const
120     {
121         std::string split(depth, '\t');
122         desc += split + "RSImage:{";
123         desc += split + "\timageFit_: " + std::to_string(static_cast<int>(imageFit_)) + "\n";
124         desc += split + "\timageRepeat_: " + std::to_string(static_cast<int>(imageRepeat_)) + "\n";
125         int radiusSize = 4;
126         for (int i = 0; i < radiusSize; i++) {
127             desc += split + "\tPointF:{ \n";
128             desc += split + "\t\t x_: " + std::to_string(radius_[i].GetX()) + "\n";
129             desc += split + "\t\t y_: " + std::to_string(radius_[i].GetY()) + "\n";
130             desc += split + "\t}\n";
131         }
132         desc += split + frameRect_.ToString();
133         desc += split + "\tscale_: " + std::to_string(scale_) + "\n";
134         desc += split + "}\n";
135     }
136 
137 private:
138     bool HasRadius() const;
139     void ApplyCanvasClip(Drawing::Canvas& canvas);
140     void UploadGpu(Drawing::Canvas& canvas);
141     std::pair<float, float> CalculateByDegree(const Drawing::Rect& rect);
142     void DrawImageWithRotateDegree(
143             Drawing::Canvas& canvas, const Drawing::Rect& rect, const Drawing::SamplingOptions& samplingOptions);
144     void DrawImageRepeatRect(const Drawing::SamplingOptions& samplingOptions, Drawing::Canvas& canvas);
145     void CalcRepeatBounds(int& minX, int& maxX, int& minY, int& maxY);
146     void DrawImageOnCanvas(
147         const Drawing::SamplingOptions& samplingOptions, Drawing::Canvas& canvas, const bool hdrImageDraw);
148 #ifdef ROSEN_OHOS
149     static bool UnmarshalIdSizeAndNodeId(Parcel& parcel, uint64_t& uniqueId, int& width, int& height, NodeId& nodeId);
150     static bool UnmarshalImageProperties(Parcel& parcel, int& fitNum, int& repeatNum,
151         std::vector<Drawing::Point>& radius, double& scale, int32_t& degree);
152     static void ProcessImageAfterCreation(RSImage* rsImage, const uint64_t uniqueId, const bool useSkImage,
153         const std::shared_ptr<Media::PixelMap>& pixelMap);
154 #endif
155     std::shared_ptr<Drawing::Data> compressData_;
156     ImageFit imageFit_ = ImageFit::COVER;
157     ImageRepeat imageRepeat_ = ImageRepeat::NO_REPEAT;
158     std::vector<Drawing::Point> radius_ = std::vector<Drawing::Point>(4);
159     std::optional<Drawing::RectI> innerRect_ = std::nullopt;
160     bool hasRadius_ = false;
161     RectF frameRect_;
162     double scale_ = 1.0;
163     NodeId nodeId_ = 0;
164     int32_t rotateDegree_;
165     Drawing::Paint paint_;
166     uint32_t dynamicRangeMode_ = 0;
167 };
168 
169 template<>
ROSEN_EQ(const std::shared_ptr<RSImage> & x,const std::shared_ptr<RSImage> & y)170 inline bool ROSEN_EQ(const std::shared_ptr<RSImage>& x, const std::shared_ptr<RSImage>& y)
171 {
172     if (x == y) {
173         return true;
174     }
175     return (x && y) ? x->IsEqual(*y) : false;
176 }
177 } // namespace Rosen
178 } // namespace OHOS
179 #endif // RENDER_SERVICE_CLIENT_CORE_RENDER_RS_IMAGE_H
180