Commit d876028a by ibaker Committed by Tianyi Feng

CEA-608: Only truncate to 32 visible characters

We introduced truncation to 32 chars in <unknown commit>
and included indent and offset in the calculation. I think this is
technically correct, but it causes problems with the content in
Issue: google/ExoPlayer#11019 and it doesn't seem a problem to only truncate actual
cue text (i.e. ignore offset and indent).

#minor-release

PiperOrigin-RevId: 544677965
(cherry picked from commit d5e45209eeb7b3ce96cc9dcf32ea98bb42cf12ce)
parent f729b6d8
...@@ -1609,24 +1609,6 @@ public final class Util { ...@@ -1609,24 +1609,6 @@ public final class Util {
} }
/** /**
* Truncates a sequence of ASCII characters to a maximum length.
*
* <p>This preserves span styling in the {@link CharSequence}. If that's not important, use {@link
* Ascii#truncate(CharSequence, int, String)}.
*
* <p><b>Note:</b> This is not safe to use in general on Unicode text because it may separate
* characters from combining characters or split up surrogate pairs.
*
* @param sequence The character sequence to truncate.
* @param maxLength The max length to truncate to.
* @return {@code sequence} directly if {@code sequence.length() <= maxLength}, otherwise {@code
* sequence.subsequence(0, maxLength}.
*/
public static CharSequence truncateAscii(CharSequence sequence, int maxLength) {
return sequence.length() <= maxLength ? sequence : sequence.subSequence(0, maxLength);
}
/**
* Returns a byte array containing values parsed from the hex string provided. * Returns a byte array containing values parsed from the hex string provided.
* *
* @param hexString The hex string to convert to bytes. * @param hexString The hex string to convert to bytes.
......
...@@ -38,10 +38,6 @@ import android.net.Uri; ...@@ -38,10 +38,6 @@ import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.Looper; import android.os.Looper;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.StrikethroughSpan;
import android.text.style.UnderlineSpan;
import android.util.SparseLongArray; import android.util.SparseLongArray;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
...@@ -897,45 +893,6 @@ public class UtilTest { ...@@ -897,45 +893,6 @@ public class UtilTest {
} }
@Test @Test
public void truncateAscii_shortInput_returnsInput() {
String input = "a short string";
assertThat(Util.truncateAscii(input, 100)).isSameInstanceAs(input);
}
@Test
public void truncateAscii_longInput_truncated() {
String input = "a much longer string";
assertThat(Util.truncateAscii(input, 5).toString()).isEqualTo("a muc");
}
@Test
public void truncateAscii_preservesStylingSpans() {
SpannableString input = new SpannableString("a short string");
input.setSpan(new UnderlineSpan(), 0, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
input.setSpan(new StrikethroughSpan(), 4, 10, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
CharSequence result = Util.truncateAscii(input, 7);
assertThat(result).isInstanceOf(SpannableString.class);
assertThat(result.toString()).isEqualTo("a short");
// TODO(internal b/161804035): Use SpannedSubject when it's available in a dependency we can use
// from here.
Spanned spannedResult = (Spanned) result;
Object[] spans = spannedResult.getSpans(0, result.length(), Object.class);
assertThat(spans).hasLength(2);
assertThat(spans[0]).isInstanceOf(UnderlineSpan.class);
assertThat(spannedResult.getSpanStart(spans[0])).isEqualTo(0);
assertThat(spannedResult.getSpanEnd(spans[0])).isEqualTo(7);
assertThat(spannedResult.getSpanFlags(spans[0])).isEqualTo(Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
assertThat(spans[1]).isInstanceOf(StrikethroughSpan.class);
assertThat(spannedResult.getSpanStart(spans[1])).isEqualTo(4);
assertThat(spannedResult.getSpanEnd(spans[1])).isEqualTo(7);
assertThat(spannedResult.getSpanFlags(spans[1])).isEqualTo(Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
@Test
public void toHexString_returnsHexString() { public void toHexString_returnsHexString() {
byte[] bytes = createByteArray(0x12, 0xFC, 0x06); byte[] bytes = createByteArray(0x12, 0xFC, 0x06);
......
...@@ -39,7 +39,6 @@ import com.google.android.exoplayer2.util.Assertions; ...@@ -39,7 +39,6 @@ import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
...@@ -955,8 +954,7 @@ public final class Cea608Decoder extends CeaDecoder { ...@@ -955,8 +954,7 @@ public final class Cea608Decoder extends CeaDecoder {
} }
public void append(char text) { public void append(char text) {
// Don't accept more than 32 chars. We'll trim further, considering indent & tabOffset, in // Don't accept more than 32 chars.
// build().
if (captionStringBuilder.length() < SCREEN_CHARWIDTH) { if (captionStringBuilder.length() < SCREEN_CHARWIDTH) {
captionStringBuilder.append(text); captionStringBuilder.append(text);
} }
...@@ -974,17 +972,14 @@ public final class Cea608Decoder extends CeaDecoder { ...@@ -974,17 +972,14 @@ public final class Cea608Decoder extends CeaDecoder {
@Nullable @Nullable
public Cue build(@Cue.AnchorType int forcedPositionAnchor) { public Cue build(@Cue.AnchorType int forcedPositionAnchor) {
// The number of empty columns before the start of the text, in the range [0-31].
int startPadding = indent + tabOffset;
int maxTextLength = SCREEN_CHARWIDTH - startPadding;
SpannableStringBuilder cueString = new SpannableStringBuilder(); SpannableStringBuilder cueString = new SpannableStringBuilder();
// Add any rolled up captions, separated by new lines. // Add any rolled up captions, separated by new lines.
for (int i = 0; i < rolledUpCaptions.size(); i++) { for (int i = 0; i < rolledUpCaptions.size(); i++) {
cueString.append(Util.truncateAscii(rolledUpCaptions.get(i), maxTextLength)); cueString.append(rolledUpCaptions.get(i));
cueString.append('\n'); cueString.append('\n');
} }
// Add the current line. // Add the current line.
cueString.append(Util.truncateAscii(buildCurrentLine(), maxTextLength)); cueString.append(buildCurrentLine());
if (cueString.length() == 0) { if (cueString.length() == 0) {
// The cue is empty. // The cue is empty.
...@@ -992,6 +987,8 @@ public final class Cea608Decoder extends CeaDecoder { ...@@ -992,6 +987,8 @@ public final class Cea608Decoder extends CeaDecoder {
} }
int positionAnchor; int positionAnchor;
// The number of empty columns before the start of the text, in the range [0-31].
int startPadding = indent + tabOffset;
// The number of empty columns after the end of the text, in the same range. // The number of empty columns after the end of the text, in the same range.
int endPadding = SCREEN_CHARWIDTH - startPadding - cueString.length(); int endPadding = SCREEN_CHARWIDTH - startPadding - cueString.length();
int startEndPaddingDelta = startPadding - endPadding; int startEndPaddingDelta = startPadding - endPadding;
......
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