diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index e9d12f511a9a4..409994d7cd848 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -54,6 +54,9 @@ import android.text.style.UnderlineSpan;
import java.io.IOException;
import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -691,6 +694,22 @@ class HtmlToSpannedConverter implements ContentHandler {
private static Pattern sBackgroundColorPattern;
private static Pattern sTextDecorationPattern;
+ /**
+ * Name-value mapping of HTML/CSS colors which have different values in {@link Color}.
+ */
+ private static final Map sColorMap;
+
+ static {
+ sColorMap = new HashMap<>();
+ sColorMap.put("darkgray", 0xFFA9A9A9);
+ sColorMap.put("gray", 0xFF808080);
+ sColorMap.put("lightgray", 0xFFD3D3D3);
+ sColorMap.put("darkgrey", 0xFFA9A9A9);
+ sColorMap.put("grey", 0xFF808080);
+ sColorMap.put("lightgrey", 0xFFD3D3D3);
+ sColorMap.put("green", 0xFF008000);
+ }
+
private static Pattern getTextAlignPattern() {
if (sTextAlignPattern == null) {
sTextAlignPattern = Pattern.compile("(?:\\s+|\\A)text-align\\s*:\\s*(\\S*)\\b");
@@ -948,7 +967,7 @@ class HtmlToSpannedConverter implements ContentHandler {
final int len = text.length();
if (margin > 0) {
appendNewlines(text, margin);
- text.setSpan(new Newline(margin), len, len, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ start(text, new Newline(margin));
}
String style = attributes.getValue("", "style");
@@ -957,14 +976,11 @@ class HtmlToSpannedConverter implements ContentHandler {
if (m.find()) {
String alignment = m.group(1);
if (alignment.equalsIgnoreCase("start")) {
- text.setSpan(new Alignment(Layout.Alignment.ALIGN_NORMAL),
- len, len, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ start(text, new Alignment(Layout.Alignment.ALIGN_NORMAL));
} else if (alignment.equalsIgnoreCase("center")) {
- text.setSpan(new Alignment(Layout.Alignment.ALIGN_CENTER),
- len, len, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ start(text, new Alignment(Layout.Alignment.ALIGN_CENTER));
} else if (alignment.equalsIgnoreCase("end")) {
- text.setSpan(new Alignment(Layout.Alignment.ALIGN_OPPOSITE),
- len, len, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ start(text, new Alignment(Layout.Alignment.ALIGN_OPPOSITE));
}
}
}
@@ -1053,7 +1069,7 @@ class HtmlToSpannedConverter implements ContentHandler {
private static void start(Editable text, Object mark) {
int len = text.length();
- text.setSpan(mark, len, len, Spannable.SPAN_MARK_MARK);
+ text.setSpan(mark, len, len, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
private static void end(Editable text, Class kind, Object repl) {
@@ -1064,25 +1080,22 @@ class HtmlToSpannedConverter implements ContentHandler {
}
}
- private static void startCssStyle(Editable text, Attributes attributes) {
+ private void startCssStyle(Editable text, Attributes attributes) {
String style = attributes.getValue("", "style");
if (style != null) {
- final int len = text.length();
Matcher m = getForegroundColorPattern().matcher(style);
if (m.find()) {
- int c = Color.getHtmlColor(m.group(1));
+ int c = getHtmlColor(m.group(1));
if (c != -1) {
- text.setSpan(new Foreground(c | 0xFF000000), len, len,
- Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+ start(text, new Foreground(c | 0xFF000000));
}
}
m = getBackgroundColorPattern().matcher(style);
if (m.find()) {
- int c = Color.getHtmlColor(m.group(1));
+ int c = getHtmlColor(m.group(1));
if (c != -1) {
- text.setSpan(new Background(c | 0xFF000000), len, len,
- Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+ start(text, new Background(c | 0xFF000000));
}
}
@@ -1090,7 +1103,7 @@ class HtmlToSpannedConverter implements ContentHandler {
if (m.find()) {
String textDecoration = m.group(1);
if (textDecoration.equalsIgnoreCase("line-through")) {
- text.setSpan(new Strikethrough(), len, len, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+ start(text, new Strikethrough());
}
}
}
@@ -1134,58 +1147,41 @@ class HtmlToSpannedConverter implements ContentHandler {
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
- private static void startFont(Editable text, Attributes attributes) {
+ private void startFont(Editable text, Attributes attributes) {
String color = attributes.getValue("", "color");
String face = attributes.getValue("", "face");
- int len = text.length();
- text.setSpan(new Font(color, face), len, len, Spannable.SPAN_MARK_MARK);
+ if (!TextUtils.isEmpty(color)) {
+ int c = getHtmlColor(color);
+ if (c != -1) {
+ start(text, new Foreground(c | 0xFF000000));
+ }
+ }
+
+ if (!TextUtils.isEmpty(face)) {
+ start(text, new Font(face));
+ }
}
private static void endFont(Editable text) {
- int len = text.length();
- Font f = getLast(text, Font.class);
- int where = text.getSpanStart(f);
- text.removeSpan(f);
+ Font font = getLast(text, Font.class);
+ if (font != null) {
+ setSpanFromMark(text, font, new TypefaceSpan(font.mFace));
+ }
- if (where != len) {
- 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, null);
- text.setSpan(new TextAppearanceSpan(null, 0, 0, colors, null),
- where, len,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- } else {
- int c = Color.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,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
+ Foreground foreground = getLast(text, Foreground.class);
+ if (foreground != null) {
+ setSpanFromMark(text, foreground,
+ new ForegroundColorSpan(foreground.mForegroundColor));
}
}
private static void startA(Editable text, Attributes attributes) {
String href = attributes.getValue("", "href");
-
- int len = text.length();
- text.setSpan(new Href(href), len, len, Spannable.SPAN_MARK_MARK);
+ start(text, new Href(href));
}
private static void endA(Editable text) {
- int len = text.length();
Href h = getLast(text, Href.class);
if (h != null) {
if (h.mHref != null) {
@@ -1194,6 +1190,17 @@ class HtmlToSpannedConverter implements ContentHandler {
}
}
+ private int getHtmlColor(String color) {
+ if ((mFlags & Html.FROM_HTML_OPTION_USE_CSS_COLORS)
+ == Html.FROM_HTML_OPTION_USE_CSS_COLORS) {
+ Integer i = sColorMap.get(color.toLowerCase(Locale.US));
+ if (i != null) {
+ return i;
+ }
+ }
+ return Color.getHtmlColor(color);
+ }
+
public void setDocumentLocator(Locator locator) {
}
@@ -1278,11 +1285,9 @@ class HtmlToSpannedConverter implements ContentHandler {
private static class Bullet { }
private static class Font {
- public String mColor;
public String mFace;
- public Font(String color, String face) {
- mColor = color;
+ public Font(String face) {
mFace = face;
}
}