1 /*
2  * Copyright (c) 2023-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 "bridge/declarative_frontend/jsview/models/canvas/canvas_rendering_context_2d_model_impl.h"
17 
18 #include <type_traits>
19 
20 #include "base/image/pixel_map.h"
21 #include "core/common/container.h"
22 #include "core/components/common/properties/paint_state.h"
23 #include "core/components/custom_paint/custom_paint_component.h"
24 #include "core/components/custom_paint/offscreen_canvas.h"
25 #include "core/pipeline/pipeline_context.h"
26 
27 #ifdef PIXEL_MAP_SUPPORTED
28 #include "pixel_map.h"
29 #endif
30 
31 namespace OHOS::Ace::Framework {
SetPattern(RefPtr<AceType> pattern)32 void CanvasRenderingContext2DModelImpl::SetPattern(RefPtr<AceType> pattern)
33 {
34     pattern_ = AceType::DynamicCast<CanvasTaskPool>(pattern);
35 }
36 
SetFillText(const PaintState & state,const FillTextInfo & fillTextInfo)37 void CanvasRenderingContext2DModelImpl::SetFillText(const PaintState& state, const FillTextInfo& fillTextInfo)
38 {
39     CHECK_NULL_VOID(pattern_);
40     pattern_->FillText(fillTextInfo.text, Offset(fillTextInfo.x, fillTextInfo.y));
41 }
42 
SetStrokeText(const PaintState & state,const FillTextInfo & fillTextInfo)43 void CanvasRenderingContext2DModelImpl::SetStrokeText(const PaintState& state, const FillTextInfo& fillTextInfo)
44 {
45     CHECK_NULL_VOID(pattern_);
46     pattern_->StrokeText(fillTextInfo.text, Offset(fillTextInfo.x, fillTextInfo.y));
47 }
48 
SetAntiAlias(bool anti)49 void CanvasRenderingContext2DModelImpl::SetAntiAlias(bool anti)
50 {
51     CHECK_NULL_VOID(pattern_);
52     pattern_->SetAntiAlias(anti);
53 }
54 
SetFontWeight(const FontWeight & weight)55 void CanvasRenderingContext2DModelImpl::SetFontWeight(const FontWeight& weight)
56 {
57     CHECK_NULL_VOID(pattern_);
58     pattern_->UpdateFontWeight(weight);
59 }
60 
SetFontStyle(const FontStyle & fontStyle)61 void CanvasRenderingContext2DModelImpl::SetFontStyle(const FontStyle& fontStyle)
62 {
63     CHECK_NULL_VOID(pattern_);
64     pattern_->UpdateFontStyle(fontStyle);
65 }
66 
SetFontFamilies(const std::vector<std::string> & families)67 void CanvasRenderingContext2DModelImpl::SetFontFamilies(const std::vector<std::string>& families)
68 {
69     CHECK_NULL_VOID(pattern_);
70     pattern_->UpdateFontFamilies(families);
71 }
72 
SetFontSize(const Dimension & size)73 void CanvasRenderingContext2DModelImpl::SetFontSize(const Dimension& size)
74 {
75     CHECK_NULL_VOID(pattern_);
76     pattern_->UpdateFontSize(size);
77 }
78 
GetLineDash()79 std::vector<double> CanvasRenderingContext2DModelImpl::GetLineDash()
80 {
81     return pattern_ ? pattern_->GetLineDash().lineDash : std::vector<double> {};
82 }
83 
SetFillGradient(const std::shared_ptr<Ace::Gradient> & gradient)84 void CanvasRenderingContext2DModelImpl::SetFillGradient(const std::shared_ptr<Ace::Gradient>& gradient)
85 {
86     CHECK_NULL_VOID(pattern_);
87     pattern_->UpdateFillGradient(*gradient);
88 }
89 
SetFillPattern(const std::shared_ptr<Ace::Pattern> & pattern)90 void CanvasRenderingContext2DModelImpl::SetFillPattern(const std::shared_ptr<Ace::Pattern>& pattern)
91 {
92     CHECK_NULL_VOID(pattern_);
93     pattern_->UpdateFillPattern(*(pattern.get()));
94 }
95 
SetFillColor(const Color & color,bool colorFlag)96 void CanvasRenderingContext2DModelImpl::SetFillColor(const Color& color, bool colorFlag)
97 {
98     if (pattern_ && colorFlag) {
99         pattern_->UpdateFillColor(color);
100     }
101 }
102 
SetStrokeGradient(const std::shared_ptr<Ace::Gradient> & gradient)103 void CanvasRenderingContext2DModelImpl::SetStrokeGradient(const std::shared_ptr<Ace::Gradient>& gradient)
104 {
105     CHECK_NULL_VOID(pattern_);
106     pattern_->UpdateStrokeGradient(*gradient);
107 }
108 
SetStrokePattern(const std::shared_ptr<Ace::Pattern> & pattern)109 void CanvasRenderingContext2DModelImpl::SetStrokePattern(const std::shared_ptr<Ace::Pattern>& pattern)
110 {
111     CHECK_NULL_VOID(pattern_);
112     pattern_->UpdateStrokePattern(*(pattern.get()));
113 }
114 
SetStrokeColor(const Color & color,bool colorFlag)115 void CanvasRenderingContext2DModelImpl::SetStrokeColor(const Color& color, bool colorFlag)
116 {
117     if (pattern_ && colorFlag) {
118         pattern_->UpdateStrokeColor(color);
119     }
120 }
121 
DrawImage(const ImageInfo & imageInfo)122 void CanvasRenderingContext2DModelImpl::DrawImage(const ImageInfo& imageInfo)
123 {
124     CHECK_NULL_VOID(pattern_);
125     if (imageInfo.isImage) {
126         pattern_->DrawImage(imageInfo.image, imageInfo.imgWidth, imageInfo.imgHeight);
127         return;
128     }
129     pattern_->DrawPixelMap(imageInfo.pixelMap, imageInfo.image);
130 }
131 
PutImageData(const ImageData & imageData)132 void CanvasRenderingContext2DModelImpl::PutImageData(const ImageData& imageData)
133 {
134     CHECK_NULL_VOID(pattern_);
135     pattern_->PutImageData(imageData);
136 }
137 
GetImageData(const ImageSize & imageSize)138 std::unique_ptr<ImageData> CanvasRenderingContext2DModelImpl::GetImageData(const ImageSize& imageSize)
139 {
140     return pattern_ ? pattern_->GetImageData(imageSize.left, imageSize.top, imageSize.width, imageSize.height)
141                     : nullptr;
142 }
143 
DrawPixelMap(const ImageInfo & imageInfo)144 void CanvasRenderingContext2DModelImpl::DrawPixelMap(const ImageInfo& imageInfo)
145 {
146     CHECK_NULL_VOID(pattern_);
147     pattern_->DrawPixelMap(imageInfo.pixelMap, imageInfo.image);
148 }
149 
GetJsonData(const std::string & path)150 std::string CanvasRenderingContext2DModelImpl::GetJsonData(const std::string& path)
151 {
152     return pattern_ ? pattern_->GetJsonData(path) : "";
153 }
154 
ToDataURL(const std::string & dataUrl,double quality)155 std::string CanvasRenderingContext2DModelImpl::ToDataURL(const std::string& dataUrl, double quality)
156 {
157     return pattern_ ? pattern_->ToDataURL(dataUrl + "," + std::to_string(quality)) : "";
158 }
159 
SetLineCap(const LineCapStyle & lineCap)160 void CanvasRenderingContext2DModelImpl::SetLineCap(const LineCapStyle& lineCap)
161 {
162     CHECK_NULL_VOID(pattern_);
163     pattern_->UpdateLineCap(lineCap);
164 }
165 
SetLineJoin(const LineJoinStyle & lineJoin)166 void CanvasRenderingContext2DModelImpl::SetLineJoin(const LineJoinStyle& lineJoin)
167 {
168     CHECK_NULL_VOID(pattern_);
169     pattern_->UpdateLineJoin(lineJoin);
170 }
171 
SetMiterLimit(double limit)172 void CanvasRenderingContext2DModelImpl::SetMiterLimit(double limit)
173 {
174     CHECK_NULL_VOID(pattern_);
175     pattern_->UpdateMiterLimit(limit);
176 }
177 
SetLineWidth(double lineWidth)178 void CanvasRenderingContext2DModelImpl::SetLineWidth(double lineWidth)
179 {
180     CHECK_NULL_VOID(pattern_);
181     pattern_->UpdateLineWidth(lineWidth);
182 }
183 
SetGlobalAlpha(double alpha)184 void CanvasRenderingContext2DModelImpl::SetGlobalAlpha(double alpha)
185 {
186     CHECK_NULL_VOID(pattern_);
187     pattern_->UpdateGlobalAlpha(alpha);
188 }
189 
SetCompositeType(const CompositeOperation & type)190 void CanvasRenderingContext2DModelImpl::SetCompositeType(const CompositeOperation& type)
191 {
192     CHECK_NULL_VOID(pattern_);
193     pattern_->UpdateCompositeOperation(type);
194 }
195 
SetLineDashOffset(double lineDashOffset)196 void CanvasRenderingContext2DModelImpl::SetLineDashOffset(double lineDashOffset)
197 {
198     CHECK_NULL_VOID(pattern_);
199     pattern_->UpdateLineDashOffset(lineDashOffset);
200 }
201 
SetShadowBlur(double blur)202 void CanvasRenderingContext2DModelImpl::SetShadowBlur(double blur)
203 {
204     CHECK_NULL_VOID(pattern_);
205     pattern_->UpdateShadowBlur(blur);
206 }
207 
SetShadowColor(const Color & color)208 void CanvasRenderingContext2DModelImpl::SetShadowColor(const Color& color)
209 {
210     CHECK_NULL_VOID(pattern_);
211     pattern_->UpdateShadowColor(color);
212 }
213 
SetShadowOffsetX(double offsetX)214 void CanvasRenderingContext2DModelImpl::SetShadowOffsetX(double offsetX)
215 {
216     CHECK_NULL_VOID(pattern_);
217     pattern_->UpdateShadowOffsetX(offsetX);
218 }
219 
SetShadowOffsetY(double offsetY)220 void CanvasRenderingContext2DModelImpl::SetShadowOffsetY(double offsetY)
221 {
222     CHECK_NULL_VOID(pattern_);
223     pattern_->UpdateShadowOffsetY(offsetY);
224 }
225 
SetSmoothingEnabled(bool enabled)226 void CanvasRenderingContext2DModelImpl::SetSmoothingEnabled(bool enabled)
227 {
228     CHECK_NULL_VOID(pattern_);
229     pattern_->UpdateSmoothingEnabled(enabled);
230 }
231 
SetSmoothingQuality(const std::string & quality)232 void CanvasRenderingContext2DModelImpl::SetSmoothingQuality(const std::string& quality)
233 {
234     CHECK_NULL_VOID(pattern_);
235     pattern_->UpdateSmoothingQuality(quality);
236 }
237 
MoveTo(double x,double y)238 void CanvasRenderingContext2DModelImpl::MoveTo(double x, double y)
239 {
240     CHECK_NULL_VOID(pattern_);
241     pattern_->MoveTo(x, y);
242 }
243 
LineTo(double x,double y)244 void CanvasRenderingContext2DModelImpl::LineTo(double x, double y)
245 {
246     CHECK_NULL_VOID(pattern_);
247     pattern_->LineTo(x, y);
248 }
249 
BezierCurveTo(const BezierCurveParam & param)250 void CanvasRenderingContext2DModelImpl::BezierCurveTo(const BezierCurveParam& param)
251 {
252     CHECK_NULL_VOID(pattern_);
253     pattern_->BezierCurveTo(param);
254 }
255 
QuadraticCurveTo(const QuadraticCurveParam & param)256 void CanvasRenderingContext2DModelImpl::QuadraticCurveTo(const QuadraticCurveParam& param)
257 {
258     CHECK_NULL_VOID(pattern_);
259     pattern_->QuadraticCurveTo(param);
260 }
261 
ArcTo(const ArcToParam & param)262 void CanvasRenderingContext2DModelImpl::ArcTo(const ArcToParam& param)
263 {
264     CHECK_NULL_VOID(pattern_);
265     pattern_->ArcTo(param);
266 }
267 
Arc(const ArcParam & param)268 void CanvasRenderingContext2DModelImpl::Arc(const ArcParam& param)
269 {
270     CHECK_NULL_VOID(pattern_);
271     pattern_->Arc(param);
272 }
273 
Ellipse(const EllipseParam & param)274 void CanvasRenderingContext2DModelImpl::Ellipse(const EllipseParam& param)
275 {
276     CHECK_NULL_VOID(pattern_);
277     pattern_->Ellipse(param);
278 }
279 
SetFillRuleForPath(const CanvasFillRule & fillRule)280 void CanvasRenderingContext2DModelImpl::SetFillRuleForPath(const CanvasFillRule& fillRule)
281 {
282     CHECK_NULL_VOID(pattern_);
283     pattern_->UpdateFillRuleForPath(fillRule);
284     pattern_->Fill();
285 }
286 
SetFillRuleForPath2D(const CanvasFillRule & fillRule,const RefPtr<CanvasPath2D> & path)287 void CanvasRenderingContext2DModelImpl::SetFillRuleForPath2D(
288     const CanvasFillRule& fillRule, const RefPtr<CanvasPath2D>& path)
289 {
290     CHECK_NULL_VOID(pattern_);
291     pattern_->UpdateFillRuleForPath2D(fillRule);
292     pattern_->Fill(path);
293 }
294 
SetStrokeRuleForPath2D(const CanvasFillRule & fillRule,const RefPtr<CanvasPath2D> & path)295 void CanvasRenderingContext2DModelImpl::SetStrokeRuleForPath2D(
296     const CanvasFillRule& fillRule, const RefPtr<CanvasPath2D>& path)
297 {
298     CHECK_NULL_VOID(pattern_);
299     pattern_->UpdateFillRuleForPath2D(fillRule);
300     pattern_->Stroke(path);
301 }
302 
SetStrokeRuleForPath(const CanvasFillRule & fillRule)303 void CanvasRenderingContext2DModelImpl::SetStrokeRuleForPath(const CanvasFillRule& fillRule)
304 {
305     CHECK_NULL_VOID(pattern_);
306     pattern_->UpdateFillRuleForPath(fillRule);
307     pattern_->Stroke();
308 }
309 
SetClipRuleForPath(const CanvasFillRule & fillRule)310 void CanvasRenderingContext2DModelImpl::SetClipRuleForPath(const CanvasFillRule& fillRule)
311 {
312     CHECK_NULL_VOID(pattern_);
313     pattern_->UpdateFillRuleForPath(fillRule);
314     pattern_->Clip();
315 }
316 
SetClipRuleForPath2D(const CanvasFillRule & fillRule,const RefPtr<CanvasPath2D> & path)317 void CanvasRenderingContext2DModelImpl::SetClipRuleForPath2D(
318     const CanvasFillRule& fillRule, const RefPtr<CanvasPath2D>& path)
319 {
320     CHECK_NULL_VOID(pattern_);
321     pattern_->UpdateFillRuleForPath2D(fillRule);
322     pattern_->Clip(path);
323 }
324 
AddRect(const Rect & rect)325 void CanvasRenderingContext2DModelImpl::AddRect(const Rect& rect)
326 {
327     CHECK_NULL_VOID(pattern_);
328     pattern_->AddRect(rect);
329 }
330 
BeginPath()331 void CanvasRenderingContext2DModelImpl::BeginPath()
332 {
333     CHECK_NULL_VOID(pattern_);
334     pattern_->BeginPath();
335 }
336 
ClosePath()337 void CanvasRenderingContext2DModelImpl::ClosePath()
338 {
339     CHECK_NULL_VOID(pattern_);
340     pattern_->ClosePath();
341 }
342 
Restore()343 void CanvasRenderingContext2DModelImpl::Restore()
344 {
345     CHECK_NULL_VOID(pattern_);
346     pattern_->Restore();
347 }
348 
CanvasRendererSave()349 void CanvasRenderingContext2DModelImpl::CanvasRendererSave()
350 {
351     CHECK_NULL_VOID(pattern_);
352     pattern_->Save();
353 }
354 
CanvasRendererRotate(double angle)355 void CanvasRenderingContext2DModelImpl::CanvasRendererRotate(double angle)
356 {
357     CHECK_NULL_VOID(pattern_);
358     pattern_->Rotate(angle);
359 }
360 
CanvasRendererScale(double x,double y)361 void CanvasRenderingContext2DModelImpl::CanvasRendererScale(double x, double y)
362 {
363     CHECK_NULL_VOID(pattern_);
364     pattern_->Scale(x, y);
365 }
366 
SetTransform(TransformParam & param,bool lengthFlag)367 void CanvasRenderingContext2DModelImpl::SetTransform(TransformParam& param, bool lengthFlag)
368 {
369     if (!lengthFlag) {
370         return;
371     }
372     std::swap(param.skewX, param.skewY);
373 
374     CHECK_NULL_VOID(pattern_);
375     pattern_->SetTransform(param);
376 }
377 
ResetTransform()378 void CanvasRenderingContext2DModelImpl::ResetTransform()
379 {
380     CHECK_NULL_VOID(pattern_);
381     pattern_->ResetTransform();
382 }
383 
Transform(const TransformParam & param)384 void CanvasRenderingContext2DModelImpl::Transform(const TransformParam& param)
385 {
386     CHECK_NULL_VOID(pattern_);
387     pattern_->Transform(param);
388 }
389 
Translate(double x,double y)390 void CanvasRenderingContext2DModelImpl::Translate(double x, double y)
391 {
392     CHECK_NULL_VOID(pattern_);
393     pattern_->Translate(x, y);
394 }
395 
SetLineDash(const std::vector<double> & lineDash)396 void CanvasRenderingContext2DModelImpl::SetLineDash(const std::vector<double>& lineDash)
397 {
398     CHECK_NULL_VOID(pattern_);
399     pattern_->UpdateLineDash(lineDash);
400 }
401 
SetTextAlign(const TextAlign & align)402 void CanvasRenderingContext2DModelImpl::SetTextAlign(const TextAlign& align)
403 {
404     CHECK_NULL_VOID(pattern_);
405     pattern_->UpdateTextAlign(align);
406 }
407 
SetTextBaseline(const TextBaseline & baseline)408 void CanvasRenderingContext2DModelImpl::SetTextBaseline(const TextBaseline& baseline)
409 {
410     CHECK_NULL_VOID(pattern_);
411     pattern_->UpdateTextBaseline(baseline);
412 }
413 
GetMeasureTextWidth(const PaintState & state,const std::string & text)414 double CanvasRenderingContext2DModelImpl::GetMeasureTextWidth(const PaintState& state, const std::string& text)
415 {
416     return pattern_ ? pattern_->MeasureText(text, state) : 0.0;
417 }
418 
GetMeasureTextHeight(const PaintState & state,const std::string & text)419 double CanvasRenderingContext2DModelImpl::GetMeasureTextHeight(const PaintState& state, const std::string& text)
420 {
421     return pattern_ ? pattern_->MeasureTextHeight(text, state) : 0.0;
422 }
423 
FillRect(const Rect & rect)424 void CanvasRenderingContext2DModelImpl::FillRect(const Rect& rect)
425 {
426     CHECK_NULL_VOID(pattern_);
427     pattern_->FillRect(rect);
428 }
429 
StrokeRect(const Rect & rect)430 void CanvasRenderingContext2DModelImpl::StrokeRect(const Rect& rect)
431 {
432     CHECK_NULL_VOID(pattern_);
433     pattern_->StrokeRect(rect);
434 }
435 
ClearRect(const Rect & rect)436 void CanvasRenderingContext2DModelImpl::ClearRect(const Rect& rect)
437 {
438     CHECK_NULL_VOID(pattern_);
439     pattern_->ClearRect(rect);
440 }
441 
DrawBitmapMesh(const BitmapMeshInfo & bitmapMeshInfo)442 void CanvasRenderingContext2DModelImpl::DrawBitmapMesh(const BitmapMeshInfo& bitmapMeshInfo)
443 {
444     CHECK_NULL_VOID(bitmapMeshInfo.pool);
445     auto pool = AceType::DynamicCast<CanvasTaskPool>(bitmapMeshInfo.pool);
446     CHECK_NULL_VOID(pool);
447     CHECK_NULL_VOID(bitmapMeshInfo.offscreenPattern);
448     auto offscreenPattern = AceType::DynamicCast<OffscreenCanvas>(bitmapMeshInfo.offscreenPattern);
449     CHECK_NULL_VOID(offscreenPattern);
450     pool->DrawBitmapMesh(offscreenPattern, bitmapMeshInfo.mesh, bitmapMeshInfo.column, bitmapMeshInfo.row);
451 }
452 
GetPixelMap(const ImageSize & imageSize)453 RefPtr<Ace::PixelMap> CanvasRenderingContext2DModelImpl::GetPixelMap(const ImageSize& imageSize)
454 {
455 #ifdef PIXEL_MAP_SUPPORTED
456     // 1 Get data from canvas
457     std::unique_ptr<ImageData> canvasData = GetImageData(imageSize);
458     CHECK_NULL_RETURN(canvasData, nullptr);
459 
460     uint32_t finalHeight = static_cast<uint32_t>(std::abs(imageSize.height));
461     uint32_t finalWidth = static_cast<uint32_t>(std::abs(imageSize.width));
462     if (finalHeight > 0 && finalWidth > (UINT32_MAX / finalHeight)) {
463         LOGE("Integer Overflow!!!the product of finalHeight and finalWidth is too big.");
464         return nullptr;
465     }
466     uint32_t length = finalHeight * finalWidth;
467     uint32_t* data = new uint32_t[length];
468     for (uint32_t i = 0; i < finalHeight; i++) {
469         for (uint32_t j = 0; j < finalWidth; j++) {
470             uint32_t idx = i * finalWidth + j;
471             data[idx] = canvasData->data[idx];
472         }
473     }
474 
475     // 2 Create pixelmap
476     OHOS::Media::InitializationOptions options;
477     options.alphaType = OHOS::Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
478     options.pixelFormat = OHOS::Media::PixelFormat::RGBA_8888;
479     options.scaleMode = OHOS::Media::ScaleMode::CENTER_CROP;
480     options.size.width = static_cast<int32_t>(finalWidth);
481     options.size.height = static_cast<int32_t>(finalHeight);
482     options.editable = true;
483     auto pixelmap = Ace::PixelMap::Create(OHOS::Media::PixelMap::Create(data, length, options));
484     delete[] data;
485     return pixelmap;
486 #else
487     return nullptr;
488 #endif
489 }
490 
GetImageDataModel(const ImageSize & imageSize,uint8_t * buffer)491 void CanvasRenderingContext2DModelImpl::GetImageDataModel(const ImageSize& imageSize, uint8_t* buffer)
492 {
493     auto finalHeight = static_cast<uint32_t>(std::abs(imageSize.height));
494     auto finalWidth = static_cast<uint32_t>(std::abs(imageSize.width));
495     std::unique_ptr<Ace::ImageData> data = GetImageData(imageSize);
496     if (data != nullptr) {
497         for (uint32_t idx = 0; idx < finalHeight * finalWidth; ++idx) {
498             Color color = Color(data->data[idx]);
499             buffer[4 * idx] = color.GetRed(); // 4 * idx: the 1st byte format: red.
500             buffer[4 * idx + 1] = color.GetGreen(); // 4 * idx + 1: the 2nd byte format: green.
501             buffer[4 * idx + 2] = color.GetBlue(); // 4 * idx + 2: the 3rd byte format: blue.
502             buffer[4 * idx + 3] = color.GetAlpha(); // 4 * idx + 3: the 4th byte format: alpha.
503         }
504     }
505 }
506 
GetMeasureTextMetrics(const PaintState & state,const std::string & text)507 TextMetrics CanvasRenderingContext2DModelImpl::GetMeasureTextMetrics(const PaintState& state, const std::string& text)
508 {
509     return pattern_ ? pattern_->MeasureTextMetrics(text, state) : TextMetrics {};
510 }
511 
512 // All interfaces that only the 'CanvasRenderingContext2D' has.
GetWidth(double & width)513 void CanvasRenderingContext2DModelImpl::GetWidth(double& width)
514 {
515     CHECK_NULL_VOID(pattern_);
516     width = pattern_->GetWidth();
517 }
518 
GetHeight(double & height)519 void CanvasRenderingContext2DModelImpl::GetHeight(double& height)
520 {
521     CHECK_NULL_VOID(pattern_);
522     height = pattern_->GetHeight();
523 }
524 
SetTransferFromImageBitmap(RefPtr<AceType> offscreenCPattern)525 void CanvasRenderingContext2DModelImpl::SetTransferFromImageBitmap(RefPtr<AceType> offscreenCPattern)
526 {
527     CHECK_NULL_VOID(pattern_);
528     auto offscreenCanvas = AceType::DynamicCast<OffscreenCanvas>(offscreenCPattern);
529     CHECK_NULL_VOID(offscreenCanvas);
530     pattern_->TransferFromImageBitmap(offscreenCanvas);
531 }
532 } // namespace OHOS::Ace::Framework
533