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