StringBlockpublic final class StringBlock extends Object Conveniences for retrieving data out of a compiled string resource.
{@hide} |
Fields Summary |
---|
private static final String | TAG | private static final boolean | localLOGV | private final long | mNative | private final boolean | mUseSparse | private final boolean | mOwnsNative | private CharSequence[] | mStrings | private android.util.SparseArray | mSparseStrings | StyleIDs | mStyleIDs |
Constructors Summary |
---|
public StringBlock(byte[] data, boolean useSparse)
mNative = nativeCreate(data, 0, data.length);
mUseSparse = useSparse;
mOwnsNative = true;
if (localLOGV) Log.v(TAG, "Created string block " + this
+ ": " + nativeGetSize(mNative));
| public StringBlock(byte[] data, int offset, int size, boolean useSparse)
mNative = nativeCreate(data, offset, size);
mUseSparse = useSparse;
mOwnsNative = true;
if (localLOGV) Log.v(TAG, "Created string block " + this
+ ": " + nativeGetSize(mNative));
| StringBlock(long obj, boolean useSparse)Create from an existing string block native object. This is
-extremely- dangerous -- only use it if you absolutely know what you
are doing! The given native object must exist for the entire lifetime
of this newly creating StringBlock.
mNative = obj;
mUseSparse = useSparse;
mOwnsNative = false;
if (localLOGV) Log.v(TAG, "Created string block " + this
+ ": " + nativeGetSize(mNative));
|
Methods Summary |
---|
private static void | addParagraphSpan(Spannable buffer, java.lang.Object what, int start, int end)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
instead of just whatever range they put it on.
int len = buffer.length();
if (start != 0 && start != len && buffer.charAt(start - 1) != '\n") {
for (start--; start > 0; start--) {
if (buffer.charAt(start - 1) == '\n") {
break;
}
}
}
if (end != 0 && end != len && buffer.charAt(end - 1) != '\n") {
for (end++; end < len; end++) {
if (buffer.charAt(end - 1) == '\n") {
break;
}
}
}
buffer.setSpan(what, start, end, Spannable.SPAN_PARAGRAPH);
| private java.lang.CharSequence | applyStyles(java.lang.String str, int[] style, android.content.res.StringBlock$StyleIDs ids)
if (style.length == 0)
return str;
SpannableString buffer = new SpannableString(str);
int i=0;
while (i < style.length) {
int type = style[i];
if (localLOGV) Log.v(TAG, "Applying style span id=" + type
+ ", start=" + style[i+1] + ", end=" + style[i+2]);
if (type == ids.boldId) {
buffer.setSpan(new StyleSpan(Typeface.BOLD),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.italicId) {
buffer.setSpan(new StyleSpan(Typeface.ITALIC),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.underlineId) {
buffer.setSpan(new UnderlineSpan(),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.ttId) {
buffer.setSpan(new TypefaceSpan("monospace"),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.bigId) {
buffer.setSpan(new RelativeSizeSpan(1.25f),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.smallId) {
buffer.setSpan(new RelativeSizeSpan(0.8f),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.subId) {
buffer.setSpan(new SubscriptSpan(),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.supId) {
buffer.setSpan(new SuperscriptSpan(),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.strikeId) {
buffer.setSpan(new StrikethroughSpan(),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.listItemId) {
addParagraphSpan(buffer, new BulletSpan(10),
style[i+1], style[i+2]+1);
} else if (type == ids.marqueeId) {
buffer.setSpan(TextUtils.TruncateAt.MARQUEE,
style[i+1], style[i+2]+1,
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
} else {
String tag = nativeGetString(mNative, type);
if (tag.startsWith("font;")) {
String sub;
sub = subtag(tag, ";height=");
if (sub != null) {
int size = Integer.parseInt(sub);
addParagraphSpan(buffer, new Height(size),
style[i+1], style[i+2]+1);
}
sub = subtag(tag, ";size=");
if (sub != null) {
int size = Integer.parseInt(sub);
buffer.setSpan(new AbsoluteSizeSpan(size, true),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
sub = subtag(tag, ";fgcolor=");
if (sub != null) {
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) {
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);
}
} else if (tag.startsWith("a;")) {
String sub;
sub = subtag(tag, ";href=");
if (sub != null) {
buffer.setSpan(new URLSpan(sub),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} else if (tag.startsWith("annotation;")) {
int len = tag.length();
int next;
for (int t = tag.indexOf(';"); t < len; t = next) {
int eq = tag.indexOf('=", t);
if (eq < 0) {
break;
}
next = tag.indexOf(';", eq);
if (next < 0) {
next = len;
}
String key = tag.substring(t + 1, eq);
String value = tag.substring(eq + 1, next);
buffer.setSpan(new Annotation(key, value),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
i += 3;
}
return new SpannedString(buffer);
| protected void | finalize()
try {
super.finalize();
} finally {
if (mOwnsNative) {
nativeDestroy(mNative);
}
}
| public java.lang.CharSequence | get(int idx)
synchronized (this) {
if (mStrings != null) {
CharSequence res = mStrings[idx];
if (res != null) {
return res;
}
} else if (mSparseStrings != null) {
CharSequence res = mSparseStrings.get(idx);
if (res != null) {
return res;
}
} else {
final int num = nativeGetSize(mNative);
if (mUseSparse && num > 250) {
mSparseStrings = new SparseArray<CharSequence>();
} else {
mStrings = new CharSequence[num];
}
}
String str = nativeGetString(mNative, idx);
CharSequence res = str;
int[] style = nativeGetStyle(mNative, idx);
if (localLOGV) Log.v(TAG, "Got string: " + str);
if (localLOGV) Log.v(TAG, "Got styles: " + Arrays.toString(style));
if (style != null) {
if (mStyleIDs == null) {
mStyleIDs = new StyleIDs();
}
// the style array is a flat array of <type, start, end> hence
// the magic constant 3.
for (int styleIndex = 0; styleIndex < style.length; styleIndex += 3) {
int styleId = style[styleIndex];
if (styleId == mStyleIDs.boldId || styleId == mStyleIDs.italicId
|| styleId == mStyleIDs.underlineId || styleId == mStyleIDs.ttId
|| styleId == mStyleIDs.bigId || styleId == mStyleIDs.smallId
|| styleId == mStyleIDs.subId || styleId == mStyleIDs.supId
|| styleId == mStyleIDs.strikeId || styleId == mStyleIDs.listItemId
|| styleId == mStyleIDs.marqueeId) {
// id already found skip to next style
continue;
}
String styleTag = nativeGetString(mNative, styleId);
if (styleTag.equals("b")) {
mStyleIDs.boldId = styleId;
} else if (styleTag.equals("i")) {
mStyleIDs.italicId = styleId;
} else if (styleTag.equals("u")) {
mStyleIDs.underlineId = styleId;
} else if (styleTag.equals("tt")) {
mStyleIDs.ttId = styleId;
} else if (styleTag.equals("big")) {
mStyleIDs.bigId = styleId;
} else if (styleTag.equals("small")) {
mStyleIDs.smallId = styleId;
} else if (styleTag.equals("sup")) {
mStyleIDs.supId = styleId;
} else if (styleTag.equals("sub")) {
mStyleIDs.subId = styleId;
} else if (styleTag.equals("strike")) {
mStyleIDs.strikeId = styleId;
} else if (styleTag.equals("li")) {
mStyleIDs.listItemId = styleId;
} else if (styleTag.equals("marquee")) {
mStyleIDs.marqueeId = styleId;
}
}
res = applyStyles(str, style, mStyleIDs);
}
if (mStrings != null) mStrings[idx] = res;
else mSparseStrings.put(idx, res);
return res;
}
| private static CharacterStyle | getColor(java.lang.String color, boolean foreground)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.
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);
}
| private static native long | nativeCreate(byte[] data, int offset, int size)
| private static native void | nativeDestroy(long obj)
| private static native int | nativeGetSize(long obj)
| private static native java.lang.String | nativeGetString(long obj, int idx)
| private static native int[] | nativeGetStyle(long obj, int idx)
| private static java.lang.String | subtag(java.lang.String full, java.lang.String attribute)
int start = full.indexOf(attribute);
if (start < 0) {
return null;
}
start += attribute.length();
int end = full.indexOf(';", start);
if (end < 0) {
return full.substring(start);
} else {
return full.substring(start, end);
}
|
|