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