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 #ifndef PATH_EFFECT_H
17 #define PATH_EFFECT_H
18 
19 #include "draw/path.h"
20 #include "drawing/engine_adapter/impl_interface/path_effect_impl.h"
21 #include "utils/drawing_macros.h"
22 #include "utils/scalar.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 namespace Drawing {
27 enum class PathDashStyle {
28     TRANSLATE,
29     ROTATE,
30     MORPH,
31 };
32 class DRAWING_API PathEffect {
33 public:
34     enum class PathEffectType {
35         NO_TYPE,
36         DASH,
37         PATH_DASH,
38         CORNER,
39         DISCRETE,
40         SUM,
41         COMPOSE,
42     };
43 
44     /**
45      * @brief Create a Dash PathEffect. Note: only affects stroked paths.
46      *
47      * @param intervals array containing an even number of entries (>=2), with
48      * the even indices specifying the length of "on" intervals, and the odd
49      * indices specifying the length of "off" intervals. This array will be
50      * copied in Make, and can be disposed of freely after.
51      * @param count number of elements in the intervals array.
52      * @param phase offset into the intervals array (mod the sum of all of the intervals).
53      * For example: if intervals[] = {10, 20}, count = 2, and phase = 25,
54      * this will set up a dashed path like so:
55      * 5 pixels off
56      * 10 pixels on
57      * 20 pixels off
58      * 10 pixels on
59      * 20 pixels off
60      * ...
61      * A phase of -5, 25, 55, 85, etc. would all result in the same path,
62      * because the sum of all the intervals is 30.
63      * @return A shared pointer to PathEffect.
64      */
65     static std::shared_ptr<PathEffect> CreateDashPathEffect(const scalar intervals[], int count, scalar phase);
66     static std::shared_ptr<PathEffect> CreatePathDashEffect(
67         const Path& path, scalar advance, scalar phase, PathDashStyle style);
68 
69     /**
70      * @brief Create a Corner Path Effect.
71      *
72      * @param radius radius must be > 0 to have an effect.
73      * It specifies the distance from each corner that should be "rounded".
74      * @return A shared pointer to PathEffect.
75      */
76     static std::shared_ptr<PathEffect> CreateCornerPathEffect(scalar radius);
77 
78     /**
79      * @brief Create a Discrete PathEffect object.
80      * This path effect chops a path into discrete segments, and randomly displaces them.
81      * Break the path into segments of segLength length, and randomly move the endpoints
82      * away from the original path by a maximum of deviation.
83      * Note: works on filled or framed paths.
84      *
85      * @param segLength
86      * @param dev
87      * @param seedAssist This is a caller-supplied seedAssist that modifies
88      * the seed value that is used to randomize the path segments' endpoints.
89      * If not supplied it defaults to 0, in which case filtering a path multiple
90      * times will result in the same set of segments (this is useful for testing).
91      * If a caller does not want this behaviour they can pass in a different seedAssist
92      * to get a different set of path segments.
93      * @return A shared pointer to PathEffect.
94      */
95     static std::shared_ptr<PathEffect> CreateDiscretePathEffect(scalar segLength, scalar dev, uint32_t seedAssist = 0);
96 
97     /**
98      * @brief Create a Sum PathEffect object that apples each effect (first and second) to the original path,
99      * and returns a path with the sum of these.
100      *
101      * result = first(path) + second(path)
102      *
103      * @param e1 first PathEffect
104      * @param e2 second PathEffect
105      * @return std::shared_ptr<PathEffect>
106      */
107     static std::shared_ptr<PathEffect> CreateSumPathEffect(PathEffect& e1, PathEffect& e2);
108     /**
109      * @brief Create a Compose PathEffect that applies the inner effect to the path, and then applies the
110      *  outer effect to the result of the inner's.
111      *
112      * result = outer(inner(path))
113      * @return a share pointer to PathEffect
114      */
115     static std::shared_ptr<PathEffect> CreateComposePathEffect(PathEffect& e1, PathEffect& e2);
116 
~PathEffect()117     virtual ~PathEffect() {}
118     PathEffectType GetType() const;
GetDrawingType()119     virtual DrawingType GetDrawingType() const
120     {
121         return DrawingType::COMMON;
122     }
123     PathEffect(PathEffectType t, const scalar intervals[], int count, scalar phase) noexcept;
124     PathEffect(PathEffectType t, const Path& path, scalar advance, scalar phase, PathDashStyle style) noexcept;
125     PathEffect(PathEffectType t, scalar radius) noexcept;
126     PathEffect(PathEffectType t, scalar segLength, scalar dev, uint32_t seedAssist) noexcept;
127     PathEffect(PathEffectType t, PathEffect& e1, PathEffect& e2) noexcept;
128     PathEffect(PathEffectType t) noexcept;
129 
130     template<typename T>
GetImpl()131     T* GetImpl() const
132     {
133         return impl_->DowncastingTo<T>();
134     }
135 
136     std::shared_ptr<Data> Serialize() const;
137     bool Deserialize(std::shared_ptr<Data> data);
138 protected:
139     PathEffect() noexcept;
140 
141 private:
142     PathEffectType type_;
143     std::shared_ptr<PathEffectImpl> impl_;
144 };
145 } // namespace Drawing
146 } // namespace Rosen
147 } // namespace OHOS
148 #endif