1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.systemui.monet;
17 
18 
19 import androidx.annotation.ColorInt;
20 
21 import com.android.internal.annotations.VisibleForTesting;
22 import com.android.internal.graphics.ColorUtils;
23 
24 
25 /**
26  * Generate sets of colors that are shades of the same color
27  */
28 @VisibleForTesting
29 public class Shades {
30     /**
31      *  Combining the ability to convert between relative luminance and perceptual luminance with
32      *  contrast leads to a design system that can be based on a linear value to determine contrast,
33      *  rather than a ratio.
34      *
35      *  This codebase implements a design system that has that property, and as a result, we can
36      *  guarantee that any shades 5 steps from each other have a contrast ratio of at least 4.5.
37      *  4.5 is the requirement for smaller text contrast in WCAG 2.1 and earlier.
38      *
39      *  However, lstar 50 does _not_ have a contrast ratio >= 4.5 with lstar 100.
40      *  lstar 49.6 is the smallest lstar that will lead to a contrast ratio >= 4.5 with lstar 100,
41      *  and it also contrasts >= 4.5 with lstar 100.
42      */
43     public static final float MIDDLE_LSTAR = 49.6f;
44 
45     /**
46      * Generate shades of a color. Ordered in lightness _descending_.
47      * <p>
48      * The first shade will be at 95% lightness, the next at 90, 80, etc. through 0.
49      *
50      * @param hue    hue in CAM16 color space
51      * @param chroma chroma in CAM16 color space
52      * @return shades of a color, as argb integers. Ordered by lightness descending.
53      */
of(float hue, float chroma)54     public static @ColorInt int[] of(float hue, float chroma) {
55         int[] shades = new int[12];
56         // At tone 90 and above, blue and yellow hues can reach a much higher chroma.
57         // To preserve a consistent appearance across all hues, use a maximum chroma of 40.
58         shades[0] = ColorUtils.CAMToColor(hue, Math.min(40f, chroma), 99);
59         shades[1] = ColorUtils.CAMToColor(hue, Math.min(40f, chroma), 95);
60         for (int i = 2; i < 12; i++) {
61             float lStar = (i == 6) ? MIDDLE_LSTAR : 100 - 10 * (i - 1);
62             shades[i] = ColorUtils.CAMToColor(hue, chroma, lStar);
63         }
64         return shades;
65     }
66 }
67