use of android.text.Spanned in project android_frameworks_base by ResurrectionRemix.
the class Notification method removeTextSizeSpans.
private static CharSequence removeTextSizeSpans(CharSequence charSequence) {
if (charSequence instanceof Spanned) {
Spanned ss = (Spanned) charSequence;
Object[] spans = ss.getSpans(0, ss.length(), Object.class);
SpannableStringBuilder builder = new SpannableStringBuilder(ss.toString());
for (Object span : spans) {
Object resultSpan = span;
if (resultSpan instanceof CharacterStyle) {
resultSpan = ((CharacterStyle) span).getUnderlying();
}
if (resultSpan instanceof TextAppearanceSpan) {
TextAppearanceSpan originalSpan = (TextAppearanceSpan) resultSpan;
resultSpan = new TextAppearanceSpan(originalSpan.getFamily(), originalSpan.getTextStyle(), -1, originalSpan.getTextColor(), originalSpan.getLinkTextColor());
} else if (resultSpan instanceof RelativeSizeSpan || resultSpan instanceof AbsoluteSizeSpan) {
continue;
} else {
resultSpan = span;
}
builder.setSpan(resultSpan, ss.getSpanStart(span), ss.getSpanEnd(span), ss.getSpanFlags(span));
}
return builder;
}
return charSequence;
}
use of android.text.Spanned in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class SpannableStringUtils method concatWithNonParagraphSuggestionSpansOnly.
/**
* Returns a CharSequence concatenating the specified CharSequences, retaining their
* SuggestionSpans that don't have the PARAGRAPH flag, but not other spans.
*
* This code is almost entirely taken from {@link TextUtils#concat(CharSequence...)}, except
* it calls copyNonParagraphSuggestionSpansFrom instead of {@link TextUtils#copySpansFrom}.
*/
public static CharSequence concatWithNonParagraphSuggestionSpansOnly(CharSequence... text) {
if (text.length == 0) {
return "";
}
if (text.length == 1) {
return text[0];
}
boolean spanned = false;
for (int i = 0; i < text.length; i++) {
if (text[i] instanceof Spanned) {
spanned = true;
break;
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < text.length; i++) {
sb.append(text[i]);
}
if (!spanned) {
return sb.toString();
}
SpannableString ss = new SpannableString(sb);
int off = 0;
for (int i = 0; i < text.length; i++) {
int len = text[i].length();
if (text[i] instanceof Spanned) {
copyNonParagraphSuggestionSpansFrom((Spanned) text[i], 0, len, ss, off);
}
off += len;
}
return new SpannedString(ss);
}
use of android.text.Spanned in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class TextRange method getSuggestionSpansAtWord.
/**
* Gets the suggestion spans that are put squarely on the word, with the exact start
* and end of the span matching the boundaries of the word.
* @return the list of spans.
*/
public SuggestionSpan[] getSuggestionSpansAtWord() {
if (!(mTextAtCursor instanceof Spanned && mWord instanceof Spanned)) {
return new SuggestionSpan[0];
}
final Spanned text = (Spanned) mTextAtCursor;
// Note: it's fine to pass indices negative or greater than the length of the string
// to the #getSpans() method. The reason we need to get from -1 to +1 is that, the
// spans were cut at the cursor position, and #getSpans(start, end) does not return
// spans that end at `start' or begin at `end'. Consider the following case:
// this| is (The | symbolizes the cursor position
// ---- ---
// In this case, the cursor is in position 4, so the 0~7 span has been split into
// a 0~4 part and a 4~7 part.
// If we called #getSpans(0, 4) in this case, we would only get the part from 0 to 4
// of the span, and not the part from 4 to 7, so we would not realize the span actually
// extends from 0 to 7. But if we call #getSpans(-1, 5) we'll get both the 0~4 and
// the 4~7 spans and we can merge them accordingly.
// Any span starting more than 1 char away from the word boundaries in any direction
// does not touch the word, so we don't need to consider it. That's why requesting
// -1 ~ +1 is enough.
// Of course this is only relevant if the cursor is at one end of the word. If it's
// in the middle, the -1 and +1 are not necessary, but they are harmless.
final SuggestionSpan[] spans = text.getSpans(mWordAtCursorStartIndex - 1, mWordAtCursorEndIndex + 1, SuggestionSpan.class);
int readIndex = 0;
int writeIndex = 0;
for (; readIndex < spans.length; ++readIndex) {
final SuggestionSpan span = spans[readIndex];
// down.
if (null == span)
continue;
// Tentative span start and end. This may be modified later if we realize the
// same span is also applied to other parts of the string.
int spanStart = text.getSpanStart(span);
int spanEnd = text.getSpanEnd(span);
for (int i = readIndex + 1; i < spans.length; ++i) {
if (span.equals(spans[i])) {
// We found the same span somewhere else. Read the new extent of this
// span, and adjust our values accordingly.
spanStart = Math.min(spanStart, text.getSpanStart(spans[i]));
spanEnd = Math.max(spanEnd, text.getSpanEnd(spans[i]));
// ...and mark the span as processed.
spans[i] = null;
}
}
if (spanStart == mWordAtCursorStartIndex && spanEnd == mWordAtCursorEndIndex) {
// If the span does not start and stop here, ignore it. It probably extends
// past the start or end of the word, as happens in missing space correction
// or EasyEditSpans put by voice input.
spans[writeIndex++] = spans[readIndex];
}
}
return writeIndex == readIndex ? spans : Arrays.copyOfRange(spans, 0, writeIndex);
}
use of android.text.Spanned in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class TextInfoCompatUtilsTests method testGetCharSequence.
public void testGetCharSequence() {
final SpannableString text = new SpannableString(TEST_TEXT);
text.setSpan(TEST_STYLE_SPAN, TEST_STYLE_SPAN_START, TEST_STYLE_SPAN_END, TEST_STYLE_SPAN_FLAGS);
text.setSpan(TEST_URL_SPAN_URL, TEST_URL_SPAN_START, TEST_URL_SPAN_END, TEST_URL_SPAN_FLAGS);
final TextInfo textInfo = TextInfoCompatUtils.newInstance(text, TEST_CHAR_SEQUENCE_START, TEST_CHAR_SEQUENCE_END, TEST_COOKIE, TEST_SEQUENCE_NUMBER);
final Spanned expectedSpanned = (Spanned) text.subSequence(TEST_CHAR_SEQUENCE_START, TEST_CHAR_SEQUENCE_END);
final CharSequence actualCharSequence = TextInfoCompatUtils.getCharSequenceOrString(textInfo);
// This should be valid even if TextInfo#getCharSequence is not supported.
assertTrue(TextUtils.equals(expectedSpanned, actualCharSequence));
if (TextInfoCompatUtils.isCharSequenceSupported()) {
// This is valid only if TextInfo#getCharSequence is supported.
assertTrue("should be Spanned", actualCharSequence instanceof Spanned);
assertTrue(Arrays.equals(marshall(expectedSpanned), marshall(actualCharSequence)));
}
}
use of android.text.Spanned in project android_packages_inputmethods_LatinIME by CyanogenMod.
the class SpannableStringUtilsTests method testConcatWithSuggestionSpansOnly.
public void testConcatWithSuggestionSpansOnly() {
SpannableStringBuilder s = new SpannableStringBuilder("test string\ntest string\n" + "test string\ntest string\ntest string\ntest string\ntest string\ntest string\n" + "test string\ntest string\n");
final int N = 10;
for (int i = 0; i < N; ++i) {
// Put a PARAGRAPH-flagged span that should not be found in the result.
s.setSpan(new SuggestionSpan(getContext(), new String[] { "" + i }, Spanned.SPAN_PARAGRAPH), i * 12, i * 12 + 12, Spanned.SPAN_PARAGRAPH);
// Put a normal suggestion span that should be found in the result.
s.setSpan(new SuggestionSpan(getContext(), new String[] { "" + i }, 0), i, i * 2, 0);
// Put a URL span than should not be found in the result.
s.setSpan(new URLSpan("http://a"), i, i * 2, 0);
}
final CharSequence a = s.subSequence(0, 15);
final CharSequence b = s.subSequence(15, s.length());
final Spanned result = (Spanned) SpannableStringUtils.concatWithNonParagraphSuggestionSpansOnly(a, b);
Object[] spans = result.getSpans(0, result.length(), SuggestionSpan.class);
for (int i = 0; i < spans.length; i++) {
final int flags = result.getSpanFlags(spans[i]);
assertEquals("Should not find a span with PARAGRAPH flag", flags & Spanned.SPAN_PARAGRAPH, 0);
assertTrue("Should be a SuggestionSpan", spans[i] instanceof SuggestionSpan);
}
}
Aggregations