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