1 /*
2  * Copyright (c) 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_NG_PATTERN_CUSTOM_PAINT_CUSTOM_PAINT_PAINT_METHOD_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_CUSTOM_PAINT_CUSTOM_PAINT_PAINT_METHOD_H
18 
19 #include "base/geometry/ng/offset_t.h"
20 #include "base/memory/ace_type.h"
21 #include "base/utils/macros.h"
22 #include "core/common/font_manager.h"
23 #include "core/components/common/properties/paint_state.h"
24 #include "core/components_ng/image_provider/svg_dom_base.h"
25 #include "core/components_ng/pattern/canvas/canvas_modifier.h"
26 #include "core/components_ng/render/drawing.h"
27 #include "core/components_ng/render/node_paint_method.h"
28 #ifndef ACE_UNITTEST
29 #include "core/image/image_loader.h"
30 #include "core/image/image_object.h"
31 #include "core/image/image_source_info.h"
32 #endif
33 #include "core/pipeline_ng/pipeline_context.h"
34 
35 namespace OHOS::Ace::NG {
36 
37 const int32_t DEFAULT_SAVE_COUNT = 1;
38 
39 enum class FilterType {
40     NONE,
41     GRAYSCALE,
42     SEPIA,
43     INVERT,
44     OPACITY,
45     BRIGHTNESS,
46     CONTRAST,
47     BLUR,
48     DROP_SHADOW,
49     SATURATE,
50     HUE_ROTATE
51 };
52 
53 struct FilterProperty {
54     FilterType filterType_;
55     std::string filterParam_;
56 };
57 
58 class CustomPaintPaintMethod : public NodePaintMethod {
59     DECLARE_ACE_TYPE(CustomPaintPaintMethod, NodePaintMethod)
60 public:
61     ~CustomPaintPaintMethod() override = default;
62 
GetContentModifier(PaintWrapper * paintWrapper)63     RefPtr<Modifier> GetContentModifier(PaintWrapper* paintWrapper) override
64     {
65         return contentModifier_;
66     }
67 
68     void SetFillRuleForPath(const CanvasFillRule& rule);
69     void SetFillRuleForPath2D(const CanvasFillRule& rule);
70 
71     void FillRect(const Rect& rect);
72     void StrokeRect(const Rect& rect);
73     void ClearRect(const Rect& rect);
74     void Fill();
75     void Fill(const RefPtr<CanvasPath2D>& path);
76     void Stroke();
77     void Stroke(const RefPtr<CanvasPath2D>& path);
78     void Clip();
79     void Clip(const RefPtr<CanvasPath2D>& path);
80     void BeginPath();
81     void ClosePath();
82     void MoveTo(double x, double y);
83     void LineTo(double x, double y);
84     void Arc(const ArcParam& param);
85     void ArcTo(const ArcToParam& param);
86     void AddRect(const Rect& rect);
87     void Ellipse(const EllipseParam& param);
88     void BezierCurveTo(const BezierCurveParam& param);
89     void QuadraticCurveTo(const QuadraticCurveParam& param);
90     void PutImageData(const Ace::ImageData& imageData);
91 
92     void Save();
93     void Restore();
94     void Scale(double x, double y);
95     void Rotate(double angle);
96     void SetTransform(const TransformParam& param);
97     virtual TransformParam GetTransform() const;
98     void ResetTransform();
99     void Transform(const TransformParam& param);
100     void Translate(double x, double y);
101     void SaveLayer();
102     void RestoreLayer();
103     void SetFilterParam(const std::string& filterStr);
104 
SetAntiAlias(bool isEnabled)105     void SetAntiAlias(bool isEnabled)
106     {
107         antiAlias_ = isEnabled;
108     }
109 
SetFillColor(const Color & color)110     void SetFillColor(const Color& color)
111     {
112         state_.fillState.SetColor(color);
113         state_.fillState.SetTextColor(color);
114     }
115 
SetFillPattern(const Ace::Pattern & pattern)116     void SetFillPattern(const Ace::Pattern& pattern)
117     {
118         state_.fillState.SetPattern(pattern);
119     }
120 
SetFillPatternNG(const std::weak_ptr<Ace::Pattern> & pattern)121     void SetFillPatternNG(const std::weak_ptr<Ace::Pattern>& pattern)
122     {
123         state_.fillState.SetPatternNG(pattern);
124     }
125 
SetFillGradient(const Ace::Gradient & gradient)126     void SetFillGradient(const Ace::Gradient& gradient)
127     {
128         state_.fillState.SetGradient(gradient);
129     }
130 
SetAlpha(double alpha)131     void SetAlpha(double alpha)
132     {
133         state_.globalState.SetAlpha(alpha);
134     }
135 
SetCompositeType(CompositeOperation operation)136     void SetCompositeType(CompositeOperation operation)
137     {
138         state_.globalState.SetType(operation);
139     }
140 
141     // direction is also available in strokeText
SetTextDirection(TextDirection direction)142     void SetTextDirection(TextDirection direction)
143     {
144         state_.fillState.SetOffTextDirection(direction);
145     }
146 
SetStrokeColor(const Color & color)147     void SetStrokeColor(const Color& color)
148     {
149         state_.strokeState.SetColor(color);
150     }
151 
SetStrokePatternNG(const std::weak_ptr<Ace::Pattern> & pattern)152     void SetStrokePatternNG(const std::weak_ptr<Ace::Pattern>& pattern)
153     {
154         state_.strokeState.SetPatternNG(pattern);
155     }
156 
SetStrokePattern(const Ace::Pattern & pattern)157     void SetStrokePattern(const Ace::Pattern& pattern)
158     {
159         state_.strokeState.SetPattern(pattern);
160     }
161 
SetStrokeGradient(const Ace::Gradient & gradient)162     void SetStrokeGradient(const Ace::Gradient& gradient)
163     {
164         state_.strokeState.SetGradient(gradient);
165     }
166 
SetLineCap(LineCapStyle style)167     void SetLineCap(LineCapStyle style)
168     {
169         state_.strokeState.SetLineCap(style);
170     }
171 
SetLineDashOffset(double offset)172     void SetLineDashOffset(double offset)
173     {
174         state_.strokeState.SetLineDashOffset(offset);
175     }
176 
SetLineJoin(LineJoinStyle style)177     void SetLineJoin(LineJoinStyle style)
178     {
179         state_.strokeState.SetLineJoin(style);
180     }
181 
SetLineWidth(double width)182     void SetLineWidth(double width)
183     {
184         state_.strokeState.SetLineWidth(width);
185     }
186 
SetMiterLimit(double limit)187     void SetMiterLimit(double limit)
188     {
189         state_.strokeState.SetMiterLimit(limit);
190     }
191 
GetLineDash()192     virtual LineDashParam GetLineDash() const
193     {
194         return lineDash_;
195     }
196 
SetLineDashParam(const std::vector<double> & segments)197     void SetLineDashParam(const std::vector<double>& segments)
198     {
199         lineDash_.lineDash = segments;
200     }
201 
SetLineDash(const std::vector<double> & segments)202     void SetLineDash(const std::vector<double>& segments)
203     {
204         state_.strokeState.SetLineDash(segments);
205     }
206 
SetTextAlign(TextAlign align)207     void SetTextAlign(TextAlign align)
208     {
209         state_.fillState.SetTextAlign(align);
210         state_.strokeState.SetTextAlign(align);
211     }
212 
SetTextBaseline(TextBaseline baseline)213     void SetTextBaseline(TextBaseline baseline)
214     {
215         state_.fillState.SetTextBaseline(baseline);
216         state_.strokeState.SetTextBaseline(baseline);
217     }
218 
SetShadowColor(const Color & color)219     void SetShadowColor(const Color& color)
220     {
221         state_.shadow.SetColor(color);
222     }
223 
SetShadowBlur(double blur)224     void SetShadowBlur(double blur)
225     {
226         state_.shadow.SetBlurRadius(blur);
227     }
228 
SetShadowOffsetX(double x)229     void SetShadowOffsetX(double x)
230     {
231         state_.shadow.SetOffsetX(x);
232     }
233 
SetShadowOffsetY(double y)234     void SetShadowOffsetY(double y)
235     {
236         state_.shadow.SetOffsetY(y);
237     }
238 
SetSmoothingEnabled(bool enabled)239     void SetSmoothingEnabled(bool enabled)
240     {
241         smoothingEnabled_ = enabled;
242     }
243 
SetSmoothingQuality(const std::string & quality)244     void SetSmoothingQuality(const std::string& quality)
245     {
246         smoothingQuality_ = quality;
247     }
248 
SetFontSize(const Dimension & size)249     void SetFontSize(const Dimension& size)
250     {
251         state_.fillState.SetFontSize(size);
252         state_.strokeState.SetFontSize(size);
253     }
254 
SetFontStyle(OHOS::Ace::FontStyle style)255     void SetFontStyle(OHOS::Ace::FontStyle style)
256     {
257         state_.fillState.SetFontStyle(style);
258         state_.strokeState.SetFontStyle(style);
259     }
260 
SetFontWeight(FontWeight weight)261     void SetFontWeight(FontWeight weight)
262     {
263         state_.fillState.SetFontWeight(weight);
264         state_.strokeState.SetFontWeight(weight);
265     }
266 
SetFontFamilies(const std::vector<std::string> & fontFamilies)267     void SetFontFamilies(const std::vector<std::string>& fontFamilies)
268     {
269         state_.fillState.SetFontFamilies(fontFamilies);
270         state_.strokeState.SetFontFamilies(fontFamilies);
271     }
272 
273     void SaveProperties();
274     void RestoreProperties();
275     void ResetTransformMatrix();
276     void ResetLineDash();
277     void RotateMatrix(double angle);
278     void ScaleMatrix(double x, double y);
279     void SetTransformMatrix(const TransformParam& param);
280     void TransformMatrix(const TransformParam& param);
281     void TranslateMatrix(double tx, double ty);
282     void DrawSvgImage(RefPtr<SvgDomBase> svgDom, const Ace::CanvasImage& canvasImage, const ImageFit& imageFit);
283     void DrawImage(const Ace::CanvasImage& canvasImage, double width, double height);
284     void FillText(const std::string& text, double x, double y, std::optional<double> maxWidth);
285     void StrokeText(const std::string& text, double x, double y, std::optional<double> maxWidth);
286     TextMetrics MeasureTextMetrics(const std::string& text, const PaintState& state);
SetDensity(double density)287     void SetDensity(double density)
288     {
289         density_ = density;
290     }
291 
292 protected:
293     std::optional<double> CalcTextScale(double maxIntrinsicWidth, std::optional<double> maxWidth);
294     bool HasShadow() const;
295     void UpdateFontFamilies();
296     void UpdateLineDash(RSPen& pen);
297     void UpdatePaintShader(RSPen* pen, RSBrush* brush, const Ace::Gradient& gradient);
298     void UpdatePaintShader(const Ace::Pattern& pattern, RSPen* pen, RSBrush* brush);
299     bool UpdateFillParagraph(const std::string& text);
300     void UpdateFillTxtStyle(RSTextStyle& txtStyle);
301     bool UpdateStrokeParagraph(const std::string& text);
302     void UpdateStrokeShadowParagraph(const std::string& text, const RSPen* pen, const RSParagraphStyle& style);
303     void InitPaintBlend(RSBrush& brush);
304     void InitPaintBlend(RSPen& pen);
305     std::shared_ptr<RSShaderEffect> MakeConicGradient(RSBrush* brush, const Ace::Gradient& gradient);
306 
307     void Path2DFill();
308     void Path2DStroke();
309     void Path2DClip();
310     void ParsePath2D(const RefPtr<CanvasPath2D>& path);
311     void Path2DAddPath(const PathArgs& args);
312     void Path2DClosePath();
313     void Path2DMoveTo(const PathArgs& args);
314     void Path2DLineTo(const PathArgs& args);
315     void Path2DArc(const PathArgs& args);
316     void Path2DArcTo(const PathArgs& args);
317     void Path2DRect(const PathArgs& args);
318     void Path2DEllipse(const PathArgs& args);
319     void Path2DBezierCurveTo(const PathArgs& args);
320     void Path2DQuadraticCurveTo(const PathArgs& args);
321     void Path2DSetTransform(const PathArgs& args);
322     RSMatrix GetMatrixFromPattern(const Ace::Pattern& pattern);
323 
324     void SetGrayFilter(const std::string& percent);
325     void SetSepiaFilter(const std::string& percent);
326     void SetSaturateFilter(const std::string& percent);
327     void SetHueRotateFilter(const std::string& percent);
328     void SetInvertFilter(const std::string& percent);
329     void SetOpacityFilter(const std::string& percent);
330     void SetBrightnessFilter(const std::string& percent);
331     void SetContrastFilter(const std::string& percent);
332     void SetBlurFilter(const std::string& percent);
333 
334     bool GetFilterType(const std::string& filterStr, std::vector<FilterProperty>& filters);
335     bool IsPercentStr(std::string& percentStr);
336     double PxStrToDouble(const std::string& str);
337     double BlurStrToDouble(const std::string& str);
338     bool CheckNumberAndPercentage(const std::string& param, bool isClamped, float& result);
339     void InitImagePaint(RSPen* pen, RSBrush* brush, RSSamplingOptions& options);
340     void GetStrokePaint(RSPen& pen, RSSamplingOptions& options);
341     void GetFillPaint(RSBrush& brush, RSSamplingOptions& options);
342 
343     void SetPaintImage(RSPen* pen, RSBrush* brush);
344     void ClearPaintImage(RSPen* pen, RSBrush* brush);
345     float PercentStrToFloat(const std::string& percentStr);
346     bool CheckFilterProperty(FilterType filterType, const std::string& filterParam);
347     bool ParseFilter(std::string& filter, std::vector<FilterProperty>& filters);
348     FilterType FilterStrToFilterType(const std::string& filterStr);
349 
350     std::shared_ptr<RSImage> GetImage(const std::string& src);
351     void PaintShadow(const RSPath& path, const Shadow& shadow, const RSBrush* brush = nullptr,
352         const RSPen* pen = nullptr, RSSaveLayerOps* slo = nullptr);
353     void PaintImageShadow(const RSPath& path, const Shadow& shadow, const RSBrush* brush = nullptr,
354         const RSPen* pen = nullptr, RSSaveLayerOps* slo = nullptr);
355     void PaintText(const float width, double x, double y, std::optional<double> maxWidth, bool isStroke);
356     void PaintStrokeTextShadow(
357         const float width, const double dx, const double dy, const std::optional<double> scale, RSSaveLayerOps* slo);
358     double GetAlignOffset(TextAlign align, double width);
359     double GetBaselineOffset(TextBaseline baseline, std::unique_ptr<RSParagraph>& paragraph);
360     RSTextAlign GetEffectiveAlign(RSTextAlign align, RSTextDirection direction) const;
361 #ifndef ACE_UNITTEST
362     double GetFontBaseline(const Rosen::Drawing::FontMetrics& fontMetrics, TextBaseline baseline) const;
363     double GetFontAlign(TextAlign align, std::unique_ptr<RSParagraph>& paragraph) const;
364     virtual void ConvertTxtStyle(const TextStyle& textStyle, Rosen::TextStyle& txtStyle) = 0;
365 #endif
366     void ResetStates();
367     void DrawImageInternal(const Ace::CanvasImage& canvasImage, const std::shared_ptr<RSImage>& image);
368 
369     // PaintHolder includes fillState, strokeState, globalState and shadow for save
370     PaintHolder state_;
371     std::vector<PaintHolder> saveStates_;
372     LineDashParam lineDash_;
373     RSMatrix matrix_;
374     std::vector<RSMatrix> matrixStates_;
375     std::vector<LineDashParam> lineDashStates_;
376 
377     bool smoothingEnabled_ = true;
378     std::string smoothingQuality_ = "low";
379     bool antiAlias_ = false;
380     std::unique_ptr<RSParagraph> paragraph_;
381     std::unique_ptr<RSParagraph> shadowParagraph_;
382 
383     WeakPtr<PipelineBase> context_;
384 
385     RSPath rsPath_;
386     RSPath rsPath2d_;
387     RSBrush imageBrush_;
388     RSSamplingOptions sampleOptions_;
389     std::shared_ptr<RSCanvas> rsCanvas_;
390 
391     Ace::CanvasImage canvasImage_;
392     std::unique_ptr<Shadow> imageShadow_;
393     RSColorMatrix colorMatrix_;
394     double density_ = 1.0;
395 
396 #ifndef ACE_UNITTEST
397     sk_sp<SkSVGDOM> skiaDom_ = nullptr;
398     ImageSourceInfo currentSource_;
399     ImageSourceInfo loadingSource_;
400 #endif
401 
402     RefPtr<CanvasModifier> contentModifier_;
403 
404     SizeF lastLayoutSize_;
405     RefPtr<ImageCache> imageCache_;
406     enum DrawImageType {
407         THREE_PARAMS,
408         FIVE_PARAMS,
409         NINE_PARAMS,
410     };
411     static const LinearMapNode<void (*)(std::shared_ptr<RSImage>&, std::shared_ptr<RSShaderEffect>&, RSMatrix&)>
412         staticPattern[];
413     const float defaultOpacity = 1.0f;
414     std::shared_ptr<RSColorFilter> colorFilter_ = RSColorFilter::CreateMatrixColorFilter(colorMatrix_);
415     std::shared_ptr<RSImageFilter> blurFilter_ = RSImageFilter::CreateBlurImageFilter(0, 0, RSTileMode::DECAL, nullptr);
416     std::vector<std::shared_ptr<RSColorFilter>> saveColorFilter_;
417     std::vector<std::shared_ptr<RSImageFilter>> saveBlurFilter_;
418 };
419 } // namespace OHOS::Ace::NG
420 
421 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_CUSTOM_PAINT_CUSTOM_PAINT_PAINT_METHOD_H
422