| 220 | } |
| 221 | |
| 222 | Color parseColor(string_view str) { |
| 223 | if (str.empty()) { |
| 224 | return Color{0, 0, 0, 0}; |
| 225 | } |
| 226 | |
| 227 | if (str.starts_with("#")) { |
| 228 | unsigned int hexValue = 0; |
| 229 | istringstream iss(string{str.substr(1)}); |
| 230 | iss >> hex >> hexValue; |
| 231 | |
| 232 | if (str.size() == 4) { |
| 233 | // #RGB |
| 234 | return Color{ |
| 235 | toLinear(((hexValue >> 8) & 0xF) / 15.0f), |
| 236 | toLinear(((hexValue >> 4) & 0xF) / 15.0f), |
| 237 | toLinear((hexValue & 0xF) / 15.0f), |
| 238 | 1.0f, |
| 239 | }; |
| 240 | } else if (str.size() == 5) { |
| 241 | // #RGBA |
| 242 | return Color{ |
| 243 | toLinear(((hexValue >> 12) & 0xF) / 15.0f), |
| 244 | toLinear(((hexValue >> 8) & 0xF) / 15.0f), |
| 245 | toLinear(((hexValue >> 4) & 0xF) / 15.0f), |
| 246 | (hexValue & 0xF) / 15.0f, |
| 247 | }; |
| 248 | } else if (str.size() == 7) { |
| 249 | // #RRGGBB |
| 250 | return Color{ |
| 251 | toLinear(((hexValue >> 16) & 0xFF) / 255.0f), |
| 252 | toLinear(((hexValue >> 8) & 0xFF) / 255.0f), |
| 253 | toLinear((hexValue & 0xFF) / 255.0f), |
| 254 | 1.0f, |
| 255 | }; |
| 256 | } else if (str.size() == 9) { |
| 257 | // #RRGGBBAA |
| 258 | return Color{ |
| 259 | toLinear(((hexValue >> 24) & 0xFF) / 255.0f), |
| 260 | toLinear(((hexValue >> 16) & 0xFF) / 255.0f), |
| 261 | toLinear(((hexValue >> 8) & 0xFF) / 255.0f), |
| 262 | (hexValue & 0xFF) / 255.0f, |
| 263 | }; |
| 264 | } else { |
| 265 | throw runtime_error{fmt::format("Invalid hex color format: {}", str)}; |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | const auto parts = split(str, ","); |
| 270 | if (parts.size() < 3 || parts.size() > 4) { |
| 271 | throw runtime_error{fmt::format("Invalid color format: {}", str)}; |
| 272 | } |
| 273 | |
| 274 | Color color = {0.0f, 0.0f, 0.0f, 1.0f}; |
| 275 | for (size_t i = 0; i < parts.size(); ++i) { |
| 276 | if (!fromChars(trim(parts[i]), color[i])) { |
| 277 | throw runtime_error{fmt::format("Invalid color component: {}", parts[i])}; |
| 278 | } |
| 279 | } |