Loading core/java/android/text/Html.java +62 −45 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Typeface; import android.graphics.drawable.Drawable; Loading @@ -40,6 +41,7 @@ import android.text.style.StrikethroughSpan; import android.text.style.StyleSpan; import android.text.style.SubscriptSpan; import android.text.style.SuperscriptSpan; import android.text.style.TextAppearanceSpan; import android.text.style.TypefaceSpan; import android.text.style.URLSpan; import android.text.style.UnderlineSpan; Loading @@ -49,6 +51,7 @@ import com.android.internal.util.XmlUtils; import java.io.IOException; import java.io.StringReader; import java.nio.CharBuffer; import java.util.HashMap; /** * This class processes HTML strings into displayable styled text. Loading Loading @@ -633,55 +636,26 @@ class HtmlToSpannedConverter implements ContentHandler { if (where != len) { Font f = (Font) obj; if (f.mColor != null) { int c = -1; if (f.mColor.equalsIgnoreCase("aqua")) { c = 0x00FFFF; } else if (f.mColor.equalsIgnoreCase("black")) { c = 0x000000; } else if (f.mColor.equalsIgnoreCase("blue")) { c = 0x0000FF; } else if (f.mColor.equalsIgnoreCase("fuchsia")) { c = 0xFF00FF; } else if (f.mColor.equalsIgnoreCase("green")) { c = 0x008000; } else if (f.mColor.equalsIgnoreCase("grey")) { c = 0x808080; } else if (f.mColor.equalsIgnoreCase("lime")) { c = 0x00FF00; } else if (f.mColor.equalsIgnoreCase("maroon")) { c = 0x800000; } else if (f.mColor.equalsIgnoreCase("navy")) { c = 0x000080; } else if (f.mColor.equalsIgnoreCase("olive")) { c = 0x808000; } else if (f.mColor.equalsIgnoreCase("purple")) { c = 0x800080; } else if (f.mColor.equalsIgnoreCase("red")) { c = 0xFF0000; } else if (f.mColor.equalsIgnoreCase("silver")) { c = 0xC0C0C0; } else if (f.mColor.equalsIgnoreCase("teal")) { c = 0x008080; } else if (f.mColor.equalsIgnoreCase("white")) { c = 0xFFFFFF; } else if (f.mColor.equalsIgnoreCase("yellow")) { c = 0xFFFF00; } else { try { c = XmlUtils.convertValueToInt(f.mColor, -1); } catch (NumberFormatException nfe) { // Can't understand the color, so just drop it. } if (!TextUtils.isEmpty(f.mColor)) { if (f.mColor.startsWith("@")) { Resources res = Resources.getSystem(); String name = f.mColor.substring(1); int colorRes = res.getIdentifier(name, "color", "android"); if (colorRes != 0) { ColorStateList colors = res.getColorStateList(colorRes); text.setSpan(new TextAppearanceSpan(null, 0, 0, colors, null), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else { int c = getHtmlColor(f.mColor); if (c != -1) { text.setSpan(new ForegroundColorSpan(c | 0xFF000000), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } if (f.mFace != null) { text.setSpan(new TypefaceSpan(f.mFace), where, len, Loading Loading @@ -843,4 +817,47 @@ 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; } } } } tests/AndroidTests/src/com/android/unit_tests/HtmlTest.java +58 −4 Original line number Diff line number Diff line Loading @@ -16,11 +16,25 @@ package com.android.unit_tests; import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Typeface; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.text.*; import android.text.style.*; import android.text.Html; import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; import android.text.style.ForegroundColorSpan; import android.text.style.QuoteSpan; import android.text.style.StrikethroughSpan; import android.text.style.StyleSpan; import android.text.style.SubscriptSpan; import android.text.style.SuperscriptSpan; import android.text.style.TextAppearanceSpan; import android.text.style.TypefaceSpan; import android.text.style.URLSpan; import android.text.style.UnderlineSpan; import junit.framework.TestCase; Loading @@ -35,14 +49,54 @@ public class HtmlTest extends TestCase { s = Html.fromHtml("<font color=\"#00FF00\">something</font>"); colors = s.getSpans(0, s.length(), ForegroundColorSpan.class); assertEquals(colors[0].getForegroundColor(), 0xFF00FF00); assertEquals(1, colors.length); assertEquals(0xFF00FF00, colors[0].getForegroundColor()); s = Html.fromHtml("<font color=\"navy\">something</font>"); colors = s.getSpans(0, s.length(), ForegroundColorSpan.class); assertEquals(colors[0].getForegroundColor(), 0xFF000080); assertEquals(1, colors.length); assertEquals(0xFF000080, colors[0].getForegroundColor()); s = Html.fromHtml("<font color=\"gibberish\">something</font>"); colors = s.getSpans(0, s.length(), ForegroundColorSpan.class); assertEquals(0, colors.length); } @MediumTest public void testResourceColor() throws Exception { ColorStateList c = Resources.getSystem().getColorStateList(android.R.color.primary_text_dark); Spanned s; TextAppearanceSpan[] colors; s = Html.fromHtml("<font color=\"@android:color/primary_text_dark\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(1, colors.length); assertEquals(c.toString(), colors[0].getTextColor().toString()); s = Html.fromHtml("<font color=\"@android:primary_text_dark\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(1, colors.length); assertEquals(c.toString(), colors[0].getTextColor().toString()); s = Html.fromHtml("<font color=\"@color/primary_text_dark\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(1, colors.length); assertEquals(c.toString(), colors[0].getTextColor().toString()); s = Html.fromHtml("<font color=\"@primary_text_dark\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(1, colors.length); assertEquals(c.toString(), colors[0].getTextColor().toString()); s = Html.fromHtml("<font color=\"@" + android.R.color.primary_text_dark + "\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(1, colors.length); assertEquals(c.toString(), colors[0].getTextColor().toString()); s = Html.fromHtml("<font color=\"gibberish\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(colors.length, 0); } Loading Loading
core/java/android/text/Html.java +62 −45 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Typeface; import android.graphics.drawable.Drawable; Loading @@ -40,6 +41,7 @@ import android.text.style.StrikethroughSpan; import android.text.style.StyleSpan; import android.text.style.SubscriptSpan; import android.text.style.SuperscriptSpan; import android.text.style.TextAppearanceSpan; import android.text.style.TypefaceSpan; import android.text.style.URLSpan; import android.text.style.UnderlineSpan; Loading @@ -49,6 +51,7 @@ import com.android.internal.util.XmlUtils; import java.io.IOException; import java.io.StringReader; import java.nio.CharBuffer; import java.util.HashMap; /** * This class processes HTML strings into displayable styled text. Loading Loading @@ -633,55 +636,26 @@ class HtmlToSpannedConverter implements ContentHandler { if (where != len) { Font f = (Font) obj; if (f.mColor != null) { int c = -1; if (f.mColor.equalsIgnoreCase("aqua")) { c = 0x00FFFF; } else if (f.mColor.equalsIgnoreCase("black")) { c = 0x000000; } else if (f.mColor.equalsIgnoreCase("blue")) { c = 0x0000FF; } else if (f.mColor.equalsIgnoreCase("fuchsia")) { c = 0xFF00FF; } else if (f.mColor.equalsIgnoreCase("green")) { c = 0x008000; } else if (f.mColor.equalsIgnoreCase("grey")) { c = 0x808080; } else if (f.mColor.equalsIgnoreCase("lime")) { c = 0x00FF00; } else if (f.mColor.equalsIgnoreCase("maroon")) { c = 0x800000; } else if (f.mColor.equalsIgnoreCase("navy")) { c = 0x000080; } else if (f.mColor.equalsIgnoreCase("olive")) { c = 0x808000; } else if (f.mColor.equalsIgnoreCase("purple")) { c = 0x800080; } else if (f.mColor.equalsIgnoreCase("red")) { c = 0xFF0000; } else if (f.mColor.equalsIgnoreCase("silver")) { c = 0xC0C0C0; } else if (f.mColor.equalsIgnoreCase("teal")) { c = 0x008080; } else if (f.mColor.equalsIgnoreCase("white")) { c = 0xFFFFFF; } else if (f.mColor.equalsIgnoreCase("yellow")) { c = 0xFFFF00; } else { try { c = XmlUtils.convertValueToInt(f.mColor, -1); } catch (NumberFormatException nfe) { // Can't understand the color, so just drop it. } if (!TextUtils.isEmpty(f.mColor)) { if (f.mColor.startsWith("@")) { Resources res = Resources.getSystem(); String name = f.mColor.substring(1); int colorRes = res.getIdentifier(name, "color", "android"); if (colorRes != 0) { ColorStateList colors = res.getColorStateList(colorRes); text.setSpan(new TextAppearanceSpan(null, 0, 0, colors, null), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else { int c = getHtmlColor(f.mColor); if (c != -1) { text.setSpan(new ForegroundColorSpan(c | 0xFF000000), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } if (f.mFace != null) { text.setSpan(new TypefaceSpan(f.mFace), where, len, Loading Loading @@ -843,4 +817,47 @@ 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; } } } }
tests/AndroidTests/src/com/android/unit_tests/HtmlTest.java +58 −4 Original line number Diff line number Diff line Loading @@ -16,11 +16,25 @@ package com.android.unit_tests; import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Typeface; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.text.*; import android.text.style.*; import android.text.Html; import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; import android.text.style.ForegroundColorSpan; import android.text.style.QuoteSpan; import android.text.style.StrikethroughSpan; import android.text.style.StyleSpan; import android.text.style.SubscriptSpan; import android.text.style.SuperscriptSpan; import android.text.style.TextAppearanceSpan; import android.text.style.TypefaceSpan; import android.text.style.URLSpan; import android.text.style.UnderlineSpan; import junit.framework.TestCase; Loading @@ -35,14 +49,54 @@ public class HtmlTest extends TestCase { s = Html.fromHtml("<font color=\"#00FF00\">something</font>"); colors = s.getSpans(0, s.length(), ForegroundColorSpan.class); assertEquals(colors[0].getForegroundColor(), 0xFF00FF00); assertEquals(1, colors.length); assertEquals(0xFF00FF00, colors[0].getForegroundColor()); s = Html.fromHtml("<font color=\"navy\">something</font>"); colors = s.getSpans(0, s.length(), ForegroundColorSpan.class); assertEquals(colors[0].getForegroundColor(), 0xFF000080); assertEquals(1, colors.length); assertEquals(0xFF000080, colors[0].getForegroundColor()); s = Html.fromHtml("<font color=\"gibberish\">something</font>"); colors = s.getSpans(0, s.length(), ForegroundColorSpan.class); assertEquals(0, colors.length); } @MediumTest public void testResourceColor() throws Exception { ColorStateList c = Resources.getSystem().getColorStateList(android.R.color.primary_text_dark); Spanned s; TextAppearanceSpan[] colors; s = Html.fromHtml("<font color=\"@android:color/primary_text_dark\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(1, colors.length); assertEquals(c.toString(), colors[0].getTextColor().toString()); s = Html.fromHtml("<font color=\"@android:primary_text_dark\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(1, colors.length); assertEquals(c.toString(), colors[0].getTextColor().toString()); s = Html.fromHtml("<font color=\"@color/primary_text_dark\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(1, colors.length); assertEquals(c.toString(), colors[0].getTextColor().toString()); s = Html.fromHtml("<font color=\"@primary_text_dark\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(1, colors.length); assertEquals(c.toString(), colors[0].getTextColor().toString()); s = Html.fromHtml("<font color=\"@" + android.R.color.primary_text_dark + "\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(1, colors.length); assertEquals(c.toString(), colors[0].getTextColor().toString()); s = Html.fromHtml("<font color=\"gibberish\">something</font>"); colors = s.getSpans(0, s.length(), TextAppearanceSpan.class); assertEquals(colors.length, 0); } Loading