Commit ec69977a by Abel Jimenez

ssa bold and italic

parent 71409c44
......@@ -507,6 +507,13 @@
"subtitle_language": "en"
},
{
"name": "SubStation Alpha Style",
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/video-avc-baseline-480.mp4",
"subtitle_uri": "https://drive.google.com/uc?export=download&id=16IrvtynQ6-ANRpRX7hU6xEQeFU91LmXl",
"subtitle_mime_type": "text/x-ssa",
"subtitle_language": "en"
},
{
"name": "MPEG-4 Timed Text",
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/mp4/dizzy-with-tx3g.mp4"
}
......
......@@ -18,9 +18,11 @@ package com.google.android.exoplayer2.text.ssa;
import static com.google.android.exoplayer2.text.Cue.LINE_TYPE_FRACTION;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.graphics.Typeface;
import android.text.Layout;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.text.Cue;
......@@ -319,6 +321,27 @@ public final class SsaDecoder extends SimpleSubtitleDecoder {
style.fontSize / screenHeight,
Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING);
}
if (style.bold && style.italic) {
spannableText.setSpan(
new StyleSpan(Typeface.BOLD_ITALIC),
0,
spannableText.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else if(style.bold){
spannableText.setSpan(
new StyleSpan(Typeface.BOLD),
0,
spannableText.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else if(style.italic){
spannableText.setSpan(
new StyleSpan(Typeface.ITALIC),
0,
spannableText.length(),
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
@SsaStyle.SsaAlignment int alignment;
......
......@@ -92,16 +92,22 @@ import java.util.regex.Pattern;
@SsaAlignment public final int alignment;
@Nullable @ColorInt public final Integer primaryColor;
public final float fontSize;
public final boolean bold;
public final boolean italic;
private SsaStyle(
String name,
@SsaAlignment int alignment,
@Nullable @ColorInt Integer primaryColor,
float fontSize) {
float fontSize,
boolean bold,
boolean italic) {
this.name = name;
this.alignment = alignment;
this.primaryColor = primaryColor;
this.fontSize = fontSize;
this.bold = bold;
this.italic = italic;
}
@Nullable
......@@ -121,7 +127,9 @@ import java.util.regex.Pattern;
styleValues[format.nameIndex].trim(),
parseAlignment(styleValues[format.alignmentIndex].trim()),
parseColor(styleValues[format.primaryColorIndex].trim()),
parseFontSize(styleValues[format.fontSizeIndex].trim()));
parseFontSize(styleValues[format.fontSizeIndex].trim()),
parseBold(styleValues[format.boldIndex].trim()),
parseItalic(styleValues[format.italicIndex].trim()));
} catch (RuntimeException e) {
Log.w(TAG, "Skipping malformed 'Style:' line: '" + styleLine + "'", e);
return null;
......@@ -207,6 +215,36 @@ import java.util.regex.Pattern;
}
}
private static boolean parseBold(String bold) {
try {
int boldFlag = Integer.parseInt(bold);
if(boldFlag == 1 || boldFlag == -1){
return true;
}
else{
return false;
}
} catch (NumberFormatException e) {
Log.w(TAG, "Failed to parse bold: '" + bold + "'", e);
return false;
}
}
private static boolean parseItalic(String italic) {
try {
int italicFlag = Integer.parseInt(italic);
if(italicFlag == 1 || italicFlag == -1){
return true;
}
else{
return false;
}
} catch (NumberFormatException e) {
Log.w(TAG, "Failed to parse italic: '" + italic + "'", e);
return false;
}
}
/**
* Represents a {@code Format:} line from the {@code [V4+ Styles]} section
*
......@@ -219,6 +257,8 @@ import java.util.regex.Pattern;
public final int alignmentIndex;
public final int primaryColorIndex;
public final int fontSizeIndex;
public final int boldIndex;
public final int italicIndex;
public final int length;
private Format(
......@@ -226,11 +266,15 @@ import java.util.regex.Pattern;
int alignmentIndex,
int primaryColorIndex,
int fontSizeIndex,
int boldIndex,
int italicIndex,
int length) {
this.nameIndex = nameIndex;
this.alignmentIndex = alignmentIndex;
this.primaryColorIndex = primaryColorIndex;
this.fontSizeIndex = fontSizeIndex;
this.boldIndex = boldIndex;
this.italicIndex = italicIndex;
this.length = length;
}
......@@ -245,6 +289,8 @@ import java.util.regex.Pattern;
int alignmentIndex = C.INDEX_UNSET;
int primaryColorIndex = C.INDEX_UNSET;
int fontSizeIndex = C.INDEX_UNSET;
int boldIndex = C.INDEX_UNSET;
int italicIndex = C.INDEX_UNSET;
String[] keys =
TextUtils.split(styleFormatLine.substring(SsaDecoder.FORMAT_LINE_PREFIX.length()), ",");
for (int i = 0; i < keys.length; i++) {
......@@ -261,10 +307,16 @@ import java.util.regex.Pattern;
case "fontsize":
fontSizeIndex = i;
break;
case "bold":
boldIndex = i;
break;
case "italic":
italicIndex = i;
break;
}
}
return nameIndex != C.INDEX_UNSET
? new Format(nameIndex, alignmentIndex, primaryColorIndex, fontSizeIndex, keys.length)
? new Format(nameIndex, alignmentIndex, primaryColorIndex, fontSizeIndex, boldIndex, italicIndex, keys.length)
: null;
}
}
......
......@@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.graphics.Color;
import android.graphics.Typeface;
import android.text.Layout;
import android.text.Spanned;
import androidx.test.core.app.ApplicationProvider;
......@@ -49,6 +50,7 @@ public final class SsaDecoderTest {
private static final String POSITIONS_WITHOUT_PLAYRES = "media/ssa/positioning_without_playres";
private static final String STYLE_COLORS = "media/ssa/style_colors";
private static final String STYLE_FONT_SIZE = "media/ssa/style_font_size";
private static final String STYLE_BOLD_ITALIC = "media/ssa/style_bold_italic";
@Test
public void decodeEmpty() throws IOException {
......@@ -335,6 +337,24 @@ public final class SsaDecoderTest {
assertThat(secondCue.textSizeType).isEqualTo(Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING);
}
@Test
public void decodeBoldItalic() throws IOException{
SsaDecoder decoder = new SsaDecoder();
byte[] bytes = TestUtil.getByteArray(ApplicationProvider.getApplicationContext(), STYLE_BOLD_ITALIC);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(6);
Spanned firstCueText =
(Spanned) Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(0))).text;
SpannedSubject.assertThat(firstCueText).hasBoldSpanBetween(0, firstCueText.length());
Spanned secondCueText =
(Spanned) Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(2))).text;
SpannedSubject.assertThat(secondCueText).hasItalicSpanBetween(0, secondCueText.length());
Spanned thirdCueText =
(Spanned) Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(4))).text;
SpannedSubject.assertThat(thirdCueText).hasBoldItalicSpanBetween(0, thirdCueText.length());
}
private static void assertTypicalCue1(Subtitle subtitle, int eventIndex) {
assertThat(subtitle.getEventTime(eventIndex)).isEqualTo(0);
assertThat(subtitle.getCues(subtitle.getEventTime(eventIndex)).get(0).text.toString())
......
......@@ -9,11 +9,12 @@ PlayResY: 720
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: FontBold ,Roboto,50,&H000000FF,&H000000FF,&H00000000,&H00000000,-1,0,0,0,100,100,0,0,1,3,0,2,50,50,70,1
Style: FontItalic ,Roboto,50,&H000000FF,&H000000FF,&H00000000,&H00000000,0,-1,0,0,100,100,0,0,1,3,0,2,50,50,70,1
Style: FontItalic ,Roboto,50,&H000000FF,&H000000FF,&H00000000,&H00000000,-1,-1,0,0,100,100,0,0,1,3,0,2,50,50,70,1
Style: FontBoldItalic ,Roboto,50,&H000000FF,&H000000FF,&H00000000,&H00000000,-1,-1,0,0,100,100,0,0,1,3,0,2,50,50,70,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:00.95,0:00:03.11,FontSizeSmall ,Arnold,0,0,0,,First line with font size 30.
Dialogue: 0,0:00:08.50,0:00:11.50,FontSizeBig ,Arnold,0,0,0,,Second line with font size 72.2.
\ No newline at end of file
Dialogue: 0,0:00:01.00,0:00:03.00,FontBold ,Abel,0,0,0,,First line with Bold.
Dialogue: 0,0:00:05.00,0:00:07.00,FontItalic ,Abel,0,0,0,,Second line with Italic.
Dialogue: 0,0:00:09.00,0:00:11.00,FontBoldItalic ,Abel,0,0,0,,Third line with Bold Italic.
\ No newline at end of file
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