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

Commit a8d80794 authored by James O'Leary's avatar James O'Leary Committed by Automerger Merge Worker
Browse files

Merge "Update styles to match latest specs" into tm-dev am: 79e56b5d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17160465

Change-Id: I3095943a383155dd82ab3451b032d72c93fe3903
parents 696d1696 79e56b5d
Loading
Loading
Loading
Loading
+153 −49
Original line number Diff line number Diff line
@@ -31,37 +31,134 @@ const val ACCENT1_CHROMA = 48.0f
const val GOOGLE_BLUE = 0xFF1b6ef3.toInt()
const val MIN_CHROMA = 5

internal enum class ChromaStrategy {
    EQ, GTE
internal interface Hue {
    fun get(sourceColor: Cam): Double

    /**
     * Given a hue, and a mapping of hues to hue rotations, find which hues in the mapping the
     * hue fall betweens, and use the hue rotation of the lower hue.
     *
     * @param sourceHue hue of source color
     * @param hueAndRotations list of pairs, where the first item in a pair is a hue, and the
     *    second item in the pair is a hue rotation that should be applied
     */
    fun getHueRotation(sourceHue: Float, hueAndRotations: List<Pair<Int, Int>>): Double {
        for (i in 0..hueAndRotations.size) {
            val previousIndex = if (i == 0) hueAndRotations.size - 1 else i - 1
            val thisHue = hueAndRotations[i].first
            val previousHue = hueAndRotations[previousIndex].first
            if (ColorScheme.angleIsBetween(sourceHue, thisHue, previousHue)) {
                return ColorScheme.wrapDegreesDouble(sourceHue.toDouble() +
                        hueAndRotations[previousIndex].first)
            }
        }

        // If this statement executes, something is wrong, there should have been a rotation
        // found using the arrays.
        return sourceHue.toDouble()
    }
}

internal class HueSource : Hue {
    override fun get(sourceColor: Cam): Double {
        return sourceColor.hue.toDouble()
    }
}

internal class HueAdd(val amountDegrees: Double) : Hue {
    override fun get(sourceColor: Cam): Double {
        return ColorScheme.wrapDegreesDouble(sourceColor.hue.toDouble() + amountDegrees)
    }
}

internal class HueSubtract(val amountDegrees: Double) : Hue {
    override fun get(sourceColor: Cam): Double {
        return ColorScheme.wrapDegreesDouble(sourceColor.hue.toDouble() - amountDegrees)
    }
}

internal class HueVibrantSecondary() : Hue {
    val hueToRotations = listOf(Pair(24, 15), Pair(53, 15), Pair(91, 15), Pair(123, 15),
            Pair(141, 15), Pair(172, 15), Pair(198, 15), Pair(234, 18), Pair(272, 18),
            Pair(302, 18), Pair(329, 30), Pair(354, 15))
    override fun get(sourceColor: Cam): Double {
        return getHueRotation(sourceColor.hue, hueToRotations)
    }
}

internal enum class HueStrategy {
    SOURCE, ADD, SUBTRACT
internal class HueVibrantTertiary() : Hue {
    val hueToRotations = listOf(Pair(24, 30), Pair(53, 30), Pair(91, 15), Pair(123, 30),
            Pair(141, 27), Pair(172, 27), Pair(198, 30), Pair(234, 35), Pair(272, 30),
            Pair(302, 30), Pair(329, 60), Pair(354, 30))
    override fun get(sourceColor: Cam): Double {
        return getHueRotation(sourceColor.hue, hueToRotations)
    }
}

internal class Chroma(val strategy: ChromaStrategy, val value: Double) {
    fun get(sourceChroma: Double): Double {
        return when (strategy) {
            ChromaStrategy.EQ -> value
            ChromaStrategy.GTE -> sourceChroma.coerceAtLeast(value)
internal class HueExpressiveSecondary() : Hue {
    val hueToRotations = listOf(Pair(24, 95), Pair(53, 45), Pair(91, 45), Pair(123, 20),
            Pair(141, 45), Pair(172, 45), Pair(198, 15), Pair(234, 15),
            Pair(272, 45), Pair(302, 45), Pair(329, 45), Pair(354, 45))
    override fun get(sourceColor: Cam): Double {
        return getHueRotation(sourceColor.hue, hueToRotations)
    }
}

internal class HueExpressiveTertiary() : Hue {
    val hueToRotations = listOf(Pair(24, 20), Pair(53, 20), Pair(91, 20), Pair(123, 45),
            Pair(141, 20), Pair(172, 20), Pair(198, 90), Pair(234, 90), Pair(272, 20),
            Pair(302, 20), Pair(329, 120), Pair(354, 120))
    override fun get(sourceColor: Cam): Double {
        return getHueRotation(sourceColor.hue, hueToRotations)
    }
}

internal interface Chroma {
    fun get(sourceColor: Cam): Double

internal class Hue(val strategy: HueStrategy = HueStrategy.SOURCE, val value: Double = 0.0) {
    fun get(sourceHue: Double): Double {
        return when (strategy) {
            HueStrategy.SOURCE -> sourceHue
            HueStrategy.ADD -> ColorScheme.wrapDegreesDouble(sourceHue + value)
            HueStrategy.SUBTRACT -> ColorScheme.wrapDegreesDouble(sourceHue - value)
    /**
     * Given a hue, and a mapping of hues to hue rotations, find which hues in the mapping the
     * hue fall betweens, and use the hue rotation of the lower hue.
     *
     * @param sourceHue hue of source color
     * @param hueAndChromas list of pairs, where the first item in a pair is a hue, and the
     *    second item in the pair is a chroma that should be applied
     */
    fun getSpecifiedChroma(sourceHue: Float, hueAndChromas: List<Pair<Int, Int>>): Double {
        for (i in 0..hueAndChromas.size) {
            val previousIndex = if (i == 0) hueAndChromas.size - 1 else i - 1
            val thisHue = hueAndChromas[i].first
            val previousHue = hueAndChromas[previousIndex].first
            if (ColorScheme.angleIsBetween(sourceHue, thisHue, previousHue)) {
                return hueAndChromas[i].second.toDouble()
            }
        }

        // If this statement executes, something is wrong, there should have been a rotation
        // found using the arrays.
        return sourceHue.toDouble()
    }
}

internal class TonalSpec(val hue: Hue = Hue(), val chroma: Chroma) {
internal class ChromaConstant(val chroma: Double) : Chroma {
    override fun get(sourceColor: Cam): Double {
        return chroma
    }
}

internal class ChromaExpressiveNeutral() : Chroma {
    val hueToChromas = listOf(Pair(24, 8), Pair(53, 8), Pair(91, 8), Pair(123, 8),
            Pair(141, 6), Pair(172, 6), Pair(198, 8), Pair(234, 8), Pair(272, 8),
            Pair(302, 8), Pair(329, 8), Pair(354, 8))
    override fun get(sourceColor: Cam): Double {
        return getSpecifiedChroma(sourceColor.hue, hueToChromas)
    }
}

internal class TonalSpec(val hue: Hue = HueSource(), val chroma: Chroma) {
    fun shades(sourceColor: Cam): List<Int> {
        val hue = hue.get(sourceColor.hue.toDouble())
        val chroma = chroma.get(sourceColor.chroma.toDouble())
        val hue = hue.get(sourceColor)
        val chroma = chroma.get(sourceColor)
        return Shades.of(hue.toFloat(), chroma.toFloat()).toList()
    }
}
@@ -76,46 +173,46 @@ internal class CoreSpec(

enum class Style(internal val coreSpec: CoreSpec) {
    SPRITZ(CoreSpec(
            a1 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 12.0)),
            a2 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 8.0)),
            a3 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 16.0)),
            n1 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 4.0)),
            n2 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 8.0))
            a1 = TonalSpec(HueSource(), ChromaConstant(12.0)),
            a2 = TonalSpec(HueSource(), ChromaConstant(8.0)),
            a3 = TonalSpec(HueSource(), ChromaConstant(16.0)),
            n1 = TonalSpec(HueSource(), ChromaConstant(2.0)),
            n2 = TonalSpec(HueSource(), ChromaConstant(2.0))
    )),
    TONAL_SPOT(CoreSpec(
            a1 = TonalSpec(chroma = Chroma(ChromaStrategy.GTE, 32.0)),
            a2 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 16.0)),
            a3 = TonalSpec(Hue(HueStrategy.ADD, 60.0), Chroma(ChromaStrategy.EQ, 24.0)),
            n1 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 4.0)),
            n2 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 8.0))
            a1 = TonalSpec(HueSource(), ChromaConstant(36.0)),
            a2 = TonalSpec(HueSource(), ChromaConstant(16.0)),
            a3 = TonalSpec(HueAdd(60.0), ChromaConstant(24.0)),
            n1 = TonalSpec(HueSource(), ChromaConstant(4.0)),
            n2 = TonalSpec(HueSource(), ChromaConstant(8.0))
    )),
    VIBRANT(CoreSpec(
            a1 = TonalSpec(chroma = Chroma(ChromaStrategy.GTE, 48.0)),
            a2 = TonalSpec(Hue(HueStrategy.ADD, 15.0), Chroma(ChromaStrategy.EQ, 24.0)),
            a3 = TonalSpec(Hue(HueStrategy.ADD, 30.0), Chroma(ChromaStrategy.GTE, 32.0)),
            n1 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 8.0)),
            n2 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 16.0))
            a1 = TonalSpec(HueSource(), ChromaConstant(48.0)),
            a2 = TonalSpec(HueVibrantSecondary(), ChromaConstant(24.0)),
            a3 = TonalSpec(HueVibrantTertiary(), ChromaConstant(32.0)),
            n1 = TonalSpec(HueSource(), ChromaConstant(6.0)),
            n2 = TonalSpec(HueSource(), ChromaConstant(12.0))
    )),
    EXPRESSIVE(CoreSpec(
            a1 = TonalSpec(Hue(HueStrategy.SUBTRACT, 60.0), Chroma(ChromaStrategy.GTE, 64.0)),
            a2 = TonalSpec(Hue(HueStrategy.SUBTRACT, 30.0), Chroma(ChromaStrategy.EQ, 24.0)),
            a3 = TonalSpec(chroma = Chroma(ChromaStrategy.GTE, 48.0)),
            n1 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 12.0)),
            n2 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 16.0))
            a1 = TonalSpec(HueAdd(240.0), ChromaConstant(40.0)),
            a2 = TonalSpec(HueExpressiveSecondary(), ChromaConstant(24.0)),
            a3 = TonalSpec(HueExpressiveTertiary(), ChromaConstant(40.0)),
            n1 = TonalSpec(HueAdd(15.0), ChromaExpressiveNeutral()),
            n2 = TonalSpec(HueAdd(15.0), ChromaConstant(12.0))
    )),
    RAINBOW(CoreSpec(
            a1 = TonalSpec(chroma = Chroma(ChromaStrategy.GTE, 48.0)),
            a2 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 16.0)),
            a3 = TonalSpec(Hue(HueStrategy.ADD, 60.0), Chroma(ChromaStrategy.EQ, 24.0)),
            n1 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 0.0)),
            n2 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 0.0))
            a1 = TonalSpec(HueSource(), ChromaConstant(48.0)),
            a2 = TonalSpec(HueSource(), ChromaConstant(16.0)),
            a3 = TonalSpec(HueAdd(60.0), ChromaConstant(24.0)),
            n1 = TonalSpec(HueSource(), ChromaConstant(0.0)),
            n2 = TonalSpec(HueSource(), ChromaConstant(0.0))
    )),
    FRUIT_SALAD(CoreSpec(
            a1 = TonalSpec(Hue(HueStrategy.SUBTRACT, 50.0), Chroma(ChromaStrategy.GTE, 48.0)),
            a2 = TonalSpec(Hue(HueStrategy.SUBTRACT, 50.0), Chroma(ChromaStrategy.EQ, 36.0)),
            a3 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 36.0)),
            n1 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 10.0)),
            n2 = TonalSpec(chroma = Chroma(ChromaStrategy.EQ, 16.0))
            a1 = TonalSpec(HueSubtract(50.0), ChromaConstant(48.0)),
            a2 = TonalSpec(HueSubtract(50.0), ChromaConstant(36.0)),
            a3 = TonalSpec(HueSource(), ChromaConstant(36.0)),
            n1 = TonalSpec(HueSource(), ChromaConstant(10.0)),
            n2 = TonalSpec(HueSource(), ChromaConstant(16.0))
    )),
}

@@ -296,6 +393,13 @@ class ColorScheme(
            return seeds
        }

        internal fun angleIsBetween(angle: Float, a: Int, b: Int): Boolean {
            if (a < b) {
                return a <= angle && angle <= b
            }
            return a <= angle || angle <= b
        }

        private fun wrapDegrees(degrees: Int): Int {
            return when {
                degrees < 0 -> {
+0 −3
Original line number Diff line number Diff line
@@ -59,9 +59,6 @@ public class Shades {
        shades[1] = ColorUtils.CAMToColor(hue, Math.min(40f, chroma), 95);
        for (int i = 2; i < 12; i++) {
            float lStar = (i == 6) ? MIDDLE_LSTAR : 100 - 10 * (i - 1);
            if (lStar >= 90) {
                chroma = Math.min(40f, chroma);
            }
            shades[i] = ColorUtils.CAMToColor(hue, chroma, lStar);
        }
        return shades;
+2 −2
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ public class ColorSchemeTest extends SysuiTestCase {
                Style.VIBRANT /* style */);
        int neutralMid = colorScheme.getNeutral1().get(colorScheme.getNeutral1().size() / 2);
        Cam cam = Cam.fromInt(neutralMid);
        Assert.assertEquals(cam.getChroma(), 8.0, 1.0);
        Assert.assertTrue(cam.getChroma() <= 8.0);
    }

    @Test
@@ -133,7 +133,7 @@ public class ColorSchemeTest extends SysuiTestCase {
                Style.EXPRESSIVE /* style */);
        int neutralMid = colorScheme.getNeutral1().get(colorScheme.getNeutral1().size() / 2);
        Cam cam = Cam.fromInt(neutralMid);
        Assert.assertEquals(cam.getChroma(), 12.0, 1.0);
        Assert.assertTrue(cam.getChroma() <= 8.0);
    }

    /**