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