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