• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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/pattern/canvas/canvas_paint_method.h"
17 
18 #include "base/log/ace_trace.h"
19 #include "core/components_ng/pattern/canvas/custom_paint_util.h"
20 
21 #ifndef ACE_UNITTEST
22 #ifdef USE_NEW_SKIA
23 #include "src/base/SkBase64.h"
24 #else
25 #include "include/utils/SkBase64.h"
26 #endif
27 #include "core/components/common/painter/rosen_decoration_painter.h"
28 #include "core/components/font/constants_converter.h"
29 #include "core/components/font/rosen_font_collection.h"
30 #include "core/components_ng/render/adapter/rosen_render_context.h"
31 #include "core/image/image_cache.h"
32 #endif
33 
34 namespace OHOS::Ace::NG {
35 constexpr Dimension DEFAULT_FONT_SIZE = 14.0_px;
CanvasPaintMethod(RefPtr<CanvasModifier> contentModifier,const RefPtr<FrameNode> & frameNode)36 CanvasPaintMethod::CanvasPaintMethod(RefPtr<CanvasModifier> contentModifier, const RefPtr<FrameNode>& frameNode)
37     : frameNode_(frameNode)
38 {
39     matrix_.Reset();
40     context_ = frameNode ? frameNode->GetContextRefPtr() : nullptr;
41     imageShadow_ = std::make_unique<Shadow>();
42     contentModifier_ = contentModifier;
43     // The default value of the font size in canvas is 14px.
44     SetFontSize(DEFAULT_FONT_SIZE);
45     if (apiVersion_ >= static_cast<int32_t>(PlatformVersion::VERSION_EIGHTEEN)) {
46         isPathChanged_ = false;
47         isPath2dChanged_ = false;
48     }
49 }
50 
PushTask(const TaskFunc & task)51 void CanvasPaintMethod::PushTask(const TaskFunc& task)
52 {
53     static constexpr uint32_t suggestSize = 100000;
54     tasks_.emplace_back(task);
55     if (tasks_.size() >= suggestSize && tasks_.size() % suggestSize == 0) {
56         TAG_LOGI(AceLogTag::ACE_CANVAS, "[%{public}s] Canvas task size: %{public}zu", customNodeName_.c_str(),
57             tasks_.size());
58     }
59     CHECK_EQUAL_VOID(needMarkDirty_, false);
60     needMarkDirty_ = false;
61     auto host = frameNode_.Upgrade();
62     CHECK_NULL_VOID(host);
63     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
64 }
65 
HasTask() const66 bool CanvasPaintMethod::HasTask() const
67 {
68     return !tasks_.empty();
69 }
70 
FlushTask()71 void CanvasPaintMethod::FlushTask()
72 {
73     ACE_SCOPED_TRACE("Canvas tasks count: %zu.", tasks_.size());
74     for (auto& task : tasks_) {
75         task(*this);
76     }
77     tasks_.clear();
78     needMarkDirty_ = true;
79 }
80 
UpdateContentModifier(PaintWrapper * paintWrapper)81 void CanvasPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
82 {
83     ACE_SCOPED_TRACE("Canvas[%d] CanvasPaintMethod::UpdateContentModifier", GetId());
84     auto host = frameNode_.Upgrade();
85     CHECK_NULL_VOID(host);
86     auto geometryNode = host->GetGeometryNode();
87     CHECK_NULL_VOID(geometryNode);
88     auto pixelGridRoundSize = geometryNode->GetPixelGridRoundSize();
89     lastLayoutSize_.SetSizeT(pixelGridRoundSize);
90     auto recordingCanvas = std::static_pointer_cast<RSRecordingCanvas>(rsCanvas_);
91     CHECK_NULL_VOID(recordingCanvas);
92     SetCustomTextType();
93 
94     if (!HasTask()) {
95         return;
96     }
97 
98     FireOnModifierUpdateFunc();
99     recordingCanvas->Scale(1.0, 1.0);
100     FlushTask();
101     if (!contentModifier_) {
102         ACE_SCOPED_TRACE("Canvas[%d] contentModifier is NULL", GetId());
103         TAG_LOGE(AceLogTag::ACE_CANVAS, "Canvas[%{public}d] contentModifier is NULL", GetId());
104         return;
105     }
106     contentModifier_->MarkModifierDirty();
107 }
108 
UpdateRecordingCanvas(float width,float height)109 void CanvasPaintMethod::UpdateRecordingCanvas(float width, float height)
110 {
111     ACE_SCOPED_TRACE("Canvas[%d] CanvasPaintMethod::UpdateRecordingCanvas[%f, %f]", GetId(), width, height);
112     rsCanvas_ = std::make_shared<RSRecordingCanvas>(width, height);
113     contentModifier_->UpdateCanvas(std::static_pointer_cast<RSRecordingCanvas>(rsCanvas_));
114     CHECK_NULL_VOID(rsCanvas_);
115     rsCanvas_->Save();
116     FireRSCanvasCallback(width, height);
117     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_THIRTEEN)) {
118         ResetStates();
119     }
120     needMarkDirty_ = true;
121 }
122 
SetCustomTextType()123 void CanvasPaintMethod::SetCustomTextType()
124 {
125     auto recordingCanvas = std::static_pointer_cast<RSRecordingCanvas>(rsCanvas_);
126     CHECK_NULL_VOID(recordingCanvas);
127     auto context = context_.Upgrade();
128     CHECK_NULL_VOID(context);
129     auto fontManager = context->GetFontManager();
130     CHECK_NULL_VOID(fontManager);
131     recordingCanvas->SetIsCustomTextType(fontManager->IsDefaultFontChanged());
132 }
133 
DrawPixelMap(RefPtr<PixelMap> pixelMap,const Ace::CanvasImage & canvasImage)134 void CanvasPaintMethod::DrawPixelMap(RefPtr<PixelMap> pixelMap, const Ace::CanvasImage& canvasImage)
135 {
136 #ifndef ACE_UNITTEST
137     InitImagePaint(nullptr, &imageBrush_, sampleOptions_);
138     imageBrush_.SetAntiAlias(antiAlias_);
139     RSBrush compositeOperationpBrush;
140     InitPaintBlend(compositeOperationpBrush);
141     RSSaveLayerOps layerOps(nullptr, &compositeOperationpBrush);
142     if (state_.globalState.GetType() != CompositeOperation::SOURCE_OVER) {
143         rsCanvas_->SaveLayer(layerOps);
144     }
145 
146     if (state_.globalState.HasGlobalAlpha()) {
147         imageBrush_.SetAlphaF(state_.globalState.GetAlpha());
148     }
149 
150     if (HasShadow()) {
151         auto tempPixelMap = pixelMap->GetPixelMapSharedPtr();
152         CHECK_NULL_VOID(tempPixelMap);
153         RSRect rec;
154         if (canvasImage.flag == DrawImageType::THREE_PARAMS) {
155             rec = RSRect(canvasImage.dx, canvasImage.dy,
156                 canvasImage.dx + tempPixelMap->GetWidth(), canvasImage.dy + tempPixelMap->GetHeight());
157         } else {
158             rec = RSRect(canvasImage.dx, canvasImage.dy,
159                 canvasImage.dx + canvasImage.dWidth, canvasImage.dy + canvasImage.dHeight);
160         }
161         RSPath path;
162         path.AddRect(rec);
163         PaintImageShadow(path, state_.shadow, &imageBrush_, nullptr,
164             (state_.globalState.GetType() != CompositeOperation::SOURCE_OVER) ? &layerOps : nullptr);
165     }
166     DrawPixelMapInternal(pixelMap, canvasImage);
167     if (state_.globalState.GetType() != CompositeOperation::SOURCE_OVER) {
168         rsCanvas_->Restore();
169     }
170 #endif
171 }
172 
DrawPixelMapInternal(RefPtr<PixelMap> pixelMap,const Ace::CanvasImage & canvasImage)173 void CanvasPaintMethod::DrawPixelMapInternal(RefPtr<PixelMap> pixelMap, const Ace::CanvasImage& canvasImage)
174 {
175 #ifndef ACE_UNITTEST
176     const std::shared_ptr<Media::PixelMap> tempPixelMap = pixelMap->GetPixelMapSharedPtr();
177     CHECK_NULL_VOID(tempPixelMap);
178     RSRect srcRect;
179     RSRect dstRect;
180     CalculatePixelMapRect(canvasImage, tempPixelMap->GetWidth(), tempPixelMap->GetHeight(), srcRect, dstRect);
181     auto recordingCanvas = std::static_pointer_cast<RSRecordingCanvas>(rsCanvas_);
182     CHECK_NULL_VOID(recordingCanvas);
183     recordingCanvas->AttachBrush(imageBrush_);
184     recordingCanvas->DrawPixelMapRect(tempPixelMap, srcRect, dstRect, sampleOptions_);
185     recordingCanvas->DetachBrush();
186 #endif
187 }
188 
CalculatePixelMapRect(const Ace::CanvasImage & canvasImage,int32_t width,int32_t height,RSRect & srcRect,RSRect & dstRect)189 void CanvasPaintMethod::CalculatePixelMapRect(
190     const Ace::CanvasImage& canvasImage, int32_t width, int32_t height, RSRect& srcRect, RSRect& dstRect)
191 {
192     switch (canvasImage.flag) {
193         case DrawImageType::THREE_PARAMS: {
194             srcRect = RSRect(0, 0, width, height);
195             dstRect = RSRect(canvasImage.dx, canvasImage.dy, canvasImage.dx + width, canvasImage.dy + height);
196             break;
197         }
198         case DrawImageType::FIVE_PARAMS: {
199             srcRect = RSRect(0, 0, width, height);
200             dstRect = RSRect(canvasImage.dx, canvasImage.dy, canvasImage.dx + canvasImage.dWidth,
201                 canvasImage.dy + canvasImage.dHeight);
202             break;
203         }
204         case DrawImageType::NINE_PARAMS: {
205             srcRect = RSRect(canvasImage.sx, canvasImage.sy, canvasImage.sx + canvasImage.sWidth,
206                 canvasImage.sy + canvasImage.sHeight);
207             dstRect = RSRect(canvasImage.dx, canvasImage.dy, canvasImage.dx + canvasImage.dWidth,
208                 canvasImage.dy + canvasImage.dHeight);
209             break;
210         }
211         default:
212             break;
213     }
214 }
215 
CloseImageBitmap(const std::string & src)216 void CanvasPaintMethod::CloseImageBitmap(const std::string& src)
217 {
218 #ifndef ACE_UNITTEST
219     CHECK_NULL_VOID(imageCache_);
220     auto cacheImage = imageCache_->GetCacheImage(src);
221     CHECK_NULL_VOID(cacheImage);
222     CHECK_NULL_VOID(cacheImage->imagePtr);
223     imageCache_->ClearCacheImage(src);
224 #endif
225 }
226 
GetImageData(double left,double top,double width,double height)227 std::unique_ptr<Ace::ImageData> CanvasPaintMethod::GetImageData(double left, double top, double width, double height)
228 {
229     auto host = frameNode_.Upgrade();
230     CHECK_NULL_RETURN(host, nullptr);
231     auto renderContext = host->GetRenderContext();
232     CHECK_NULL_RETURN(renderContext, nullptr);
233     double dirtyWidth = std::abs(width);
234     double dirtyHeight = std::abs(height);
235     double scaledLeft = left + std::min(width, 0.0);
236     double scaledTop = top + std::min(height, 0.0);
237 
238     // copy the bitmap to tempCanvas
239     RSBitmap currentBitmap;
240     if (!DrawBitmap(renderContext, currentBitmap)) {
241         return nullptr;
242     }
243 
244     RSBitmapFormat format { RSColorType::COLORTYPE_BGRA_8888, RSAlphaType::ALPHATYPE_PREMUL };
245     RSBitmap tempCache;
246     tempCache.Build(dirtyWidth, dirtyHeight, format);
247     int32_t size = dirtyWidth * dirtyHeight;
248 
249     RSCanvas tempCanvas;
250     tempCanvas.Bind(tempCache);
251     auto srcRect = RSRect(scaledLeft, scaledTop, dirtyWidth + scaledLeft, dirtyHeight + scaledTop);
252     auto dstRect = RSRect(0.0, 0.0, dirtyWidth, dirtyHeight);
253     RSImage rsImage;
254     rsImage.BuildFromBitmap(currentBitmap);
255     tempCanvas.DrawImageRect(rsImage, srcRect, dstRect, RSSamplingOptions());
256     const uint8_t* pixels = static_cast<const uint8_t*>(tempCache.GetPixels());
257     CHECK_NULL_RETURN(pixels, nullptr);
258     std::unique_ptr<Ace::ImageData> imageData = std::make_unique<Ace::ImageData>();
259     imageData->dirtyWidth = dirtyWidth;
260     imageData->dirtyHeight = dirtyHeight;
261     // a pixel include 4 data(blue, green, red, alpha)
262     for (int i = 0; i < size * 4; i += 4) {
263         auto blue = pixels[i];
264         auto green = pixels[i + 1];
265         auto red = pixels[i + 2];
266         auto alpha = pixels[i + 3];
267         imageData->data.emplace_back(Color::FromARGB(alpha, red, green, blue).GetValue());
268     }
269     return imageData;
270 }
271 
GetImageData(const std::shared_ptr<Ace::ImageData> & imageData)272 void CanvasPaintMethod::GetImageData(const std::shared_ptr<Ace::ImageData>& imageData)
273 {
274 #ifndef ACE_UNITTEST
275     auto host = frameNode_.Upgrade();
276     CHECK_NULL_VOID(host);
277     auto renderContext = host->GetRenderContext();
278     auto rosenRenderContext = AceType::DynamicCast<RosenRenderContext>(renderContext);
279     CHECK_NULL_VOID(rosenRenderContext);
280     CHECK_NULL_VOID(imageData);
281     auto dirtyWidth = std::abs(imageData->dirtyWidth);
282     auto dirtyHeight = std::abs(imageData->dirtyHeight);
283     auto scaledLeft = imageData->dirtyX + std::min(imageData->dirtyWidth, 0);
284     auto scaledTop = imageData->dirtyY + std::min(imageData->dirtyHeight, 0);
285 
286     auto recordingCanvas = std::static_pointer_cast<RSRecordingCanvas>(rsCanvas_);
287     CHECK_NULL_VOID(recordingCanvas);
288     auto drawCmdList = recordingCanvas->GetDrawCmdList();
289     auto rect = RSRect(scaledLeft, scaledTop, dirtyWidth + scaledLeft, dirtyHeight + scaledTop);
290     auto pixelMap = imageData->pixelMap;
291     CHECK_NULL_VOID(pixelMap);
292     auto sharedPixelMap = pixelMap->GetPixelMapSharedPtr();
293     if (rosenRenderContext->GetPixelMap(sharedPixelMap, drawCmdList, &rect) || !drawCmdList || drawCmdList->IsEmpty()) {
294         return;
295     }
296     RSBitmap bitmap;
297     RSImageInfo info = RSImageInfo(rect.GetWidth(), rect.GetHeight(),
298         RSColorType::COLORTYPE_RGBA_8888, RSAlphaType::ALPHATYPE_PREMUL);
299     bitmap.InstallPixels(info, pixelMap->GetWritablePixels(), pixelMap->GetRowBytes());
300     RSCanvas canvas;
301     canvas.Bind(bitmap);
302     canvas.Translate(-rect.GetLeft(), -rect.GetTop());
303     drawCmdList->Playback(canvas, &rect);
304 #endif
305 }
306 
307 #ifdef PIXEL_MAP_SUPPORTED
TransferFromImageBitmap(const RefPtr<PixelMap> & pixelMap)308 void CanvasPaintMethod::TransferFromImageBitmap(const RefPtr<PixelMap>& pixelMap)
309 {
310     CHECK_NULL_VOID(pixelMap);
311     InitImagePaint(nullptr, &imageBrush_, sampleOptions_);
312     auto recordingCanvas = std::static_pointer_cast<RSRecordingCanvas>(rsCanvas_);
313     CHECK_NULL_VOID(recordingCanvas);
314     const std::shared_ptr<Media::PixelMap> tempPixelMap = pixelMap->GetPixelMapSharedPtr();
315     CHECK_NULL_VOID(tempPixelMap);
316     RSRect srcRect = RSRect(0, 0, tempPixelMap->GetWidth(), tempPixelMap->GetHeight());
317     RSRect dstRect = RSRect(0, 0, tempPixelMap->GetWidth(), tempPixelMap->GetHeight());
318     recordingCanvas->AttachBrush(imageBrush_);
319     recordingCanvas->DrawPixelMapRect(tempPixelMap, srcRect, dstRect, sampleOptions_);
320     recordingCanvas->DetachBrush();
321 }
322 #endif
323 
ToDataURL(const std::string & type,const double quality)324 std::string CanvasPaintMethod::ToDataURL(const std::string& type, const double quality)
325 {
326 #ifndef ACE_UNITTEST
327     auto host = frameNode_.Upgrade();
328     CHECK_NULL_RETURN(host, UNSUPPORTED);
329     auto renderContext = host->GetRenderContext();
330     CHECK_NULL_RETURN(renderContext, UNSUPPORTED);
331     std::string mimeType = GetMimeType(type);
332     // Quality needs to be between 0.0 and 1.0 for MimeType jpeg and webp
333     double qua = GetQuality(mimeType, quality);
334     double width = lastLayoutSize_.Width();
335     double height = lastLayoutSize_.Height();
336     auto imageInfo = SkImageInfo::Make(width, height, SkColorType::kBGRA_8888_SkColorType,
337         (mimeType == IMAGE_JPEG) ? SkAlphaType::kOpaque_SkAlphaType : SkAlphaType::kUnpremul_SkAlphaType);
338     RSBitmapFormat format { RSColorType::COLORTYPE_BGRA_8888,
339         (mimeType == IMAGE_JPEG) ? RSAlphaType::ALPHATYPE_OPAQUE : RSAlphaType::ALPHATYPE_UNPREMUL };
340     RSBitmap tempCache;
341     tempCache.Build(width, height, format);
342     RSBitmap currentBitmap;
343     if (!DrawBitmap(renderContext, currentBitmap)) {
344         return UNSUPPORTED;
345     }
346     bool success = currentBitmap.GetPixmap().ScalePixels(
347         tempCache.GetPixmap(), RSSamplingOptions(RSCubicResampler { 1 / 3.0f, 1 / 3.0f }));
348     CHECK_NULL_RETURN(success, UNSUPPORTED);
349     RSPixmap rsSrc = tempCache.GetPixmap();
350     SkPixmap src { imageInfo, rsSrc.GetAddr(), rsSrc.GetRowBytes() };
351     SkDynamicMemoryWStream dst;
352     success = EncodeImage(mimeType, qua, src, dst);
353     CHECK_NULL_RETURN(success, UNSUPPORTED);
354     auto result = dst.detachAsData();
355     CHECK_NULL_RETURN(result, UNSUPPORTED);
356     size_t len = SkBase64::Encode(result->data(), result->size(), nullptr);
357     if (len > MAX_LENGTH) {
358         return UNSUPPORTED;
359     }
360     SkString info(len);
361 #ifdef USE_NEW_SKIA
362     SkBase64::Encode(result->data(), result->size(), info.data());
363 #else
364     SkBase64::Encode(result->data(), result->size(), info.writable_str());
365 #endif
366     return std::string(URL_PREFIX).append(mimeType).append(URL_SYMBOL).append(info.c_str());
367 #else
368     return UNSUPPORTED;
369 #endif
370 }
371 
DrawBitmap(RefPtr<RenderContext> renderContext,RSBitmap & currentBitmap)372 bool CanvasPaintMethod::DrawBitmap(RefPtr<RenderContext> renderContext, RSBitmap& currentBitmap)
373 {
374 #ifndef ACE_UNITTEST
375     auto recordingCanvas = std::static_pointer_cast<RSRecordingCanvas>(rsCanvas_);
376     CHECK_NULL_RETURN(recordingCanvas, false);
377     auto rosenRenderContext = AceType::DynamicCast<RosenRenderContext>(renderContext);
378     CHECK_NULL_RETURN(rosenRenderContext, false);
379     auto drawCmdList = recordingCanvas->GetDrawCmdList();
380     CHECK_NULL_RETURN(drawCmdList, false);
381     bool res = rosenRenderContext->GetBitmap(currentBitmap, drawCmdList);
382     if (res) {
383         return true;
384     }
385     if (drawCmdList->IsEmpty()) {
386         return false;
387     }
388     currentBitmap.Free();
389     RSBitmapFormat format;
390     if (apiVersion_ >= static_cast<int32_t>(PlatformVersion::VERSION_FOURTEEN)) {
391         format = { RSColorType::COLORTYPE_BGRA_8888, RSAlphaType::ALPHATYPE_PREMUL };
392     } else {
393         format = { RSColorType::COLORTYPE_BGRA_8888, RSAlphaType::ALPHATYPE_OPAQUE };
394     }
395     currentBitmap.Build(lastLayoutSize_.Width(), lastLayoutSize_.Height(), format);
396 
397     RSCanvas currentCanvas;
398     currentCanvas.Bind(currentBitmap);
399     drawCmdList->Playback(currentCanvas);
400     return true;
401 #else
402     return false;
403 #endif
404 }
405 
GetJsonData(const std::string & path)406 std::string CanvasPaintMethod::GetJsonData(const std::string& path)
407 {
408 #ifndef ACE_UNITTEST
409     AssetImageLoader imageLoader;
410     return imageLoader.LoadJsonData(path, context_);
411 #else
412     return "";
413 #endif
414 }
415 
Reset()416 void CanvasPaintMethod::Reset()
417 {
418     ResetStates();
419     CHECK_NULL_VOID(rsCanvas_);
420     if (rsCanvas_->GetSaveCount() >= DEFAULT_SAVE_COUNT) {
421         rsCanvas_->RestoreToCount(0);
422     }
423     rsCanvas_->ResetMatrix();
424     rsCanvas_->Clear(RSColor::COLOR_TRANSPARENT);
425     rsCanvas_->Save();
426 }
427 
GetId() const428 int32_t CanvasPaintMethod::GetId() const
429 {
430     auto host = frameNode_.Upgrade();
431     CHECK_NULL_RETURN(host, -1);
432     return host->GetId();
433 }
434 
GetSystemDirection()435 TextDirection CanvasPaintMethod::GetSystemDirection()
436 {
437     auto host = frameNode_.Upgrade();
438     CHECK_NULL_RETURN(host, TextDirection::AUTO);
439     auto layoutProperty = host->GetLayoutProperty<LayoutProperty>();
440     CHECK_NULL_RETURN(host, TextDirection::AUTO);
441     auto direction = layoutProperty->GetLayoutDirection();
442     if (direction == TextDirection::AUTO) {
443         direction = AceApplicationInfo::GetInstance().IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR;
444     }
445     return direction;
446 }
447 
448 #ifndef ACE_UNITTEST
ConvertTxtStyle(const TextStyle & textStyle,Rosen::TextStyle & txtStyle)449 void CanvasPaintMethod::ConvertTxtStyle(const TextStyle& textStyle, Rosen::TextStyle& txtStyle)
450 {
451     Constants::ConvertTxtStyle(textStyle, context_, txtStyle);
452 }
453 #endif
454 
GetDumpInfo()455 std::string CanvasPaintMethod::GetDumpInfo()
456 {
457     CHECK_NULL_RETURN(rsCanvas_, "Canvas is nullptr");
458     // translate
459     std::string trans = "TRANS: " + std::to_string(rsCanvas_->GetTotalMatrix().Get(RSMatrix::TRANS_X)) + ", " +
460                         std::to_string(rsCanvas_->GetTotalMatrix().Get(RSMatrix::TRANS_Y)) + "; ";
461     // scale
462     std::string scale = "SCALE: " + std::to_string(rsCanvas_->GetTotalMatrix().Get(RSMatrix::SCALE_X)) + ", " +
463                         std::to_string(rsCanvas_->GetTotalMatrix().Get(RSMatrix::SCALE_Y)) + "; ";
464     // rotate
465     std::string skew = "SKEW: " + std::to_string(rsCanvas_->GetTotalMatrix().Get(RSMatrix::SKEW_X)) + ", " +
466                        std::to_string(rsCanvas_->GetTotalMatrix().Get(RSMatrix::SKEW_Y)) + "; ";
467     return trans.append(scale).append(skew);
468 }
469 
SetHostCustomNodeName()470 void CanvasPaintMethod::SetHostCustomNodeName()
471 {
472     auto frameNode = frameNode_.Upgrade();
473     CHECK_NULL_VOID(frameNode);
474     auto customNode = frameNode->GetParentCustomNode();
475     CHECK_NULL_VOID(customNode);
476     customNodeName_ = customNode->GetJSViewName();
477 }
478 
GetSimplifyDumpInfo(std::unique_ptr<JsonValue> & json)479 void CanvasPaintMethod::GetSimplifyDumpInfo(std::unique_ptr<JsonValue>& json)
480 {
481     CHECK_NULL_VOID(rsCanvas_);
482     auto matrix = rsCanvas_->GetTotalMatrix();
483     json->Put("Trans",
484         (std::to_string(matrix.Get(RSMatrix::TRANS_X)) + "," + std::to_string(matrix.Get(RSMatrix::TRANS_Y))).c_str());
485     json->Put("Scale",
486         (std::to_string(matrix.Get(RSMatrix::SCALE_X)) + "," + std::to_string(matrix.Get(RSMatrix::SCALE_Y))).c_str());
487     json->Put("Skew",
488         (std::to_string(matrix.Get(RSMatrix::SKEW_X)) + "," + std::to_string(matrix.Get(RSMatrix::SKEW_Y))).c_str());
489 }
490 } // namespace OHOS::Ace::NG
491