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