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 /**
17  * @file fill_gradient_lut.h
18  * @brief Defines Gradient mode
19  * @since 1.0
20  * @version 1.0
21  */
22 
23 #ifndef GRAPHIC_LITE_FILL_GRADIENT_LUT_H
24 #define GRAPHIC_LITE_FILL_GRADIENT_LUT_H
25 
26 #include "gfx_utils/color.h"
27 #include "gfx_utils/diagram/vertexprimitive/geometry_dda_line.h"
28 #include "gfx_utils/diagram/vertexprimitive/geometry_plaindata_array.h"
29 #include "gfx_utils/diagram/vertexprimitive/geometry_range_adapter.h"
30 #include "gfx_utils/diagram/spancolorfill/fill_interpolator.h"
31 #include "gfx_utils/vector.h"
32 namespace OHOS {
33 const uint32_t COLOR_PROFILE_SIZE = 4;
34 const uint16_t COLOR_LUT_SIZE = 512;
35 /**
36 * @brief According to remove_all,add_color,and build_lut,
37 * build the color gradient process, start, end and middle gradient colors
38 * @param The parameters are colorinterpolator color interpolator and colorlutsize color cell size
39 * @since 1.0
40 * @version 1.0
41 */
42 class FillGradientLut {
43 #if defined(GRAPHIC_ENABLE_GRADIENT_FILL_FLAG) && GRAPHIC_ENABLE_GRADIENT_FILL_FLAG
44 public:
FillGradientLut()45     FillGradientLut() : colorProfile_(COLOR_PROFILE_SIZE), colorType_(COLOR_LUT_SIZE), colorLutSize_(COLOR_LUT_SIZE) {}
46     /**
47      * @brief Remove all colors
48      * @since 1.0
49      * @version 1.0
50      */
RemoveAll()51     void RemoveAll()
52     {
53         colorProfile_.Clear();
54     }
55 
56     /**
57      * @brief Add the color and position you want to gradient during the gradient process
58      * @param offset (0-1)
59      * @param color Added color
60      * @since 1.0
61      * @version 1.0
62      */
AddColor(float offset,const Rgba8T & color)63     void AddColor(float offset, const Rgba8T& color)
64     {
65         colorProfile_.PushBack(ColorPoint(offset, color));
66     }
67 
68     /**
69      * @brief Building a color_typ array from gradient colors
70      * Array length 0-255
71      * The contents of the array are distributed on the array according to the gradient color
72      * @since 1.0
73      * @version 1.0
74      */
BuildLut()75     void BuildLut()
76     {
77         /*
78          * For gradient color array memory quick sort
79          */
80         QuickSort(colorProfile_, OffsetLess);
81         colorProfile_.ReSize(RemoveDuplicates(colorProfile_, OffsetEqual));
82         if (colorProfile_.Size() > 1) {
83             uint32_t index;
84             uint32_t start = static_cast<uint32_t>(colorProfile_[0].offset * colorLutSize_);
85             uint32_t end;
86             Rgba8T color = colorProfile_[0].color;
87 
88             /*
89              * Assign initial color calculation to colorprofile [0]
90              */
91             for (index = 0; index < start; index++) {
92                 colorType_[index] = color;
93             }
94             /*
95              * From 1 to colorprofile Interpolation color calculation between size ()
96              */
97             for (index = 1; index < colorProfile_.Size(); index++) {
98                 end = static_cast<uint32_t>(colorProfile_[index].offset * colorLutSize_);
99                 ColorInterpolator ci(colorProfile_[index - 1].color,
100                                      colorProfile_[index].color,
101                                      end - start + 1);
102                 while (start < end) {
103                     colorType_[start] = ci.GetColor();
104                     ++ci;
105                     ++start;
106                 }
107             }
108             color = colorProfile_.End()->color;
109             /*
110              * Give end color to colorprofile last
111              */
112             for (; end < colorType_.GetSize(); end++) {
113                 color = colorProfile_.End()->color;
114                 colorType_[end] = color;
115             }
116         }
117     }
118 
119     /**
120      * @brief size Returns the size of the colorprofile
121      */
GetSize()122     uint32_t GetSize()
123     {
124         return colorLutSize_;
125     }
126 
127     /**
128      * @brief Override [] operator
129      */
130     const Rgba8T& operator[](uint32_t i) const
131     {
132         return colorType_[i];
133     }
134 private:
135     struct ColorPoint {
136         float offset;
137         Rgba8T color;
138 
ColorPointColorPoint139         ColorPoint() {}
140         /**
141          * @brief Input parameter
142          * @param offsetValue (0-1)
143          * @param color_ Added color
144          */
ColorPointColorPoint145         ColorPoint(float offsetValue, const Rgba8T& colorValue)
146             : offset(offsetValue), color(colorValue)
147         {
148             if (offset < 0.0f) {
149                 offset = 0.0f;
150             }
151             if (offset > 1.0f) {
152                 offset = 1.0f;
153             }
154         }
155     };
156 
157     /**
158      * @brief OffsetLess Returns the comparison result that the offset of a is smaller than that of B
159      * @param colorPoint1 struct ColorPoint struct
160      * @param colorPoint2 struct ColorPoint struct
161      * @return true: colorpoint1 precedes colorpoint2 false colorpoint1 follows colorpoint2
162      */
OffsetLess(const ColorPoint & colorPoint1,const ColorPoint & colorPoint2)163     static bool OffsetLess(const ColorPoint& colorPoint1, const ColorPoint& colorPoint2)
164     {
165         return colorPoint1.offset < colorPoint2.offset;
166     }
167 
168     /**
169      * @brief OffsetEqual Returns a comparison result in
170      * which the offset of comparison a is equal to that of comparison b
171      * @param colorPoint1 struct ColorPoint struct
172      * @param colorPoint2 struct ColorPoint struct
173      * @return Return true: the offsets of colorpoint1 and colorpoint2 are equal,
174      * and false: the offsets of a and B are not equal
175      */
OffsetEqual(const ColorPoint & colorPoint1,const ColorPoint & colorPoint2)176     static bool OffsetEqual(const ColorPoint& colorPoint1, const ColorPoint& colorPoint2)
177     {
178         return colorPoint1.offset == colorPoint2.offset;
179     }
180     Graphic::Vector<ColorPoint> colorProfile_;
181     GeometryPlainDataArray<Rgba8T> colorType_;
182     uint16_t colorLutSize_;
183 #endif
184 };
185 } // namespace OHOS
186 #endif
187