FileDocCategorySizeDatePackage
ResourceHelper.javaAPI DocAndroid 1.5 API13341Wed May 06 22:42:02 BST 2009com.android.layoutlib.bridge

ResourceHelper

public final class ResourceHelper extends Object
Helper class to provide various convertion method used in handling android resources.

Fields Summary
private static final Pattern
sFloatPattern
private static final float[]
sFloatOut
private static final android.util.TypedValue
mValue
private static final UnitEntry[]
sUnitNames
Constructors Summary
Methods Summary
static intgetColor(java.lang.String value)
Returns the color value represented by the given string value

param
value the color value
return
the color as an int
throw
NumberFormatException if the conversion failed.


                                    
        
        if (value != null) {
            if (value.startsWith("#") == false) {
                throw new NumberFormatException();
            }

            value = value.substring(1);
            
            // make sure it's not longer than 32bit
            if (value.length() > 8) {
                throw new NumberFormatException();
            }
            
            if (value.length() == 3) { // RGB format
                char[] color = new char[8];
                color[0] = color[1] = 'F";
                color[2] = color[3] = value.charAt(0);
                color[4] = color[5] = value.charAt(1);
                color[6] = color[7] = value.charAt(2);
                value = new String(color);
            } else if (value.length() == 4) { // ARGB format
                char[] color = new char[8];
                color[0] = color[1] = value.charAt(0);
                color[2] = color[3] = value.charAt(1);
                color[4] = color[5] = value.charAt(2);
                color[6] = color[7] = value.charAt(3);
                value = new String(color);
            } else if (value.length() == 6) {
                value = "FF" + value;
            }

            // this is a RRGGBB or AARRGGBB value
            
            // Integer.parseInt will fail to parse strings like "ff191919", so we use
            // a Long, but cast the result back into an int, since we know that we're only
            // dealing with 32 bit values.
            return (int)Long.parseLong(value, 16);
        }

        throw new NumberFormatException();
    
public static android.graphics.drawable.DrawablegetDrawable(java.lang.String value, BridgeContext context, boolean isFramework)
Returns a drawable from the given value.

param
value The value. A path to a 9 patch, a bitmap or a xml based drawable, or an hexadecimal color
param
context
param
isFramework indicates whether the resource is a framework resources. Framework resources are cached, and loaded only once.

        Drawable d = null;
        
        String lowerCaseValue = value.toLowerCase();

        if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
            File f = new File(value);
            if (f.isFile()) {
                NinePatch ninePatch = Bridge.getCached9Patch(value,
                        isFramework ? null : context.getProjectKey());
                
                if (ninePatch == null) {
                    try {
                        ninePatch = NinePatch.load(new File(value).toURL(), false /* convert */);
                        
                        Bridge.setCached9Patch(value, ninePatch,
                                isFramework ? null : context.getProjectKey());
                    } catch (MalformedURLException e) {
                        // URL is wrong, we'll return null below
                    } catch (IOException e) {
                        // failed to read the file, we'll return null below.
                    }
                }
                
                if (ninePatch != null) {
                    return new NinePatchDrawable(ninePatch);
                }
            }
            
            return null;
        } else if (lowerCaseValue.endsWith(".xml")) {
            // create a blockparser for the file
            File f = new File(value);
            if (f.isFile()) {
                try {
                    // let the framework inflate the Drawable from the XML file.
                    KXmlParser parser = new KXmlParser();
                    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
                    parser.setInput(new FileReader(f));
                    
                    d = Drawable.createFromXml(context.getResources(),
                            // FIXME: we need to know if this resource is platform or not
                            new BridgeXmlBlockParser(parser, context, false));
                    return d;
                } catch (XmlPullParserException e) {
                    context.getLogger().error(e);
                } catch (FileNotFoundException e) {
                    // will not happen, since we pre-check
                } catch (IOException e) {
                    context.getLogger().error(e);
                }
            }

            return null;
        } else {
            File bmpFile = new File(value);
            if (bmpFile.isFile()) {
                try {
                    Bitmap bitmap = Bridge.getCachedBitmap(value,
                            isFramework ? null : context.getProjectKey());
                    
                    if (bitmap == null) {
                        bitmap = new Bitmap(bmpFile);
                        Bridge.setCachedBitmap(value, bitmap,
                                isFramework ? null : context.getProjectKey());
                    }
                    
                    return new BitmapDrawable(bitmap);
                } catch (IOException e) {
                    // we'll return null below
                    // TODO: log the error.
                }
            } else {
                // attempt to get a color from the value
                try {
                    int color = getColor(value);
                    return new ColorDrawable(color);
                } catch (NumberFormatException e) {
                    // we'll return null below.
                    // TODO: log the error
                }
            }
        }
        
        return null;
    
public static android.util.TypedValuegetValue(java.lang.String s)
Returns the raw value from the given string. This object is only valid until the next call on to {@link ResourceHelper}.

    
                              
         
        if (stringToFloat(s, mValue)) {
            return mValue;
        }
        
        return null;
    
private static booleanparseUnit(java.lang.String str, android.util.TypedValue outValue, float[] outScale)

        str = str.trim();

        for (UnitEntry unit : sUnitNames) {
            if (unit.name.equals(str)) {
                outValue.type = unit.type;
                outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
                outScale[0] = unit.scale;
                
                return true;
            }
        }

        return false;
    
public static booleanstringToFloat(java.lang.String s, android.util.TypedValue outValue)
Convert the string into a {@link TypedValue}.

param
s
param
outValue
return
true if success.

        // remove the space before and after
        s.trim();
        int len = s.length();

        if (len <= 0) {
            return false;
        }

        // check that there's no non ascii characters.
        char[] buf = s.toCharArray();
        for (int i = 0 ; i < len ; i++) {
            if (buf[i] > 255) {
                return false;
            }
        }

        // check the first character
        if (buf[0] < '0" && buf[0] > '9" && buf[0] != '.") {
            return false;
        }
        
        // now look for the string that is after the float...
        Matcher m = sFloatPattern.matcher(s);
        if (m.matches()) {
            String f_str = m.group(1);
            String end = m.group(2);

            float f;
            try {
                f = Float.parseFloat(f_str);
            } catch (NumberFormatException e) {
                // this shouldn't happen with the regexp above.
                return false;
            }
            
            if (end.length() > 0 && end.charAt(0) != ' ") {
                // Might be a unit...
                if (parseUnit(end, outValue, sFloatOut)) {
                     
                    f *= sFloatOut[0];
                    boolean neg = f < 0;
                    if (neg) {
                        f = -f;
                    }
                    long bits = (long)(f*(1<<23)+.5f);
                    int radix;
                    int shift;
                    if ((bits&0x7fffff) == 0) {
                        // Always use 23p0 if there is no fraction, just to make
                        // things easier to read.
                        radix = TypedValue.COMPLEX_RADIX_23p0;
                        shift = 23;
                    } else if ((bits&0xffffffffff800000L) == 0) {
                        // Magnitude is zero -- can fit in 0 bits of precision.
                        radix = TypedValue.COMPLEX_RADIX_0p23;
                        shift = 0;
                    } else if ((bits&0xffffffff80000000L) == 0) {
                        // Magnitude can fit in 8 bits of precision.
                        radix = TypedValue.COMPLEX_RADIX_8p15;
                        shift = 8;
                    } else if ((bits&0xffffff8000000000L) == 0) {
                        // Magnitude can fit in 16 bits of precision.
                        radix = TypedValue.COMPLEX_RADIX_16p7;
                        shift = 16;
                    } else {
                        // Magnitude needs entire range, so no fractional part.
                        radix = TypedValue.COMPLEX_RADIX_23p0;
                        shift = 23;
                    }
                    int mantissa = (int)(
                        (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
                    if (neg) {
                        mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
                    }
                    outValue.data |= 
                        (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
                        | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
                    return true;
                }
                return false;
            }
            
            // make sure it's only spaces at the end.
            end = end.trim();
    
            if (end.length() == 0) {
                if (outValue != null) {
                    outValue.type = TypedValue.TYPE_FLOAT;
                    outValue.data = Float.floatToIntBits(f);
                    return true;
                }
            }
        }

        return false;