From 83ce54ed3e4005b56b571e723d090003c4e6bf7c Mon Sep 17 00:00:00 2001 From: Chris Gervang Date: Tue, 28 Jul 2026 08:29:01 -0700 Subject: [PATCH] fix(core): accept alpha in hsl colors (#4435) --- CHANGELOG.md | 1 + test/util/color.test.cpp | 17 +++++++++++++++++ vendor/csscolorparser/csscolorparser.cpp | 2 ++ 3 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4c5e325b..5d4259879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ ### 🐞 Bug fixes - *...Add new stuff here...* +- [core] Accept alpha values in legacy comma-separated `hsl()` colors ([#4434](https://github.com/maplibre/maplibre-native/issues/4434)). - [core] Fix thread-unsafe headless OpenGL display singleton initialization [#4332](https://github.com/maplibre/maplibre-native/pull/4332) - [macos] Fix `mlt-cpp` and `mbgl-vendor-icu` not being included in the amalgamation - [core] Fix memory access violation exception in vector_tile_data.cpp [#632](https://github.com/maplibre/maplibre-native/pull/632) diff --git a/test/util/color.test.cpp b/test/util/color.test.cpp index c806931f9..24413924d 100644 --- a/test/util/color.test.cpp +++ b/test/util/color.test.cpp @@ -26,6 +26,8 @@ const std::map> testCases = { {"rgb(-10, 0, 0)", Color(0.0f, 0.0f, 0.0f, 1.0f)}, // Clamped to 0 {"rgba(300, 0, 0, 1.0)", Color(1.0f, 0.0f, 0.0f, 1.0f)}, // Clamped to 1 {"rgba(100,100,100,0.2)", Color(20.0f / 255, 20.0f / 255, 20.0f / 255, 0.2f)}, + {"hsl(120,100%,25%)", Color(0.0f, 0.5f, 0.0f, 1.0f)}, + {"hsl(240,0%,55%,0.2)", Color(0.11f, 0.11f, 0.11f, 0.2f)}, // 4-digit hex with alpha (#RGBA) {"#0F0F", Color(0.0f, 1.0f, 0.0f, 1.0f)}, {"#F00C", Color(0.8f, 0.0f, 0.0f, 0.8f)}, // Red with ~80% alpha @@ -38,6 +40,9 @@ const std::map> testCases = { // Invalid inputs {"not-a-color", std::nullopt}, {"", std::nullopt}, + {"hsl(120,100%)", std::nullopt}, + {"hsl(120,100%,50%,1,0)", std::nullopt}, + {"hsla(120,100%,50%)", std::nullopt}, }; TEST(ColorParse, AllCases) { @@ -61,3 +66,15 @@ TEST(ColorParse, AllCases) { } } } + +TEST(ColorParse, HSLWithAlphaMatchesHSLA) { + const auto hsl = Color::parse("hsl(114,55%,73%,0.8)"); + const auto hsla = Color::parse("hsla(114,55%,73%,0.8)"); + + ASSERT_TRUE(hsl.has_value()); + ASSERT_TRUE(hsla.has_value()); + EXPECT_FLOAT_EQ(hsl->r, hsla->r); + EXPECT_FLOAT_EQ(hsl->g, hsla->g); + EXPECT_FLOAT_EQ(hsl->b, hsla->b); + EXPECT_FLOAT_EQ(hsl->a, hsla->a); +} diff --git a/vendor/csscolorparser/csscolorparser.cpp b/vendor/csscolorparser/csscolorparser.cpp index 00b2f6617..c7195ae6c 100644 --- a/vendor/csscolorparser/csscolorparser.cpp +++ b/vendor/csscolorparser/csscolorparser.cpp @@ -282,6 +282,8 @@ std::optional parse(const std::string& css_str) { return {}; } alpha = parse_css_float(params.back()); + } else if (params.size() == 4) { + alpha = parse_css_float(params.back()); } else { if (params.size() != 3) { return {};