Commit 388b8d1d by Egor Neliuba

Add support for SSA OutlineColour (only background)

OutlineColour should be treated as the background color if BorderStyle=3. Since currently BorderStyle is ignored, we can always treat OutlineColor as the background color.
parent cf0a6806
...@@ -21,6 +21,7 @@ import static com.google.android.exoplayer2.util.Util.castNonNull; ...@@ -21,6 +21,7 @@ import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.text.Layout; import android.text.Layout;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan; import android.text.style.ForegroundColorSpan;
import android.text.style.StrikethroughSpan; import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
...@@ -319,6 +320,13 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { ...@@ -319,6 +320,13 @@ public final class SsaDecoder extends SimpleSubtitleDecoder {
/* end= */ spannableText.length(), /* end= */ spannableText.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE); SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
if (style.outlineColor != null) {
spannableText.setSpan(
new BackgroundColorSpan(style.outlineColor),
/* start= */ 0,
/* end= */ spannableText.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (style.fontSize != Cue.DIMEN_UNSET && screenHeight != Cue.DIMEN_UNSET) { if (style.fontSize != Cue.DIMEN_UNSET && screenHeight != Cue.DIMEN_UNSET) {
cue.setTextSize( cue.setTextSize(
style.fontSize / screenHeight, Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING); style.fontSize / screenHeight, Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING);
......
...@@ -95,6 +95,7 @@ import java.util.regex.Pattern; ...@@ -95,6 +95,7 @@ import java.util.regex.Pattern;
public final String name; public final String name;
public final @SsaAlignment int alignment; public final @SsaAlignment int alignment;
@Nullable @ColorInt public final Integer primaryColor; @Nullable @ColorInt public final Integer primaryColor;
@Nullable @ColorInt public final Integer outlineColor;
public final float fontSize; public final float fontSize;
public final boolean bold; public final boolean bold;
public final boolean italic; public final boolean italic;
...@@ -105,6 +106,7 @@ import java.util.regex.Pattern; ...@@ -105,6 +106,7 @@ import java.util.regex.Pattern;
String name, String name,
@SsaAlignment int alignment, @SsaAlignment int alignment,
@Nullable @ColorInt Integer primaryColor, @Nullable @ColorInt Integer primaryColor,
@Nullable @ColorInt Integer outlineColor,
float fontSize, float fontSize,
boolean bold, boolean bold,
boolean italic, boolean italic,
...@@ -113,6 +115,7 @@ import java.util.regex.Pattern; ...@@ -113,6 +115,7 @@ import java.util.regex.Pattern;
this.name = name; this.name = name;
this.alignment = alignment; this.alignment = alignment;
this.primaryColor = primaryColor; this.primaryColor = primaryColor;
this.outlineColor = outlineColor;
this.fontSize = fontSize; this.fontSize = fontSize;
this.bold = bold; this.bold = bold;
this.italic = italic; this.italic = italic;
...@@ -141,6 +144,9 @@ import java.util.regex.Pattern; ...@@ -141,6 +144,9 @@ import java.util.regex.Pattern;
format.primaryColorIndex != C.INDEX_UNSET format.primaryColorIndex != C.INDEX_UNSET
? parseColor(styleValues[format.primaryColorIndex].trim()) ? parseColor(styleValues[format.primaryColorIndex].trim())
: null, : null,
format.outlineColorIndex != C.INDEX_UNSET
? parseColor(styleValues[format.outlineColorIndex].trim())
: null,
format.fontSizeIndex != C.INDEX_UNSET format.fontSizeIndex != C.INDEX_UNSET
? parseFontSize(styleValues[format.fontSizeIndex].trim()) ? parseFontSize(styleValues[format.fontSizeIndex].trim())
: Cue.DIMEN_UNSET, : Cue.DIMEN_UNSET,
...@@ -257,6 +263,7 @@ import java.util.regex.Pattern; ...@@ -257,6 +263,7 @@ import java.util.regex.Pattern;
public final int nameIndex; public final int nameIndex;
public final int alignmentIndex; public final int alignmentIndex;
public final int primaryColorIndex; public final int primaryColorIndex;
public final int outlineColorIndex;
public final int fontSizeIndex; public final int fontSizeIndex;
public final int boldIndex; public final int boldIndex;
public final int italicIndex; public final int italicIndex;
...@@ -268,6 +275,7 @@ import java.util.regex.Pattern; ...@@ -268,6 +275,7 @@ import java.util.regex.Pattern;
int nameIndex, int nameIndex,
int alignmentIndex, int alignmentIndex,
int primaryColorIndex, int primaryColorIndex,
int outlineColorIndex,
int fontSizeIndex, int fontSizeIndex,
int boldIndex, int boldIndex,
int italicIndex, int italicIndex,
...@@ -277,6 +285,7 @@ import java.util.regex.Pattern; ...@@ -277,6 +285,7 @@ import java.util.regex.Pattern;
this.nameIndex = nameIndex; this.nameIndex = nameIndex;
this.alignmentIndex = alignmentIndex; this.alignmentIndex = alignmentIndex;
this.primaryColorIndex = primaryColorIndex; this.primaryColorIndex = primaryColorIndex;
this.outlineColorIndex = outlineColorIndex;
this.fontSizeIndex = fontSizeIndex; this.fontSizeIndex = fontSizeIndex;
this.boldIndex = boldIndex; this.boldIndex = boldIndex;
this.italicIndex = italicIndex; this.italicIndex = italicIndex;
...@@ -295,6 +304,7 @@ import java.util.regex.Pattern; ...@@ -295,6 +304,7 @@ import java.util.regex.Pattern;
int nameIndex = C.INDEX_UNSET; int nameIndex = C.INDEX_UNSET;
int alignmentIndex = C.INDEX_UNSET; int alignmentIndex = C.INDEX_UNSET;
int primaryColorIndex = C.INDEX_UNSET; int primaryColorIndex = C.INDEX_UNSET;
int outlineColorIndex = C.INDEX_UNSET;
int fontSizeIndex = C.INDEX_UNSET; int fontSizeIndex = C.INDEX_UNSET;
int boldIndex = C.INDEX_UNSET; int boldIndex = C.INDEX_UNSET;
int italicIndex = C.INDEX_UNSET; int italicIndex = C.INDEX_UNSET;
...@@ -313,6 +323,9 @@ import java.util.regex.Pattern; ...@@ -313,6 +323,9 @@ import java.util.regex.Pattern;
case "primarycolour": case "primarycolour":
primaryColorIndex = i; primaryColorIndex = i;
break; break;
case "outlinecolour":
outlineColorIndex = i;
break;
case "fontsize": case "fontsize":
fontSizeIndex = i; fontSizeIndex = i;
break; break;
...@@ -335,6 +348,7 @@ import java.util.regex.Pattern; ...@@ -335,6 +348,7 @@ import java.util.regex.Pattern;
nameIndex, nameIndex,
alignmentIndex, alignmentIndex,
primaryColorIndex, primaryColorIndex,
outlineColorIndex,
fontSizeIndex, fontSizeIndex,
boldIndex, boldIndex,
italicIndex, italicIndex,
......
...@@ -301,7 +301,7 @@ public final class SsaDecoderTest { ...@@ -301,7 +301,7 @@ public final class SsaDecoderTest {
SsaDecoder decoder = new SsaDecoder(); SsaDecoder decoder = new SsaDecoder();
byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_COLORS); byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_COLORS);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false); Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(14); assertThat(subtitle.getEventTimeCount()).isEqualTo(16);
// &H000000FF (AABBGGRR) -> #FFFF0000 (AARRGGBB) // &H000000FF (AABBGGRR) -> #FFFF0000 (AARRGGBB)
Spanned firstCueText = Spanned firstCueText =
(Spanned) Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(0))).text; (Spanned) Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(0))).text;
...@@ -342,6 +342,11 @@ public final class SsaDecoderTest { ...@@ -342,6 +342,11 @@ public final class SsaDecoderTest {
(Spanned) Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(12))).text; (Spanned) Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(12))).text;
SpannedSubject.assertThat(seventhCueText) SpannedSubject.assertThat(seventhCueText)
.hasNoForegroundColorSpanBetween(0, seventhCueText.length()); .hasNoForegroundColorSpanBetween(0, seventhCueText.length());
Spanned eighthCueText =
(Spanned) Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(14))).text;
SpannedSubject.assertThat(eighthCueText)
.hasBackgroundColorSpanBetween(0, eighthCueText.length())
.withColor(Color.BLUE);
} }
@Test @Test
......
...@@ -5,14 +5,15 @@ PlayResX: 1280 ...@@ -5,14 +5,15 @@ PlayResX: 1280
PlayResY: 720 PlayResY: 720
[V4+ Styles] [V4+ Styles]
Format: Name ,PrimaryColour Format: Name ,PrimaryColour,OutlineColour
Style: PrimaryColourStyleHexRed ,&H000000FF Style: PrimaryColourStyleHexRed ,&H000000FF ,&H00000000
Style: PrimaryColourStyleHexYellow ,&H0000FFFF Style: PrimaryColourStyleHexYellow ,&H0000FFFF ,&H00000000
Style: PrimaryColourStyleHexGreen ,&HFF00 Style: PrimaryColourStyleHexGreen ,&HFF00 ,&H00000000
Style: PrimaryColourStyleHexAlpha ,&HA00000FF Style: PrimaryColourStyleHexAlpha ,&HA00000FF ,&H00000000
Style: PrimaryColourStyleDecimal ,16711680 Style: PrimaryColourStyleDecimal ,16711680 ,&H00000000
Style: PrimaryColourStyleDecimalAlpha,2164195328 Style: PrimaryColourStyleDecimalAlpha,2164195328 ,&H00000000
Style: PrimaryColourStyleInvalid ,blue Style: PrimaryColourStyleInvalid ,blue ,&H00000000
Style: OutlineColourStyleBlue ,&H00000000 ,&H00FF0000
[Events] [Events]
...@@ -24,3 +25,4 @@ Dialogue: 0:00:07.00,0:00:08.00,PrimaryColourStyleHexAlpha ,Fourth line in RE ...@@ -24,3 +25,4 @@ Dialogue: 0:00:07.00,0:00:08.00,PrimaryColourStyleHexAlpha ,Fourth line in RE
Dialogue: 0:00:09.00,0:00:10.00,PrimaryColourStyleDecimal ,Fifth line in BLUE (16711680). Dialogue: 0:00:09.00,0:00:10.00,PrimaryColourStyleDecimal ,Fifth line in BLUE (16711680).
Dialogue: 0:00:11.00,0:00:12.00,PrimaryColourStyleDecimalAlpha,Sixth line in BLUE with alpha (2164195328). Dialogue: 0:00:11.00,0:00:12.00,PrimaryColourStyleDecimalAlpha,Sixth line in BLUE with alpha (2164195328).
Dialogue: 0:00:13.00,0:00:14.00,PrimaryColourInvalid ,Seventh line with invalid color. Dialogue: 0:00:13.00,0:00:14.00,PrimaryColourInvalid ,Seventh line with invalid color.
Dialogue: 0:00:15.00,0:00:16.00,OutlineColourStyleBlue ,Eighth line with BLUE (&H00FF0000) outline.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment