Loading core/java/android/content/res/StringBlock.java +73 −14 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.content.res; import android.graphics.Color; import android.text.*; import android.text.style.*; import android.util.Log; Loading @@ -24,7 +25,7 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import com.android.internal.util.XmlUtils; import java.util.Arrays; /** * Conveniences for retrieving data out of a compiled string resource. Loading @@ -33,7 +34,7 @@ import com.android.internal.util.XmlUtils; */ final class StringBlock { private static final String TAG = "AssetManager"; private static final boolean localLOGV = false || false; private static final boolean localLOGV = false; private final int mNative; private final boolean mUseSparse; Loading Loading @@ -82,7 +83,7 @@ final class StringBlock { CharSequence res = str; int[] style = nativeGetStyle(mNative, idx); if (localLOGV) Log.v(TAG, "Got string: " + str); if (localLOGV) Log.v(TAG, "Got styles: " + style); if (localLOGV) Log.v(TAG, "Got styles: " + Arrays.toString(style)); if (style != null) { if (mStyleIDs == null) { mStyleIDs = new StyleIDs(); Loading Loading @@ -139,10 +140,14 @@ final class StringBlock { } protected void finalize() throws Throwable { try { super.finalize(); } finally { if (mOwnsNative) { nativeDestroy(mNative); } } } static final class StyleIDs { private int boldId = -1; Loading Loading @@ -236,16 +241,28 @@ final class StringBlock { sub = subtag(tag, ";fgcolor="); if (sub != null) { int color = XmlUtils.convertValueToUnsignedInt(sub, -1); buffer.setSpan(new ForegroundColorSpan(color), buffer.setSpan(getColor(sub, true), style[i+1], style[i+2]+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } sub = subtag(tag, ";color="); if (sub != null) { buffer.setSpan(getColor(sub, true), style[i+1], style[i+2]+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } sub = subtag(tag, ";bgcolor="); if (sub != null) { int color = XmlUtils.convertValueToUnsignedInt(sub, -1); buffer.setSpan(new BackgroundColorSpan(color), buffer.setSpan(getColor(sub, false), style[i+1], style[i+2]+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } sub = subtag(tag, ";face="); if (sub != null) { buffer.setSpan(new TypefaceSpan(sub), style[i+1], style[i+2]+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } Loading Loading @@ -288,6 +305,48 @@ final class StringBlock { return new SpannedString(buffer); } /** * Returns a span for the specified color string representation. * If the specified string does not represent a color (null, empty, etc.) * the color black is returned instead. * * @param color The color as a string. Can be a resource reference, * HTML hexadecimal, octal or a name * @param foreground True if the color will be used as the foreground color, * false otherwise * * @return A CharacterStyle * * @see Color#getHtmlColor(String) */ private static CharacterStyle getColor(String color, boolean foreground) { int c = 0xff000000; if (!TextUtils.isEmpty(color)) { if (color.startsWith("@")) { Resources res = Resources.getSystem(); String name = color.substring(1); int colorRes = res.getIdentifier(name, "color", "android"); if (colorRes != 0) { ColorStateList colors = res.getColorStateList(colorRes); if (foreground) { return new TextAppearanceSpan(null, 0, 0, colors, null); } else { c = colors.getDefaultColor(); } } } else { c = Color.getHtmlColor(color); } } if (foreground) { return new ForegroundColorSpan(c); } else { return new BackgroundColorSpan(c); } } /** * If a translator has messed up the edges of paragraph-level markup, * fix it to actually cover the entire paragraph that it is attached to Loading Loading @@ -423,11 +482,11 @@ final class StringBlock { + ": " + nativeGetSize(mNative)); } private static final native int nativeCreate(byte[] data, private static native int nativeCreate(byte[] data, int offset, int size); private static final native int nativeGetSize(int obj); private static final native String nativeGetString(int obj, int idx); private static final native int[] nativeGetStyle(int obj, int idx); private static final native void nativeDestroy(int obj); private static native int nativeGetSize(int obj); private static native String nativeGetString(int obj, int idx); private static native int[] nativeGetStyle(int obj, int idx); private static native void nativeDestroy(int obj); } core/java/android/text/Html.java +7 −51 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.text; import android.graphics.Color; import com.android.internal.util.ArrayUtils; import org.ccil.cowan.tagsoup.HTMLSchema; import org.ccil.cowan.tagsoup.Parser; Loading Loading @@ -181,7 +182,7 @@ public class Html { } } if (needDiv) { out.append("<div " + elements + ">"); out.append("<div ").append(elements).append(">"); } withinDiv(out, text, i, next); Loading Loading @@ -391,7 +392,7 @@ public class Html { } else if (c == '&') { out.append("&"); } else if (c > 0x7E || c < ' ') { out.append("&#" + ((int) c) + ";"); out.append("&#").append((int) c).append(";"); } else if (c == ' ') { while (i + 1 < end && text.charAt(i + 1) == ' ') { out.append(" "); Loading Loading @@ -616,8 +617,6 @@ class HtmlToSpannedConverter implements ContentHandler { if (where != len) { text.setSpan(repl, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } return; } private static void startImg(SpannableStringBuilder text, Loading Loading @@ -673,7 +672,7 @@ class HtmlToSpannedConverter implements ContentHandler { Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else { int c = getHtmlColor(f.mColor); int c = Color.getHtmlColor(f.mColor); if (c != -1) { text.setSpan(new ForegroundColorSpan(c | 0xFF000000), where, len, Loading Loading @@ -842,47 +841,4 @@ class HtmlToSpannedConverter implements ContentHandler { mLevel = level; } } private static HashMap<String,Integer> COLORS = buildColorMap(); private static HashMap<String,Integer> buildColorMap() { HashMap<String,Integer> map = new HashMap<String,Integer>(); map.put("aqua", 0x00FFFF); map.put("black", 0x000000); map.put("blue", 0x0000FF); map.put("fuchsia", 0xFF00FF); map.put("green", 0x008000); map.put("grey", 0x808080); map.put("lime", 0x00FF00); map.put("maroon", 0x800000); map.put("navy", 0x000080); map.put("olive", 0x808000); map.put("purple", 0x800080); map.put("red", 0xFF0000); map.put("silver", 0xC0C0C0); map.put("teal", 0x008080); map.put("white", 0xFFFFFF); map.put("yellow", 0xFFFF00); return map; } /** * Converts an HTML color (named or numeric) to an integer RGB value. * * @param color Non-null color string. * @return A color value, or {@code -1} if the color string could not be interpreted. */ private static int getHtmlColor(String color) { Integer i = COLORS.get(color.toLowerCase()); if (i != null) { return i; } else { try { return XmlUtils.convertValueToInt(color, -1); } catch (NumberFormatException nfe) { return -1; } } } } core/java/com/android/internal/util/XmlUtils.java +4 −7 Original line number Diff line number Diff line Loading @@ -123,18 +123,15 @@ public class XmlUtils return Integer.parseInt(nm.substring(index), base) * sign; } public static final int convertValueToUnsignedInt(String value, int defaultValue) { if (null == value) public static int convertValueToUnsignedInt(String value, int defaultValue) { if (null == value) { return defaultValue; } return parseUnsignedIntAttribute(value); } public static final int parseUnsignedIntAttribute(CharSequence charSeq) { public static int parseUnsignedIntAttribute(CharSequence charSeq) { String value = charSeq.toString(); long bits; Loading graphics/java/android/graphics/Color.java +42 −5 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.graphics; import android.util.MathUtils; import com.android.internal.util.XmlUtils; import java.util.HashMap; import java.util.Locale; Loading Loading @@ -200,7 +201,9 @@ public class Color { * #RRGGBB * #AARRGGBB * 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta', * 'yellow', 'lightgray', 'darkgray' * 'yellow', 'lightgray', 'darkgray', 'grey', 'lightgrey', 'darkgrey', * 'aqua', 'fuschia', 'lime', 'maroon', 'navy', 'olive', 'purple', * 'silver', 'teal' */ public static int parseColor(String colorString) { if (colorString.charAt(0) == '#') { Loading Loading @@ -366,6 +369,28 @@ public class Color { private static native void nativeRGBToHSV(int red, int greed, int blue, float hsv[]); private static native int nativeHSVToColor(int alpha, float hsv[]); /** * Converts an HTML color (named or numeric) to an integer RGB value. * * @param color Non-null color string. * * @return A color value, or {@code -1} if the color string could not be interpreted. * * @hide */ public static int getHtmlColor(String color) { Integer i = sColorNameMap.get(color.toLowerCase()); if (i != null) { return i; } else { try { return XmlUtils.convertValueToInt(color, -1); } catch (NumberFormatException nfe) { return -1; } } } private static final HashMap<String, Integer> sColorNameMap; static { Loading @@ -381,6 +406,18 @@ public class Color { sColorNameMap.put("yellow", YELLOW); sColorNameMap.put("cyan", CYAN); sColorNameMap.put("magenta", MAGENTA); sColorNameMap.put("aqua", 0x00FFFF); sColorNameMap.put("fuchsia", 0xFF00FF); sColorNameMap.put("darkgrey", DKGRAY); sColorNameMap.put("grey", GRAY); sColorNameMap.put("lightgrey", LTGRAY); sColorNameMap.put("lime", 0x00FF00); sColorNameMap.put("maroon", 0x800000); sColorNameMap.put("navy", 0x000080); sColorNameMap.put("olive", 0x808000); sColorNameMap.put("purple", 0x800080); sColorNameMap.put("silver", 0xC0C0C0); sColorNameMap.put("teal", 0x008080); } } Loading
core/java/android/content/res/StringBlock.java +73 −14 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.content.res; import android.graphics.Color; import android.text.*; import android.text.style.*; import android.util.Log; Loading @@ -24,7 +25,7 @@ import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import com.android.internal.util.XmlUtils; import java.util.Arrays; /** * Conveniences for retrieving data out of a compiled string resource. Loading @@ -33,7 +34,7 @@ import com.android.internal.util.XmlUtils; */ final class StringBlock { private static final String TAG = "AssetManager"; private static final boolean localLOGV = false || false; private static final boolean localLOGV = false; private final int mNative; private final boolean mUseSparse; Loading Loading @@ -82,7 +83,7 @@ final class StringBlock { CharSequence res = str; int[] style = nativeGetStyle(mNative, idx); if (localLOGV) Log.v(TAG, "Got string: " + str); if (localLOGV) Log.v(TAG, "Got styles: " + style); if (localLOGV) Log.v(TAG, "Got styles: " + Arrays.toString(style)); if (style != null) { if (mStyleIDs == null) { mStyleIDs = new StyleIDs(); Loading Loading @@ -139,10 +140,14 @@ final class StringBlock { } protected void finalize() throws Throwable { try { super.finalize(); } finally { if (mOwnsNative) { nativeDestroy(mNative); } } } static final class StyleIDs { private int boldId = -1; Loading Loading @@ -236,16 +241,28 @@ final class StringBlock { sub = subtag(tag, ";fgcolor="); if (sub != null) { int color = XmlUtils.convertValueToUnsignedInt(sub, -1); buffer.setSpan(new ForegroundColorSpan(color), buffer.setSpan(getColor(sub, true), style[i+1], style[i+2]+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } sub = subtag(tag, ";color="); if (sub != null) { buffer.setSpan(getColor(sub, true), style[i+1], style[i+2]+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } sub = subtag(tag, ";bgcolor="); if (sub != null) { int color = XmlUtils.convertValueToUnsignedInt(sub, -1); buffer.setSpan(new BackgroundColorSpan(color), buffer.setSpan(getColor(sub, false), style[i+1], style[i+2]+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } sub = subtag(tag, ";face="); if (sub != null) { buffer.setSpan(new TypefaceSpan(sub), style[i+1], style[i+2]+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } Loading Loading @@ -288,6 +305,48 @@ final class StringBlock { return new SpannedString(buffer); } /** * Returns a span for the specified color string representation. * If the specified string does not represent a color (null, empty, etc.) * the color black is returned instead. * * @param color The color as a string. Can be a resource reference, * HTML hexadecimal, octal or a name * @param foreground True if the color will be used as the foreground color, * false otherwise * * @return A CharacterStyle * * @see Color#getHtmlColor(String) */ private static CharacterStyle getColor(String color, boolean foreground) { int c = 0xff000000; if (!TextUtils.isEmpty(color)) { if (color.startsWith("@")) { Resources res = Resources.getSystem(); String name = color.substring(1); int colorRes = res.getIdentifier(name, "color", "android"); if (colorRes != 0) { ColorStateList colors = res.getColorStateList(colorRes); if (foreground) { return new TextAppearanceSpan(null, 0, 0, colors, null); } else { c = colors.getDefaultColor(); } } } else { c = Color.getHtmlColor(color); } } if (foreground) { return new ForegroundColorSpan(c); } else { return new BackgroundColorSpan(c); } } /** * If a translator has messed up the edges of paragraph-level markup, * fix it to actually cover the entire paragraph that it is attached to Loading Loading @@ -423,11 +482,11 @@ final class StringBlock { + ": " + nativeGetSize(mNative)); } private static final native int nativeCreate(byte[] data, private static native int nativeCreate(byte[] data, int offset, int size); private static final native int nativeGetSize(int obj); private static final native String nativeGetString(int obj, int idx); private static final native int[] nativeGetStyle(int obj, int idx); private static final native void nativeDestroy(int obj); private static native int nativeGetSize(int obj); private static native String nativeGetString(int obj, int idx); private static native int[] nativeGetStyle(int obj, int idx); private static native void nativeDestroy(int obj); }
core/java/android/text/Html.java +7 −51 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.text; import android.graphics.Color; import com.android.internal.util.ArrayUtils; import org.ccil.cowan.tagsoup.HTMLSchema; import org.ccil.cowan.tagsoup.Parser; Loading Loading @@ -181,7 +182,7 @@ public class Html { } } if (needDiv) { out.append("<div " + elements + ">"); out.append("<div ").append(elements).append(">"); } withinDiv(out, text, i, next); Loading Loading @@ -391,7 +392,7 @@ public class Html { } else if (c == '&') { out.append("&"); } else if (c > 0x7E || c < ' ') { out.append("&#" + ((int) c) + ";"); out.append("&#").append((int) c).append(";"); } else if (c == ' ') { while (i + 1 < end && text.charAt(i + 1) == ' ') { out.append(" "); Loading Loading @@ -616,8 +617,6 @@ class HtmlToSpannedConverter implements ContentHandler { if (where != len) { text.setSpan(repl, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } return; } private static void startImg(SpannableStringBuilder text, Loading Loading @@ -673,7 +672,7 @@ class HtmlToSpannedConverter implements ContentHandler { Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else { int c = getHtmlColor(f.mColor); int c = Color.getHtmlColor(f.mColor); if (c != -1) { text.setSpan(new ForegroundColorSpan(c | 0xFF000000), where, len, Loading Loading @@ -842,47 +841,4 @@ class HtmlToSpannedConverter implements ContentHandler { mLevel = level; } } private static HashMap<String,Integer> COLORS = buildColorMap(); private static HashMap<String,Integer> buildColorMap() { HashMap<String,Integer> map = new HashMap<String,Integer>(); map.put("aqua", 0x00FFFF); map.put("black", 0x000000); map.put("blue", 0x0000FF); map.put("fuchsia", 0xFF00FF); map.put("green", 0x008000); map.put("grey", 0x808080); map.put("lime", 0x00FF00); map.put("maroon", 0x800000); map.put("navy", 0x000080); map.put("olive", 0x808000); map.put("purple", 0x800080); map.put("red", 0xFF0000); map.put("silver", 0xC0C0C0); map.put("teal", 0x008080); map.put("white", 0xFFFFFF); map.put("yellow", 0xFFFF00); return map; } /** * Converts an HTML color (named or numeric) to an integer RGB value. * * @param color Non-null color string. * @return A color value, or {@code -1} if the color string could not be interpreted. */ private static int getHtmlColor(String color) { Integer i = COLORS.get(color.toLowerCase()); if (i != null) { return i; } else { try { return XmlUtils.convertValueToInt(color, -1); } catch (NumberFormatException nfe) { return -1; } } } }
core/java/com/android/internal/util/XmlUtils.java +4 −7 Original line number Diff line number Diff line Loading @@ -123,18 +123,15 @@ public class XmlUtils return Integer.parseInt(nm.substring(index), base) * sign; } public static final int convertValueToUnsignedInt(String value, int defaultValue) { if (null == value) public static int convertValueToUnsignedInt(String value, int defaultValue) { if (null == value) { return defaultValue; } return parseUnsignedIntAttribute(value); } public static final int parseUnsignedIntAttribute(CharSequence charSeq) { public static int parseUnsignedIntAttribute(CharSequence charSeq) { String value = charSeq.toString(); long bits; Loading
graphics/java/android/graphics/Color.java +42 −5 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.graphics; import android.util.MathUtils; import com.android.internal.util.XmlUtils; import java.util.HashMap; import java.util.Locale; Loading Loading @@ -200,7 +201,9 @@ public class Color { * #RRGGBB * #AARRGGBB * 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta', * 'yellow', 'lightgray', 'darkgray' * 'yellow', 'lightgray', 'darkgray', 'grey', 'lightgrey', 'darkgrey', * 'aqua', 'fuschia', 'lime', 'maroon', 'navy', 'olive', 'purple', * 'silver', 'teal' */ public static int parseColor(String colorString) { if (colorString.charAt(0) == '#') { Loading Loading @@ -366,6 +369,28 @@ public class Color { private static native void nativeRGBToHSV(int red, int greed, int blue, float hsv[]); private static native int nativeHSVToColor(int alpha, float hsv[]); /** * Converts an HTML color (named or numeric) to an integer RGB value. * * @param color Non-null color string. * * @return A color value, or {@code -1} if the color string could not be interpreted. * * @hide */ public static int getHtmlColor(String color) { Integer i = sColorNameMap.get(color.toLowerCase()); if (i != null) { return i; } else { try { return XmlUtils.convertValueToInt(color, -1); } catch (NumberFormatException nfe) { return -1; } } } private static final HashMap<String, Integer> sColorNameMap; static { Loading @@ -381,6 +406,18 @@ public class Color { sColorNameMap.put("yellow", YELLOW); sColorNameMap.put("cyan", CYAN); sColorNameMap.put("magenta", MAGENTA); sColorNameMap.put("aqua", 0x00FFFF); sColorNameMap.put("fuchsia", 0xFF00FF); sColorNameMap.put("darkgrey", DKGRAY); sColorNameMap.put("grey", GRAY); sColorNameMap.put("lightgrey", LTGRAY); sColorNameMap.put("lime", 0x00FF00); sColorNameMap.put("maroon", 0x800000); sColorNameMap.put("navy", 0x000080); sColorNameMap.put("olive", 0x808000); sColorNameMap.put("purple", 0x800080); sColorNameMap.put("silver", 0xC0C0C0); sColorNameMap.put("teal", 0x008080); } }