StyleSpan[] before = getEditableText().getSpans(start - 1, start, StyleSpan.class); StyleSpan[] after = getEditableText().getSpans(start, start + 1, StyleSpan.class); return before.length > 0 && after.length > 0 && before[0].getStyle() == style && after[0].getStyle() == style; StyleSpan[] spans = getEditableText().getSpans(i, i + 1, StyleSpan.class); for (StyleSpan span : spans) { if (span.getStyle() == style) { builder.append(getEditableText().subSequence(i, i + 1).toString()); break;
private void assertStyle(Spannable spannable, int fontStyle) { StyleSpan[] styleSpans = spannable.getSpans(0, spannable.length(), StyleSpan.class); assertThat(styleSpans[styleSpans.length - 1].getStyle()).isEqualTo(fontStyle); }
@Test public void testParseMultipleTagsOfSameKind() { Spanned text = parseCueText("blah <b>blah</b> blah <b>foo</b>"); assertThat(text.toString()).isEqualTo("blah blah blah foo"); StyleSpan[] spans = getSpans(text, StyleSpan.class); assertThat(spans).hasLength(2); assertThat(text.getSpanStart(spans[0])).isEqualTo(5); assertThat(text.getSpanEnd(spans[0])).isEqualTo(9); assertThat(text.getSpanStart(spans[1])).isEqualTo(15); assertThat(text.getSpanEnd(spans[1])).isEqualTo(18); assertThat(spans[0].getStyle()).isEqualTo(BOLD); assertThat(spans[1].getStyle()).isEqualTo(BOLD); }
@Test public void testParseCloseNonExistingTag() throws Exception { Spanned text = parseCueText("blah<b>blah</i>blah</b>blah"); assertThat(text.toString()).isEqualTo("blahblahblahblah"); StyleSpan[] spans = getSpans(text, StyleSpan.class); assertThat(spans).hasLength(1); assertThat(spans[0].getStyle()).isEqualTo(BOLD); assertThat(text.getSpanStart(spans[0])).isEqualTo(4); assertThat(text.getSpanEnd(spans[0])).isEqualTo(8); // should be 12 when valid }
@Test public void testParseWellFormedUnclosedEndAtParent() throws Exception { Spanned text = parseCueText("An unclosed u tag with <i><u>underline and italic</i> inside"); assertThat(text.toString()).isEqualTo("An unclosed u tag with underline and italic inside"); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); assertThat(underlineSpans).hasLength(1); assertThat(styleSpans).hasLength(1); assertThat(text.getSpanStart(underlineSpans[0])).isEqualTo(23); assertThat(text.getSpanStart(styleSpans[0])).isEqualTo(23); assertThat(text.getSpanEnd(underlineSpans[0])).isEqualTo(43); assertThat(text.getSpanEnd(styleSpans[0])).isEqualTo(43); assertThat(styleSpans[0].getStyle()).isEqualTo(ITALIC); }
@Test public void testParseStrictValidClassesAndTrailingTokens() throws Exception { Spanned text = parseCueText("<v.first.loud Esme>" + "This <u.style1.style2 some stuff>is</u> text with <b.foo><i.bar>html</i></b> tags"); assertThat(text.toString()).isEqualTo("This is text with html tags"); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); assertThat(underlineSpans).hasLength(1); assertThat(styleSpans).hasLength(2); assertThat(styleSpans[0].getStyle()).isEqualTo(ITALIC); assertThat(styleSpans[1].getStyle()).isEqualTo(BOLD); assertThat(text.getSpanStart(underlineSpans[0])).isEqualTo(5); assertThat(text.getSpanEnd(underlineSpans[0])).isEqualTo(7); assertThat(text.getSpanStart(styleSpans[0])).isEqualTo(18); assertThat(text.getSpanStart(styleSpans[1])).isEqualTo(18); assertThat(text.getSpanEnd(styleSpans[0])).isEqualTo(22); assertThat(text.getSpanEnd(styleSpans[1])).isEqualTo(22); }
@Test public void testParseWellFormedUnclosedEndAtCueEnd() throws Exception { Spanned text = parseCueText("An <u some trailing stuff>unclosed u tag with " + "<i>italic</i> inside"); assertThat(text.toString()).isEqualTo("An unclosed u tag with italic inside"); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); assertThat(underlineSpans).hasLength(1); assertThat(styleSpans).hasLength(1); assertThat(styleSpans[0].getStyle()).isEqualTo(ITALIC); assertThat(text.getSpanStart(underlineSpans[0])).isEqualTo(3); assertThat(text.getSpanStart(styleSpans[0])).isEqualTo(23); assertThat(text.getSpanEnd(styleSpans[0])).isEqualTo(29); assertThat(text.getSpanEnd(underlineSpans[0])).isEqualTo(36); }
@Test public void testDecodeWithOtherExtension() throws IOException, SubtitleDecoderException { Tx3gDecoder decoder = new Tx3gDecoder(Collections.emptyList()); byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_OTHER_EXTENSION); Subtitle subtitle = decoder.decode(bytes, bytes.length, false); SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text); assertThat(text.toString()).isEqualTo("CC Test"); assertThat(text.getSpans(0, text.length(), Object.class)).hasLength(2); StyleSpan styleSpan = findSpan(text, 0, 6, StyleSpan.class); assertThat(styleSpan.getStyle()).isEqualTo(Typeface.BOLD); ForegroundColorSpan colorSpan = findSpan(text, 0, 6, ForegroundColorSpan.class); assertThat(colorSpan.getForegroundColor()).isEqualTo(Color.GREEN); assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f); }
@Test public void testDecodeWithStyl() throws IOException, SubtitleDecoderException { Tx3gDecoder decoder = new Tx3gDecoder(Collections.emptyList()); byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_STYL); Subtitle subtitle = decoder.decode(bytes, bytes.length, false); SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text); assertThat(text.toString()).isEqualTo("CC Test"); assertThat(text.getSpans(0, text.length(), Object.class)).hasLength(3); StyleSpan styleSpan = findSpan(text, 0, 6, StyleSpan.class); assertThat(styleSpan.getStyle()).isEqualTo(Typeface.BOLD_ITALIC); findSpan(text, 0, 6, UnderlineSpan.class); ForegroundColorSpan colorSpan = findSpan(text, 0, 6, ForegroundColorSpan.class); assertThat(colorSpan.getForegroundColor()).isEqualTo(Color.GREEN); assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f); }
@Test public void testParseMalformedNestedElements() throws Exception { Spanned text = parseCueText("<b><u>An unclosed u tag with <i>italic</u> inside</i></b>"); assertThat(text.toString()).isEqualTo("An unclosed u tag with italic inside"); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); assertThat(underlineSpans).hasLength(1); assertThat(styleSpans).hasLength(2); // all tags applied until matching start tag found assertThat(text.getSpanStart(underlineSpans[0])).isEqualTo(0); assertThat(text.getSpanEnd(underlineSpans[0])).isEqualTo(29); if (styleSpans[0].getStyle() == Typeface.BOLD) { assertThat(text.getSpanStart(styleSpans[0])).isEqualTo(0); assertThat(text.getSpanStart(styleSpans[1])).isEqualTo(23); assertThat(text.getSpanEnd(styleSpans[1])).isEqualTo(29); assertThat(text.getSpanEnd(styleSpans[0])).isEqualTo(36); } else { assertThat(text.getSpanStart(styleSpans[1])).isEqualTo(0); assertThat(text.getSpanStart(styleSpans[0])).isEqualTo(23); assertThat(text.getSpanEnd(styleSpans[0])).isEqualTo(29); assertThat(text.getSpanEnd(styleSpans[1])).isEqualTo(36); } }
@Test public void testDecodeWithMultipleStyl() throws IOException, SubtitleDecoderException { Tx3gDecoder decoder = new Tx3gDecoder(Collections.emptyList()); byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_MULTIPLE_STYL); Subtitle subtitle = decoder.decode(bytes, bytes.length, false); SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text); assertThat(text.toString()).isEqualTo("Line 2\nLine 3"); assertThat(text.getSpans(0, text.length(), Object.class)).hasLength(4); StyleSpan styleSpan = findSpan(text, 0, 5, StyleSpan.class); assertThat(styleSpan.getStyle()).isEqualTo(Typeface.ITALIC); findSpan(text, 7, 12, UnderlineSpan.class); ForegroundColorSpan colorSpan = findSpan(text, 0, 5, ForegroundColorSpan.class); assertThat(colorSpan.getForegroundColor()).isEqualTo(Color.GREEN); colorSpan = findSpan(text, 7, 12, ForegroundColorSpan.class); assertThat(colorSpan.getForegroundColor()).isEqualTo(Color.GREEN); assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f); }
@Test public void testInitializationAllDefaultsDecodeWithStyl() throws IOException, SubtitleDecoderException { byte[] initBytes = TestUtil.getByteArray(RuntimeEnvironment.application, INITIALIZATION_ALL_DEFAULTS); Tx3gDecoder decoder = new Tx3gDecoder(Collections.singletonList(initBytes)); byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_STYL); Subtitle subtitle = decoder.decode(bytes, bytes.length, false); SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text); assertThat(text.toString()).isEqualTo("CC Test"); assertThat(text.getSpans(0, text.length(), Object.class)).hasLength(3); StyleSpan styleSpan = findSpan(text, 0, 6, StyleSpan.class); assertThat(styleSpan.getStyle()).isEqualTo(Typeface.BOLD_ITALIC); findSpan(text, 0, 6, UnderlineSpan.class); ForegroundColorSpan colorSpan = findSpan(text, 0, 6, ForegroundColorSpan.class); assertThat(colorSpan.getForegroundColor()).isEqualTo(Color.GREEN); assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f); }
@Test public void testInitializationDecodeWithTbox() throws IOException, SubtitleDecoderException { byte[] initBytes = TestUtil.getByteArray(RuntimeEnvironment.application, INITIALIZATION); Tx3gDecoder decoder = new Tx3gDecoder(Collections.singletonList(initBytes)); byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_TBOX); Subtitle subtitle = decoder.decode(bytes, bytes.length, false); SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text); assertThat(text.toString()).isEqualTo("CC Test"); assertThat(text.getSpans(0, text.length(), Object.class)).hasLength(4); StyleSpan styleSpan = findSpan(text, 0, text.length(), StyleSpan.class); assertThat(styleSpan.getStyle()).isEqualTo(Typeface.BOLD_ITALIC); findSpan(text, 0, text.length(), UnderlineSpan.class); TypefaceSpan typefaceSpan = findSpan(text, 0, text.length(), TypefaceSpan.class); assertThat(typefaceSpan.getFamily()).isEqualTo(C.SERIF_NAME); ForegroundColorSpan colorSpan = findSpan(text, 0, text.length(), ForegroundColorSpan.class); assertThat(colorSpan.getForegroundColor()).isEqualTo(Color.RED); assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.1875f); }
@Test public void testInitializationDecodeWithStyl() throws IOException, SubtitleDecoderException { byte[] initBytes = TestUtil.getByteArray(RuntimeEnvironment.application, INITIALIZATION); Tx3gDecoder decoder = new Tx3gDecoder(Collections.singletonList(initBytes)); byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_STYL); Subtitle subtitle = decoder.decode(bytes, bytes.length, false); SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text); assertThat(text.toString()).isEqualTo("CC Test"); assertThat(text.getSpans(0, text.length(), Object.class)).hasLength(5); StyleSpan styleSpan = findSpan(text, 0, text.length(), StyleSpan.class); assertThat(styleSpan.getStyle()).isEqualTo(Typeface.BOLD_ITALIC); findSpan(text, 0, text.length(), UnderlineSpan.class); TypefaceSpan typefaceSpan = findSpan(text, 0, text.length(), TypefaceSpan.class); assertThat(typefaceSpan.getFamily()).isEqualTo(C.SERIF_NAME); ForegroundColorSpan colorSpan = findSpan(text, 0, text.length(), ForegroundColorSpan.class); assertThat(colorSpan.getForegroundColor()).isEqualTo(Color.RED); colorSpan = findSpan(text, 0, 6, ForegroundColorSpan.class); assertThat(colorSpan.getForegroundColor()).isEqualTo(Color.GREEN); assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.1f); }
if (span.getStyle() == style) { list.add(new KnifePart(getEditableText().getSpanStart(span), getEditableText().getSpanEnd(span))); getEditableText().removeSpan(span);
assertThat(text.getSpans(/* start= */ 5, text.length(), StyleSpan.class)[0].getStyle()) .isEqualTo(Typeface.BOLD); assertThat(text.getSpans(/* start= */ 5, text.length(), TypefaceSpan.class)).hasLength(1); assertThat(text.getSpans(/* start= */ 6, /* end= */ 22, StyleSpan.class)).hasLength(0); assertThat(text.getSpans(/* start= */ 30, text.length(), StyleSpan.class)).hasLength(1); assertThat(text.getSpans(/* start= */ 30, text.length(), StyleSpan.class)[0].getStyle()) .isEqualTo(Typeface.BOLD); assertThat(text.getSpans(/* start= */ 9, /* end= */ 17, StyleSpan.class)).hasLength(0); assertThat(text.getSpans(/* start= */ 19, text.length(), StyleSpan.class)).hasLength(1); assertThat(text.getSpans(/* start= */ 19, text.length(), StyleSpan.class)[0].getStyle()) .isEqualTo(Typeface.ITALIC);
assertThat(s4.getSpans(/* start= */ 0, /* end= */ 16, BackgroundColorSpan.class)).hasLength(2); assertThat(s4.getSpans(/* start= */ 17, s4.length(), StyleSpan.class)).hasLength(1); assertThat(s4.getSpans(/* start= */ 17, s4.length(), StyleSpan.class)[0].getStyle()) .isEqualTo(Typeface.BOLD);
public static Object cloneSpan(Object span) { if (span instanceof ForegroundColorSpan) return new ForegroundColorSpan(((ForegroundColorSpan) span).getForegroundColor()); if (span instanceof BackgroundColorSpan) return new BackgroundColorSpan(((BackgroundColorSpan) span).getBackgroundColor()); if (span instanceof StyleSpan) return new StyleSpan(((StyleSpan) span).getStyle()); return null; }