1 /* 2 * Copyright (C) 2017 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 17 package com.android.compatibility.common.util; 18 19 import static org.junit.Assert.fail; 20 21 import android.graphics.Color; 22 23 import androidx.annotation.NonNull; 24 import androidx.annotation.Nullable; 25 26 import java.util.function.Function; 27 import java.util.function.IntUnaryOperator; 28 29 public class ColorUtils { verifyColor(int expected, int observed)30 public static void verifyColor(int expected, int observed) { 31 verifyColor(expected, observed, 0); 32 } 33 verifyColor(int expected, int observed, int tolerance)34 public static void verifyColor(int expected, int observed, int tolerance) { 35 verifyColor("", expected, observed, tolerance); 36 } 37 38 /** 39 * Verify that two colors match within a per-channel tolerance. 40 * 41 * @param s String with extra information about the test with an error. 42 * @param expected Expected color. 43 * @param observed Observed color. 44 * @param tolerance Per-channel tolerance by which the color can mismatch. 45 */ verifyColor(@onNull String s, int expected, int observed, int tolerance)46 public static void verifyColor(@NonNull String s, int expected, int observed, int tolerance) { 47 s += " expected 0x" + Integer.toHexString(expected) 48 + ", observed 0x" + Integer.toHexString(observed) 49 + ", tolerated channel error 0x" + tolerance; 50 String red = verifyChannel("red", expected, observed, tolerance, (i) -> Color.red(i)); 51 String green = verifyChannel("green", expected, observed, tolerance, (i) -> Color.green(i)); 52 String blue = verifyChannel("blue", expected, observed, tolerance, (i) -> Color.blue(i)); 53 String alpha = verifyChannel("alpha", expected, observed, tolerance, (i) -> Color.alpha(i)); 54 55 buildErrorString(s, red, green, blue, alpha); 56 } 57 buildErrorString(@onNull String s, @Nullable String red, @Nullable String green, @Nullable String blue, @Nullable String alpha)58 private static void buildErrorString(@NonNull String s, @Nullable String red, 59 @Nullable String green, @Nullable String blue, @Nullable String alpha) { 60 String err = null; 61 for (String channel : new String[]{red, green, blue, alpha}) { 62 if (channel == null) continue; 63 if (err == null) err = s; 64 err += "\n\t\t" + channel; 65 } 66 if (err != null) { 67 fail(err); 68 } 69 } 70 verifyChannel(String channelName, int expected, int observed, int tolerance, IntUnaryOperator f)71 private static String verifyChannel(String channelName, int expected, int observed, 72 int tolerance, IntUnaryOperator f) { 73 int e = f.applyAsInt(expected); 74 int o = f.applyAsInt(observed); 75 if (Math.abs(e - o) <= tolerance) { 76 return null; 77 } 78 return "Channel " + channelName + " mismatch: expected<0x" + Integer.toHexString(e) 79 + ">, observed: <0x" + Integer.toHexString(o) + ">"; 80 } 81 82 /** 83 * Verify that two colors match within a per-channel tolerance. 84 * 85 * @param msg String with extra information about the test with an error. 86 * @param expected Expected color. 87 * @param observed Observed color. 88 * @param tolerance Per-channel tolerance by which the color can mismatch. 89 */ verifyColor(@onNull String msg, Color expected, Color observed, float tolerance)90 public static void verifyColor(@NonNull String msg, Color expected, Color observed, 91 float tolerance) { 92 if (!expected.getColorSpace().equals(observed.getColorSpace())) { 93 fail("Cannot compare Colors with different color spaces! expected: " + expected 94 + "\tobserved: " + observed); 95 } 96 msg += " expected " + expected + ", observed " + observed + ", tolerated channel error " 97 + tolerance; 98 String red = verifyChannel("red", expected, observed, tolerance, (c) -> c.red()); 99 String green = verifyChannel("green", expected, observed, tolerance, (c) -> c.green()); 100 String blue = verifyChannel("blue", expected, observed, tolerance, (c) -> c.blue()); 101 String alpha = verifyChannel("alpha", expected, observed, tolerance, (c) -> c.alpha()); 102 103 buildErrorString(msg, red, green, blue, alpha); 104 } 105 verifyChannel(String channelName, Color expected, Color observed, float tolerance, Function<Color, Float> f)106 private static String verifyChannel(String channelName, Color expected, Color observed, 107 float tolerance, Function<Color, Float> f) { 108 float e = f.apply(expected); 109 float o = f.apply(observed); 110 float diff = Math.abs(e - o); 111 if (diff <= tolerance) { 112 return null; 113 } 114 return "Channel " + channelName + " mismatch: expected<" + e + ">, observed: <" + o 115 + ">, difference: <" + diff + ">"; 116 } 117 } 118