• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.h
18  * @brief Defines Scanline gradient mode
19  * @since 1.0
20  * @version 1.0
21  */
22 
23 
24 #ifndef GRAPHIC_LITE_FILL_GRADIENT_H
25 #define GRAPHIC_LITE_FILL_GRADIENT_H
26 
27 
28 #include "gfx_utils/color.h"
29 #include "gfx_utils/diagram/common/common_basics.h"
30 #include "gfx_utils/diagram/spancolorfill/fill_interpolator.h"
31 #include "gfx_utils/diagram/spancolorfill/fill_gradient_lut.h"
32 #include "gfx_utils/graphic_math.h"
33 #include "fill_base.h"
34 namespace OHOS {
35 class Gradient {
36 public:
37     virtual int16_t  Calculate(int16_t x, int16_t y, int16_t startRadius, int16_t endRadius, int16_t size) = 0;
38 };
39 
40 /**
41  * Gradient scanline fill
42  * @ColorT Color source type, Interpolator span interpolator
43  * @GradientFgradient_function The function of
44  * the corresponding mode to calculate the position of the current point
45  * @ColorF Color array
46  */
47 class FillGradient : public SpanBase {
48 #if defined(GRAPHIC_ENABLE_GRADIENT_FILL_FLAG) && GRAPHIC_ENABLE_GRADIENT_FILL_FLAG
49 public:
FillGradient()50     FillGradient() {}
51     /**
52      * @brief SpanGradient Constructor for scanline gradient
53      * @param inter Interpolator
54      * @param GradientFunction
55      * The function of the corresponding mode to calculate the position of the current point
56      * @param ColorFunction Gradient array
57      * @param distance1 The parameter content is determined according to the mode:
58      * it is the starting circle radius when radiating the gradient
59      * @param distance2 Determine the parameter content according to the mode:
60      * the radius of the end circle in the case of radial gradient and
61      * the distance of the starting and ending points in the case of linear gradient
62      */
FillGradient(FillInterpolator & inter,Gradient & GradientFunction,FillGradientLut & ColorFunction,float distance1,float distance2)63     FillGradient(FillInterpolator& inter, Gradient& GradientFunction,
64                  FillGradientLut& ColorFunction, float distance1, float distance2)
65         : interpolator_(&inter),
66           gradientFunction_(&GradientFunction),
67           colorFunction_(&ColorFunction),
68           distance1_(static_cast<int32_t>(distance1 * GRADIENT_SUBPIXEL_SCALE)),
69           distance2_(static_cast<int32_t>(distance2 * GRADIENT_SUBPIXEL_SCALE)) {}
70 
Prepare()71     void Prepare() {}
72 
73     /**
74      * @brief Generate From colorfunction_ Remove the rgba from the span
75      * @param span First address of scan line to be filled
76      * @param x coordinate-x
77      * @param y coordinate-y
78      * @param len Scan line length
79      */
Generate(Rgba8T * span,int32_t x,int32_t y,uint32_t len)80     void Generate(Rgba8T* span, int32_t x, int32_t y, uint32_t len)
81     {
82         int32_t downscaleShift = FillInterpolator::SUBPIXEL_SHIFT - GRADIENT_SUBPIXEL_SHIFT;
83         interpolator_->Begin(x, y, len);
84         for (; len; --len, ++(*interpolator_), span++) {
85             interpolator_->Coordinates(&x, &y);
86             int32_t index = gradientFunction_->Calculate(x >> downscaleShift, y >> downscaleShift,
87                                                          distance1_, distance2_, colorFunction_->GetSize());
88             span->red = (*colorFunction_)[index].red;
89             span->green = (*colorFunction_)[index].green;
90             span->blue = (*colorFunction_)[index].blue;
91             span->alpha = (*colorFunction_)[index].alpha;
92         }
93     }
94 private:
95     FillInterpolator* interpolator_;
96     Gradient* gradientFunction_;
97     FillGradientLut* colorFunction_;
98     int32_t distance1_;
99     int32_t distance2_;
100 };
101 
102 
103 /**
104  * GradientFunction
105  * @brief The subscript of the current (x, y) ColorFunction array when calculating the radial gradient
106  * @since 1.0
107  * @version 1.0
108  */
109 class GradientRadialCalculate : public virtual Gradient {
110 public:
GradientRadialCalculate()111     GradientRadialCalculate()
112         : endRadius_(HUNDRED_TIMES * GRADIENT_SUBPIXEL_SCALE), dx_(0), dy_(0)
113     {
114         UpdateValues();
115     }
116 
117     /**
118      * @brief GradientRadialCalculate Constructor arguments
119      * @param endRadius End circle radius
120      * @param dx In the x-axis direction, the distance from the end circle center to the start circle center
121      * @param dy In the y-axis direction, the distance from the end circle center to the start circle center
122      */
GradientRadialCalculate(float endRadius,float dx,float dy)123     GradientRadialCalculate(float endRadius, float dx, float dy)
124         : endRadius_(static_cast<int32_t>(endRadius * GRADIENT_SUBPIXEL_SCALE)),
125           dx_(static_cast<int32_t>(dx * GRADIENT_SUBPIXEL_SCALE)),
126           dy_(static_cast<int32_t>(dy * GRADIENT_SUBPIXEL_SCALE))
127     {
128         UpdateValues();
129     }
130 
131     /**
132      * @brief calculate The subscript of the current (x, y) ColorFunction array
133      * when calculating the radial gradient
134      * @param x coordinate x
135      * @param y coordinate y
136      * @param startRadius Start circle radius
137      * @param endRadius End circle radius
138      * @param size colorFunction_µÄsize
139      * @return
140      */
Calculate(int16_t x,int16_t y,int16_t startRadius,int16_t endRadius,int16_t size)141     int16_t  Calculate(int16_t x, int16_t y, int16_t startRadius, int16_t endRadius, int16_t size)
142     {
143         float dx = x - dx_;
144         float dy = y - dy_;
145         float distanceRadius = dx * dy_ - dy * dx_;
146         float radiusDistance = endRadiusSquare_ * (dx * dx + dy * dy)
147                 - distanceRadius * distanceRadius;
148         float deltaRadius = endRadius - startRadius; // Difference of radius
149         if (deltaRadius < 1) {
150             deltaRadius = 1;
151         }
152         int16_t index = static_cast<int16_t>((((dx * dx_ + dy * dy_ +
153                         Sqrt(fabs(radiusDistance)))
154                         * mul_ - startRadius) * size) / deltaRadius);
155         if (index < 0) {
156             index = 0;
157         }
158         if (index >= size) {
159             index = size - 1;
160         }
161         return index;
162     }
163 
164 private:
165     /**
166      * @brief update mul_
167      */
UpdateValues()168     void UpdateValues()
169     {
170         endRadiusSquare_ = float(endRadius_) * float(endRadius_);
171         float dxSquare_ = float(dx_) * float(dx_);
172         float dySquare_ = float(dy_) * float(dy_);
173         float dRadius = (endRadiusSquare_ - (dxSquare_ + dySquare_));
174         if (dRadius == 0.0f) {
175             if (dx_) {
176                 if (dx_ < 0.0f) {
177                     ++dx_;
178                 } else {
179                     --dx_;
180                 }
181             }
182             if (dy_) {
183                 if (dy_ < 0.0f) {
184                     ++dy_;
185                 } else {
186                     --dy_;
187                 }
188             }
189             dxSquare_ = float(dx_) * float(dx_);
190             dySquare_ = float(dy_) * float(dy_);
191             dRadius = (endRadiusSquare_ - (dxSquare_ + dySquare_));
192         }
193         mul_ = endRadius_ / dRadius;
194     }
195 
196     int32_t endRadius_;
197     /** In the x-axis direction, the distance from the end circle center to the start circle center */
198     int32_t dx_;
199     /** In the y-axis direction, the distance from the end circle center to the start circle center */
200     int32_t dy_;
201     float endRadiusSquare_;
202     float mul_;
203 };
204 
205 /**
206  * @brief The subscript of the current (x, y) ColorFunction array when calculating a linear gradient
207  * @since 1.0
208  * @version 1.0
209  */
210 class GradientLinearCalculate : public virtual Gradient {
211 public:
212     /**
213      * @brief The subscript of the current (x, y) ColorFunction array when calculating a linear gradient
214      * @param x coordinate x
215      * @param distance Distance between start and end of linear gradient
216      * @param size color_functionµÄsize
217      * @return
218      */
Calculate(int16_t x,int16_t,int16_t,int16_t distance,int16_t size)219     int16_t Calculate(int16_t x, int16_t, int16_t, int16_t distance, int16_t size)
220     {
221         if (distance < 1) {
222             distance = 1;
223         }
224         int16_t index = (x * size) / distance;
225         if (index < 0) {
226             index = 0;
227         }
228         if (index >= size) {
229             index = size - 1;
230         }
231         return index;
232     }
233 #endif
234 };
235 } // namespace OHOS
236 #endif
237