1 /* 2 * Copyright (C) 2024 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.internal.widget.remotecompose.core.operations; 17 18 /** 19 * Utilities to be used across all core operations 20 */ 21 public class Utils { asNan(int v)22 public static float asNan(int v) { 23 return Float.intBitsToFloat(v | -0x800000); 24 } 25 idFromNan(float value)26 public static int idFromNan(float value) { 27 int b = Float.floatToRawIntBits(value); 28 return b & 0xFFFFF; 29 } 30 getActualValue(float lr)31 public static float getActualValue(float lr) { 32 return 0; 33 } 34 35 /** 36 * trim a string to n characters if needing to trim 37 * end in "..." 38 * 39 * @param str 40 * @param n 41 * @return 42 */ trimString(String str, int n)43 static String trimString(String str, int n) { 44 if (str.length() > n) { 45 str = str.substring(0, n - 3) + "..."; 46 } 47 return str; 48 } 49 50 /** 51 * print the id and the value of a float 52 * @param idvalue 53 * @param value 54 * @return 55 */ floatToString(float idvalue, float value)56 public static String floatToString(float idvalue, float value) { 57 if (Float.isNaN(idvalue)) { 58 return "[" + idFromNan(idvalue) + "]" + floatToString(value); 59 } 60 return floatToString(value); 61 } 62 63 /** 64 * Convert float to string but render nan id in brackets [n] 65 * @param value 66 * @return 67 */ floatToString(float value)68 public static String floatToString(float value) { 69 if (Float.isNaN(value)) { 70 return "[" + idFromNan(value) + "]"; 71 } 72 return Float.toString(value); 73 } 74 75 /** 76 * Debugging util to print a message and include the file/line it came from 77 * @param str 78 */ log(String str)79 public static void log(String str) { 80 StackTraceElement s = new Throwable().getStackTrace()[1]; 81 System.out.println("(" + s.getFileName() + ":" + s.getLineNumber() + ")." + str); 82 } 83 84 /** 85 * Debugging util to print the stack 86 * @param str 87 * @param n 88 */ logStack(String str, int n)89 public static void logStack(String str, int n) { 90 StackTraceElement[] st = new Throwable().getStackTrace(); 91 for (int i = 1; i < n + 1; i++) { 92 StackTraceElement s = st[i]; 93 String space = new String(new char[i]).replace('\0', ' '); 94 System.out.println(space + "(" + s.getFileName() 95 + ":" + s.getLineNumber() + ")." + str); 96 } 97 } 98 99 /** 100 * Is a variable Allowed int calculation and references. 101 * 102 * @param v 103 * @return 104 */ isVariable(float v)105 public static boolean isVariable(float v) { 106 if (Float.isNaN(v)) { 107 int id = idFromNan(v); 108 return id > 40 || id < 10; 109 } 110 return false; 111 } 112 113 /** 114 * print a color in the familiar 0xAARRGGBB pattern 115 * 116 * @param color 117 * @return 118 */ colorInt(int color)119 public static String colorInt(int color) { 120 String str = "000000000000" + Integer.toHexString(color); 121 return "0x" + str.substring(str.length() - 8); 122 } 123 124 /** 125 * Interpolate two colors. 126 * gamma corrected colors are interpolated in the form c1 * (1-t) + c2 * t 127 * 128 * @param c1 129 * @param c2 130 * @param t 131 * @return 132 */ interpolateColor(int c1, int c2, float t)133 public static int interpolateColor(int c1, int c2, float t) { 134 if (Float.isNaN(t) || t == 0.0f) { 135 return c1; 136 } else if (t == 1.0f) { 137 return c2; 138 } 139 int a = 0xFF & (c1 >> 24); 140 int r = 0xFF & (c1 >> 16); 141 int g = 0xFF & (c1 >> 8); 142 int b = 0xFF & c1; 143 float f_r = (float) Math.pow(r / 255.0f, 2.2); 144 float f_g = (float) Math.pow(g / 255.0f, 2.2); 145 float f_b = (float) Math.pow(b / 255.0f, 2.2); 146 float c1fr = f_r; 147 float c1fg = f_g; 148 float c1fb = f_b; 149 float c1fa = a / 255f; 150 151 a = 0xFF & (c2 >> 24); 152 r = 0xFF & (c2 >> 16); 153 g = 0xFF & (c2 >> 8); 154 b = 0xFF & c2; 155 f_r = (float) Math.pow(r / 255.0f, 2.2); 156 f_g = (float) Math.pow(g / 255.0f, 2.2); 157 f_b = (float) Math.pow(b / 255.0f, 2.2); 158 float c2fr = f_r; 159 float c2fg = f_g; 160 float c2fb = f_b; 161 float c2fa = a / 255f; 162 f_r = c1fr + t * (c2fr - c1fr); 163 f_g = c1fg + t * (c2fg - c1fg); 164 f_b = c1fb + t * (c2fb - c1fb); 165 float f_a = c1fa + t * (c2fa - c1fa); 166 167 int outr = clamp((int) ((float) Math.pow(f_r, 1.0 / 2.2) * 255.0f)); 168 int outg = clamp((int) ((float) Math.pow(f_g, 1.0 / 2.2) * 255.0f)); 169 int outb = clamp((int) ((float) Math.pow(f_b, 1.0 / 2.2) * 255.0f)); 170 int outa = clamp((int) (f_a * 255.0f)); 171 172 173 return (outa << 24 | outr << 16 | outg << 8 | outb); 174 } 175 176 /** 177 * Efficient clamping function 178 * 179 * @param c 180 * @return number between 0 and 255 181 */ clamp(int c)182 public static int clamp(int c) { 183 int n = 255; 184 c &= ~(c >> 31); 185 c -= n; 186 c &= (c >> 31); 187 c += n; 188 return c; 189 } 190 191 /** 192 * convert hue saturation and value to RGB 193 * 194 * @param hue 0..1 195 * @param saturation 0..1 0=on the gray scale 196 * @param value 0..1 0=black 197 * @return 198 */ hsvToRgb(float hue, float saturation, float value)199 public static int hsvToRgb(float hue, float saturation, float value) { 200 int h = (int) (hue * 6); 201 float f = hue * 6 - h; 202 int p = (int) (0.5f + 255 * value * (1 - saturation)); 203 int q = (int) (0.5f + 255 * value * (1 - f * saturation)); 204 int t = (int) (0.5f + 255 * value * (1 - (1 - f) * saturation)); 205 int v = (int) (0.5f + 255 * value); 206 switch (h) { 207 case 0: 208 return 0XFF000000 | (v << 16) + (t << 8) + p; 209 case 1: 210 return 0XFF000000 | (q << 16) + (v << 8) + p; 211 case 2: 212 return 0XFF000000 | (p << 16) + (v << 8) + t; 213 case 3: 214 return 0XFF000000 | (p << 16) + (q << 8) + v; 215 case 4: 216 return 0XFF000000 | (t << 16) + (p << 8) + v; 217 case 5: 218 return 0XFF000000 | (v << 16) + (p << 8) + q; 219 220 } 221 return 0; 222 } 223 224 225 } 226