1 /*
2  * Copyright (c) 2021-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/custom_paint/custom_paint_component.h"
17 
18 #include "core/components/custom_paint/custom_paint_element.h"
19 
20 namespace OHOS::Ace {
21 
CreateRenderNode()22 RefPtr<RenderNode> CustomPaintComponent::CreateRenderNode()
23 {
24     return RenderCustomPaint::Create();
25 }
26 
CreateElement()27 RefPtr<Element> CustomPaintComponent::CreateElement()
28 {
29     return AceType::MakeRefPtr<CustomPaintElement>();
30 }
31 
SetRenderNode(const WeakPtr<RenderCustomPaint> & paint)32 void CanvasTaskPool::SetRenderNode(const WeakPtr<RenderCustomPaint>& paint)
33 {
34     renderNode_ = paint;
35 }
36 
ToDataURL(const std::string & args)37 std::string CanvasTaskPool::ToDataURL(const std::string& args)
38 {
39     auto paint = renderNode_.Upgrade();
40     if (!paint) {
41         return args;
42     }
43     if (paint->HasTask()) {
44         paint->FlushPipelineImmediately();
45     }
46     return paint->ToDataURL(args);
47 }
TransferFromImageBitmap(const RefPtr<OffscreenCanvas> & offscreenCanvas)48 void CanvasTaskPool::TransferFromImageBitmap(const RefPtr<OffscreenCanvas>& offscreenCanvas)
49 {
50     auto task = [offscreenCanvas](RenderCustomPaint& interface, const Offset&) {
51         interface.TransferFromImageBitmap(offscreenCanvas);
52     };
53     PushTask(task);
54 }
55 
DrawBitmapMesh(const RefPtr<OffscreenCanvas> & offscreenCanvas,const std::vector<double> & mesh,int32_t column,int32_t row)56 void CanvasTaskPool::DrawBitmapMesh(const RefPtr<OffscreenCanvas>& offscreenCanvas,
57     const std::vector<double>& mesh, int32_t column, int32_t row)
58 {
59     auto task = [offscreenCanvas, mesh, column, row](RenderCustomPaint& interface, const Offset&) {
60         interface.DrawBitmapMesh(offscreenCanvas, mesh, column, row);
61     };
62     PushTask(task);
63 }
64 
SetWebGLInstance(CanvasRenderContextBase * context)65 void CanvasTaskPool::SetWebGLInstance(CanvasRenderContextBase* context)
66 {
67     auto paint = renderNode_.Upgrade();
68     if (!paint) {
69         LOGE("CanvasTaskPool::SetWebGLInstance invalid renderNode");
70         return;
71     }
72     paint->SetWebGLInstance(context);
73 }
74 
WebGLInit(CanvasRenderContextBase * context)75 void CanvasTaskPool::WebGLInit(CanvasRenderContextBase* context)
76 {
77     auto paint = renderNode_.Upgrade();
78     if (!paint) {
79         LOGE("CanvasTaskPool::SetWebGLInstance invalid renderNode");
80         return;
81     }
82     paint->WebGLInit(context);
83 }
84 
WebGLUpdate()85 void CanvasTaskPool::WebGLUpdate()
86 {
87     auto task = [](RenderCustomPaint& interface, const Offset& offset) { interface.WebGLUpdate(); };
88     PushTask(task);
89 }
90 
SetAntiAlias(bool isEnabled)91 void CanvasTaskPool::SetAntiAlias(bool isEnabled)
92 {
93     auto task = [isEnabled](RenderCustomPaint& interface, const Offset&) { interface.SetAntiAlias(isEnabled); };
94     PushTask(task);
95 }
96 
FillRect(const Rect & rect)97 void CanvasTaskPool::FillRect(const Rect& rect)
98 {
99     auto task = [rect](RenderCustomPaint& interface, const Offset& offset) { interface.FillRect(offset, rect); };
100     PushTask(task);
101 }
102 
StrokeRect(const Rect & rect)103 void CanvasTaskPool::StrokeRect(const Rect& rect)
104 {
105     auto task = [rect](RenderCustomPaint& interface, const Offset& offset) { interface.StrokeRect(offset, rect); };
106     PushTask(task);
107 }
108 
ClearRect(const Rect & rect)109 void CanvasTaskPool::ClearRect(const Rect& rect)
110 {
111     auto task = [rect](RenderCustomPaint& interface, const Offset& offset) { interface.ClearRect(offset, rect); };
112     PushTask(task);
113 }
114 
FillText(const std::string & text,const Offset & textOffset)115 void CanvasTaskPool::FillText(const std::string& text, const Offset& textOffset)
116 {
117     auto task = [text, textOffset](RenderCustomPaint& interface, const Offset& offset) {
118         interface.FillText(offset, text, textOffset.GetX(), textOffset.GetY());
119     };
120     PushTask(task);
121 }
122 
StrokeText(const std::string & text,const Offset & textOffset)123 void CanvasTaskPool::StrokeText(const std::string& text, const Offset& textOffset)
124 {
125     auto task = [text, textOffset](RenderCustomPaint& interface, const Offset& offset) {
126         interface.StrokeText(offset, text, textOffset.GetX(), textOffset.GetY());
127     };
128     PushTask(task);
129 }
130 
MeasureText(const std::string & text,const PaintState & state)131 double CanvasTaskPool::MeasureText(const std::string& text, const PaintState& state)
132 {
133     auto paint = renderNode_.Upgrade();
134     if (!paint) {
135         return 0.0;
136     }
137     return paint->MeasureText(text, state);
138 }
139 
MeasureTextHeight(const std::string & text,const PaintState & state)140 double CanvasTaskPool::MeasureTextHeight(const std::string& text, const PaintState& state)
141 {
142     auto paint = renderNode_.Upgrade();
143     if (!paint) {
144         return 0.0;
145     }
146     return paint->MeasureTextHeight(text, state);
147 }
148 
MeasureTextMetrics(const std::string & text,const PaintState & state)149 TextMetrics CanvasTaskPool::MeasureTextMetrics(const std::string& text, const PaintState& state)
150 {
151     auto paint = renderNode_.Upgrade();
152     if (!paint) {
153         return { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
154     }
155     return paint->MeasureTextMetrics(text, state);
156 }
157 
MoveTo(double x,double y)158 void CanvasTaskPool::MoveTo(double x, double y)
159 {
160     auto task = [x, y](RenderCustomPaint& interface, const Offset& offset) { interface.MoveTo(offset, x, y); };
161     PushTask(task);
162 }
163 
LineTo(double x,double y)164 void CanvasTaskPool::LineTo(double x, double y)
165 {
166     auto task = [x, y](RenderCustomPaint& interface, const Offset& offset) { interface.LineTo(offset, x, y); };
167     PushTask(task);
168 }
169 
BezierCurveTo(const BezierCurveParam & param)170 void CanvasTaskPool::BezierCurveTo(const BezierCurveParam& param)
171 {
172     auto task = [param](RenderCustomPaint& interface, const Offset& offset) { interface.BezierCurveTo(offset, param); };
173     PushTask(task);
174 }
175 
QuadraticCurveTo(const QuadraticCurveParam & param)176 void CanvasTaskPool::QuadraticCurveTo(const QuadraticCurveParam& param)
177 {
178     auto task = [param](
179                     RenderCustomPaint& interface, const Offset& offset) { interface.QuadraticCurveTo(offset, param); };
180     PushTask(task);
181 }
182 
Arc(const ArcParam & param)183 void CanvasTaskPool::Arc(const ArcParam& param)
184 {
185     auto task = [param](RenderCustomPaint& interface, const Offset& offset) { interface.Arc(offset, param); };
186     PushTask(task);
187 }
188 
AddRect(const Rect & rect)189 void CanvasTaskPool::AddRect(const Rect& rect)
190 {
191     auto task = [rect](RenderCustomPaint& interface, const Offset& offset) { interface.AddRect(offset, rect); };
192     PushTask(task);
193 }
194 
ArcTo(const OHOS::Ace::ArcToParam & param)195 void CanvasTaskPool::ArcTo(const OHOS::Ace::ArcToParam& param)
196 {
197     auto task = [param](RenderCustomPaint& interface, const Offset& offset) { interface.ArcTo(offset, param); };
198     PushTask(task);
199 }
200 
Ellipse(const OHOS::Ace::EllipseParam & param)201 void CanvasTaskPool::Ellipse(const OHOS::Ace::EllipseParam& param)
202 {
203     auto task = [param](RenderCustomPaint& interface, const Offset& offset) { interface.Ellipse(offset, param); };
204     PushTask(task);
205 }
206 
Fill()207 void CanvasTaskPool::Fill()
208 {
209     auto task = [](RenderCustomPaint& interface, const Offset& offset) { interface.Fill(offset); };
210     PushTask(task);
211 }
212 
Fill(const RefPtr<CanvasPath2D> & path)213 void CanvasTaskPool::Fill(const RefPtr<CanvasPath2D>& path)
214 {
215     auto task = [path](RenderCustomPaint& interface, const Offset& offset) { interface.Fill(offset, path); };
216     PushTask(task);
217 }
218 
Stroke()219 void CanvasTaskPool::Stroke()
220 {
221     auto task = [](RenderCustomPaint& interface, const Offset& offset) { interface.Stroke(offset); };
222     PushTask(task);
223 }
224 
Stroke(const RefPtr<CanvasPath2D> & path)225 void CanvasTaskPool::Stroke(const RefPtr<CanvasPath2D>& path)
226 {
227     auto task = [path](RenderCustomPaint& interface, const Offset& offset) { interface.Stroke(offset, path); };
228     PushTask(task);
229 }
230 
Clip()231 void CanvasTaskPool::Clip()
232 {
233     auto task = [](RenderCustomPaint& interface, const Offset& offset) { interface.Clip(); };
234     PushTask(task);
235 }
236 
Clip(const RefPtr<CanvasPath2D> & path)237 void CanvasTaskPool::Clip(const RefPtr<CanvasPath2D>& path)
238 {
239     auto task = [path](RenderCustomPaint& interface, const Offset& offset) { interface.Clip(path); };
240     PushTask(task);
241 }
242 
BeginPath()243 void CanvasTaskPool::BeginPath()
244 {
245     auto task = [](RenderCustomPaint& interface, const Offset& offset) { interface.BeginPath(); };
246     PushTask(task);
247 }
248 
ResetTransform()249 void CanvasTaskPool::ResetTransform()
250 {
251     auto task = [](RenderCustomPaint& interface, const Offset& offset) { interface.ResetTransform(); };
252     PushTask(task);
253 }
254 
ClosePath()255 void CanvasTaskPool::ClosePath()
256 {
257     auto task = [](RenderCustomPaint& interface, const Offset& offset) { interface.ClosePath(); };
258     PushTask(task);
259 }
260 
Save()261 void CanvasTaskPool::Save()
262 {
263     auto task = [](RenderCustomPaint& interface, const Offset& offset) { interface.Save(); };
264     PushTask(task);
265 }
266 
Restore()267 void CanvasTaskPool::Restore()
268 {
269     auto task = [](RenderCustomPaint& interface, const Offset& offset) { interface.Restore(); };
270     PushTask(task);
271 }
272 
Rotate(double angle)273 void CanvasTaskPool::Rotate(double angle)
274 {
275     auto task = [angle](RenderCustomPaint& interface, const Offset& offset) { interface.Rotate(angle); };
276     PushTask(task);
277 }
278 
Scale(double x,double y)279 void CanvasTaskPool::Scale(double x, double y)
280 {
281     auto task = [x, y](RenderCustomPaint& interface, const Offset& offset) { interface.Scale(x, y); };
282     PushTask(task);
283 }
284 
SetTransform(const TransformParam & param)285 void CanvasTaskPool::SetTransform(const TransformParam& param)
286 {
287     auto task = [param](RenderCustomPaint& interface, const Offset& offset) { interface.SetTransform(param); };
288     PushTask(task);
289 }
290 
Transform(const TransformParam & param)291 void CanvasTaskPool::Transform(const TransformParam& param)
292 {
293     auto task = [param](RenderCustomPaint& interface, const Offset& offset) { interface.Transform(param); };
294     PushTask(task);
295 }
296 
Translate(double x,double y)297 void CanvasTaskPool::Translate(double x, double y)
298 {
299     auto task = [x, y](RenderCustomPaint& interface, const Offset& offset) { interface.Translate(x, y); };
300     PushTask(task);
301 }
302 
DrawImage(const CanvasImage & image,double width,double height)303 void CanvasTaskPool::DrawImage(const CanvasImage& image, double width, double height)
304 {
305     auto task = [image, width, height](RenderCustomPaint& interface, const Offset& offset) {
306         interface.DrawImage(offset, image, width, height);
307     };
308     PushTask(task);
309 }
310 
DrawPixelMap(RefPtr<PixelMap> pixelMap,const CanvasImage & image)311 void CanvasTaskPool::DrawPixelMap(RefPtr<PixelMap> pixelMap, const CanvasImage& image)
312 {
313     auto task = [pixelMap, image](RenderCustomPaint& interface, const Offset& offset) {
314         interface.DrawPixelMap(pixelMap, image);
315     };
316     PushTask(task);
317 }
318 
PutImageData(const ImageData & imageData)319 void CanvasTaskPool::PutImageData(const ImageData& imageData)
320 {
321     auto task = [imageData](
322                     RenderCustomPaint& interface, const Offset& offset) { interface.PutImageData(offset, imageData); };
323     PushTask(task);
324 }
325 
GetImageData(double left,double top,double width,double height)326 std::unique_ptr<ImageData> CanvasTaskPool::GetImageData(double left, double top, double width, double height)
327 {
328     auto paint = renderNode_.Upgrade();
329     if (!paint) {
330         std::unique_ptr<ImageData> data = std::make_unique<ImageData>();
331         data->dirtyWidth = width;
332         data->dirtyHeight = height;
333         return data;
334     }
335     if (paint->HasTask()) {
336         paint->FlushPipelineImmediately();
337     }
338     return paint->GetImageData(left, top, width, height);
339 }
340 
GetJsonData(const std::string & path)341 std::string CanvasTaskPool::GetJsonData(const std::string& path)
342 {
343     auto paint = renderNode_.Upgrade();
344     if (!paint) {
345         return "";
346     }
347 
348     return paint->GetJsonData(path);
349 }
350 
GetLineDash() const351 LineDashParam CanvasTaskPool::GetLineDash() const
352 {
353     auto paint = renderNode_.Upgrade();
354     if (!paint) {
355         return { {}, 0.0 };
356     }
357 
358     return paint->GetLineDash();
359 }
360 
GetWidth() const361 double CanvasTaskPool::GetWidth() const
362 {
363     auto paint = renderNode_.Upgrade();
364     if (!paint) {
365         return 0.0;
366     }
367 
368     return paint->GetLayoutSize().Width();
369 }
370 
GetHeight() const371 double CanvasTaskPool::GetHeight() const
372 {
373     auto paint = renderNode_.Upgrade();
374     if (!paint) {
375         return 0.0;
376     }
377 
378     return paint->GetLayoutSize().Height();
379 }
380 
UpdateFillRuleForPath(const CanvasFillRule rule)381 void CanvasTaskPool::UpdateFillRuleForPath(const CanvasFillRule rule)
382 {
383     auto task = [rule](RenderCustomPaint& interface, const Offset& offset) {
384         interface.SetFillRuleForPath(rule);
385     };
386     PushTask(task);
387 }
388 
UpdateFillRuleForPath2D(const CanvasFillRule rule)389 void CanvasTaskPool::UpdateFillRuleForPath2D(const CanvasFillRule rule)
390 {
391     auto task = [rule](RenderCustomPaint& interface, const Offset& offset) {
392         interface.SetFillRuleForPath2D(rule);
393     };
394     PushTask(task);
395 }
396 
UpdateFillColor(const Color & color)397 void CanvasTaskPool::UpdateFillColor(const Color& color)
398 {
399     auto task = [color](RenderCustomPaint& interface, const Offset& offset) {
400         interface.SetFillColor(color);
401         interface.SetFillPattern(Pattern());
402         interface.SetFillGradient(Gradient());
403     };
404     PushTask(task);
405 }
406 
UpdateStrokeColor(const Color & color)407 void CanvasTaskPool::UpdateStrokeColor(const Color& color)
408 {
409     auto task = [color](RenderCustomPaint& interface, const Offset& offset) {
410         interface.SetStrokeColor(color);
411         interface.SetStrokePattern(Pattern());
412         interface.SetStrokeGradient(Gradient());
413     };
414     PushTask(task);
415 }
416 
UpdateFillGradient(const Gradient & gradient)417 void CanvasTaskPool::UpdateFillGradient(const Gradient& gradient)
418 {
419     auto task = [gradient](RenderCustomPaint& interface, const Offset& offset) {
420         interface.SetFillGradient(gradient);
421         interface.SetFillColor(Color());
422         interface.SetFillPattern(Pattern());
423     };
424     PushTask(task);
425 }
426 
UpdateStrokeGradient(const Gradient & grad)427 void CanvasTaskPool::UpdateStrokeGradient(const Gradient& grad)
428 {
429     auto task = [grad](RenderCustomPaint& interface, const Offset& offset) {
430         interface.SetStrokeGradient(grad);
431         interface.SetStrokeColor(Color());
432         interface.SetStrokePattern(Pattern());
433     };
434     PushTask(task);
435 }
436 
UpdateFillPattern(const Pattern & pattern)437 void CanvasTaskPool::UpdateFillPattern(const Pattern& pattern)
438 {
439     auto task = [pattern](RenderCustomPaint& interface, const Offset& offset) {
440         interface.SetFillPattern(pattern);
441         interface.SetFillGradient(Gradient());
442         interface.SetFillColor(Color());
443     };
444     PushTask(task);
445 }
446 
UpdateStrokePattern(const Pattern & pattern)447 void CanvasTaskPool::UpdateStrokePattern(const Pattern& pattern)
448 {
449     auto task = [pattern](RenderCustomPaint& interface, const Offset& offset) {
450         interface.SetStrokePattern(pattern);
451         interface.SetStrokeGradient(Gradient());
452         interface.SetStrokeColor(Color());
453     };
454     PushTask(task);
455 }
456 
UpdateLineWidth(double width)457 void CanvasTaskPool::UpdateLineWidth(double width)
458 {
459     auto task = [width](RenderCustomPaint& interface, const Offset& offset) { interface.SetLineWidth(width); };
460     PushTask(task);
461 }
462 
UpdateLineCap(LineCapStyle cap)463 void CanvasTaskPool::UpdateLineCap(LineCapStyle cap)
464 {
465     auto task = [cap](RenderCustomPaint& interface, const Offset& offset) { interface.SetLineCap(cap); };
466     PushTask(task);
467 }
468 
UpdateLineJoin(LineJoinStyle join)469 void CanvasTaskPool::UpdateLineJoin(LineJoinStyle join)
470 {
471     auto task = [join](RenderCustomPaint& interface, const Offset& offset) { interface.SetLineJoin(join); };
472     PushTask(task);
473 }
474 
UpdateMiterLimit(double limit)475 void CanvasTaskPool::UpdateMiterLimit(double limit)
476 {
477     auto task = [limit](RenderCustomPaint& interface, const Offset& offset) { interface.SetMiterLimit(limit); };
478     PushTask(task);
479 }
480 
UpdateTextBaseline(TextBaseline baseline)481 void CanvasTaskPool::UpdateTextBaseline(TextBaseline baseline)
482 {
483     auto task = [baseline](RenderCustomPaint& interface, const Offset& offset) { interface.SetTextBaseline(baseline); };
484     PushTask(task);
485 }
486 
UpdateTextAlign(TextAlign align)487 void CanvasTaskPool::UpdateTextAlign(TextAlign align)
488 {
489     auto task = [align](RenderCustomPaint& interface, const Offset& offset) { interface.SetTextAlign(align); };
490     PushTask(task);
491 }
492 
UpdateFontSize(const Dimension & size)493 void CanvasTaskPool::UpdateFontSize(const Dimension& size)
494 {
495     auto task = [size](RenderCustomPaint& interface, const Offset& offset) { interface.SetFontSize(size); };
496     PushTask(task);
497 }
498 
UpdateFontFamilies(const std::vector<std::string> & families)499 void CanvasTaskPool::UpdateFontFamilies(const std::vector<std::string>& families)
500 {
501     auto task = [families](RenderCustomPaint& interface, const Offset& offset) { interface.SetFontFamilies(families); };
502     PushTask(task);
503 }
504 
UpdateFontWeight(FontWeight weight)505 void CanvasTaskPool::UpdateFontWeight(FontWeight weight)
506 {
507     auto task = [weight](RenderCustomPaint& interface, const Offset& offset) { interface.SetFontWeight(weight); };
508     PushTask(task);
509 }
510 
UpdateFontStyle(FontStyle style)511 void CanvasTaskPool::UpdateFontStyle(FontStyle style)
512 {
513     auto task = [style](RenderCustomPaint& interface, const Offset& offset) { interface.SetFontStyle(style); };
514     PushTask(task);
515 }
516 
UpdateGlobalAlpha(double alpha)517 void CanvasTaskPool::UpdateGlobalAlpha(double alpha)
518 {
519     auto task = [alpha](RenderCustomPaint& interface, const Offset& offset) { interface.SetAlpha(alpha); };
520     PushTask(task);
521 }
522 
UpdateLineDashOffset(double dash)523 void CanvasTaskPool::UpdateLineDashOffset(double dash)
524 {
525     auto task = [dash](RenderCustomPaint& interface, const Offset& offset) { interface.SetLineDashOffset(dash); };
526     PushTask(task);
527 }
528 
UpdateLineDash(const std::vector<double> & segments)529 void CanvasTaskPool::UpdateLineDash(const std::vector<double>& segments)
530 {
531     auto task = [segments](RenderCustomPaint& interface, const Offset& offset) { interface.SetLineDash(segments); };
532     PushTask(task);
533 }
534 
UpdateShadowBlur(double blur)535 void CanvasTaskPool::UpdateShadowBlur(double blur)
536 {
537     auto task = [blur](RenderCustomPaint& interface, const Offset& offset) { interface.SetShadowBlur(blur); };
538     PushTask(task);
539 }
540 
UpdateShadowColor(const Color & color)541 void CanvasTaskPool::UpdateShadowColor(const Color& color)
542 {
543     auto task = [color](RenderCustomPaint& interface, const Offset& offset) { interface.SetShadowColor(color); };
544     PushTask(task);
545 }
546 
UpdateShadowOffsetX(double offsetX)547 void CanvasTaskPool::UpdateShadowOffsetX(double offsetX)
548 {
549     auto task = [offsetX](RenderCustomPaint& interface, const Offset& offset) { interface.SetShadowOffsetX(offsetX); };
550     PushTask(task);
551 }
552 
UpdateShadowOffsetY(double offsetY)553 void CanvasTaskPool::UpdateShadowOffsetY(double offsetY)
554 {
555     auto task = [offsetY](RenderCustomPaint& interface, const Offset& offset) { interface.SetShadowOffsetY(offsetY); };
556     PushTask(task);
557 }
558 
UpdateCompositeOperation(CompositeOperation type)559 void CanvasTaskPool::UpdateCompositeOperation(CompositeOperation type)
560 {
561     auto task = [type](RenderCustomPaint& interface, const Offset& offset) { interface.SetCompositeType(type); };
562     PushTask(task);
563 }
564 
UpdateSmoothingEnabled(bool enabled)565 void CanvasTaskPool::UpdateSmoothingEnabled(bool enabled)
566 {
567     auto task =
568         [enabled](RenderCustomPaint& interface, const Offset& offset) { interface.SetSmoothingEnabled(enabled); };
569     PushTask(task);
570 }
571 
UpdateSmoothingQuality(const std::string & quality)572 void CanvasTaskPool::UpdateSmoothingQuality(const std::string& quality)
573 {
574     auto task =
575         [quality](RenderCustomPaint& interface, const Offset& offset) { interface.SetSmoothingQuality(quality); };
576     PushTask(task);
577 }
578 
579 } // namespace OHOS::Ace
580