1 /*
2 * Copyright (c) 2024-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 #include "drawing_canvas_utils.h"
17
18 #include <memory>
19
20 #include "pipeline/rs_recording_canvas.h"
21 #include "pixel_map.h"
22 #include "render/rs_pixel_map_util.h"
23 #include "utils/log.h"
24
25 using namespace OHOS;
26 using namespace Rosen;
27
DrawPixelMapNine(Drawing::Canvas * canvas,std::shared_ptr<Media::PixelMap> pixelMap,const Drawing::Rect * center,const Drawing::Rect * dst,const Drawing::FilterMode mode)28 OH_Drawing_ErrorCode DrawingCanvasUtils::DrawPixelMapNine(Drawing::Canvas* canvas,
29 std::shared_ptr<Media::PixelMap> pixelMap, const Drawing::Rect* center, const Drawing::Rect* dst,
30 const Drawing::FilterMode mode)
31 {
32 #ifdef OHOS_PLATFORM
33 if (!canvas || !pixelMap || !dst) {
34 return OH_DRAWING_ERROR_INVALID_PARAMETER;
35 }
36 Drawing::RectI centerRectI;
37 if (center) {
38 centerRectI = Drawing::RectI(Drawing::DrawingFloatSaturate2Int(center->GetLeft()),
39 Drawing::DrawingFloatSaturate2Int(center->GetTop()),
40 Drawing::DrawingFloatSaturate2Int(center->GetRight()),
41 Drawing::DrawingFloatSaturate2Int(center->GetBottom()));
42 } else {
43 centerRectI = Drawing::RectI(0, 0, pixelMap->GetWidth(), pixelMap->GetHeight());
44 }
45 if (canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
46 ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(canvas);
47 canvas_->DrawPixelMapNine(pixelMap, centerRectI, *dst, mode);
48 return OH_DRAWING_SUCCESS;
49 }
50 std::shared_ptr<Drawing::Image> image = RSPixelMapUtil::ExtractDrawingImage(pixelMap);
51 if (!image) {
52 return OH_DRAWING_ERROR_INVALID_PARAMETER;
53 }
54 canvas->DrawImageNine(image.get(), centerRectI, *dst, mode);
55 #endif
56 return OH_DRAWING_SUCCESS;
57 }
58
DrawPixelMapRect(Drawing::Canvas * canvas,std::shared_ptr<Media::PixelMap> pixelMap,const Drawing::Rect * src,const Drawing::Rect * dst,const Drawing::SamplingOptions * sampling)59 void DrawingCanvasUtils::DrawPixelMapRect(Drawing::Canvas* canvas, std::shared_ptr<Media::PixelMap> pixelMap,
60 const Drawing::Rect* src, const Drawing::Rect* dst, const Drawing::SamplingOptions* sampling)
61 {
62 #ifdef OHOS_PLATFORM
63 if (!canvas || !pixelMap || !dst) {
64 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
65 return;
66 }
67 if (canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
68 ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(canvas);
69 canvas_->DrawPixelMapRect(pixelMap,
70 src ? *src : Drawing::Rect(0, 0, pixelMap->GetWidth(), pixelMap->GetHeight()),
71 *dst, sampling ? *sampling : Drawing::SamplingOptions());
72 return;
73 }
74 std::shared_ptr<Drawing::Image> image = RSPixelMapUtil::ExtractDrawingImage(pixelMap);
75 if (!image) {
76 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
77 return;
78 }
79 canvas->DrawImageRect(*image, src ? *src : Drawing::Rect(0, 0, pixelMap->GetWidth(), pixelMap->GetHeight()),
80 *dst, sampling ? *sampling : Drawing::SamplingOptions());
81 #endif
82 }
83
DrawPixelMapRectConstraint(Drawing::Canvas * canvas,std::shared_ptr<Media::PixelMap> pixelMap,const Drawing::Rect * src,const Drawing::Rect * dst,const Drawing::SamplingOptions * sampling,const Drawing::SrcRectConstraint constraint)84 OH_Drawing_ErrorCode DrawingCanvasUtils::DrawPixelMapRectConstraint(Drawing::Canvas* canvas,
85 std::shared_ptr<Media::PixelMap> pixelMap, const Drawing::Rect* src, const Drawing::Rect* dst,
86 const Drawing::SamplingOptions* sampling, const Drawing::SrcRectConstraint constraint)
87 {
88 #ifdef OHOS_PLATFORM
89 if (!canvas || !pixelMap || !dst) {
90 return OH_DRAWING_ERROR_INVALID_PARAMETER;
91 }
92 if (canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
93 ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(canvas);
94 canvas_->DrawPixelMapRect(pixelMap,
95 src ? *src : Drawing::Rect(0, 0, pixelMap->GetWidth(), pixelMap->GetHeight()),
96 *dst, sampling ? *sampling : Drawing::SamplingOptions(), constraint);
97 return OH_DRAWING_SUCCESS;
98 }
99 std::shared_ptr<Drawing::Image> image = RSPixelMapUtil::ExtractDrawingImage(pixelMap);
100 if (!image) {
101 return OH_DRAWING_ERROR_INVALID_PARAMETER;
102 }
103 canvas->DrawImageRect(*image, src ? *src : Drawing::Rect(0, 0, pixelMap->GetWidth(), pixelMap->GetHeight()),
104 *dst, sampling ? *sampling : Drawing::SamplingOptions(), constraint);
105 #endif
106 return OH_DRAWING_SUCCESS;
107 }
108
DrawRecordCmd(Drawing::Canvas * canvas,const std::shared_ptr<Drawing::RecordCmd> recordCmd,bool canNesting)109 void DrawingCanvasUtils::DrawRecordCmd(Drawing::Canvas* canvas,
110 const std::shared_ptr<Drawing::RecordCmd> recordCmd, bool canNesting)
111 {
112 if (!canNesting && canvas->GetDrawingType() == Drawing::DrawingType::RECORDING) {
113 ExtendRecordingCanvas* canvas_ = reinterpret_cast<ExtendRecordingCanvas*>(canvas);
114 if (canvas_->IsRecordCmd()) {
115 LOGE("RecordingCanvas::DrawRecordCmd, operation is unsupported!");
116 return;
117 }
118 }
119 canvas->DrawRecordCmd(recordCmd);
120 }
121
122 #ifdef OHOS_PLATFORM
ColorSpaceToDrawingColorSpace(Media::ColorSpace colorSpace)123 static std::shared_ptr<Drawing::ColorSpace> ColorSpaceToDrawingColorSpace(Media::ColorSpace colorSpace)
124 {
125 switch (colorSpace) {
126 case Media::ColorSpace::DISPLAY_P3:
127 return Drawing::ColorSpace::CreateRGB(
128 Drawing::CMSTransferFuncType::SRGB, Drawing::CMSMatrixType::DCIP3);
129 case Media::ColorSpace::LINEAR_SRGB:
130 return Drawing::ColorSpace::CreateSRGBLinear();
131 case Media::ColorSpace::SRGB:
132 return Drawing::ColorSpace::CreateSRGB();
133 default:
134 return Drawing::ColorSpace::CreateSRGB();
135 }
136 }
137
PixelFormatToDrawingColorType(Media::PixelFormat pixelFormat)138 static Drawing::ColorType PixelFormatToDrawingColorType(Media::PixelFormat pixelFormat)
139 {
140 switch (pixelFormat) {
141 case Media::PixelFormat::RGB_565:
142 return Drawing::ColorType::COLORTYPE_RGB_565;
143 case Media::PixelFormat::RGBA_8888:
144 return Drawing::ColorType::COLORTYPE_RGBA_8888;
145 case Media::PixelFormat::BGRA_8888:
146 return Drawing::ColorType::COLORTYPE_BGRA_8888;
147 case Media::PixelFormat::ALPHA_8:
148 return Drawing::ColorType::COLORTYPE_ALPHA_8;
149 case Media::PixelFormat::RGBA_F16:
150 return Drawing::ColorType::COLORTYPE_RGBA_F16;
151 case Media::PixelFormat::UNKNOWN:
152 case Media::PixelFormat::ARGB_8888:
153 case Media::PixelFormat::RGB_888:
154 case Media::PixelFormat::NV21:
155 case Media::PixelFormat::NV12:
156 case Media::PixelFormat::CMYK:
157 default:
158 return Drawing::ColorType::COLORTYPE_UNKNOWN;
159 }
160 }
161
AlphaTypeToDrawingAlphaType(Media::AlphaType alphaType)162 static Drawing::AlphaType AlphaTypeToDrawingAlphaType(Media::AlphaType alphaType)
163 {
164 switch (alphaType) {
165 case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
166 return Drawing::AlphaType::ALPHATYPE_UNKNOWN;
167 case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
168 return Drawing::AlphaType::ALPHATYPE_OPAQUE;
169 case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
170 return Drawing::AlphaType::ALPHATYPE_PREMUL;
171 case Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
172 return Drawing::AlphaType::ALPHATYPE_UNPREMUL;
173 default:
174 return Drawing::AlphaType::ALPHATYPE_UNKNOWN;
175 }
176 }
177
ExtractDrawingBitmap(std::shared_ptr<Media::PixelMap> pixelMap,Drawing::Bitmap & bitmap)178 bool DrawingCanvasUtils::ExtractDrawingBitmap(std::shared_ptr<Media::PixelMap> pixelMap, Drawing::Bitmap& bitmap)
179 {
180 if (!pixelMap) {
181 return false;
182 }
183 Media::ImageInfo imageInfo;
184 pixelMap->GetImageInfo(imageInfo);
185 Drawing::ImageInfo drawingImageInfo { imageInfo.size.width, imageInfo.size.height,
186 PixelFormatToDrawingColorType(imageInfo.pixelFormat),
187 AlphaTypeToDrawingAlphaType(imageInfo.alphaType),
188 ColorSpaceToDrawingColorSpace(imageInfo.colorSpace) };
189 bitmap.Build(drawingImageInfo, pixelMap->GetRowStride());
190 bitmap.SetPixels(const_cast<void*>(reinterpret_cast<const void*>(pixelMap->GetPixels())));
191 return true;
192 }
193 #endif