blob: 964017396bbd03e8d2000782b82eb1ed35c0dde2 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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
17package android.util;
18
Tor Norbye7b9c9122013-05-30 16:48:33 -070019import android.annotation.AnyRes;
Alan Viveretteac85f902016-03-11 15:15:51 -050020import android.content.pm.ActivityInfo.Config;
Tor Norbye7b9c9122013-05-30 16:48:33 -070021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022/**
23 * Container for a dynamically typed data value. Primarily used with
24 * {@link android.content.res.Resources} for holding resource values.
25 */
26public class TypedValue {
27 /** The value contains no data. */
28 public static final int TYPE_NULL = 0x00;
29
30 /** The <var>data</var> field holds a resource identifier. */
31 public static final int TYPE_REFERENCE = 0x01;
32 /** The <var>data</var> field holds an attribute resource
33 * identifier (referencing an attribute in the current theme
34 * style, not a resource entry). */
35 public static final int TYPE_ATTRIBUTE = 0x02;
36 /** The <var>string</var> field holds string data. In addition, if
37 * <var>data</var> is non-zero then it is the string block
38 * index of the string and <var>assetCookie</var> is the set of
39 * assets the string came from. */
40 public static final int TYPE_STRING = 0x03;
41 /** The <var>data</var> field holds an IEEE 754 floating point number. */
42 public static final int TYPE_FLOAT = 0x04;
43 /** The <var>data</var> field holds a complex number encoding a
44 * dimension value. */
45 public static final int TYPE_DIMENSION = 0x05;
46 /** The <var>data</var> field holds a complex number encoding a fraction
47 * of a container. */
48 public static final int TYPE_FRACTION = 0x06;
49
50 /** Identifies the start of plain integer values. Any type value
51 * from this to {@link #TYPE_LAST_INT} means the
52 * <var>data</var> field holds a generic integer value. */
53 public static final int TYPE_FIRST_INT = 0x10;
54
55 /** The <var>data</var> field holds a number that was
56 * originally specified in decimal. */
57 public static final int TYPE_INT_DEC = 0x10;
58 /** The <var>data</var> field holds a number that was
59 * originally specified in hexadecimal (0xn). */
60 public static final int TYPE_INT_HEX = 0x11;
61 /** The <var>data</var> field holds 0 or 1 that was originally
62 * specified as "false" or "true". */
63 public static final int TYPE_INT_BOOLEAN = 0x12;
64
65 /** Identifies the start of integer values that were specified as
66 * color constants (starting with '#'). */
67 public static final int TYPE_FIRST_COLOR_INT = 0x1c;
68
69 /** The <var>data</var> field holds a color that was originally
70 * specified as #aarrggbb. */
71 public static final int TYPE_INT_COLOR_ARGB8 = 0x1c;
72 /** The <var>data</var> field holds a color that was originally
73 * specified as #rrggbb. */
74 public static final int TYPE_INT_COLOR_RGB8 = 0x1d;
75 /** The <var>data</var> field holds a color that was originally
76 * specified as #argb. */
77 public static final int TYPE_INT_COLOR_ARGB4 = 0x1e;
78 /** The <var>data</var> field holds a color that was originally
79 * specified as #rgb. */
80 public static final int TYPE_INT_COLOR_RGB4 = 0x1f;
81
82 /** Identifies the end of integer values that were specified as color
83 * constants. */
84 public static final int TYPE_LAST_COLOR_INT = 0x1f;
85
86 /** Identifies the end of plain integer values. */
87 public static final int TYPE_LAST_INT = 0x1f;
88
89 /* ------------------------------------------------------------ */
90
91 /** Complex data: bit location of unit information. */
92 public static final int COMPLEX_UNIT_SHIFT = 0;
93 /** Complex data: mask to extract unit information (after shifting by
94 * {@link #COMPLEX_UNIT_SHIFT}). This gives us 16 possible types, as
95 * defined below. */
96 public static final int COMPLEX_UNIT_MASK = 0xf;
97
98 /** {@link #TYPE_DIMENSION} complex unit: Value is raw pixels. */
99 public static final int COMPLEX_UNIT_PX = 0;
100 /** {@link #TYPE_DIMENSION} complex unit: Value is Device Independent
101 * Pixels. */
102 public static final int COMPLEX_UNIT_DIP = 1;
103 /** {@link #TYPE_DIMENSION} complex unit: Value is a scaled pixel. */
104 public static final int COMPLEX_UNIT_SP = 2;
105 /** {@link #TYPE_DIMENSION} complex unit: Value is in points. */
106 public static final int COMPLEX_UNIT_PT = 3;
107 /** {@link #TYPE_DIMENSION} complex unit: Value is in inches. */
108 public static final int COMPLEX_UNIT_IN = 4;
109 /** {@link #TYPE_DIMENSION} complex unit: Value is in millimeters. */
110 public static final int COMPLEX_UNIT_MM = 5;
111
112 /** {@link #TYPE_FRACTION} complex unit: A basic fraction of the overall
113 * size. */
114 public static final int COMPLEX_UNIT_FRACTION = 0;
115 /** {@link #TYPE_FRACTION} complex unit: A fraction of the parent size. */
116 public static final int COMPLEX_UNIT_FRACTION_PARENT = 1;
117
118 /** Complex data: where the radix information is, telling where the decimal
119 * place appears in the mantissa. */
120 public static final int COMPLEX_RADIX_SHIFT = 4;
121 /** Complex data: mask to extract radix information (after shifting by
122 * {@link #COMPLEX_RADIX_SHIFT}). This give us 4 possible fixed point
123 * representations as defined below. */
124 public static final int COMPLEX_RADIX_MASK = 0x3;
125
126 /** Complex data: the mantissa is an integral number -- i.e., 0xnnnnnn.0 */
127 public static final int COMPLEX_RADIX_23p0 = 0;
128 /** Complex data: the mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn */
129 public static final int COMPLEX_RADIX_16p7 = 1;
130 /** Complex data: the mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn */
131 public static final int COMPLEX_RADIX_8p15 = 2;
132 /** Complex data: the mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn */
133 public static final int COMPLEX_RADIX_0p23 = 3;
134
135 /** Complex data: bit location of mantissa information. */
136 public static final int COMPLEX_MANTISSA_SHIFT = 8;
137 /** Complex data: mask to extract mantissa information (after shifting by
138 * {@link #COMPLEX_MANTISSA_SHIFT}). This gives us 23 bits of precision;
139 * the top bit is the sign. */
140 public static final int COMPLEX_MANTISSA_MASK = 0xffffff;
141
142 /* ------------------------------------------------------------ */
143
144 /**
Alan Viverettef2969402014-10-29 17:09:36 -0700145 * {@link #TYPE_NULL} data indicating the value was not specified.
146 */
147 public static final int DATA_NULL_UNDEFINED = 0;
148 /**
149 * {@link #TYPE_NULL} data indicating the value was explicitly set to null.
150 */
151 public static final int DATA_NULL_EMPTY = 1;
152
153 /* ------------------------------------------------------------ */
154
155 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 * If {@link #density} is equal to this value, then the density should be
Dianne Hackborna53b8282009-07-17 11:13:48 -0700157 * treated as the system's default density value: {@link DisplayMetrics#DENSITY_DEFAULT}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 */
159 public static final int DENSITY_DEFAULT = 0;
160
Dianne Hackborna53b8282009-07-17 11:13:48 -0700161 /**
162 * If {@link #density} is equal to this value, then there is no density
163 * associated with the resource and it should not be scaled.
164 */
165 public static final int DENSITY_NONE = 0xffff;
166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 /* ------------------------------------------------------------ */
168
169 /** The type held by this value, as defined by the constants here.
170 * This tells you how to interpret the other fields in the object. */
171 public int type;
172
173 /** If the value holds a string, this is it. */
174 public CharSequence string;
175
176 /** Basic data in the value, interpreted according to {@link #type} */
177 public int data;
178
179 /** Additional information about where the value came from; only
180 * set for strings. */
181 public int assetCookie;
182
183 /** If Value came from a resource, this holds the corresponding resource id. */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700184 @AnyRes
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 public int resourceId;
186
Alan Viveretteac85f902016-03-11 15:15:51 -0500187 /**
188 * If the value came from a resource, these are the configurations for
189 * which its contents can change.
Adam Lesinski41a2fb12017-04-12 15:05:53 -0700190 *
191 * <p>For example, if a resource has a value defined for the -land resource qualifier,
192 * this field will have the {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION} bit set.
193 * </p>
194 *
195 * @see android.content.pm.ActivityInfo#CONFIG_MCC
196 * @see android.content.pm.ActivityInfo#CONFIG_MNC
197 * @see android.content.pm.ActivityInfo#CONFIG_LOCALE
198 * @see android.content.pm.ActivityInfo#CONFIG_TOUCHSCREEN
199 * @see android.content.pm.ActivityInfo#CONFIG_KEYBOARD
200 * @see android.content.pm.ActivityInfo#CONFIG_KEYBOARD_HIDDEN
201 * @see android.content.pm.ActivityInfo#CONFIG_NAVIGATION
202 * @see android.content.pm.ActivityInfo#CONFIG_ORIENTATION
203 * @see android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
204 * @see android.content.pm.ActivityInfo#CONFIG_UI_MODE
205 * @see android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE
206 * @see android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE
207 * @see android.content.pm.ActivityInfo#CONFIG_DENSITY
208 * @see android.content.pm.ActivityInfo#CONFIG_LAYOUT_DIRECTION
209 * @see android.content.pm.ActivityInfo#CONFIG_COLOR_MODE
210 *
Alan Viveretteac85f902016-03-11 15:15:51 -0500211 */
212 public @Config int changingConfigurations = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213
214 /**
215 * If the Value came from a resource, this holds the corresponding pixel density.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 * */
217 public int density;
218
219 /* ------------------------------------------------------------ */
220
221 /** Return the data for this value as a float. Only use for values
222 * whose type is {@link #TYPE_FLOAT}. */
223 public final float getFloat() {
224 return Float.intBitsToFloat(data);
225 }
226
227 private static final float MANTISSA_MULT =
228 1.0f / (1<<TypedValue.COMPLEX_MANTISSA_SHIFT);
229 private static final float[] RADIX_MULTS = new float[] {
230 1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,
231 1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT
232 };
233
234 /**
Ashley Roseaa554ae2018-09-05 16:04:01 -0400235 * Determine if a value is a color by comparing {@link type} to {@link #TYPE_FIRST_COLOR_INT}
236 * and {@link #TYPE_LAST_COLOR_INT}.
237 *
238 * @return true if this value is a color
239 */
240 public boolean isColorType() {
241 return (type >= TYPE_FIRST_COLOR_INT && type <= TYPE_LAST_COLOR_INT);
242 }
243
244 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 * Retrieve the base value from a complex data integer. This uses the
246 * {@link #COMPLEX_MANTISSA_MASK} and {@link #COMPLEX_RADIX_MASK} fields of
247 * the data to compute a floating point representation of the number they
248 * describe. The units are ignored.
249 *
250 * @param complex A complex data value.
251 *
252 * @return A floating point value corresponding to the complex data.
253 */
254 public static float complexToFloat(int complex)
255 {
256 return (complex&(TypedValue.COMPLEX_MANTISSA_MASK
257 <<TypedValue.COMPLEX_MANTISSA_SHIFT))
258 * RADIX_MULTS[(complex>>TypedValue.COMPLEX_RADIX_SHIFT)
259 & TypedValue.COMPLEX_RADIX_MASK];
260 }
261
262 /**
263 * Converts a complex data value holding a dimension to its final floating
264 * point value. The given <var>data</var> must be structured as a
265 * {@link #TYPE_DIMENSION}.
266 *
267 * @param data A complex data value holding a unit, magnitude, and
268 * mantissa.
269 * @param metrics Current display metrics to use in the conversion --
270 * supplies display density and scaling information.
271 *
272 * @return The complex floating point value multiplied by the appropriate
273 * metrics depending on its unit.
274 */
275 public static float complexToDimension(int data, DisplayMetrics metrics)
276 {
277 return applyDimension(
278 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
279 complexToFloat(data),
280 metrics);
281 }
282
283 /**
284 * Converts a complex data value holding a dimension to its final value
285 * as an integer pixel offset. This is the same as
286 * {@link #complexToDimension}, except the raw floating point value is
287 * truncated to an integer (pixel) value.
288 * The given <var>data</var> must be structured as a
289 * {@link #TYPE_DIMENSION}.
290 *
291 * @param data A complex data value holding a unit, magnitude, and
292 * mantissa.
293 * @param metrics Current display metrics to use in the conversion --
294 * supplies display density and scaling information.
295 *
296 * @return The number of pixels specified by the data and its desired
297 * multiplier and units.
298 */
299 public static int complexToDimensionPixelOffset(int data,
300 DisplayMetrics metrics)
301 {
302 return (int)applyDimension(
303 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
304 complexToFloat(data),
305 metrics);
306 }
307
308 /**
309 * Converts a complex data value holding a dimension to its final value
310 * as an integer pixel size. This is the same as
311 * {@link #complexToDimension}, except the raw floating point value is
312 * converted to an integer (pixel) value for use as a size. A size
313 * conversion involves rounding the base value, and ensuring that a
314 * non-zero base value is at least one pixel in size.
315 * The given <var>data</var> must be structured as a
316 * {@link #TYPE_DIMENSION}.
317 *
318 * @param data A complex data value holding a unit, magnitude, and
319 * mantissa.
320 * @param metrics Current display metrics to use in the conversion --
321 * supplies display density and scaling information.
322 *
323 * @return The number of pixels specified by the data and its desired
324 * multiplier and units.
325 */
326 public static int complexToDimensionPixelSize(int data,
327 DisplayMetrics metrics)
328 {
329 final float value = complexToFloat(data);
330 final float f = applyDimension(
331 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
332 value,
333 metrics);
Chet Haase724792d2016-06-07 16:05:12 -0700334 final int res = (int) ((f >= 0) ? (f + 0.5f) : (f - 0.5f));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 if (res != 0) return res;
336 if (value == 0) return 0;
337 if (value > 0) return 1;
338 return -1;
339 }
340
Jeff Brown8aca9e32014-01-24 12:40:23 -0800341 /**
342 * @hide Was accidentally exposed in API level 1 for debugging purposes.
343 * Kept for compatibility just in case although the debugging code has been removed.
344 */
345 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 public static float complexToDimensionNoisy(int data, DisplayMetrics metrics)
347 {
Jeff Brown8aca9e32014-01-24 12:40:23 -0800348 return complexToDimension(data, metrics);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 }
350
351 /**
Christopher Lane9f357ae2014-10-31 14:52:06 -0700352 * Return the complex unit type for this value. For example, a dimen type
353 * with value 12sp will return {@link #COMPLEX_UNIT_SP}. Only use for values
354 * whose type is {@link #TYPE_DIMENSION}.
355 *
356 * @return The complex unit type.
357 */
358 public int getComplexUnit()
359 {
360 return COMPLEX_UNIT_MASK & (data>>TypedValue.COMPLEX_UNIT_SHIFT);
361 }
362
363 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 * Converts an unpacked complex data value holding a dimension to its final floating
365 * point value. The two parameters <var>unit</var> and <var>value</var>
366 * are as in {@link #TYPE_DIMENSION}.
367 *
368 * @param unit The unit to convert from.
369 * @param value The value to apply the unit to.
370 * @param metrics Current display metrics to use in the conversion --
371 * supplies display density and scaling information.
372 *
373 * @return The complex floating point value multiplied by the appropriate
374 * metrics depending on its unit.
375 */
376 public static float applyDimension(int unit, float value,
377 DisplayMetrics metrics)
378 {
379 switch (unit) {
380 case COMPLEX_UNIT_PX:
381 return value;
382 case COMPLEX_UNIT_DIP:
383 return value * metrics.density;
384 case COMPLEX_UNIT_SP:
385 return value * metrics.scaledDensity;
386 case COMPLEX_UNIT_PT:
387 return value * metrics.xdpi * (1.0f/72);
388 case COMPLEX_UNIT_IN:
389 return value * metrics.xdpi;
390 case COMPLEX_UNIT_MM:
391 return value * metrics.xdpi * (1.0f/25.4f);
392 }
393 return 0;
394 }
395
396 /**
397 * Return the data for this value as a dimension. Only use for values
398 * whose type is {@link #TYPE_DIMENSION}.
399 *
400 * @param metrics Current display metrics to use in the conversion --
401 * supplies display density and scaling information.
402 *
403 * @return The complex floating point value multiplied by the appropriate
404 * metrics depending on its unit.
405 */
406 public float getDimension(DisplayMetrics metrics)
407 {
408 return complexToDimension(data, metrics);
409 }
410
411 /**
412 * Converts a complex data value holding a fraction to its final floating
413 * point value. The given <var>data</var> must be structured as a
414 * {@link #TYPE_FRACTION}.
415 *
416 * @param data A complex data value holding a unit, magnitude, and
417 * mantissa.
418 * @param base The base value of this fraction. In other words, a
419 * standard fraction is multiplied by this value.
420 * @param pbase The parent base value of this fraction. In other
421 * words, a parent fraction (nn%p) is multiplied by this
422 * value.
423 *
424 * @return The complex floating point value multiplied by the appropriate
425 * base value depending on its unit.
426 */
427 public static float complexToFraction(int data, float base, float pbase)
428 {
429 switch ((data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK) {
430 case COMPLEX_UNIT_FRACTION:
431 return complexToFloat(data) * base;
432 case COMPLEX_UNIT_FRACTION_PARENT:
433 return complexToFloat(data) * pbase;
434 }
435 return 0;
436 }
437
438 /**
439 * Return the data for this value as a fraction. Only use for values whose
440 * type is {@link #TYPE_FRACTION}.
441 *
442 * @param base The base value of this fraction. In other words, a
443 * standard fraction is multiplied by this value.
444 * @param pbase The parent base value of this fraction. In other
445 * words, a parent fraction (nn%p) is multiplied by this
446 * value.
447 *
448 * @return The complex floating point value multiplied by the appropriate
449 * base value depending on its unit.
450 */
451 public float getFraction(float base, float pbase)
452 {
453 return complexToFraction(data, base, pbase);
454 }
455
456 /**
457 * Regardless of the actual type of the value, try to convert it to a
458 * string value. For example, a color type will be converted to a
459 * string of the form #aarrggbb.
460 *
461 * @return CharSequence The coerced string value. If the value is
462 * null or the type is not known, null is returned.
463 */
464 public final CharSequence coerceToString()
465 {
466 int t = type;
467 if (t == TYPE_STRING) {
468 return string;
469 }
470 return coerceToString(t, data);
471 }
472
473 private static final String[] DIMENSION_UNIT_STRS = new String[] {
474 "px", "dip", "sp", "pt", "in", "mm"
475 };
476 private static final String[] FRACTION_UNIT_STRS = new String[] {
477 "%", "%p"
478 };
479
480 /**
481 * Perform type conversion as per {@link #coerceToString()} on an
482 * explicitly supplied type and data.
483 *
484 * @param type The data type identifier.
485 * @param data The data value.
486 *
487 * @return String The coerced string value. If the value is
488 * null or the type is not known, null is returned.
489 */
490 public static final String coerceToString(int type, int data)
491 {
492 switch (type) {
493 case TYPE_NULL:
494 return null;
495 case TYPE_REFERENCE:
496 return "@" + data;
497 case TYPE_ATTRIBUTE:
498 return "?" + data;
499 case TYPE_FLOAT:
500 return Float.toString(Float.intBitsToFloat(data));
501 case TYPE_DIMENSION:
502 return Float.toString(complexToFloat(data)) + DIMENSION_UNIT_STRS[
503 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
504 case TYPE_FRACTION:
505 return Float.toString(complexToFloat(data)*100) + FRACTION_UNIT_STRS[
506 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
507 case TYPE_INT_HEX:
508 return "0x" + Integer.toHexString(data);
509 case TYPE_INT_BOOLEAN:
510 return data != 0 ? "true" : "false";
511 }
512
513 if (type >= TYPE_FIRST_COLOR_INT && type <= TYPE_LAST_COLOR_INT) {
514 return "#" + Integer.toHexString(data);
515 } else if (type >= TYPE_FIRST_INT && type <= TYPE_LAST_INT) {
516 return Integer.toString(data);
517 }
518
519 return null;
520 }
521
522 public void setTo(TypedValue other)
523 {
524 type = other.type;
525 string = other.string;
526 data = other.data;
527 assetCookie = other.assetCookie;
528 resourceId = other.resourceId;
529 density = other.density;
530 }
531
532 public String toString()
533 {
534 StringBuilder sb = new StringBuilder();
535 sb.append("TypedValue{t=0x").append(Integer.toHexString(type));
536 sb.append("/d=0x").append(Integer.toHexString(data));
537 if (type == TYPE_STRING) {
538 sb.append(" \"").append(string != null ? string : "<null>").append("\"");
539 }
540 if (assetCookie != 0) {
541 sb.append(" a=").append(assetCookie);
542 }
543 if (resourceId != 0) {
544 sb.append(" r=0x").append(Integer.toHexString(resourceId));
545 }
546 sb.append("}");
547 return sb.toString();
548 }
549};
550