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 : char {
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 }) {}
Color(uint32_t value,uint32_t resId)58 constexpr explicit Color(uint32_t value, uint32_t resId)
59 : colorValue_(ColorParam { .value = value }), resourceId_(resId) {}
60 ~Color() = default;
61
62 static Color FromARGB(uint8_t alpha, uint8_t red, uint8_t green, uint8_t blue);
63 static Color FromRGBO(uint8_t red, uint8_t green, uint8_t blue, double opacity);
64 static Color FromRGB(uint8_t red, uint8_t green, uint8_t blue);
65 // Need to change the input parameters, it is more appropriate to use the passed value here.
66 static Color FromString(std::string colorStr, uint32_t maskAlpha = COLOR_ALPHA_MASK,
67 Color defaultColor = Color::BLACK);
68 static bool ParseColorString(std::string colorStr, Color& color, uint32_t maskAlpha = COLOR_ALPHA_MASK);
69 static bool ParseColorString(const std::string& colorStr, Color& color, const Color& defaultColor,
70 uint32_t maskAlpha = COLOR_ALPHA_MASK);
71 // Return the linear transition color from startColor to endColor.
72 static const Color LineColorTransition(const Color& startColor, const Color& endColor, double percent);
73
74 static const Color TRANSPARENT;
75 static const Color WHITE;
76 static const Color BLACK;
77 static const Color RED;
78 static const Color GREEN;
79 static const Color BLUE;
80 static const Color GRAY;
81 static const Color FOREGROUND;
82
83 Color BlendColor(const Color& overlayColor) const;
84
85 Color BlendColorWithAlpha(const Color& overlayColor) const;
86 Color BlendOpacity(double opacityRatio) const;
87 Color ChangeOpacity(double opacity) const;
88 Color ChangeAlpha(uint8_t alpha) const;
89
SetValue(uint32_t value)90 void SetValue(uint32_t value)
91 {
92 colorValue_.value = value;
93 }
94
GetValue()95 uint32_t GetValue() const
96 {
97 return colorValue_.value;
98 }
99
SetResourceId(uint32_t id)100 void SetResourceId(uint32_t id)
101 {
102 resourceId_ = id;
103 }
104
GetResourceId()105 uint32_t GetResourceId() const
106 {
107 return resourceId_;
108 }
109
GetAlpha()110 uint8_t GetAlpha() const
111 {
112 return colorValue_.argb.alpha;
113 }
114
GetRed()115 uint8_t GetRed() const
116 {
117 return colorValue_.argb.red;
118 }
119
GetGreen()120 uint8_t GetGreen() const
121 {
122 return colorValue_.argb.green;
123 }
124
GetBlue()125 uint8_t GetBlue() const
126 {
127 return colorValue_.argb.blue;
128 }
129
130 void UpdateColorByResourceId();
131
132 bool operator==(const Color& color) const
133 {
134 return colorValue_.value == color.GetValue();
135 }
136
137 bool operator!=(const Color& color) const
138 {
139 return !operator==(color);
140 }
141
142 Color operator+(const Color& color) const;
143
144 Color operator-(const Color& color) const;
145
146 Color operator*(double value) const;
147
148 Color operator/(double value) const;
149
150 std::string ColorToString() const;
151
152 static Color ColorFromString(const std::string& str);
153
154 std::string ToString() const;
155
156 private:
Color(ColorParam colorValue)157 constexpr explicit Color(ColorParam colorValue) : colorValue_(colorValue) {}
158
159 static double ConvertGammaToLinear(uint8_t value);
160 static void ConvertGammaToLinear(
161 const Color& gammaColor, double& linearRed, double& linearGreen, double& linearBlue);
162 static uint8_t ConvertLinearToGamma(double value);
163 static Color ConvertLinearToGamma(double alpha, double linearRed, double linearGreen, double linearBlue);
164 static bool MatchColorWithMagic(std::string& colorStr, uint32_t maskAlpha, Color& color);
165 static bool MatchColorWithMagicMini(std::string& colorStr, uint32_t maskAlpha, Color& color);
166 static bool MatchColorWithRGB(const std::string& colorStr, Color& color);
167 static bool MatchColorWithRGBA(const std::string& colorStr, Color& color);
168 static bool MatchColorSpecialString(const std::string& colorStr, Color& color);
169 static bool ParseUintColorString(const std::string& colorStr, Color& color);
170 static bool ParseUintColorString(const std::string& colorStr, Color& color, const Color& defaultColor);
171 static bool IsRGBValid(int value);
172 static bool IsOpacityValid(double value);
173 static bool FastCheckColorType(const std::string& colorStr, const std::string& expectPrefix,
174 const std::vector<size_t>& expectLengths);
175 static bool IsHexNumber(std::string& colorStr);
176
177 float CalculateBlend(float alphaLeft, float alphaRight, float valueLeft, float valueRight) const;
178 ColorParam colorValue_ { .value = 0xff000000 };
179 uint32_t resourceId_ = 0;
180 };
181
182 namespace StringUtils {
183
StringSplitter(const std::string & source,char delimiter,std::vector<Color> & out)184 inline void StringSplitter(const std::string& source, char delimiter, std::vector<Color>& out)
185 {
186 using Func = Color (*)(const std::string&);
187 Func func = [](const std::string& value) { return Color::FromString(value); };
188 StringSplitter(source, delimiter, func, out);
189 }
190
191 } // namespace StringUtils
192
193 class ACE_FORCE_EXPORT LinearColor {
194 public:
195 LinearColor() = default;
LinearColor(uint32_t argb)196 explicit LinearColor(uint32_t argb)
197 {
198 alpha_ = static_cast<int16_t>((argb & 0xFF000000) >> 24);
199 red_ = static_cast<int16_t>((argb & 0x00FF0000) >> 16);
200 green_ = static_cast<int16_t>((argb & 0x0000FF00) >> 8);
201 blue_ = static_cast<int16_t>(argb & 0xFF);
202 }
LinearColor(const Color & color)203 explicit LinearColor(const Color& color)
204 : alpha_(color.GetAlpha()), red_(color.GetRed()), green_(color.GetGreen()), blue_(color.GetBlue())
205 {}
LinearColor(int16_t alpha,int16_t red,int16_t green,int16_t blue)206 LinearColor(int16_t alpha, int16_t red, int16_t green, int16_t blue)
207 : alpha_(alpha), red_(red), green_(green), blue_(blue)
208 {}
209 ~LinearColor() = default;
210
211 static const LinearColor TRANSPARENT;
212 static const LinearColor WHITE;
213 static const LinearColor BLACK;
214 static const LinearColor RED;
215 static const LinearColor GREEN;
216 static const LinearColor BLUE;
217 static const LinearColor GRAY;
218
219 LinearColor operator+(const LinearColor& color) const
220 {
221 return LinearColor(GetAlpha() + color.GetAlpha(), GetRed() + color.GetRed(),
222 GetGreen() + color.GetGreen(), GetBlue() + color.GetBlue());
223 }
224
225 LinearColor operator-(const LinearColor& color) const
226 {
227 return LinearColor(GetAlpha() - color.GetAlpha(), GetRed() - color.GetRed(),
228 GetGreen() - color.GetGreen(), GetBlue() - color.GetBlue());
229 }
230
231 LinearColor operator*(double value) const
232 {
233 return LinearColor(static_cast<int16_t>(round(GetAlpha() * value)),
234 static_cast<int16_t>(round(GetRed() * value)), static_cast<int16_t>(round(GetGreen() * value)),
235 static_cast<int16_t>(round(GetBlue() * value)));
236 }
237
238 bool operator==(const LinearColor& color) const
239 {
240 return alpha_ == color.GetAlpha() && red_ == color.GetRed() && green_ == color.GetGreen() &&
241 blue_ == color.GetBlue();
242 }
243
GetRed()244 int16_t GetRed() const
245 {
246 return red_;
247 }
248
GetGreen()249 int16_t GetGreen() const
250 {
251 return green_;
252 }
253
GetBlue()254 int16_t GetBlue() const
255 {
256 return blue_;
257 }
258
GetAlpha()259 int16_t GetAlpha() const
260 {
261 return alpha_;
262 }
263
GetValue()264 uint32_t GetValue() const
265 {
266 return (static_cast<uint32_t>(std::clamp<int16_t>(blue_, 0, UINT8_MAX))) |
267 (static_cast<uint32_t>((std::clamp<int16_t>(green_, 0, UINT8_MAX)) << 8)) |
268 (static_cast<uint32_t>((std::clamp<int16_t>(red_, 0, UINT8_MAX)) << 16)) |
269 (static_cast<uint32_t>((std::clamp<int16_t>(alpha_, 0, UINT8_MAX)) << 24));
270 }
271
BlendOpacity(double opacityRatio)272 Color BlendOpacity(double opacityRatio) const
273 {
274 auto alpha = static_cast<int16_t>(GetAlpha() * opacityRatio);
275 return Color::FromARGB(
276 static_cast<uint8_t>(std::clamp<int16_t>(alpha, 0, UINT8_MAX)),
277 static_cast<uint8_t>(std::clamp<int16_t>(red_, 0, UINT8_MAX)),
278 static_cast<uint8_t>(std::clamp<int16_t>(green_, 0, UINT8_MAX)),
279 static_cast<uint8_t>(std::clamp<int16_t>(blue_, 0, UINT8_MAX)));
280 }
281
ToColor()282 Color ToColor() const
283 {
284 return Color::FromARGB(
285 static_cast<uint8_t>(std::clamp<int16_t>(alpha_, 0, UINT8_MAX)),
286 static_cast<uint8_t>(std::clamp<int16_t>(red_, 0, UINT8_MAX)),
287 static_cast<uint8_t>(std::clamp<int16_t>(green_, 0, UINT8_MAX)),
288 static_cast<uint8_t>(std::clamp<int16_t>(blue_, 0, UINT8_MAX)));
289 }
290
291 private:
292 int16_t alpha_;
293 int16_t red_;
294 int16_t green_;
295 int16_t blue_;
296 };
297
298 } // namespace OHOS::Ace
299
300 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_COLOR_H
301