Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23a96af5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "AOD: Fix contrast calculation"

parents 9031554c 99d2e64b
Loading
Loading
Loading
Loading
+146 −8
Original line number Diff line number Diff line
@@ -303,17 +303,17 @@ public class NotificationColorUtil {
            return color;
        }

        double[] lab = new double[3];
        ColorUtilsFromCompat.colorToLAB(findFg ? fg : bg, lab);
        float[] hsl = new float[3];
        ColorUtilsFromCompat.colorToHSL(findFg ? fg : bg, hsl);

        double low = lab[0], high = 100;
        final double a = lab[1], b = lab[2];
        float low = hsl[2], high = 1;
        for (int i = 0; i < 15 && high - low > 0.00001; i++) {
            final double l = (low + high) / 2;
            final float l = (low + high) / 2;
            hsl[2] = l;
            if (findFg) {
                fg = ColorUtilsFromCompat.LABToColor(l, a, b);
                fg = ColorUtilsFromCompat.HSLToColor(hsl);
            } else {
                bg = ColorUtilsFromCompat.LABToColor(l, a, b);
                bg = ColorUtilsFromCompat.HSLToColor(hsl);
            }
            if (ColorUtilsFromCompat.calculateContrast(fg, bg) > minRatio) {
                high = l;
@@ -321,7 +321,7 @@ public class NotificationColorUtil {
                low = l;
            }
        }
        return ColorUtilsFromCompat.LABToColor(high, a, b);
        return findFg ? fg : bg;
    }

    public static int ensureTextContrastOnBlack(int color) {
@@ -764,6 +764,10 @@ public class NotificationColorUtil {
            return amount < low ? low : (amount > high ? high : amount);
        }

        private static float constrain(float amount, float low, float high) {
            return amount < low ? low : (amount > high ? high : amount);
        }

        private static double pivotXyzComponent(double component) {
            return component > XYZ_EPSILON
                    ? Math.pow(component, 1 / 3.0)
@@ -779,5 +783,139 @@ public class NotificationColorUtil {
            return result;
        }

        /**
         * Convert HSL (hue-saturation-lightness) components to a RGB color.
         * <ul>
         * <li>hsl[0] is Hue [0 .. 360)</li>
         * <li>hsl[1] is Saturation [0...1]</li>
         * <li>hsl[2] is Lightness [0...1]</li>
         * </ul>
         * If hsv values are out of range, they are pinned.
         *
         * @param hsl 3-element array which holds the input HSL components
         * @return the resulting RGB color
         */
        @ColorInt
        public static int HSLToColor(@NonNull float[] hsl) {
            final float h = hsl[0];
            final float s = hsl[1];
            final float l = hsl[2];

            final float c = (1f - Math.abs(2 * l - 1f)) * s;
            final float m = l - 0.5f * c;
            final float x = c * (1f - Math.abs((h / 60f % 2f) - 1f));

            final int hueSegment = (int) h / 60;

            int r = 0, g = 0, b = 0;

            switch (hueSegment) {
                case 0:
                    r = Math.round(255 * (c + m));
                    g = Math.round(255 * (x + m));
                    b = Math.round(255 * m);
                    break;
                case 1:
                    r = Math.round(255 * (x + m));
                    g = Math.round(255 * (c + m));
                    b = Math.round(255 * m);
                    break;
                case 2:
                    r = Math.round(255 * m);
                    g = Math.round(255 * (c + m));
                    b = Math.round(255 * (x + m));
                    break;
                case 3:
                    r = Math.round(255 * m);
                    g = Math.round(255 * (x + m));
                    b = Math.round(255 * (c + m));
                    break;
                case 4:
                    r = Math.round(255 * (x + m));
                    g = Math.round(255 * m);
                    b = Math.round(255 * (c + m));
                    break;
                case 5:
                case 6:
                    r = Math.round(255 * (c + m));
                    g = Math.round(255 * m);
                    b = Math.round(255 * (x + m));
                    break;
            }

            r = constrain(r, 0, 255);
            g = constrain(g, 0, 255);
            b = constrain(b, 0, 255);

            return Color.rgb(r, g, b);
        }

        /**
         * Convert the ARGB color to its HSL (hue-saturation-lightness) components.
         * <ul>
         * <li>outHsl[0] is Hue [0 .. 360)</li>
         * <li>outHsl[1] is Saturation [0...1]</li>
         * <li>outHsl[2] is Lightness [0...1]</li>
         * </ul>
         *
         * @param color  the ARGB color to convert. The alpha component is ignored
         * @param outHsl 3-element array which holds the resulting HSL components
         */
        public static void colorToHSL(@ColorInt int color, @NonNull float[] outHsl) {
            RGBToHSL(Color.red(color), Color.green(color), Color.blue(color), outHsl);
        }

        /**
         * Convert RGB components to HSL (hue-saturation-lightness).
         * <ul>
         * <li>outHsl[0] is Hue [0 .. 360)</li>
         * <li>outHsl[1] is Saturation [0...1]</li>
         * <li>outHsl[2] is Lightness [0...1]</li>
         * </ul>
         *
         * @param r      red component value [0..255]
         * @param g      green component value [0..255]
         * @param b      blue component value [0..255]
         * @param outHsl 3-element array which holds the resulting HSL components
         */
        public static void RGBToHSL(@IntRange(from = 0x0, to = 0xFF) int r,
                @IntRange(from = 0x0, to = 0xFF) int g, @IntRange(from = 0x0, to = 0xFF) int b,
                @NonNull float[] outHsl) {
            final float rf = r / 255f;
            final float gf = g / 255f;
            final float bf = b / 255f;

            final float max = Math.max(rf, Math.max(gf, bf));
            final float min = Math.min(rf, Math.min(gf, bf));
            final float deltaMaxMin = max - min;

            float h, s;
            float l = (max + min) / 2f;

            if (max == min) {
                // Monochromatic
                h = s = 0f;
            } else {
                if (max == rf) {
                    h = ((gf - bf) / deltaMaxMin) % 6f;
                } else if (max == gf) {
                    h = ((bf - rf) / deltaMaxMin) + 2f;
                } else {
                    h = ((rf - gf) / deltaMaxMin) + 4f;
                }

                s = deltaMaxMin / (1f - Math.abs(2f * l - 1f));
            }

            h = (h * 60f) % 360f;
            if (h < 0) {
                h += 360f;
            }

            outHsl[0] = constrain(h, 0f, 360f);
            outHsl[1] = constrain(s, 0f, 1f);
            outHsl[2] = constrain(l, 0f, 1f);
        }

    }
}