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 FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_COLOR_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_COLOR_H
18
19 #include <cstdint>
20 #include <string>
21
22 #include "base/utils/macros.h"
23 #include "base/utils/string_utils.h"
24
25 namespace OHOS::Ace {
26
27 constexpr uint32_t COLOR_ALPHA_MASK = 0xff000000;
28
29 union ColorParam {
30 #if BIG_ENDIANNESS
31 struct {
32 uint8_t alpha;
33 uint8_t red;
34 uint8_t green;
35 uint8_t blue;
36 } argb;
37 #else
38 struct {
39 uint8_t blue;
40 uint8_t green;
41 uint8_t red;
42 uint8_t alpha;
43 } argb;
44 #endif
45 uint32_t value;
46 };
47
48 enum class ForegroundColorStrategy : uint32_t {
49 NONE,
50 INVERT,
51 };
52
53 // A color value present by 32 bit.
54 class ACE_FORCE_EXPORT Color {
55 public:
56 Color() = default;
Color(uint32_t value)57 constexpr explicit Color(uint32_t value) : colorValue_(ColorParam { .value = value }) {}
58 ~Color() = default;
59
60 static Color FromARGB(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue);
61 static Color FromRGBO(uint8_t red, uint8_t green, uint8_t blue, double opacity);
62 static Color FromRGB(uint8_t red, uint8_t green, uint8_t blue);
63 // Need to change the input parameters, it is more appropriate to use the passed value here.
64 static Color FromString(std::string colorStr, uint32_t maskAlpha = COLOR_ALPHA_MASK,
65 Color defaultColor = Color::BLACK);
66 static bool ParseColorString(std::string colorStr, Color& color, uint32_t maskAlpha = COLOR_ALPHA_MASK);
67 // Return the linear transition color from startColor to endColor.
68 static const Color LineColorTransition(const Color& startColor, const Color& endColor, double percent);
69
70 static const Color TRANSPARENT;
71 static const Color WHITE;
72 static const Color BLACK;
73 static const Color RED;
74 static const Color GREEN;
75 static const Color BLUE;
76 static const Color GRAY;
77 static const Color FOREGROUND;
78
79 Color BlendColor(const Color& overlayColor) const;
80
81 Color BlendColorWithAlpha(const Color& overlayColor) const;
82 Color BlendOpacity(double opacityRatio) const;
83 Color ChangeOpacity(double opacity) const;
84 Color ChangeAlpha(uint8_t alpha) const;
85
SetValue(uint32_t value)86 void SetValue(uint32_t value)
87 {
88 colorValue_.value = value;
89 }
90
GetValue()91 uint32_t GetValue() const
92 {
93 return colorValue_.value;
94 }
95
GetAlpha()96 uint8_t GetAlpha() const
97 {
98 return colorValue_.argb.alpha;
99 }
100
GetRed()101 uint8_t GetRed() const
102 {
103 return colorValue_.argb.red;
104 }
105
GetGreen()106 uint8_t GetGreen() const
107 {
108 return colorValue_.argb.green;
109 }
110
GetBlue()111 uint8_t GetBlue() const
112 {
113 return colorValue_.argb.blue;
114 }
115
116 bool operator==(const Color& color) const
117 {
118 return colorValue_.value == color.GetValue();
119 }
120
121 bool operator!=(const Color& color) const
122 {
123 return !operator==(color);
124 }
125
126 Color operator+(const Color& color) const;
127
128 Color operator-(const Color& color) const;
129
130 Color operator*(double value) const;
131
132 Color operator/(double value) const;
133
134 std::string ColorToString() const;
135
136 static Color ColorFromString(const std::string& str);
137
138 private:
Color(ColorParam colorValue)139 constexpr explicit Color(ColorParam colorValue) : colorValue_(colorValue) {}
140
141 static double ConvertGammaToLinear(uint8_t value);
142 static void ConvertGammaToLinear(
143 const Color& gammaColor, double& linearRed, double& linearGreen, double& linearBlue);
144 static uint8_t ConvertLinearToGamma(double value);
145 static Color ConvertLinearToGamma(double alpha, double linearRed, double linearGreen, double linearBlue);
146 static bool MatchColorWithMagic(std::string& colorStr, uint32_t maskAlpha, Color& color);
147 static bool MatchColorWithMagicMini(std::string& colorStr, uint32_t maskAlpha, Color& color);
148 static bool MatchColorWithRGB(const std::string& colorStr, Color& color);
149 static bool MatchColorWithRGBA(const std::string& colorStr, Color& color);
150 static bool MatchColorSpecialString(const std::string& colorStr, Color& color);
151 static bool ParseUintColorString(const std::string& colorStr, Color& color);
152 static bool IsRGBValid(int value);
153 static bool IsOpacityValid(double value);
154
155 float CalculateBlend(float alphaLeft, float alphaRight, float valueLeft, float valueRight) const;
156 ColorParam colorValue_ { .value = 0xff000000 };
157 };
158
159 namespace StringUtils {
160
StringSplitter(const std::string & source,char delimiter,std::vector<Color> & out)161 inline void StringSplitter(const std::string& source, char delimiter, std::vector<Color>& out)
162 {
163 using Func = Color (*)(const std::string&);
164 Func func = [](const std::string& value) { return Color::FromString(value); };
165 StringSplitter(source, delimiter, func, out);
166 }
167
168 } // namespace StringUtils
169
170 class ACE_EXPORT LinearColor {
171 public:
172 LinearColor() = default;
LinearColor(uint32_t argb)173 explicit LinearColor(uint32_t argb)
174 {
175 alpha_ = static_cast<int16_t>((argb & 0xFF000000) >> 24);
176 red_ = static_cast<int16_t>((argb & 0x00FF0000) >> 16);
177 green_ = static_cast<int16_t>((argb & 0x0000FF00) >> 8);
178 blue_ = static_cast<int16_t>(argb & 0xFF);
179 }
LinearColor(const Color & color)180 explicit LinearColor(const Color& color)
181 : alpha_(color.GetAlpha()), red_(color.GetRed()), green_(color.GetGreen()), blue_(color.GetBlue())
182 {}
LinearColor(int16_t alpha,int16_t red,int16_t green,int16_t blue)183 LinearColor(int16_t alpha, int16_t red, int16_t green, int16_t blue)
184 : alpha_(alpha), red_(red), green_(green), blue_(blue)
185 {}
186 ~LinearColor() = default;
187
188 static const LinearColor TRANSPARENT;
189 static const LinearColor WHITE;
190 static const LinearColor BLACK;
191 static const LinearColor RED;
192 static const LinearColor GREEN;
193 static const LinearColor BLUE;
194 static const LinearColor GRAY;
195
196 LinearColor operator+(const LinearColor& color) const
197 {
198 return LinearColor(GetAlpha() + color.GetAlpha(), GetRed() + color.GetRed(),
199 GetGreen() + color.GetGreen(), GetBlue() + color.GetBlue());
200 }
201
202 LinearColor operator-(const LinearColor& color) const
203 {
204 return LinearColor(GetAlpha() - color.GetAlpha(), GetRed() - color.GetRed(),
205 GetGreen() - color.GetGreen(), GetBlue() - color.GetBlue());
206 }
207
208 LinearColor operator*(double value) const
209 {
210 return LinearColor(static_cast<int16_t>(round(GetAlpha() * value)),
211 static_cast<int16_t>(round(GetRed() * value)), static_cast<int16_t>(round(GetGreen() * value)),
212 static_cast<int16_t>(round(GetBlue() * value)));
213 }
214
215 bool operator==(const LinearColor& color) const
216 {
217 return alpha_ == color.GetAlpha() && red_ == color.GetRed() && green_ == color.GetGreen() &&
218 blue_ == color.GetBlue();
219 }
220
GetRed()221 int16_t GetRed() const
222 {
223 return red_;
224 }
225
GetGreen()226 int16_t GetGreen() const
227 {
228 return green_;
229 }
230
GetBlue()231 int16_t GetBlue() const
232 {
233 return blue_;
234 }
235
GetAlpha()236 int16_t GetAlpha() const
237 {
238 return alpha_;
239 }
240
GetValue()241 uint32_t GetValue() const
242 {
243 return (static_cast<uint32_t>(std::clamp<int16_t>(blue_, 0, UINT8_MAX))) |
244 (static_cast<uint32_t>((std::clamp<int16_t>(green_, 0, UINT8_MAX)) << 8)) |
245 (static_cast<uint32_t>((std::clamp<int16_t>(red_, 0, UINT8_MAX)) << 16)) |
246 (static_cast<uint32_t>((std::clamp<int16_t>(alpha_, 0, UINT8_MAX)) << 24));
247 }
248
BlendOpacity(double opacityRatio)249 Color BlendOpacity(double opacityRatio) const
250 {
251 auto alpha = static_cast<int16_t>(GetAlpha() * opacityRatio);
252 return Color::FromARGB(
253 static_cast<uint8_t>(std::clamp<int16_t>(alpha, 0, UINT8_MAX)),
254 static_cast<uint8_t>(std::clamp<int16_t>(red_, 0, UINT8_MAX)),
255 static_cast<uint8_t>(std::clamp<int16_t>(green_, 0, UINT8_MAX)),
256 static_cast<uint8_t>(std::clamp<int16_t>(blue_, 0, UINT8_MAX)));
257 }
258
ToColor()259 Color ToColor() const
260 {
261 return Color::FromARGB(
262 static_cast<uint8_t>(std::clamp<int16_t>(alpha_, 0, UINT8_MAX)),
263 static_cast<uint8_t>(std::clamp<int16_t>(red_, 0, UINT8_MAX)),
264 static_cast<uint8_t>(std::clamp<int16_t>(green_, 0, UINT8_MAX)),
265 static_cast<uint8_t>(std::clamp<int16_t>(blue_, 0, UINT8_MAX)));
266 }
267
268 private:
269 int16_t alpha_;
270 int16_t red_;
271 int16_t green_;
272 int16_t blue_;
273 };
274
275 } // namespace OHOS::Ace
276
277 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_COLOR_H
278