-
Notifications
You must be signed in to change notification settings - Fork 347
/
interpolation_method.dart
124 lines (110 loc) · 4.25 KB
/
interpolation_method.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2022 Google Inc. Use of this source code is governed by an
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import '../../exception.dart';
import '../../value.dart';
/// The method by which two colors are interpolated to find a color in the
/// middle.
///
/// Used by [SassColor.interpolate].
///
/// {@category Value}
class InterpolationMethod {
/// The color space in which to perform the interpolation.
final ColorSpace space;
/// How to interpolate the hues between two colors.
///
/// This is non-null if and only if [space] is a color space.
final HueInterpolationMethod? hue;
InterpolationMethod(this.space, [HueInterpolationMethod? hue])
: hue = space.isPolar ? hue ?? HueInterpolationMethod.shorter : null {
if (!space.isPolar && hue != null) {
throw ArgumentError(
"Hue interpolation method may not be set for rectangular color space "
"$space.");
}
}
/// Parses a SassScript value representing an interpolation method, not
/// beginning with "in".
///
/// Throws a [SassScriptException] if [value] isn't a valid interpolation
/// method. If [value] came from a function argument, [name] is the argument name
/// (without the `$`). This is used for error reporting.
factory InterpolationMethod.fromValue(Value value, [String? name]) {
var list = value.assertCommonListStyle(name, allowSlash: false);
if (list.isEmpty) {
throw SassScriptException(
'Expected a color interpolation method, got an empty list.', name);
}
var space = ColorSpace.fromName(
(list.first.assertString(name)..assertUnquoted(name)).text, name);
if (list.length == 1) return InterpolationMethod(space);
var hueMethod = HueInterpolationMethod._fromValue(list[1], name);
if (list.length == 2) {
throw SassScriptException(
'Expected unquoted string "hue" after $value.', name);
} else if ((list[2].assertString(name)..assertUnquoted(name))
.text
.toLowerCase() !=
'hue') {
throw SassScriptException(
'Expected unquoted string "hue" at the end of $value, was ${list[2]}.',
name);
} else if (list.length > 3) {
throw SassScriptException(
'Expected nothing after "hue" in $value.', name);
} else if (!space.isPolar) {
throw SassScriptException(
'Hue interpolation method "$hueMethod hue" may not be set for '
'rectangular color space $space.',
name);
}
return InterpolationMethod(space, hueMethod);
}
String toString() => space.toString() + (hue == null ? '' : ' $hue hue');
}
/// The method by which two hues are adjusted when interpolating between colors.
///
/// Used by [InterpolationMethod].
///
/// {@category Value}
enum HueInterpolationMethod {
/// Angles are adjusted so that `θ₂ - θ₁ ∈ [-180, 180]`.
///
/// https://www.w3.org/TR/css-color-4/#shorter
shorter,
/// Angles are adjusted so that `θ₂ - θ₁ ∈ {0, [180, 360)}`.
///
/// https://www.w3.org/TR/css-color-4/#hue-longer
longer,
/// Angles are adjusted so that `θ₂ - θ₁ ∈ [0, 360)`.
///
/// https://www.w3.org/TR/css-color-4/#hue-increasing
increasing,
/// Angles are adjusted so that `θ₂ - θ₁ ∈ (-360, 0]`.
///
/// https://www.w3.org/TR/css-color-4/#hue-decreasing
decreasing;
/// Parses a SassScript value representing a hue interpolation method, not
/// ending with "hue".
///
/// Throws a [SassScriptException] if [value] isn't a valid hue interpolation
/// method. If [value] came from a function argument, [name] is the argument
/// name (without the `$`). This is used for error reporting.
factory HueInterpolationMethod._fromValue(Value value, [String? name]) {
var text = (value.assertString(name)..assertUnquoted()).text.toLowerCase();
switch (text) {
case 'shorter':
return HueInterpolationMethod.shorter;
case 'longer':
return HueInterpolationMethod.longer;
case 'increasing':
return HueInterpolationMethod.increasing;
case 'decreasing':
return HueInterpolationMethod.decreasing;
default:
throw SassScriptException(
'Unknown hue interpolation method $value.', name);
}
}
}