mirror of
https://github.com/samsonjs/media.git
synced 2026-03-28 09:55:48 +00:00
Introduce LanguageFeatureStyle interface to mark language features
This commit is contained in:
parent
49dfe66bb3
commit
e3228064f3
7 changed files with 262 additions and 76 deletions
|
|
@ -29,4 +29,4 @@ package com.google.android.exoplayer2.text.span;
|
|||
// NOTE: There's no Android layout support for this, so this span currently doesn't extend any
|
||||
// styling superclasses (e.g. MetricAffectingSpan). The only way to render this styling is to
|
||||
// extract the spans and do the layout manually.
|
||||
public final class HorizontalTextInVerticalContextSpan {}
|
||||
public final class HorizontalTextInVerticalContextSpan implements LanguageFeatureStyle {}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.text.span;
|
||||
|
||||
/**
|
||||
* Marker interface to mark classes that are language features.
|
||||
*/
|
||||
public interface LanguageFeatureStyle {
|
||||
}
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ package com.google.android.exoplayer2.text.span;
|
|||
// extract the spans and do the layout manually.
|
||||
// TODO: Consider adding support for parenthetical text to be used when rendering doesn't support
|
||||
// rubies (e.g. HTML <rp> tag).
|
||||
public final class RubySpan {
|
||||
public final class RubySpan implements LanguageFeatureStyle {
|
||||
|
||||
/** The ruby text, i.e. the smaller explanatory characters. */
|
||||
public final String rubyText;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import java.lang.annotation.Retention;
|
|||
// NOTE: There's no Android layout support for text emphasis, so this span currently doesn't extend
|
||||
// any styling superclasses (e.g. MetricAffectingSpan). The only way to render this emphasis is to
|
||||
// extract the spans and do the layout manually.
|
||||
public final class TextEmphasisSpan {
|
||||
public final class TextEmphasisSpan implements LanguageFeatureStyle {
|
||||
|
||||
/**
|
||||
* The possible mark shapes that can be used.
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import androidx.annotation.IntDef;
|
|||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.text.TextOutput;
|
||||
import com.google.android.exoplayer2.text.span.LanguageFeatureStyle;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
|
|
@ -374,47 +375,9 @@ public final class SubtitleView extends FrameLayout implements TextOutput {
|
|||
}
|
||||
List<Cue> strippedCues = new ArrayList<>(cues.size());
|
||||
for (int i = 0; i < cues.size(); i++) {
|
||||
strippedCues.add(removeEmbeddedStyling(cues.get(i)));
|
||||
strippedCues.add(SubtitleViewUtils
|
||||
.removeEmbeddedStyling(cues.get(i), applyEmbeddedStyles, applyEmbeddedFontSizes));
|
||||
}
|
||||
return strippedCues;
|
||||
}
|
||||
|
||||
private Cue removeEmbeddedStyling(Cue cue) {
|
||||
@Nullable CharSequence cueText = cue.text;
|
||||
if (!applyEmbeddedStyles) {
|
||||
Cue.Builder strippedCue =
|
||||
cue.buildUpon().setTextSize(Cue.DIMEN_UNSET, Cue.TYPE_UNSET).clearWindowColor();
|
||||
if (cueText != null) {
|
||||
// Remove all spans, regardless of type.
|
||||
strippedCue.setText(new SpannableString(cueText.toString()));
|
||||
if (cueText instanceof Spanned) {
|
||||
SubtitleViewUtils
|
||||
.preserveJapaneseLanguageFeatures((SpannableString)strippedCue.getText(),
|
||||
(Spanned) cueText);
|
||||
}
|
||||
}
|
||||
return strippedCue.build();
|
||||
} else if (!applyEmbeddedFontSizes) {
|
||||
if (cueText == null) {
|
||||
return cue;
|
||||
}
|
||||
Cue.Builder strippedCue = cue.buildUpon().setTextSize(Cue.DIMEN_UNSET, Cue.TYPE_UNSET);
|
||||
if (cueText instanceof Spanned) {
|
||||
SpannableString spannable = SpannableString.valueOf(cueText);
|
||||
AbsoluteSizeSpan[] absSpans =
|
||||
spannable.getSpans(0, spannable.length(), AbsoluteSizeSpan.class);
|
||||
for (AbsoluteSizeSpan absSpan : absSpans) {
|
||||
spannable.removeSpan(absSpan);
|
||||
}
|
||||
RelativeSizeSpan[] relSpans =
|
||||
spannable.getSpans(0, spannable.length(), RelativeSizeSpan.class);
|
||||
for (RelativeSizeSpan relSpan : relSpans) {
|
||||
spannable.removeSpan(relSpan);
|
||||
}
|
||||
strippedCue.setText(spannable);
|
||||
}
|
||||
return strippedCue.build();
|
||||
}
|
||||
return cue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,15 @@
|
|||
package com.google.android.exoplayer2.ui;
|
||||
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.AbsoluteSizeSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
||||
import com.google.android.exoplayer2.text.span.LanguageFeatureStyle;
|
||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||
import com.google.android.exoplayer2.text.span.SpanUtil;
|
||||
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||
|
|
@ -54,26 +60,42 @@ import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
|||
}
|
||||
}
|
||||
|
||||
public static void preserveJapaneseLanguageFeatures(Spannable copy, Spanned original) {
|
||||
RubySpan[] absSpans =
|
||||
original.getSpans(0, original.length(), RubySpan.class);
|
||||
for (RubySpan rubySpan : absSpans) {
|
||||
SpanUtil.addOrReplaceSpan(copy, rubySpan, original.getSpanStart(rubySpan),
|
||||
original.getSpanEnd(rubySpan), original.getSpanFlags(rubySpan));
|
||||
}
|
||||
TextEmphasisSpan[] textEmphasisSpans =
|
||||
original.getSpans(0, original.length(), TextEmphasisSpan.class);
|
||||
for (TextEmphasisSpan textEmphasisSpan : textEmphasisSpans) {
|
||||
SpanUtil.addOrReplaceSpan(copy, textEmphasisSpan, original.getSpanStart(textEmphasisSpan),
|
||||
original.getSpanEnd(textEmphasisSpan), original.getSpanFlags(textEmphasisSpan));
|
||||
}
|
||||
HorizontalTextInVerticalContextSpan[] horizontalTextInVerticalContextSpans =
|
||||
original.getSpans(0, original.length(), HorizontalTextInVerticalContextSpan.class);
|
||||
|
||||
for (HorizontalTextInVerticalContextSpan span : horizontalTextInVerticalContextSpans) {
|
||||
SpanUtil.addOrReplaceSpan(copy, span, original.getSpanStart(span),
|
||||
original.getSpanEnd(span), original.getSpanFlags(span));
|
||||
/**
|
||||
* Returns a cue object with the specified styling removed
|
||||
* @param cue - Cue object that contains all the styling information
|
||||
* @param applyEmbeddedStyles - if true, styles embedded within the cues should be applied
|
||||
* @param applyEmbeddedFontSizes - if true, font sizes embedded within the cues should be applied.
|
||||
* Only takes effect if setApplyEmbeddedStyles is true
|
||||
* See {@link SubtitleView#setApplyEmbeddedStyles}
|
||||
* @return New cue object with the specified styling removed
|
||||
*/
|
||||
@NonNull
|
||||
static Cue removeEmbeddedStyling(@NonNull Cue cue, boolean applyEmbeddedStyles,
|
||||
boolean applyEmbeddedFontSizes) {
|
||||
@Nullable CharSequence cueText = cue.text;
|
||||
if (cueText != null && (!applyEmbeddedStyles || !applyEmbeddedFontSizes)) {
|
||||
Cue.Builder strippedCue = cue.buildUpon().setTextSize(Cue.DIMEN_UNSET, Cue.TYPE_UNSET);
|
||||
if (!applyEmbeddedStyles) {
|
||||
strippedCue.clearWindowColor();
|
||||
}
|
||||
if (cueText instanceof Spanned) {
|
||||
SpannableString spannable = SpannableString.valueOf(cueText);
|
||||
Object[] spans = spannable.getSpans(0, spannable.length(), Object.class);
|
||||
for (Object span : spans) {
|
||||
if (span instanceof LanguageFeatureStyle) {
|
||||
continue;
|
||||
}
|
||||
// applyEmbeddedFontSizes should only be applied if applyEmbeddedStyles is true
|
||||
if (!applyEmbeddedStyles || span instanceof AbsoluteSizeSpan
|
||||
|| span instanceof RelativeSizeSpan) {
|
||||
spannable.removeSpan(span);
|
||||
}
|
||||
}
|
||||
strippedCue.setText(spannable);
|
||||
}
|
||||
return strippedCue.build();
|
||||
}
|
||||
return cue;
|
||||
}
|
||||
|
||||
private SubtitleViewUtils() {}
|
||||
|
|
|
|||
|
|
@ -2,23 +2,187 @@ package com.google.android.exoplayer2.ui;
|
|||
|
||||
import static com.google.android.exoplayer2.testutil.truth.SpannedSubject.assertThat;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.Layout;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.AbsoluteSizeSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.UnderlineSpan;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||
import com.google.common.truth.Truth;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SubtitleViewUtilsTest {
|
||||
@Test
|
||||
public void testApplyEmbeddedStyles() {
|
||||
Cue cue = buildCue();
|
||||
Cue strippedCue = SubtitleViewUtils.removeEmbeddedStyling(cue, true, true);
|
||||
|
||||
Truth.assertThat(strippedCue.textAlignment).isEqualTo(cue.textAlignment);
|
||||
Truth.assertThat(strippedCue.multiRowAlignment).isEqualTo(cue.multiRowAlignment);
|
||||
Truth.assertThat(strippedCue.line).isEqualTo(cue.line);
|
||||
Truth.assertThat(strippedCue.lineType).isEqualTo(cue.lineType);
|
||||
Truth.assertThat(strippedCue.position).isEqualTo(cue.position);
|
||||
Truth.assertThat(strippedCue.positionAnchor).isEqualTo(cue.positionAnchor);
|
||||
Truth.assertThat(strippedCue.textSize).isEqualTo(cue.textSize);
|
||||
Truth.assertThat(strippedCue.textSizeType).isEqualTo(cue.textSizeType);
|
||||
Truth.assertThat(strippedCue.size).isEqualTo(cue.size);
|
||||
Truth.assertThat(strippedCue.windowColor).isEqualTo(cue.windowColor);
|
||||
Truth.assertThat(strippedCue.windowColorSet).isEqualTo(cue.windowColorSet);
|
||||
Truth.assertThat(strippedCue.verticalType).isEqualTo(cue.verticalType);
|
||||
Truth.assertThat(strippedCue.shearDegrees).isEqualTo(cue.shearDegrees);
|
||||
|
||||
Truth.assertThat(strippedCue.text).isInstanceOf(Spanned.class);
|
||||
Spannable spannable = SpannableString.valueOf(strippedCue.text);
|
||||
assertThat(spannable).hasTextEmphasisSpanBetween(
|
||||
"Text emphasis ".length(),
|
||||
"Text emphasis おはよ".length());
|
||||
assertThat(spannable).hasRubySpanBetween(
|
||||
"TextEmphasis おはよ Ruby ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます".length());
|
||||
assertThat(spannable).hasHorizontalTextInVerticalContextSpanBetween(
|
||||
"TextEmphasis おはよ Ruby ございます ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123".length());
|
||||
assertThat(spannable).hasUnderlineSpanBetween(
|
||||
"TextEmphasis おはよ Ruby ございます 123 ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline".length());
|
||||
assertThat(spannable).hasRelativeSizeSpanBetween(
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize".length());
|
||||
assertThat(spannable).hasAbsoluteSizeSpanBetween(
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreserveJapaneseLanguageFeatures() {
|
||||
SpannableString spanned = new SpannableString("TextEmphasis おはよ Ruby ございます 123 Underline");
|
||||
public void testApplyEmbeddedStylesFalse() {
|
||||
Cue cue = buildCue();
|
||||
Cue strippedCue = SubtitleViewUtils.removeEmbeddedStyling(cue, false, false);
|
||||
|
||||
Truth.assertThat(strippedCue.textAlignment).isEqualTo(cue.textAlignment);
|
||||
Truth.assertThat(strippedCue.multiRowAlignment).isEqualTo(cue.multiRowAlignment);
|
||||
Truth.assertThat(strippedCue.line).isEqualTo(cue.line);
|
||||
Truth.assertThat(strippedCue.lineType).isEqualTo(cue.lineType);
|
||||
Truth.assertThat(strippedCue.position).isEqualTo(cue.position);
|
||||
Truth.assertThat(strippedCue.positionAnchor).isEqualTo(cue.positionAnchor);
|
||||
Truth.assertThat(strippedCue.textSize).isEqualTo(Cue.DIMEN_UNSET);
|
||||
Truth.assertThat(strippedCue.textSizeType).isEqualTo(Cue.TYPE_UNSET);
|
||||
Truth.assertThat(strippedCue.size).isEqualTo(cue.size);
|
||||
Truth.assertThat(strippedCue.windowColor).isEqualTo(cue.windowColor);
|
||||
Truth.assertThat(strippedCue.windowColorSet).isEqualTo(false);
|
||||
Truth.assertThat(strippedCue.verticalType).isEqualTo(cue.verticalType);
|
||||
Truth.assertThat(strippedCue.shearDegrees).isEqualTo(cue.shearDegrees);
|
||||
|
||||
Truth.assertThat(strippedCue.text).isInstanceOf(Spanned.class);
|
||||
Spannable spannable = SpannableString.valueOf(strippedCue.text);
|
||||
assertThat(spannable).hasTextEmphasisSpanBetween(
|
||||
"Text emphasis ".length(),
|
||||
"Text emphasis おはよ".length());
|
||||
assertThat(spannable).hasRubySpanBetween(
|
||||
"TextEmphasis おはよ Ruby ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます".length());
|
||||
assertThat(spannable).hasHorizontalTextInVerticalContextSpanBetween(
|
||||
"TextEmphasis おはよ Ruby ございます ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123".length());
|
||||
assertThat(spannable).hasNoUnderlineSpanBetween(0,
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length());
|
||||
assertThat(spannable).hasNoRelativeSizeSpanBetween(0,
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length());
|
||||
assertThat(spannable).hasNoAbsoluteSizeSpanBetween(0,
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyEmbeddedStylesFalseWithApplyEmbeddedFontSizes() {
|
||||
Cue cue = buildCue();
|
||||
Cue strippedCue = SubtitleViewUtils.removeEmbeddedStyling(cue, false, true);
|
||||
|
||||
Truth.assertThat(strippedCue.textAlignment).isEqualTo(cue.textAlignment);
|
||||
Truth.assertThat(strippedCue.multiRowAlignment).isEqualTo(cue.multiRowAlignment);
|
||||
Truth.assertThat(strippedCue.line).isEqualTo(cue.line);
|
||||
Truth.assertThat(strippedCue.lineType).isEqualTo(cue.lineType);
|
||||
Truth.assertThat(strippedCue.position).isEqualTo(cue.position);
|
||||
Truth.assertThat(strippedCue.positionAnchor).isEqualTo(cue.positionAnchor);
|
||||
Truth.assertThat(strippedCue.textSize).isEqualTo(Cue.DIMEN_UNSET);
|
||||
Truth.assertThat(strippedCue.textSizeType).isEqualTo(Cue.TYPE_UNSET);
|
||||
Truth.assertThat(strippedCue.size).isEqualTo(cue.size);
|
||||
Truth.assertThat(strippedCue.windowColor).isEqualTo(cue.windowColor);
|
||||
Truth.assertThat(strippedCue.windowColorSet).isEqualTo(false);
|
||||
Truth.assertThat(strippedCue.verticalType).isEqualTo(cue.verticalType);
|
||||
Truth.assertThat(strippedCue.shearDegrees).isEqualTo(cue.shearDegrees);
|
||||
|
||||
Truth.assertThat(strippedCue.text).isInstanceOf(Spanned.class);
|
||||
Spannable spannable = SpannableString.valueOf(strippedCue.text);
|
||||
assertThat(spannable).hasTextEmphasisSpanBetween(
|
||||
"Text emphasis ".length(),
|
||||
"Text emphasis おはよ".length());
|
||||
assertThat(spannable).hasRubySpanBetween(
|
||||
"TextEmphasis おはよ Ruby ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます".length());
|
||||
assertThat(spannable).hasHorizontalTextInVerticalContextSpanBetween(
|
||||
"TextEmphasis おはよ Ruby ございます ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123".length());
|
||||
assertThat(spannable).hasNoUnderlineSpanBetween(0,
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length());
|
||||
assertThat(spannable).hasNoRelativeSizeSpanBetween(0,
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length());
|
||||
assertThat(spannable).hasNoAbsoluteSizeSpanBetween(0,
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testApplyEmbeddedFontSizes() {
|
||||
Cue cue = buildCue();
|
||||
Cue strippedCue = SubtitleViewUtils.removeEmbeddedStyling(cue, true, false);
|
||||
|
||||
Truth.assertThat(strippedCue.textAlignment).isEqualTo(cue.textAlignment);
|
||||
Truth.assertThat(strippedCue.multiRowAlignment).isEqualTo(cue.multiRowAlignment);
|
||||
Truth.assertThat(strippedCue.line).isEqualTo(cue.line);
|
||||
Truth.assertThat(strippedCue.lineType).isEqualTo(cue.lineType);
|
||||
Truth.assertThat(strippedCue.position).isEqualTo(cue.position);
|
||||
Truth.assertThat(strippedCue.positionAnchor).isEqualTo(cue.positionAnchor);
|
||||
Truth.assertThat(strippedCue.textSize).isEqualTo(Cue.DIMEN_UNSET);
|
||||
Truth.assertThat(strippedCue.textSizeType).isEqualTo(Cue.TYPE_UNSET);
|
||||
Truth.assertThat(strippedCue.size).isEqualTo(cue.size);
|
||||
Truth.assertThat(strippedCue.windowColor).isEqualTo(cue.windowColor);
|
||||
Truth.assertThat(strippedCue.windowColorSet).isEqualTo(cue.windowColorSet);
|
||||
Truth.assertThat(strippedCue.verticalType).isEqualTo(cue.verticalType);
|
||||
Truth.assertThat(strippedCue.shearDegrees).isEqualTo(cue.shearDegrees);
|
||||
|
||||
Truth.assertThat(strippedCue.text).isInstanceOf(Spanned.class);
|
||||
Spannable spannable = SpannableString.valueOf(strippedCue.text);
|
||||
assertThat(spannable).hasTextEmphasisSpanBetween(
|
||||
"Text emphasis ".length(),
|
||||
"Text emphasis おはよ".length());
|
||||
assertThat(spannable).hasRubySpanBetween(
|
||||
"TextEmphasis おはよ Ruby ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます".length());
|
||||
assertThat(spannable).hasHorizontalTextInVerticalContextSpanBetween(
|
||||
"TextEmphasis おはよ Ruby ございます ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123".length());
|
||||
assertThat(spannable).hasUnderlineSpanBetween(
|
||||
"TextEmphasis おはよ Ruby ございます 123 ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline".length());
|
||||
assertThat(spannable).hasNoRelativeSizeSpanBetween(0,
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length());
|
||||
assertThat(spannable).hasNoAbsoluteSizeSpanBetween(0,
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length());
|
||||
}
|
||||
|
||||
|
||||
private Cue buildCue() {
|
||||
SpannableString spanned = new SpannableString(
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize");
|
||||
spanned.setSpan(
|
||||
new TextEmphasisSpan(
|
||||
TextEmphasisSpan.MARK_SHAPE_CIRCLE,
|
||||
|
|
@ -42,22 +206,36 @@ public class SubtitleViewUtilsTest {
|
|||
|
||||
spanned.setSpan(
|
||||
new UnderlineSpan(),
|
||||
"TextEmphasis おはよ Ruby ございます 123".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123 ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline".length(),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
SpannableString spannable = new SpannableString(spanned.toString());
|
||||
assertThat(spannable).hasNoTextEmphasisSpanBetween(0, spannable.length());
|
||||
spanned.setSpan(
|
||||
new RelativeSizeSpan(1f),
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize".length(),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
SubtitleViewUtils.preserveJapaneseLanguageFeatures(spannable, spanned);
|
||||
assertThat(spannable)
|
||||
.hasTextEmphasisSpanBetween("Text emphasis ".length(), "Text emphasis おはよ".length());
|
||||
assertThat(spannable).hasRubySpanBetween("TextEmphasis おはよ Ruby ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます".length());
|
||||
assertThat(spannable)
|
||||
.hasHorizontalTextInVerticalContextSpanBetween("TextEmphasis おはよ Ruby ございます ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123".length());
|
||||
spanned.setSpan(
|
||||
new AbsoluteSizeSpan(10),
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize ".length(),
|
||||
"TextEmphasis おはよ Ruby ございます 123 Underline RelativeSize AbsoluteSize".length(),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
assertThat(spannable).hasNoUnderlineSpanBetween(0, spannable.length());
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue