From b6321de3ebad0c627b60aa6b1ee59039422047f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AA=E3=81=A4=E3=81=8D?= Date: Mon, 26 Jan 2026 10:44:49 -0800 Subject: [PATCH 1/4] Use gamma 2.40 for display-referred rec2020 --- lib/src/value/color/space/rec2020.dart | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/lib/src/value/color/space/rec2020.dart b/lib/src/value/color/space/rec2020.dart index 822fb2359..be33d28af 100644 --- a/lib/src/value/color/space/rec2020.dart +++ b/lib/src/value/color/space/rec2020.dart @@ -11,12 +11,6 @@ import '../conversions.dart'; import '../space.dart'; import 'utils.dart'; -/// A constant used in the rec2020 gamma encoding/decoding functions. -const _alpha = 1.09929682680944; - -/// A constant used in the rec2020 gamma encoding/decoding functions. -const _beta = 0.018053968510807; - /// The rec2020 color space. /// /// https://www.w3.org/TR/css-color-4/#predefined-rec2020 @@ -30,20 +24,18 @@ final class Rec2020ColorSpace extends ColorSpace { @protected double toLinear(double channel) { - // Algorithm from https://www.w3.org/TR/css-color-4/#color-conversion-code + // Non-linear transfer function from Rec. ITU-R BT.2020-2 table 4 + // Reference electro-optical transfer function from Rec. ITU-R BT.1886 Annex 1 + // with b (black lift) = 0 and a (user gain) = 1 + // defined over the extended range, not clamped var abs = channel.abs(); - return abs < _beta * 4.5 - ? channel / 4.5 - : channel.sign * (math.pow((abs + _alpha - 1) / _alpha, 1 / 0.45)); + return channel.sign * math.pow(abs, 2.40); } @protected double fromLinear(double channel) { - // Algorithm from https://www.w3.org/TR/css-color-4/#color-conversion-code var abs = channel.abs(); - return abs > _beta - ? channel.sign * (_alpha * math.pow(abs, 0.45) - (_alpha - 1)) - : 4.5 * channel; + return channel.sign * math.pow(abs, 1 / 2.40); } @protected From d0f357cc7bc5f65c871f63d8e95f3e8659933c76 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 27 Jan 2026 15:19:04 -0800 Subject: [PATCH 2/4] Tweak style, update pubspec and changelog --- CHANGELOG.md | 7 +++++++ lib/src/value/color/space/rec2020.dart | 18 ++++++------------ pkg/sass-parser/CHANGELOG.md | 4 ++++ pkg/sass-parser/package.json | 2 +- pkg/sass_api/CHANGELOG.md | 4 ++++ pkg/sass_api/pubspec.yaml | 4 ++-- pubspec.yaml | 2 +- 7 files changed, 25 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cdd7f5c3..25ebea2ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.98.0 + +* **Potentially breaking CSS compatibility fix:** In keeping with the latest CSS + specification, this release changes the algorithm for converting colors to and + from the `rec2020` color space. This now uses the EOTF algorithm with a gamma + of 1.961. + ## 1.97.3 * Fix a bug where nesting an at-rule within multiple style rules in plain CSS diff --git a/lib/src/value/color/space/rec2020.dart b/lib/src/value/color/space/rec2020.dart index be33d28af..08f3e494b 100644 --- a/lib/src/value/color/space/rec2020.dart +++ b/lib/src/value/color/space/rec2020.dart @@ -23,20 +23,14 @@ final class Rec2020ColorSpace extends ColorSpace { const Rec2020ColorSpace() : super('rec2020', rgbChannels); @protected - double toLinear(double channel) { - // Non-linear transfer function from Rec. ITU-R BT.2020-2 table 4 - // Reference electro-optical transfer function from Rec. ITU-R BT.1886 Annex 1 - // with b (black lift) = 0 and a (user gain) = 1 - // defined over the extended range, not clamped - var abs = channel.abs(); - return channel.sign * math.pow(abs, 2.40); - } + double toLinear(double channel) => + // Algorithm from https://drafts.csswg.org/css-color-4/#color-conversion-code + channel.sign * math.pow(channel.abs(), 2.4); @protected - double fromLinear(double channel) { - var abs = channel.abs(); - return channel.sign * math.pow(abs, 1 / 2.40); - } + double fromLinear(double channel) => + // Algorithm from https://drafts.csswg.org/css-color-4/#color-conversion-code + channel.sign * math.pow(channel.abs(), 1/2.4); @protected Float64List transformationMatrix(ColorSpace dest) => switch (dest) { diff --git a/pkg/sass-parser/CHANGELOG.md b/pkg/sass-parser/CHANGELOG.md index 3bf14ce68..9970a8dfb 100644 --- a/pkg/sass-parser/CHANGELOG.md +++ b/pkg/sass-parser/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.43 + +* No user-visible changes. + ## 0.4.42 * No user-visible changes. diff --git a/pkg/sass-parser/package.json b/pkg/sass-parser/package.json index c0ad58177..c5c4822c3 100644 --- a/pkg/sass-parser/package.json +++ b/pkg/sass-parser/package.json @@ -1,6 +1,6 @@ { "name": "sass-parser", - "version": "0.4.42", + "version": "0.4.43", "description": "A PostCSS-compatible wrapper of the official Sass parser", "repository": "sass/dart-sass", "author": "Google Inc.", diff --git a/pkg/sass_api/CHANGELOG.md b/pkg/sass_api/CHANGELOG.md index 14d75f720..e163f3261 100644 --- a/pkg/sass_api/CHANGELOG.md +++ b/pkg/sass_api/CHANGELOG.md @@ -1,3 +1,7 @@ +## 17.4.0 + +* No user-visible changes. + ## 17.3.3 * No user-visible changes. diff --git a/pkg/sass_api/pubspec.yaml b/pkg/sass_api/pubspec.yaml index 8f558a5be..5e8357d46 100644 --- a/pkg/sass_api/pubspec.yaml +++ b/pkg/sass_api/pubspec.yaml @@ -2,7 +2,7 @@ name: sass_api # Note: Every time we add a new Sass AST node, we need to bump the *major* # version because it's a breaking change for anyone who's implementing the # visitor interface(s). -version: 17.3.3 +version: 17.4.0 description: Additional APIs for Dart Sass. homepage: https://github.com/sass/dart-sass @@ -10,7 +10,7 @@ environment: sdk: ">=3.6.0 <4.0.0" dependencies: - sass: 1.97.3 + sass: 1.98.0 dev_dependencies: dartdoc: ">=8.0.14 <10.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 4f48c5e23..54feaa3c9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: sass -version: 1.97.3 +version: 1.98.0 description: A Sass implementation in Dart. homepage: https://github.com/sass/dart-sass From 7474cd78c6e59cf8269e640f2eff17352dabae05 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 27 Jan 2026 16:03:43 -0800 Subject: [PATCH 3/4] Fix CHANGELOG gamma --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25ebea2ee..9ef6274e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ * **Potentially breaking CSS compatibility fix:** In keeping with the latest CSS specification, this release changes the algorithm for converting colors to and from the `rec2020` color space. This now uses the EOTF algorithm with a gamma - of 1.961. + of 2.4. ## 1.97.3 From fb5c2fd8960ac1834dca26c6774679b96320d040 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 27 Jan 2026 16:04:35 -0800 Subject: [PATCH 4/4] Format --- lib/src/value/color/space/rec2020.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/value/color/space/rec2020.dart b/lib/src/value/color/space/rec2020.dart index 08f3e494b..f983114bc 100644 --- a/lib/src/value/color/space/rec2020.dart +++ b/lib/src/value/color/space/rec2020.dart @@ -24,13 +24,13 @@ final class Rec2020ColorSpace extends ColorSpace { @protected double toLinear(double channel) => - // Algorithm from https://drafts.csswg.org/css-color-4/#color-conversion-code - channel.sign * math.pow(channel.abs(), 2.4); + // Algorithm from https://drafts.csswg.org/css-color-4/#color-conversion-code + channel.sign * math.pow(channel.abs(), 2.4); @protected double fromLinear(double channel) => - // Algorithm from https://drafts.csswg.org/css-color-4/#color-conversion-code - channel.sign * math.pow(channel.abs(), 1/2.4); + // Algorithm from https://drafts.csswg.org/css-color-4/#color-conversion-code + channel.sign * math.pow(channel.abs(), 1 / 2.4); @protected Float64List transformationMatrix(ColorSpace dest) => switch (dest) {