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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CUSTOM_PAINT_RENDER_CUSTOM_PAINT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CUSTOM_PAINT_RENDER_CUSTOM_PAINT_H
18 
19 #include "base/utils/measure_util.h"
20 #include "core/components/common/properties/paint_state.h"
21 #include "core/components/custom_paint/canvas_render_context_base.h"
22 #include "core/components/custom_paint/custom_paint_component.h"
23 #include "core/components/custom_paint/offscreen_canvas.h"
24 
25 #include "core/pipeline/base/render_node.h"
26 
27 namespace OHOS::Ace {
28 
29 class RenderOffscreenCanvas : public OffscreenCanvas {
30     DECLARE_ACE_TYPE(RenderOffscreenCanvas, OffscreenCanvas);
31 public:
32     static RefPtr<OffscreenCanvas> Create(const WeakPtr<PipelineBase>& context, int32_t width, int32_t height);
33 };
34 
35 class RenderCustomPaint : public RenderNode {
36     DECLARE_ACE_TYPE(RenderCustomPaint, RenderNode);
37 
38 public:
39     ~RenderCustomPaint() override = default;
40 
41     static RefPtr<RenderNode> Create();
42     void Update(const RefPtr<Component>& component) override;
43     void PerformLayout() override;
44     void OnPositionChanged() override;
45     void OnSizeChanged() override;
46 
47     void PushTask(const TaskFunc& func);
48 
HasTask()49     bool HasTask() const
50     {
51         return !tasks_.empty();
52     }
53 
GetTasks()54     const std::list<TaskFunc>& GetTasks() const
55     {
56         return tasks_;
57     }
58 
SetTasks(const std::list<TaskFunc> & tasks)59     void SetTasks(const std::list<TaskFunc>& tasks)
60     {
61         tasks_ = tasks;
62     }
63 
64     void FlushPipelineImmediately();
65     void TriggerOnReadyEvent();
66 
67     virtual void TransferFromImageBitmap(const RefPtr<OffscreenCanvas>& offscreenCanvas) = 0;
68     virtual void DrawBitmapMesh(const RefPtr<OffscreenCanvas>& offscreenCanvas,
69         const std::vector<double>& mesh, int32_t column, int32_t row) = 0;
70     virtual std::string ToDataURL(const std::string& args) = 0;
71     virtual void SetAntiAlias(bool isEnabled) = 0;
72     virtual void FillRect(const Offset& offset, const Rect& rect) = 0;
73     virtual void StrokeRect(const Offset& offset, const Rect& rect) = 0;
74     virtual void ClearRect(const Offset& offset, const Rect& rect) = 0;
75 
76     virtual void FillText(const Offset& offset, const std::string& text, double x, double y) = 0;
77     virtual void StrokeText(const Offset& offset, const std::string& text, double x, double y) = 0;
78     static double PaintMeasureText(const MeasureContext& context);
79     static Size MeasureTextSize(const MeasureContext& context);
80     virtual double MeasureText(const std::string& text, const PaintState& state) = 0;
81     virtual double MeasureTextHeight(const std::string& text, const PaintState& state) = 0;
82     virtual TextMetrics MeasureTextMetrics(const std::string& text, const PaintState& state) = 0;
83 
84     virtual void MoveTo(const Offset& offset, double x, double y) = 0;
85     virtual void LineTo(const Offset& offset, double x, double y) = 0;
86     virtual void BezierCurveTo(const Offset& offset, const BezierCurveParam& param) = 0;
87     virtual void QuadraticCurveTo(const Offset& offset, const QuadraticCurveParam& param) = 0;
88     virtual void Arc(const Offset& offset, const ArcParam& param) = 0;
89     virtual void ArcTo(const Offset& offset, const ArcToParam& param) = 0;
90     virtual void Ellipse(const Offset& offset, const EllipseParam& param) = 0;
91     virtual void AddRect(const Offset& offset, const Rect& rect) = 0;
92 
93     virtual void Fill(const Offset& offset) = 0;
94     virtual void Fill(const Offset& offset, const RefPtr<CanvasPath2D>& path) = 0;
95     virtual void Stroke(const Offset& offset) = 0;
96     virtual void Stroke(const Offset& offset, const RefPtr<CanvasPath2D>& path) = 0;
97     virtual void Clip() = 0;
98     virtual void Clip(const RefPtr<CanvasPath2D>& path) = 0;
99     virtual void BeginPath() = 0;
100     virtual void ResetTransform() = 0;
101     virtual void ClosePath() = 0;
102 
103     // in render node, restore and save are used for clip and matrix operation
104     virtual void Restore() = 0;
105     virtual void Save() = 0;
106 
107     virtual void Rotate(double angle) = 0;
108     virtual void Scale(double x, double y) = 0;
109     virtual void SetTransform(const TransformParam& param) = 0;
110     virtual void Transform(const TransformParam& param) = 0;
111     virtual void Translate(double x, double y) = 0;
112     virtual void DrawImage(const Offset& offset, const CanvasImage& image, double width, double height) = 0;
113     virtual void DrawPixelMap(RefPtr<PixelMap> pixelMap, const CanvasImage& canvasImage) = 0;
114     virtual void PutImageData(const Offset& offset, const ImageData& imageData) = 0;
115     virtual std::unique_ptr<ImageData> GetImageData(double left, double top, double width, double height) = 0;
116     virtual std::string GetJsonData(const std::string& path) = 0;
117 
118     virtual void WebGLInit(CanvasRenderContextBase* context) = 0;
119     virtual void WebGLUpdate() = 0;
120 
121     virtual void SetFillRuleForPath(const CanvasFillRule& rule) = 0;
122     virtual void SetFillRuleForPath2D(const CanvasFillRule& rule) = 0;
123 
IsRepaintBoundary()124     bool IsRepaintBoundary() const override
125     {
126         return true;
127     }
128 
SetFillColor(const Color & color)129     void SetFillColor(const Color& color)
130     {
131         fillState_.SetColor(color);
132         fillState_.SetTextColor(color);
133     }
134 
SetStrokeColor(const Color & color)135     void SetStrokeColor(const Color& color)
136     {
137         strokeState_.SetColor(color);
138     }
139 
SetFillGradient(const Gradient & gradient)140     void SetFillGradient(const Gradient& gradient)
141     {
142         fillState_.SetGradient(gradient);
143     }
144 
SetStrokeGradient(const Gradient & gradient)145     void SetStrokeGradient(const Gradient& gradient)
146     {
147         strokeState_.SetGradient(gradient);
148     }
149 
SetFillPattern(const Pattern & pattern)150     void SetFillPattern(const Pattern& pattern)
151     {
152         fillState_.SetPattern(pattern);
153     }
154 
SetStrokePattern(const Pattern & pattern)155     void SetStrokePattern(const Pattern& pattern)
156     {
157         strokeState_.SetPattern(pattern);
158     }
159 
SetShadowBlur(double blur)160     void SetShadowBlur(double blur)
161     {
162         shadow_.SetBlurRadius(blur);
163     }
164 
SetShadowOffsetX(double x)165     void SetShadowOffsetX(double x)
166     {
167         shadow_.SetOffsetX(x);
168     }
169 
SetShadowOffsetY(double y)170     void SetShadowOffsetY(double y)
171     {
172         shadow_.SetOffsetY(y);
173     }
174 
SetSmoothingEnabled(bool enabled)175     void SetSmoothingEnabled(bool enabled)
176     {
177         smoothingEnabled_ = enabled;
178     }
179 
SetSmoothingQuality(const std::string & quality)180     void SetSmoothingQuality(const std::string& quality)
181     {
182         smoothingQuality_ = quality;
183     }
184 
SetShadowColor(const Color & color)185     void SetShadowColor(const Color& color)
186     {
187         shadow_.SetColor(color);
188     }
189 
SetAlpha(double alpha)190     void SetAlpha(double alpha)
191     {
192         globalState_.SetAlpha(alpha);
193     }
194 
SetCompositeType(CompositeOperation operation)195     void SetCompositeType(CompositeOperation operation)
196     {
197         globalState_.SetType(operation);
198     }
199 
SetLineDashOffset(double offset)200     void SetLineDashOffset(double offset)
201     {
202         strokeState_.SetLineDashOffset(offset);
203     }
204 
SetLineDash(const std::vector<double> & segments)205     void SetLineDash(const std::vector<double>& segments)
206     {
207         strokeState_.SetLineDash(segments);
208     }
209 
GetLineDash()210     LineDashParam GetLineDash() const
211     {
212         return strokeState_.GetLineDash();
213     }
214 
SetTextAlign(TextAlign align)215     void SetTextAlign(TextAlign align)
216     {
217         fillState_.SetTextAlign(align);
218         strokeState_.SetTextAlign(align);
219     }
220 
SetTextBaseline(TextBaseline baseline)221     void SetTextBaseline(TextBaseline baseline)
222     {
223         fillState_.SetTextBaseline(baseline);
224         strokeState_.SetTextBaseline(baseline);
225     }
226 
SetFontWeight(FontWeight weight)227     void SetFontWeight(FontWeight weight)
228     {
229         fillState_.SetFontWeight(weight);
230         strokeState_.SetFontWeight(weight);
231     }
232 
SetFontFamilies(const std::vector<std::string> & fontFamilies)233     void SetFontFamilies(const std::vector<std::string>& fontFamilies)
234     {
235         fillState_.SetFontFamilies(fontFamilies);
236         strokeState_.SetFontFamilies(fontFamilies);
237     }
238 
SetFontStyle(FontStyle style)239     void SetFontStyle(FontStyle style)
240     {
241         fillState_.SetFontStyle(style);
242         strokeState_.SetFontStyle(style);
243     }
244 
SetFontSize(const Dimension & size)245     void SetFontSize(const Dimension& size)
246     {
247         fillState_.SetFontSize(size);
248         strokeState_.SetFontSize(size);
249     }
250 
SetTextStyle(const TextStyle & style)251     void SetTextStyle(const TextStyle& style)
252     {
253         fillState_.SetTextStyle(style);
254         strokeState_.SetTextStyle(style);
255     }
256 
SetLineWidth(double width)257     void SetLineWidth(double width)
258     {
259         strokeState_.SetLineWidth(width);
260     }
261 
SetLineCap(LineCapStyle style)262     void SetLineCap(LineCapStyle style)
263     {
264         strokeState_.SetLineCap(style);
265     }
266 
SetLineJoin(LineJoinStyle style)267     void SetLineJoin(LineJoinStyle style)
268     {
269         strokeState_.SetLineJoin(style);
270     }
271 
SetMiterLimit(double limit)272     void SetMiterLimit(double limit)
273     {
274         strokeState_.SetMiterLimit(limit);
275     }
276 
SaveStates()277     void SaveStates()
278     {
279         PaintHolder holder;
280         holder.shadow = shadow_;
281         holder.fillState = fillState_;
282         holder.globalState = globalState_;
283         holder.strokeState = strokeState_;
284         saveStates_.push(holder);
285     }
286 
RestoreStates()287     void RestoreStates()
288     {
289         if (saveStates_.empty()) {
290             return;
291         }
292         auto saveState = saveStates_.top();
293         shadow_ = saveState.shadow;
294         fillState_ = saveState.fillState;
295         strokeState_ = saveState.strokeState;
296         globalState_ = saveState.globalState;
297         saveStates_.pop();
298     }
299 
SetWebGLInstance(CanvasRenderContextBase * context)300     void SetWebGLInstance(CanvasRenderContextBase* context)
301     {
302         webGLContext_ = context;
303     }
304 
GetWebGLInstance()305     CanvasRenderContextBase* GetWebGLInstance() const
306     {
307         return webGLContext_;
308     }
309 
310 protected:
311     RenderCustomPaint();
312 
313     PaintState fillState_;
314     StrokePaintState strokeState_;
315 
316     // save alpha and compositeType in GlobalPaintState
317     GlobalPaintState globalState_;
318     Shadow shadow_;
319 
320     bool smoothingEnabled_ = true;
321     std::string smoothingQuality_ = "low";
322 
323     // PaintHolder includes fillState, strokeState, globalState and shadow for save
324     std::stack<PaintHolder> saveStates_;
325 
326     RefPtr<CanvasTaskPool> pool_;
327     std::list<TaskFunc> tasks_;
328 
329     ContextType type_ = ContextType::RENDER_2D;
330     CanvasRenderContextBase* webGLContext_ = nullptr;
331 
332     Size drawSize_;
333     bool isCanvasInit_ = false;
334     std::function<void()> canvasOnReadyEvent_;
335 private:
336     Dimension width_;
337     Dimension height_;
338 };
339 
340 } // namespace OHOS::Ace
341 
342 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CUSTOM_PAINT_RENDER_CUSTOM_PAINT_H
343