• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.util;
18 
19 import android.annotation.AnyRes;
20 import android.content.pm.ActivityInfo.Config;
21 
22 /**
23  * Container for a dynamically typed data value.  Primarily used with
24  * {@link android.content.res.Resources} for holding resource values.
25  */
26 public 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     /**
145      * {@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     /**
156      * If {@link #density} is equal to this value, then the density should be
157      * treated as the system's default density value: {@link DisplayMetrics#DENSITY_DEFAULT}.
158      */
159     public static final int DENSITY_DEFAULT = 0;
160 
161     /**
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 
167     /* ------------------------------------------------------------ */
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. */
184     @AnyRes
185     public int resourceId;
186 
187     /**
188      * If the value came from a resource, these are the configurations for
189      * which its contents can change.
190      *
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      *
211      */
212     public @Config int changingConfigurations = -1;
213 
214     /**
215      * If the Value came from a resource, this holds the corresponding pixel density.
216      * */
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}. */
getFloat()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     /**
235      * Retrieve the base value from a complex data integer.  This uses the
236      * {@link #COMPLEX_MANTISSA_MASK} and {@link #COMPLEX_RADIX_MASK} fields of
237      * the data to compute a floating point representation of the number they
238      * describe.  The units are ignored.
239      *
240      * @param complex A complex data value.
241      *
242      * @return A floating point value corresponding to the complex data.
243      */
complexToFloat(int complex)244     public static float complexToFloat(int complex)
245     {
246         return (complex&(TypedValue.COMPLEX_MANTISSA_MASK
247                    <<TypedValue.COMPLEX_MANTISSA_SHIFT))
248             * RADIX_MULTS[(complex>>TypedValue.COMPLEX_RADIX_SHIFT)
249                             & TypedValue.COMPLEX_RADIX_MASK];
250     }
251 
252     /**
253      * Converts a complex data value holding a dimension to its final floating
254      * point value. 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 complex floating point value multiplied by the appropriate
263      * metrics depending on its unit.
264      */
complexToDimension(int data, DisplayMetrics metrics)265     public static float complexToDimension(int data, DisplayMetrics metrics)
266     {
267         return applyDimension(
268             (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
269             complexToFloat(data),
270             metrics);
271     }
272 
273     /**
274      * Converts a complex data value holding a dimension to its final value
275      * as an integer pixel offset.  This is the same as
276      * {@link #complexToDimension}, except the raw floating point value is
277      * truncated to an integer (pixel) value.
278      * The given <var>data</var> must be structured as a
279      * {@link #TYPE_DIMENSION}.
280      *
281      * @param data A complex data value holding a unit, magnitude, and
282      *             mantissa.
283      * @param metrics Current display metrics to use in the conversion --
284      *                supplies display density and scaling information.
285      *
286      * @return The number of pixels specified by the data and its desired
287      * multiplier and units.
288      */
complexToDimensionPixelOffset(int data, DisplayMetrics metrics)289     public static int complexToDimensionPixelOffset(int data,
290             DisplayMetrics metrics)
291     {
292         return (int)applyDimension(
293                 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
294                 complexToFloat(data),
295                 metrics);
296     }
297 
298     /**
299      * Converts a complex data value holding a dimension to its final value
300      * as an integer pixel size.  This is the same as
301      * {@link #complexToDimension}, except the raw floating point value is
302      * converted to an integer (pixel) value for use as a size.  A size
303      * conversion involves rounding the base value, and ensuring that a
304      * non-zero base value is at least one pixel in size.
305      * The given <var>data</var> must be structured as a
306      * {@link #TYPE_DIMENSION}.
307      *
308      * @param data A complex data value holding a unit, magnitude, and
309      *             mantissa.
310      * @param metrics Current display metrics to use in the conversion --
311      *                supplies display density and scaling information.
312      *
313      * @return The number of pixels specified by the data and its desired
314      * multiplier and units.
315      */
complexToDimensionPixelSize(int data, DisplayMetrics metrics)316     public static int complexToDimensionPixelSize(int data,
317             DisplayMetrics metrics)
318     {
319         final float value = complexToFloat(data);
320         final float f = applyDimension(
321                 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK,
322                 value,
323                 metrics);
324         final int res = (int) ((f >= 0) ? (f + 0.5f) : (f - 0.5f));
325         if (res != 0) return res;
326         if (value == 0) return 0;
327         if (value > 0) return 1;
328         return -1;
329     }
330 
331     /**
332      * @hide Was accidentally exposed in API level 1 for debugging purposes.
333      * Kept for compatibility just in case although the debugging code has been removed.
334      */
335     @Deprecated
complexToDimensionNoisy(int data, DisplayMetrics metrics)336     public static float complexToDimensionNoisy(int data, DisplayMetrics metrics)
337     {
338         return complexToDimension(data, metrics);
339     }
340 
341     /**
342      * Return the complex unit type for this value. For example, a dimen type
343      * with value 12sp will return {@link #COMPLEX_UNIT_SP}. Only use for values
344      * whose type is {@link #TYPE_DIMENSION}.
345      *
346      * @return The complex unit type.
347      */
getComplexUnit()348      public int getComplexUnit()
349      {
350          return COMPLEX_UNIT_MASK & (data>>TypedValue.COMPLEX_UNIT_SHIFT);
351      }
352 
353     /**
354      * Converts an unpacked complex data value holding a dimension to its final floating
355      * point value. The two parameters <var>unit</var> and <var>value</var>
356      * are as in {@link #TYPE_DIMENSION}.
357      *
358      * @param unit The unit to convert from.
359      * @param value The value to apply the unit to.
360      * @param metrics Current display metrics to use in the conversion --
361      *                supplies display density and scaling information.
362      *
363      * @return The complex floating point value multiplied by the appropriate
364      * metrics depending on its unit.
365      */
applyDimension(int unit, float value, DisplayMetrics metrics)366     public static float applyDimension(int unit, float value,
367                                        DisplayMetrics metrics)
368     {
369         switch (unit) {
370         case COMPLEX_UNIT_PX:
371             return value;
372         case COMPLEX_UNIT_DIP:
373             return value * metrics.density;
374         case COMPLEX_UNIT_SP:
375             return value * metrics.scaledDensity;
376         case COMPLEX_UNIT_PT:
377             return value * metrics.xdpi * (1.0f/72);
378         case COMPLEX_UNIT_IN:
379             return value * metrics.xdpi;
380         case COMPLEX_UNIT_MM:
381             return value * metrics.xdpi * (1.0f/25.4f);
382         }
383         return 0;
384     }
385 
386     /**
387      * Return the data for this value as a dimension.  Only use for values
388      * whose type is {@link #TYPE_DIMENSION}.
389      *
390      * @param metrics Current display metrics to use in the conversion --
391      *                supplies display density and scaling information.
392      *
393      * @return The complex floating point value multiplied by the appropriate
394      * metrics depending on its unit.
395      */
getDimension(DisplayMetrics metrics)396     public float getDimension(DisplayMetrics metrics)
397     {
398         return complexToDimension(data, metrics);
399     }
400 
401     /**
402      * Converts a complex data value holding a fraction to its final floating
403      * point value. The given <var>data</var> must be structured as a
404      * {@link #TYPE_FRACTION}.
405      *
406      * @param data A complex data value holding a unit, magnitude, and
407      *             mantissa.
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      */
complexToFraction(int data, float base, float pbase)417     public static float complexToFraction(int data, float base, float pbase)
418     {
419         switch ((data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK) {
420         case COMPLEX_UNIT_FRACTION:
421             return complexToFloat(data) * base;
422         case COMPLEX_UNIT_FRACTION_PARENT:
423             return complexToFloat(data) * pbase;
424         }
425         return 0;
426     }
427 
428     /**
429      * Return the data for this value as a fraction.  Only use for values whose
430      * type is {@link #TYPE_FRACTION}.
431      *
432      * @param base The base value of this fraction.  In other words, a
433      *             standard fraction is multiplied by this value.
434      * @param pbase The parent base value of this fraction.  In other
435      *             words, a parent fraction (nn%p) is multiplied by this
436      *             value.
437      *
438      * @return The complex floating point value multiplied by the appropriate
439      * base value depending on its unit.
440      */
getFraction(float base, float pbase)441     public float getFraction(float base, float pbase)
442     {
443         return complexToFraction(data, base, pbase);
444     }
445 
446     /**
447      * Regardless of the actual type of the value, try to convert it to a
448      * string value.  For example, a color type will be converted to a
449      * string of the form #aarrggbb.
450      *
451      * @return CharSequence The coerced string value.  If the value is
452      *         null or the type is not known, null is returned.
453      */
coerceToString()454     public final CharSequence coerceToString()
455     {
456         int t = type;
457         if (t == TYPE_STRING) {
458             return string;
459         }
460         return coerceToString(t, data);
461     }
462 
463     private static final String[] DIMENSION_UNIT_STRS = new String[] {
464         "px", "dip", "sp", "pt", "in", "mm"
465     };
466     private static final String[] FRACTION_UNIT_STRS = new String[] {
467         "%", "%p"
468     };
469 
470     /**
471      * Perform type conversion as per {@link #coerceToString()} on an
472      * explicitly supplied type and data.
473      *
474      * @param type The data type identifier.
475      * @param data The data value.
476      *
477      * @return String The coerced string value.  If the value is
478      *         null or the type is not known, null is returned.
479      */
coerceToString(int type, int data)480     public static final String coerceToString(int type, int data)
481     {
482         switch (type) {
483         case TYPE_NULL:
484             return null;
485         case TYPE_REFERENCE:
486             return "@" + data;
487         case TYPE_ATTRIBUTE:
488             return "?" + data;
489         case TYPE_FLOAT:
490             return Float.toString(Float.intBitsToFloat(data));
491         case TYPE_DIMENSION:
492             return Float.toString(complexToFloat(data)) + DIMENSION_UNIT_STRS[
493                 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
494         case TYPE_FRACTION:
495             return Float.toString(complexToFloat(data)*100) + FRACTION_UNIT_STRS[
496                 (data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
497         case TYPE_INT_HEX:
498             return "0x" + Integer.toHexString(data);
499         case TYPE_INT_BOOLEAN:
500             return data != 0 ? "true" : "false";
501         }
502 
503         if (type >= TYPE_FIRST_COLOR_INT && type <= TYPE_LAST_COLOR_INT) {
504             return "#" + Integer.toHexString(data);
505         } else if (type >= TYPE_FIRST_INT && type <= TYPE_LAST_INT) {
506             return Integer.toString(data);
507         }
508 
509         return null;
510     }
511 
setTo(TypedValue other)512     public void setTo(TypedValue other)
513     {
514         type = other.type;
515         string = other.string;
516         data = other.data;
517         assetCookie = other.assetCookie;
518         resourceId = other.resourceId;
519         density = other.density;
520     }
521 
toString()522     public String toString()
523     {
524         StringBuilder sb = new StringBuilder();
525         sb.append("TypedValue{t=0x").append(Integer.toHexString(type));
526         sb.append("/d=0x").append(Integer.toHexString(data));
527         if (type == TYPE_STRING) {
528             sb.append(" \"").append(string != null ? string : "<null>").append("\"");
529         }
530         if (assetCookie != 0) {
531             sb.append(" a=").append(assetCookie);
532         }
533         if (resourceId != 0) {
534             sb.append(" r=0x").append(Integer.toHexString(resourceId));
535         }
536         sb.append("}");
537         return sb.toString();
538     }
539 };
540 
541