Search in sources :

Example 1 with HorizontalTextInVerticalContextSpan

use of com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan in project ExoPlayer by google.

the class SubtitleViewUtilsTest method buildCue.

private static Cue buildCue() {
    SpannableString spanned = new SpannableString("TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize");
    spanned.setSpan(new TextEmphasisSpan(TextEmphasisSpan.MARK_SHAPE_CIRCLE, TextEmphasisSpan.MARK_FILL_FILLED, TextAnnotation.POSITION_BEFORE), "Text emphasis ".length(), "Text emphasis おはよ".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spanned.setSpan(new RubySpan("おはよ", TextAnnotation.POSITION_BEFORE), "TextEmphasis おはよ Ruby ".length(), "TextEmphasis おはよ Ruby ございます".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spanned.setSpan(new HorizontalTextInVerticalContextSpan(), "TextEmphasis おはよ Ruby ございます ".length(), "TextEmphasis おはよ Ruby ございます 123".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spanned.setSpan(new UnderlineSpan(), "TextEmphasis おはよ Ruby ございます 123 ".length(), "TextEmphasis おはよ Ruby ございます 123 Underline".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spanned.setSpan(new RelativeSizeSpan(1f), "TextEmphasis おはよ Ruby ございます 123 Underline ".length(), "TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    spanned.setSpan(new AbsoluteSizeSpan(10), "TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize ".length(), "TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    return new Cue.Builder().setText(spanned).setTextAlignment(Layout.Alignment.ALIGN_CENTER).setMultiRowAlignment(Layout.Alignment.ALIGN_NORMAL).setLine(5, Cue.LINE_TYPE_NUMBER).setLineAnchor(Cue.ANCHOR_TYPE_END).setPosition(0.4f).setPositionAnchor(Cue.ANCHOR_TYPE_MIDDLE).setTextSize(0.2f, Cue.TEXT_SIZE_TYPE_FRACTIONAL).setSize(0.8f).setWindowColor(Color.CYAN).setVerticalType(Cue.VERTICAL_TYPE_RL).setShearDegrees(-15f).build();
}
Also used : SpannableString(android.text.SpannableString) RubySpan(com.google.android.exoplayer2.text.span.RubySpan) Cue(com.google.android.exoplayer2.text.Cue) HorizontalTextInVerticalContextSpan(com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan) TextEmphasisSpan(com.google.android.exoplayer2.text.span.TextEmphasisSpan) RelativeSizeSpan(android.text.style.RelativeSizeSpan) UnderlineSpan(android.text.style.UnderlineSpan) AbsoluteSizeSpan(android.text.style.AbsoluteSizeSpan)

Example 2 with HorizontalTextInVerticalContextSpan

use of com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan in project ExoPlayer by google.

the class SubtitleViewUtilsTest method testRemoveEmbeddedFontSizes.

@Test
public void testRemoveEmbeddedFontSizes() {
    Cue.Builder cueBuilder = CUE.buildUpon();
    SubtitleViewUtils.removeEmbeddedFontSizes(cueBuilder);
    Cue strippedCue = cueBuilder.build();
    Spanned originalText = (Spanned) CUE.text;
    Spanned strippedText = (Spanned) strippedCue.text;
    // Assert all non text-size properties and spans are kept
    assertThat(strippedCue.textAlignment).isEqualTo(CUE.textAlignment);
    assertThat(strippedCue.multiRowAlignment).isEqualTo(CUE.multiRowAlignment);
    assertThat(strippedCue.line).isEqualTo(CUE.line);
    assertThat(strippedCue.lineType).isEqualTo(CUE.lineType);
    assertThat(strippedCue.position).isEqualTo(CUE.position);
    assertThat(strippedCue.positionAnchor).isEqualTo(CUE.positionAnchor);
    assertThat(strippedCue.size).isEqualTo(CUE.size);
    assertThat(strippedCue.windowColor).isEqualTo(CUE.windowColor);
    assertThat(strippedCue.windowColorSet).isEqualTo(CUE.windowColorSet);
    assertThat(strippedCue.verticalType).isEqualTo(CUE.verticalType);
    assertThat(strippedCue.shearDegrees).isEqualTo(CUE.shearDegrees);
    TextEmphasisSpan expectedTextEmphasisSpan = originalText.getSpans(0, originalText.length(), TextEmphasisSpan.class)[0];
    assertThat(strippedText).hasTextEmphasisSpanBetween(originalText.getSpanStart(expectedTextEmphasisSpan), originalText.getSpanEnd(expectedTextEmphasisSpan));
    RubySpan expectedRubySpan = originalText.getSpans(0, originalText.length(), RubySpan.class)[0];
    assertThat(strippedText).hasRubySpanBetween(originalText.getSpanStart(expectedRubySpan), originalText.getSpanEnd(expectedRubySpan));
    HorizontalTextInVerticalContextSpan expectedHorizontalTextInVerticalContextSpan = originalText.getSpans(0, originalText.length(), HorizontalTextInVerticalContextSpan.class)[0];
    assertThat(strippedText).hasHorizontalTextInVerticalContextSpanBetween(originalText.getSpanStart(expectedHorizontalTextInVerticalContextSpan), originalText.getSpanEnd(expectedHorizontalTextInVerticalContextSpan));
    UnderlineSpan expectedUnderlineSpan = originalText.getSpans(0, originalText.length(), UnderlineSpan.class)[0];
    assertThat(strippedText).hasUnderlineSpanBetween(originalText.getSpanStart(expectedUnderlineSpan), originalText.getSpanEnd(expectedUnderlineSpan));
    // Assert the text-size properties and spans are removed
    assertThat(strippedCue.textSize).isEqualTo(Cue.DIMEN_UNSET);
    assertThat(strippedCue.textSizeType).isEqualTo(Cue.TYPE_UNSET);
    assertThat(strippedText).hasNoRelativeSizeSpanBetween(0, strippedText.length());
    assertThat(strippedText).hasNoAbsoluteSizeSpanBetween(0, strippedText.length());
}
Also used : RubySpan(com.google.android.exoplayer2.text.span.RubySpan) Cue(com.google.android.exoplayer2.text.Cue) HorizontalTextInVerticalContextSpan(com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan) TextEmphasisSpan(com.google.android.exoplayer2.text.span.TextEmphasisSpan) Spanned(android.text.Spanned) UnderlineSpan(android.text.style.UnderlineSpan) Test(org.junit.Test)

Example 3 with HorizontalTextInVerticalContextSpan

use of com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan in project ExoPlayer by google.

the class SpannedToHtmlConverterTest method convert_supportsHorizontalTextInVerticalContextSpan.

@Test
public void convert_supportsHorizontalTextInVerticalContextSpan() {
    SpannableString spanned = new SpannableString("Vertical text with 123 horizontal numbers");
    spanned.setSpan(new HorizontalTextInVerticalContextSpan(), "Vertical text with ".length(), "Vertical text with 123".length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    SpannedToHtmlConverter.HtmlAndCss htmlAndCss = SpannedToHtmlConverter.convert(spanned, displayDensity);
    assertThat(htmlAndCss.cssRuleSets).isEmpty();
    assertThat(htmlAndCss.html).isEqualTo("Vertical text with <span style='text-combine-upright:all;'>123</span> " + "horizontal numbers");
}
Also used : SpannableString(android.text.SpannableString) HorizontalTextInVerticalContextSpan(com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan) Test(org.junit.Test)

Example 4 with HorizontalTextInVerticalContextSpan

use of com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan in project ExoPlayer by google.

the class TtmlRenderUtil method applyStylesToSpan.

public static void applyStylesToSpan(Spannable builder, int start, int end, TtmlStyle style, @Nullable TtmlNode parent, Map<String, TtmlStyle> globalStyles, @Cue.VerticalType int verticalType) {
    if (style.getStyle() != TtmlStyle.UNSPECIFIED) {
        builder.setSpan(new StyleSpan(style.getStyle()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    if (style.isLinethrough()) {
        builder.setSpan(new StrikethroughSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    if (style.isUnderline()) {
        builder.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    if (style.hasFontColor()) {
        SpanUtil.addOrReplaceSpan(builder, new ForegroundColorSpan(style.getFontColor()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    if (style.hasBackgroundColor()) {
        SpanUtil.addOrReplaceSpan(builder, new BackgroundColorSpan(style.getBackgroundColor()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    if (style.getFontFamily() != null) {
        SpanUtil.addOrReplaceSpan(builder, new TypefaceSpan(style.getFontFamily()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    if (style.getTextEmphasis() != null) {
        TextEmphasis textEmphasis = checkNotNull(style.getTextEmphasis());
        @TextEmphasisSpan.MarkShape int markShape;
        @TextEmphasisSpan.MarkFill int markFill;
        if (textEmphasis.markShape == TextEmphasis.MARK_SHAPE_AUTO) {
            // If a vertical writing mode applies, then 'auto' is equivalent to 'filled sesame';
            // otherwise, it's equivalent to 'filled circle':
            // https://www.w3.org/TR/ttml2/#style-value-emphasis-style
            markShape = (verticalType == Cue.VERTICAL_TYPE_LR || verticalType == Cue.VERTICAL_TYPE_RL) ? TextEmphasisSpan.MARK_SHAPE_SESAME : TextEmphasisSpan.MARK_SHAPE_CIRCLE;
            markFill = TextEmphasisSpan.MARK_FILL_FILLED;
        } else {
            markShape = textEmphasis.markShape;
            markFill = textEmphasis.markFill;
        }
        @TextEmphasis.Position int position;
        if (textEmphasis.position == TextEmphasis.POSITION_OUTSIDE) {
            // 'outside' is not supported by TextEmphasisSpan, so treat it as 'before':
            // https://www.w3.org/TR/ttml2/#style-value-annotation-position
            position = TextAnnotation.POSITION_BEFORE;
        } else {
            position = textEmphasis.position;
        }
        SpanUtil.addOrReplaceSpan(builder, new TextEmphasisSpan(markShape, markFill, position), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    switch(style.getRubyType()) {
        case TtmlStyle.RUBY_TYPE_BASE:
            // look for the sibling RUBY_TEXT and add it as span between start & end.
            @Nullable TtmlNode containerNode = findRubyContainerNode(parent, globalStyles);
            if (containerNode == null) {
                // No matching container node
                break;
            }
            @Nullable TtmlNode textNode = findRubyTextNode(containerNode, globalStyles);
            if (textNode == null) {
                // no matching text node
                break;
            }
            String rubyText;
            if (textNode.getChildCount() == 1 && textNode.getChild(0).text != null) {
                rubyText = Util.castNonNull(textNode.getChild(0).text);
            } else {
                Log.i(TAG, "Skipping rubyText node without exactly one text child.");
                break;
            }
            @Nullable TtmlStyle textStyle = resolveStyle(textNode.style, textNode.getStyleIds(), globalStyles);
            // Use position from ruby text node if defined.
            @TextAnnotation.Position int rubyPosition = textStyle != null ? textStyle.getRubyPosition() : TextAnnotation.POSITION_UNKNOWN;
            if (rubyPosition == TextAnnotation.POSITION_UNKNOWN) {
                // If ruby position is not defined, use position info from container node.
                @Nullable TtmlStyle containerStyle = resolveStyle(containerNode.style, containerNode.getStyleIds(), globalStyles);
                rubyPosition = containerStyle != null ? containerStyle.getRubyPosition() : rubyPosition;
            }
            builder.setSpan(new RubySpan(rubyText, rubyPosition), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            break;
        case TtmlStyle.RUBY_TYPE_DELIMITER:
        // fall through and delete the text.
        case TtmlStyle.RUBY_TYPE_TEXT:
            // We can't just remove the text directly from `builder` here because TtmlNode has fixed
            // ideas of where every node starts and ends (nodeStartsByRegion and nodeEndsByRegion) so
            // all these indices become invalid if we mutate the underlying string at this point.
            // Instead we add a special span that's then handled in TtmlNode#cleanUpText.
            builder.setSpan(new DeleteTextSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            break;
        case TtmlStyle.RUBY_TYPE_CONTAINER:
        case TtmlStyle.UNSPECIFIED:
        default:
            // Do nothing
            break;
    }
    if (style.getTextCombine()) {
        SpanUtil.addOrReplaceSpan(builder, new HorizontalTextInVerticalContextSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    switch(style.getFontSizeUnit()) {
        case TtmlStyle.FONT_SIZE_UNIT_PIXEL:
            SpanUtil.addOrReplaceSpan(builder, new AbsoluteSizeSpan((int) style.getFontSize(), true), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            break;
        case TtmlStyle.FONT_SIZE_UNIT_EM:
            SpanUtil.addOrReplaceSpan(builder, new RelativeSizeSpan(style.getFontSize()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            break;
        case TtmlStyle.FONT_SIZE_UNIT_PERCENT:
            SpanUtil.addOrReplaceSpan(builder, new RelativeSizeSpan(style.getFontSize() / 100), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            break;
        case TtmlStyle.UNSPECIFIED:
            // Do nothing.
            break;
    }
}
Also used : RubySpan(com.google.android.exoplayer2.text.span.RubySpan) ForegroundColorSpan(android.text.style.ForegroundColorSpan) TextEmphasisSpan(com.google.android.exoplayer2.text.span.TextEmphasisSpan) RelativeSizeSpan(android.text.style.RelativeSizeSpan) UnderlineSpan(android.text.style.UnderlineSpan) AbsoluteSizeSpan(android.text.style.AbsoluteSizeSpan) HorizontalTextInVerticalContextSpan(com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan) StyleSpan(android.text.style.StyleSpan) BackgroundColorSpan(android.text.style.BackgroundColorSpan) Nullable(androidx.annotation.Nullable) StrikethroughSpan(android.text.style.StrikethroughSpan) TypefaceSpan(android.text.style.TypefaceSpan)

Example 5 with HorizontalTextInVerticalContextSpan

use of com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan in project ExoPlayer by google.

the class SpannedSubjectTest method horizontalTextInVerticalContextSpan_success.

@Test
public void horizontalTextInVerticalContextSpan_success() {
    SpannableString spannable = createSpannable(new HorizontalTextInVerticalContextSpan(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    assertThat(spannable).hasHorizontalTextInVerticalContextSpanBetween(SPAN_START, SPAN_END).withFlags(Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
Also used : SpannableString(android.text.SpannableString) HorizontalTextInVerticalContextSpan(com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan) Test(org.junit.Test)

Aggregations

HorizontalTextInVerticalContextSpan (com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan)8 RubySpan (com.google.android.exoplayer2.text.span.RubySpan)5 TextEmphasisSpan (com.google.android.exoplayer2.text.span.TextEmphasisSpan)5 Test (org.junit.Test)5 SpannableString (android.text.SpannableString)4 UnderlineSpan (android.text.style.UnderlineSpan)4 AbsoluteSizeSpan (android.text.style.AbsoluteSizeSpan)3 RelativeSizeSpan (android.text.style.RelativeSizeSpan)3 Cue (com.google.android.exoplayer2.text.Cue)3 Spanned (android.text.Spanned)2 BackgroundColorSpan (android.text.style.BackgroundColorSpan)2 ForegroundColorSpan (android.text.style.ForegroundColorSpan)2 StrikethroughSpan (android.text.style.StrikethroughSpan)2 StyleSpan (android.text.style.StyleSpan)2 TypefaceSpan (android.text.style.TypefaceSpan)2 Nullable (androidx.annotation.Nullable)2