[vector_graphics_compiler] Add modern HSL color parsing#11657
[vector_graphics_compiler] Add modern HSL color parsing#11657fondoger wants to merge 2 commits intoflutter:mainfrom
Conversation
Move HSL parsing into colors.dart alongside RGB parsing and add support for modern space-separated HSL/HSLA syntax. Add HSL parser coverage for legacy and modern forms, invalid syntax, and alpha clamp behavior.
|
@andywolff @gaaclarke this is a follow-up PR to #11619. It addresses the follow-up suggestions from that review:
Related issue: flutter/flutter#186153 |
There was a problem hiding this comment.
Code Review
This pull request introduces support for modern space-separated HSL and HSLA color syntax in the vector_graphics_compiler package. It adds new parsing logic and regex patterns, refactors the SVG parser to use these centralized functions, and includes comprehensive unit tests. Feedback recommends optimizing the HSL-to-RGB conversion by reducing list allocations and ensuring that saturation, luminance, and final RGB values are properly clamped.
I am having trouble creating individual review comments. Click here to see my feedback.
packages/vector_graphics_compiler/lib/src/svg/colors.dart (351-391)
The HSL to RGB conversion logic can be optimized by avoiding multiple list allocations and reassignments. Using a simple loop or direct index access is more efficient. Additionally, saturation and luminance values should be clamped to the [0, 100] range, and the final RGB values should be clamped to [0, 255] to ensure they are valid for Color.fromARGB.
Color _cssHslRecordToColor(CssHslRecord record) {
final double hue = _parseHslValue(record.h) / 360 % 1;
final double saturation = _parseHslValue(record.s).clamp(0, 100) / 100;
final double luminance = _parseHslValue(record.l).clamp(0, 100) / 100;
final int alpha = _parseHslAlpha(record.a);
final List<double> rgb = <double>[0, 0, 0];
if (hue < 1 / 6) {
rgb[0] = 1;
rgb[1] = hue * 6;
} else if (hue < 2 / 6) {
rgb[0] = 2 - hue * 6;
rgb[1] = 1;
} else if (hue < 3 / 6) {
rgb[1] = 1;
rgb[2] = hue * 6 - 2;
} else if (hue < 4 / 6) {
rgb[1] = 4 - hue * 6;
rgb[2] = 1;
} else if (hue < 5 / 6) {
rgb[0] = hue * 6 - 4;
rgb[2] = 1;
} else {
rgb[0] = 1;
rgb[2] = 6 - hue * 6;
}
for (int i = 0; i < 3; i++) {
rgb[i] += (1 - saturation) * (0.5 - rgb[i]);
if (luminance < 0.5) {
rgb[i] *= luminance * 2;
} else {
rgb[i] = luminance * 2 * (1 - rgb[i]) + 2 * rgb[i] - 1;
}
rgb[i] *= 255;
}
return Color.fromARGB(
alpha,
rgb[0].round().clamp(0, 255),
rgb[1].round().clamp(0, 255),
rgb[2].round().clamp(0, 255),
);
}Clamp HSL saturation and lightness to percentage bounds and clamp final RGB channel values during HSL conversion. Also avoid repeated list allocations in the conversion path.
|
Thanks for the review note. I pushed a follow-up commit addressing this feedback:
The alpha percentage conversion still uses Ran locally: flutter test test/colors_test.dart test/parsers_test.dart
dart analyze lib/src/svg/colors.dart lib/src/svg/parser.dart test/colors_test.dart test/parsers_test.dart |
|
autosubmit label was removed for flutter/packages/11657, because - The status or check suite Mac_x64 ios_build_all_packages master has failed. Please fix the issues identified (or deflake) before re-applying this label. |
|
Hi @gaaclarke, could you please trigger another CI/CD run? This run failed due to some transient issues. |
👍 hit rerun |
Description
Follow-up to #11619 and flutter/flutter#185833.
This moves HSL/HSLA function parsing from
parser.dartintocolors.dart, following the existingparseCssRgb/parseRgbFunctionstructure. It also adds support for the same practical legacy/modern syntax split already supported for RGB:hsl(270, 100%, 76%)hsl(270 100% 76% / 0.5)This is intentionally scoped to the existing regex-based numeric parser style; it does not attempt to implement the full CSS Color 4 grammar.
Tests
parseCssHslrecord parser tests covering legacy syntax, modern syntax, whitespace/case variations, decimal/negative tokens, and invalid syntax.SvgParser.parseColortests for modern HSL/HSLA conversion and HSLA alpha behavior.0,0%,1,100%,50%,-0.5,-10%,2, and150%.Ran locally:
flutter test test/colors_test.dart test/parsers_test.dart dart analyze lib/src/svg/colors.dart lib/src/svg/parser.dart test/colors_test.dart test/parsers_test.dartRelated Issues
Fixes flutter/flutter#186153