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