Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dccf9337 authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Add support for face attribute to HTML string resources Bug #7480719"

parents 498486e0 a8f6d5f0
Loading
Loading
Loading
Loading
+73 −14
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.content.res;

import android.graphics.Color;
import android.text.*;
import android.text.style.*;
import android.util.Log;
@@ -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.
@@ -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;
@@ -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();
@@ -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;
@@ -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);
                    }
@@ -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
@@ -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);
}
+7 −51
Original line number Diff line number Diff line
@@ -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;
@@ -181,7 +182,7 @@ public class Html {
                }
            }
            if (needDiv) {
                out.append("<div " + elements + ">");
                out.append("<div ").append(elements).append(">");
            }

            withinDiv(out, text, i, next);
@@ -391,7 +392,7 @@ public class Html {
            } else if (c == '&') {
                out.append("&amp;");
            } 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("&nbsp;");
@@ -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,
@@ -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,
@@ -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;
            }
        }
      }

}
+4 −7
Original line number Diff line number Diff line
@@ -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;
+42 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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) == '#') {
@@ -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 {
@@ -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);

    }
}