1 /*
2 * Copyright (c) 2022-2024 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 "core/components_ng/render/adapter/pixelmap_image.h"
17
18 #include "render_service_base/include/pipeline/rs_recording_canvas.h"
19
20 #include "base/log/ace_trace.h"
21 #include "core/components/common/layout/constants.h"
22 #include "core/components_ng/image_provider/image_data.h"
23 #include "core/components_ng/pattern/image/image_dfx.h"
24 #include "core/components_ng/property/measure_utils.h"
25 #include "core/components_ng/render/adapter/image_painter_utils.h"
26 #include "core/components_ng/render/adapter/rosen/drawing_image.h"
27 #include "core/components_ng/render/canvas_image.h"
28 #include "core/components_ng/render/drawing_forward.h"
29 #include "core/pipeline/pipeline_base.h"
30
31 namespace OHOS::Ace::NG {
32 namespace {
33 // The [GRAY_COLOR_MATRIX] is of dimension [4 x 5], which transforms a RGB source color (R, G, B, A) to the
34 // destination color (R', G', B', A').
35 //
36 // A classic color image to grayscale conversion formula is [Gray = R * 0.3 + G * 0.59 + B * 0.11].
37 // Hence we get the following conversion:
38 //
39 // | M11 M12 M13 M14 M15 | | R | | R' |
40 // | M21 M22 M23 M24 M25 | | G | | G' |
41 // | M31 M32 M33 M34 M35 | x | B | = | B' |
42 // | M41 M42 M43 M44 M45 | | A | | A' |
43 // | 1 |
44 const float GRAY_COLOR_MATRIX[20] = { 0.30f, 0.59f, 0.11f, 0, 0, // red
45 0.30f, 0.59f, 0.11f, 0, 0, // green
46 0.30f, 0.59f, 0.11f, 0, 0, // blue
47 0, 0, 0, 1.0f, 0 }; // alpha transparency
48
49 constexpr int32_t BORDER_RADIUS_ARRAY_SIZE = 4;
50 constexpr int32_t DEGREE_NINETY = 90;
51 constexpr int32_t DEGREE_HUNDRED_EIGHTY = 180;
52
PrintDrawingLatticeConfig(const Rosen::Drawing::Lattice & lattice,const RSRect & dstRect)53 void PrintDrawingLatticeConfig(const Rosen::Drawing::Lattice& lattice, const RSRect& dstRect)
54 {
55 std::string drawingConfigStr;
56 drawingConfigStr.append("dstRect = " + dstRect.ToString());
57 drawingConfigStr.append("fXCount = " + std::to_string(lattice.fXCount));
58 drawingConfigStr.append("fXDivs = [");
59 for (int32_t idx = 0; idx < lattice.fXCount; ++idx) {
60 drawingConfigStr.append(std::to_string(lattice.fXDivs[idx]) + " ");
61 }
62 drawingConfigStr.append("] ");
63 drawingConfigStr.append("fYCount = " + std::to_string(lattice.fYCount));
64 drawingConfigStr.append("fYDivs = [");
65 for (int32_t idx = 0; idx < lattice.fYCount; ++idx) {
66 drawingConfigStr.append(std::to_string(lattice.fYDivs[idx]) + " ");
67 }
68 drawingConfigStr.append("] ");
69 TAG_LOGD(AceLogTag::ACE_IMAGE, "Begin to draw image with lattice : %{public}s", drawingConfigStr.c_str());
70 }
71
ConvertSlice(const ImagePaintConfig & config,RectF & result,float rawImageWidth,float rawImageHeight)72 bool ConvertSlice(const ImagePaintConfig& config, RectF& result, float rawImageWidth, float rawImageHeight)
73 {
74 const auto& slice = config.resizableSlice_;
75 CHECK_NULL_RETURN(slice.Valid(), false);
76 TAG_LOGD(AceLogTag::ACE_IMAGE, "Draw image with slice = %{public}s.", slice.ToString().c_str());
77 result.SetLeft(ConvertToPx(slice.left, ScaleProperty::CreateScaleProperty(), rawImageWidth).value_or(0.0f));
78 result.SetTop(ConvertToPx(slice.top, ScaleProperty::CreateScaleProperty(), rawImageHeight).value_or(0.0f));
79 auto rightSliceValue = ConvertToPx(slice.right, ScaleProperty::CreateScaleProperty(), rawImageWidth).value_or(0.0f);
80 auto bottomSliceValue =
81 ConvertToPx(slice.bottom, ScaleProperty::CreateScaleProperty(), rawImageHeight).value_or(0.0f);
82 // illegal case if left position if larger than right, then rect has negative width
83 if (GreatNotEqual(rawImageWidth - rightSliceValue - result.GetX(), 0.0f)) {
84 result.SetWidth(rawImageWidth - rightSliceValue - result.GetX());
85 } else {
86 return false;
87 }
88 // same illegal case for height
89 if (GreatNotEqual(rawImageHeight - bottomSliceValue - result.GetY(), 0.0f)) {
90 result.SetHeight(rawImageHeight - bottomSliceValue - result.GetY());
91 } else {
92 return false;
93 }
94 return true;
95 }
96
GetDynamicModeString(DynamicRangeMode dynamicMode)97 std::string GetDynamicModeString(DynamicRangeMode dynamicMode)
98 {
99 switch (dynamicMode) {
100 case DynamicRangeMode::HIGH:
101 return "HIGH";
102 case DynamicRangeMode::CONSTRAINT:
103 return "CONSTRAINT";
104 case DynamicRangeMode::STANDARD:
105 return "STANDARD";
106 default:
107 return "STANDARD";
108 }
109 }
110
111 #ifndef USE_ROSEN_DRAWING
UpdateSKFilter(const ImagePaintConfig & config,SKPaint & paint)112 void UpdateSKFilter(const ImagePaintConfig& config, SKPaint& paint)
113 {
114 if (config.colorFilter_.colorFilterMatrix_) {
115 paint.setColorFilter(SkColorFilters::Matrix(config.colorFilter_.colorFilterMatrix_->data()));
116 } else if (ImageRenderMode::TEMPLATE == config.renderMode_) {
117 paint.setColorFilter(SkColorFilters::Matrix(GRAY_COLOR_MATRIX));
118 }
119 }
120 #else
UpdateRSFilter(const ImagePaintConfig & config,RSFilter & filter)121 void UpdateRSFilter(const ImagePaintConfig& config, RSFilter& filter)
122 {
123 if (config.colorFilter_.colorFilterMatrix_) {
124 RSColorMatrix colorMatrix;
125 colorMatrix.SetArray(config.colorFilter_.colorFilterMatrix_->data());
126 filter.SetColorFilter(RSRecordingColorFilter::CreateMatrixColorFilter(colorMatrix));
127 } else if (config.colorFilter_.colorFilterDrawing_) {
128 auto colorFilterSptrAddr = static_cast<std::shared_ptr<RSColorFilter>*>(
129 config.colorFilter_.colorFilterDrawing_->GetDrawingColorFilterSptrAddr());
130 if (colorFilterSptrAddr && (*colorFilterSptrAddr)) {
131 filter.SetColorFilter(*colorFilterSptrAddr);
132 }
133 } else if (ImageRenderMode::TEMPLATE == config.renderMode_) {
134 RSColorMatrix colorMatrix;
135 colorMatrix.SetArray(GRAY_COLOR_MATRIX);
136 filter.SetColorFilter(RSRecordingColorFilter::CreateMatrixColorFilter(colorMatrix));
137 }
138 }
139 #endif
140
CalculateRotateDegree(ImageRotateOrientation orientation)141 int32_t CalculateRotateDegree(ImageRotateOrientation orientation)
142 {
143 switch (orientation) {
144 case ImageRotateOrientation::LEFT:
145 return -DEGREE_NINETY;
146 case ImageRotateOrientation::RIGHT:
147 return DEGREE_NINETY;
148 case ImageRotateOrientation::DOWN:
149 return DEGREE_HUNDRED_EIGHTY;
150 default:
151 return 0;
152 }
153 }
154 } // namespace
155
Create(const RefPtr<PixelMap> & pixelMap)156 RefPtr<CanvasImage> CanvasImage::Create(const RefPtr<PixelMap>& pixelMap)
157 {
158 return AceType::MakeRefPtr<PixelMapImage>(pixelMap);
159 }
160
Clone()161 RefPtr<CanvasImage> PixelMapImage::Clone()
162 {
163 return MakeRefPtr<PixelMapImage>(pixelMap_);
164 }
165
GetWidth() const166 int32_t PixelMapImage::GetWidth() const
167 {
168 auto pixmap = GetPixelMap();
169 if (pixmap) {
170 return pixmap->GetWidth();
171 }
172 TAG_LOGW(AceLogTag::ACE_IMAGE, "pixelMap_ is nullptr, return width 0.");
173 return 0;
174 }
175
GetHeight() const176 int32_t PixelMapImage::GetHeight() const
177 {
178 auto pixmap = GetPixelMap();
179 if (pixmap) {
180 return pixmap->GetHeight();
181 }
182 TAG_LOGW(AceLogTag::ACE_IMAGE, "rsCanvas is nullptr, return height 0.");
183 return 0;
184 }
185
StretchImageWithLattice(RSCanvas & canvas,const RSRect & srcRect,const RSRect & dstRect,const BorderRadiusArray & radiusXY)186 bool PixelMapImage::StretchImageWithLattice(
187 RSCanvas& canvas, const RSRect& srcRect, const RSRect& dstRect, const BorderRadiusArray& radiusXY)
188 {
189 auto pixmap = GetPixelMap();
190 const auto& config = GetPaintConfig();
191 auto drawingLattice = config.resizableLattice_;
192 CHECK_NULL_RETURN(drawingLattice, false);
193 #ifdef ENABLE_ROSEN_BACKEND
194 auto latticeSptrAddr =
195 static_cast<std::shared_ptr<Rosen::Drawing::Lattice>*>(drawingLattice->GetDrawingLatticeSptrAddr());
196 CHECK_NULL_RETURN((latticeSptrAddr && (*latticeSptrAddr)), false);
197 RSBrush brush;
198 auto filterMode = RSFilterMode::NEAREST;
199 switch (config.imageInterpolation_) {
200 case ImageInterpolation::LOW:
201 case ImageInterpolation::MEDIUM:
202 filterMode = RSFilterMode::LINEAR;
203 break;
204 case ImageInterpolation::HIGH:
205 default:
206 break;
207 }
208
209 auto filter = brush.GetFilter();
210 UpdateRSFilter(config, filter);
211 brush.SetFilter(filter);
212 auto& recordingCanvas = static_cast<Rosen::ExtendRecordingCanvas&>(canvas);
213 auto radii = ImagePainterUtils::ToRSRadius(radiusXY);
214 std::vector<RSPoint> radius;
215 for (size_t ii = 0; ii < BORDER_RADIUS_ARRAY_SIZE; ii++) {
216 RSPoint point(radii[ii].GetX(), radii[ii].GetY());
217 radius.emplace_back(point);
218 }
219 recordingCanvas.ClipAdaptiveRoundRect(radius);
220 recordingCanvas.Scale(config.scaleX_, config.scaleY_);
221
222 RSPoint pointRadius[BORDER_RADIUS_ARRAY_SIZE] = {};
223 for (size_t i = 0; i < BORDER_RADIUS_ARRAY_SIZE; i++) {
224 pointRadius[i] = radius[i];
225 }
226 std::shared_ptr<RSImage> rsImage = DrawingImage::MakeRSImageFromPixmap(pixmap);
227 CHECK_NULL_RETURN(rsImage, false);
228 auto lattice = *(*latticeSptrAddr);
229 if (SystemProperties::GetDebugEnabled()) {
230 PrintDrawingLatticeConfig(lattice, dstRect);
231 }
232 recordingCanvas.AttachBrush(brush);
233 recordingCanvas.DrawImageLattice(rsImage.get(), lattice, dstRect, filterMode);
234 recordingCanvas.DetachBrush();
235 return true;
236 #endif
237 return false;
238 }
239
StretchImageWithSlice(RSCanvas & canvas,const RSRect & srcRect,const RSRect & dstRect,const BorderRadiusArray & radiusXY)240 bool PixelMapImage::StretchImageWithSlice(
241 RSCanvas& canvas, const RSRect& srcRect, const RSRect& dstRect, const BorderRadiusArray& radiusXY)
242 {
243 auto pixmap = GetPixelMap();
244 const auto& config = GetPaintConfig();
245 const auto& slice = GetPaintConfig().resizableSlice_;
246 CHECK_NULL_RETURN(slice.Valid(), false);
247 RectF centerRect;
248 CHECK_NULL_RETURN(ConvertSlice(config, centerRect, pixmap->GetWidth(), pixmap->GetHeight()), false);
249 #ifdef ENABLE_ROSEN_BACKEND
250 RSBrush brush;
251 auto filterMode = RSFilterMode::NEAREST;
252 switch (config.imageInterpolation_) {
253 case ImageInterpolation::LOW:
254 case ImageInterpolation::MEDIUM:
255 filterMode = RSFilterMode::LINEAR;
256 break;
257 case ImageInterpolation::HIGH:
258 default:
259 break;
260 }
261
262 auto filter = brush.GetFilter();
263 UpdateRSFilter(config, filter);
264 brush.SetFilter(filter);
265 auto& recordingCanvas = static_cast<Rosen::ExtendRecordingCanvas&>(canvas);
266 auto radii = ImagePainterUtils::ToRSRadius(radiusXY);
267 std::vector<RSPoint> radius;
268 for (int ii = 0; ii < BORDER_RADIUS_ARRAY_SIZE; ii++) {
269 RSPoint point(radii[ii].GetX(), radii[ii].GetY());
270 radius.emplace_back(point);
271 }
272 recordingCanvas.ClipAdaptiveRoundRect(radius);
273 recordingCanvas.Scale(config.scaleX_, config.scaleY_);
274
275 RSPoint pointRadius[BORDER_RADIUS_ARRAY_SIZE] = {};
276 for (int i = 0; i < BORDER_RADIUS_ARRAY_SIZE; i++) {
277 pointRadius[i] = radius[i];
278 }
279 RSRectI rsCenterRect(centerRect.GetX(), centerRect.GetY(), centerRect.GetX() + centerRect.Width(),
280 centerRect.GetY() + centerRect.Height());
281 std::shared_ptr<RSImage> rsImage = DrawingImage::MakeRSImageFromPixmap(pixmap);
282 CHECK_NULL_RETURN(rsImage, false);
283 recordingCanvas.AttachBrush(brush);
284 recordingCanvas.DrawImageNine(rsImage.get(), rsCenterRect, dstRect, filterMode, &brush);
285 recordingCanvas.DetachBrush();
286 return true;
287 #endif
288 return false;
289 }
290
CheckIfNeedForStretching(RSCanvas & canvas,const RSRect & srcRect,const RSRect & dstRect,const BorderRadiusArray & radiusXY)291 bool PixelMapImage::CheckIfNeedForStretching(
292 RSCanvas& canvas, const RSRect& srcRect, const RSRect& dstRect, const BorderRadiusArray& radiusXY)
293 {
294 const auto& config = GetPaintConfig();
295
296 if (config.frameCount_ == 1 && config.resizableLattice_ &&
297 StretchImageWithLattice(canvas, srcRect, dstRect, radiusXY)) {
298 return true;
299 }
300 if (config.frameCount_ == 1 && config.resizableSlice_.Valid() &&
301 StretchImageWithSlice(canvas, srcRect, dstRect, radiusXY)) {
302 return true;
303 }
304 return false;
305 }
306
NotifyDrawCompletion(const std::string & srcInfo,const RefPtr<PixelMap> & pixmap)307 void PixelMapImage::NotifyDrawCompletion(const std::string& srcInfo, const RefPtr<PixelMap>& pixmap)
308 {
309 FireDrawCompleteCallback(RenderedImageInfo{
310 .renderSuccess = true,
311 .width = pixmap->GetWidth(),
312 .height = pixmap->GetHeight(),
313 .rowStride = pixmap->GetRowStride(),
314 .rowBytes = pixmap->GetRowBytes(),
315 .byteCount = pixmap->GetByteCount(),
316 .isHdr = pixmap->IsHdr(),
317 .alphaType = pixmap->GetAlphaType(),
318 .pixelFormat = pixmap->GetPixelFormat(),
319 .allocatorType = pixmap->GetAllocatorType(),
320 .pixelMapId = pixmap->GetId(),
321 .srcInfo = srcInfo
322 });
323 }
324
DrawToRSCanvas(RSCanvas & canvas,const RSRect & srcRect,const RSRect & dstRect,const BorderRadiusArray & radiusXY)325 void PixelMapImage::DrawToRSCanvas(
326 RSCanvas& canvas, const RSRect& srcRect, const RSRect& dstRect, const BorderRadiusArray& radiusXY)
327 {
328 auto pixmap = GetPixelMap();
329 auto dfxConfig = GetImageDfxConfig();
330 if (!pixmap || !pixmap->GetPixelMapSharedPtr()) {
331 TAG_LOGE(AceLogTag::ACE_IMAGE, "pixmap null, %{private}s-%{public}s", dfxConfig.imageSrc_.c_str(),
332 dfxConfig.ToStringWithoutSrc().c_str());
333 return;
334 }
335 #ifdef ENABLE_ROSEN_BACKEND
336 if (CheckIfNeedForStretching(canvas, srcRect, dstRect, radiusXY)) {
337 return;
338 }
339 const auto& config = GetPaintConfig();
340 ACE_SCOPED_TRACE("DrawToRSCanvas %s-[%d x %d]-[%s]", dfxConfig.ToStringWithSrc().c_str(), pixmap->GetWidth(),
341 pixmap->GetHeight(), dfxConfig.borderRadiusValue_.c_str());
342 RSBrush brush;
343 RSSamplingOptions options;
344 ImagePainterUtils::AddFilter(brush, options, config);
345 auto radii = ImagePainterUtils::ToRSRadius(radiusXY);
346 auto& recordingCanvas = static_cast<Rosen::ExtendRecordingCanvas&>(canvas);
347 std::vector<RSPoint> radius;
348 for (int ii = 0; ii < BORDER_RADIUS_ARRAY_SIZE; ii++) {
349 RSPoint point(radii[ii].GetX(), radii[ii].GetY());
350 radius.emplace_back(point);
351 }
352 recordingCanvas.ClipAdaptiveRoundRect(radius);
353 recordingCanvas.Scale(config.scaleX_, config.scaleY_);
354
355 RSPoint pointRadius[BORDER_RADIUS_ARRAY_SIZE] = {};
356 for (int i = 0; i < BORDER_RADIUS_ARRAY_SIZE; i++) {
357 pointRadius[i] = radius[i];
358 }
359 Rosen::Drawing::AdaptiveImageInfo rsImageInfo = { static_cast<int32_t>(config.imageFit_),
360 static_cast<int32_t>(config.imageRepeat_), { pointRadius[0], pointRadius[1], pointRadius[2], pointRadius[3] },
361 1.0, 0, 0, 0, static_cast<int32_t>(config.dynamicMode) };
362 rsImageInfo.fitMatrix = ToDrawingMatrix(config.imageMatrix_);
363 rsImageInfo.rotateDegree = CalculateRotateDegree(config.orientation_);
364 recordingCanvas.AttachBrush(brush);
365 if (SystemProperties::GetDebugPixelMapSaveEnabled()) {
366 TAG_LOGI(AceLogTag::ACE_IMAGE, "pixmap, %{public}s-[%{public}d * %{public}d]-[%{public}s][%{public}s]",
367 dfxConfig.ToStringWithSrc().c_str(), pixmap->GetWidth(), pixmap->GetHeight(),
368 dfxConfig.borderRadiusValue_.c_str(), GetDynamicModeString(config.dynamicMode).c_str());
369 pixmap->SavePixelMapToFile(dfxConfig.ToStringWithoutSrc() + "_ToRS_");
370 }
371 NotifyDrawCompletion(dfxConfig.ToStringWithSrc(), pixmap);
372 recordingCanvas.DrawPixelMapWithParm(pixmap->GetPixelMapSharedPtr(), rsImageInfo, options);
373 recordingCanvas.DetachBrush();
374 #endif
375 }
376
DrawRect(RSCanvas & canvas,const RSRect & dstRect)377 void PixelMapImage::DrawRect(RSCanvas& canvas, const RSRect& dstRect)
378 {
379 #ifndef USE_ROSEN_DRAWING
380 #ifdef ENABLE_ROSEN_BACKEND
381 auto rsCanvas = canvas.GetImpl<RSSkCanvas>();
382 CHECK_NULL_VOID(rsCanvas);
383 auto skCanvas = rsCanvas->ExportSkCanvas();
384 CHECK_NULL_VOID(skCanvas);
385 auto recordingCanvas = static_cast<OHOS::Rosen::RSRecordingCanvas*>(skCanvas);
386 CHECK_NULL_VOID(recordingCanvas);
387 SkPaint paint;
388 SkSamplingOptions option { SkFilterMode::kLinear, SkMipmapMode::kLinear };
389 SkRect dst { dstRect.GetLeft(), dstRect.GetTop(), dstRect.GetRight(), dstRect.GetBottom() };
390
391 CHECK_NULL_VOID(pixelMap_);
392 auto pixelMap = pixelMap_->GetPixelMapSharedPtr();
393 recordingCanvas->DrawPixelMapRect(pixelMap, dst, option, &paint);
394 #endif
395 #else
396 #ifdef ENABLE_ROSEN_BACKEND
397 auto& recordingCanvas = static_cast<Rosen::ExtendRecordingCanvas&>(canvas);
398 RSBrush brush;
399 RSSamplingOptions options { RSFilterMode::LINEAR, RSMipmapMode::LINEAR };
400 RSRect dst = RSRect(dstRect.GetLeft(), dstRect.GetTop(), dstRect.GetRight(), dstRect.GetBottom());
401
402 auto pixelMap = pixelMap_->GetPixelMapSharedPtr();
403 CHECK_NULL_VOID(pixelMap);
404 RSRect src = RSRect(0, 0, pixelMap->GetWidth(), pixelMap->GetHeight());
405 recordingCanvas.AttachBrush(brush);
406 recordingCanvas.DrawPixelMapRect(pixelMap, src, dst, options);
407 recordingCanvas.DetachBrush();
408 #endif
409 #endif
410 }
411
DrawRect(RSCanvas & canvas,const RSRect & srcRect,const RSRect & dstRect)412 void PixelMapImage::DrawRect(RSCanvas& canvas, const RSRect& srcRect, const RSRect& dstRect)
413 {
414 auto pixelMapPtr = GetPixelMap();
415 #ifndef USE_ROSEN_DRAWING
416 auto rsCanvas = canvas.GetImpl<RSSkCanvas>();
417 CHECK_NULL_VOID(rsCanvas);
418 auto skCanvas = rsCanvas->ExportSkCanvas();
419 CHECK_NULL_VOID(skCanvas);
420
421 auto recordingCanvas = static_cast<OHOS::Rosen::RSRecordingCanvas*>(skCanvas);
422 CHECK_NULL_VOID(recordingCanvas);
423 SkPaint paint;
424 SkSamplingOptions option;
425 SkRect dst { dstRect.GetLeft(), dstRect.GetTop(), dstRect.GetRight(), dstRect.GetBottom() };
426
427 CHECK_NULL_VOID(pixelMapPtr);
428 auto pixelMap = pixelMapPtr->GetPixelMapSharedPtr();
429 recordingCanvas->DrawPixelMapRect(pixelMap, dst, option, &paint);
430 #else
431 auto& recordingCanvas = static_cast<Rosen::ExtendRecordingCanvas&>(canvas);
432 RSBrush brush;
433 RSSamplingOptions options;
434 RSRect dst = RSRect(dstRect.GetLeft(), dstRect.GetTop(), dstRect.GetRight(), dstRect.GetBottom());
435
436 CHECK_NULL_VOID(pixelMapPtr);
437 auto pixelMap = pixelMapPtr->GetPixelMapSharedPtr();
438 CHECK_NULL_VOID(pixelMap);
439 RSRect src = RSRect(srcRect.GetLeft(), srcRect.GetTop(), srcRect.GetRight(), srcRect.GetBottom());
440 recordingCanvas.AttachBrush(brush);
441 recordingCanvas.DrawPixelMapRect(pixelMap, src, dst, options);
442 recordingCanvas.DetachBrush();
443 #endif
444 }
445
Cache(const std::string & key)446 void PixelMapImage::Cache(const std::string& key)
447 {
448 auto pipeline = PipelineBase::GetCurrentContext();
449 CHECK_NULL_VOID(pipeline);
450 auto cache = pipeline->GetImageCache();
451 CHECK_NULL_VOID(cache);
452 cache->CacheImageData(key, MakeRefPtr<PixmapData>(GetPixelMap()));
453 }
454
QueryFromCache(const std::string & key)455 RefPtr<CanvasImage> PixelMapImage::QueryFromCache(const std::string& key)
456 {
457 auto pipeline = PipelineBase::GetCurrentContext();
458 CHECK_NULL_RETURN(pipeline, nullptr);
459 auto cache = pipeline->GetImageCache();
460 CHECK_NULL_RETURN(cache, nullptr);
461 auto data = DynamicCast<PixmapData>(cache->GetCacheImageData(key));
462 CHECK_NULL_RETURN(data, nullptr);
463 return MakeRefPtr<PixelMapImage>(data->GetPixmap());
464 }
465
ToDrawingMatrix(const Matrix4 & matrix4)466 RSMatrix PixelMapImage::ToDrawingMatrix(const Matrix4& matrix4)
467 {
468 // Mappings from DrawingMatrix-index to input-index.
469 static const int32_t K_DRAWING_MATRIX_INDEX_TO_MATRIX4_INDEX[] = {
470 0,
471 4,
472 12,
473 1,
474 5,
475 13,
476 3,
477 7,
478 15,
479 };
480
481 RSMatrix matrix;
482 for (std::size_t i = 0; i < ArraySize(K_DRAWING_MATRIX_INDEX_TO_MATRIX4_INDEX); ++i) {
483 int32_t matrixIndex = K_DRAWING_MATRIX_INDEX_TO_MATRIX4_INDEX[i];
484 if (matrixIndex < matrix4.Count()) {
485 matrix.Set(static_cast<RSMatrix::Index>(i), matrix4[matrixIndex]);
486 } else {
487 matrix.Set(static_cast<RSMatrix::Index>(i), 0.0);
488 }
489 }
490 return matrix;
491 }
492 } // namespace OHOS::Ace::NG
493