mirror of
https://github.com/samsonjs/media.git
synced 2026-04-11 12:15:47 +00:00
Clear existing Spans when applying CSS styles in WebvttCueParser
Relying on the precedence of spans seems risky - I can't find it defined anywhere. It might have changed in Android 6.0? https://stackoverflow.com/q/34631851 PiperOrigin-RevId: 287989365
This commit is contained in:
parent
f76b4fe63e
commit
1c0e69789f
2 changed files with 31 additions and 17 deletions
|
|
@ -492,8 +492,7 @@ public final class WebvttCueParser {
|
|||
return;
|
||||
}
|
||||
if (style.getStyle() != WebvttCssStyle.UNSPECIFIED) {
|
||||
spannedText.setSpan(new StyleSpan(style.getStyle()), start, end,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
addOrReplaceSpan(spannedText, new StyleSpan(style.getStyle()), start, end);
|
||||
}
|
||||
if (style.isLinethrough()) {
|
||||
spannedText.setSpan(new StrikethroughSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
|
@ -502,34 +501,29 @@ public final class WebvttCueParser {
|
|||
spannedText.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
if (style.hasFontColor()) {
|
||||
spannedText.setSpan(new ForegroundColorSpan(style.getFontColor()), start, end,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
addOrReplaceSpan(spannedText, new ForegroundColorSpan(style.getFontColor()), start, end);
|
||||
}
|
||||
if (style.hasBackgroundColor()) {
|
||||
spannedText.setSpan(new BackgroundColorSpan(style.getBackgroundColor()), start, end,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
addOrReplaceSpan(
|
||||
spannedText, new BackgroundColorSpan(style.getBackgroundColor()), start, end);
|
||||
}
|
||||
if (style.getFontFamily() != null) {
|
||||
spannedText.setSpan(new TypefaceSpan(style.getFontFamily()), start, end,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
addOrReplaceSpan(spannedText, new TypefaceSpan(style.getFontFamily()), start, end);
|
||||
}
|
||||
Layout.Alignment textAlign = style.getTextAlign();
|
||||
if (textAlign != null) {
|
||||
spannedText.setSpan(
|
||||
new AlignmentSpan.Standard(textAlign), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
addOrReplaceSpan(spannedText, new AlignmentSpan.Standard(textAlign), start, end);
|
||||
}
|
||||
switch (style.getFontSizeUnit()) {
|
||||
case WebvttCssStyle.FONT_SIZE_UNIT_PIXEL:
|
||||
spannedText.setSpan(new AbsoluteSizeSpan((int) style.getFontSize(), true), start, end,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
addOrReplaceSpan(
|
||||
spannedText, new AbsoluteSizeSpan((int) style.getFontSize(), true), start, end);
|
||||
break;
|
||||
case WebvttCssStyle.FONT_SIZE_UNIT_EM:
|
||||
spannedText.setSpan(new RelativeSizeSpan(style.getFontSize()), start, end,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
addOrReplaceSpan(spannedText, new RelativeSizeSpan(style.getFontSize()), start, end);
|
||||
break;
|
||||
case WebvttCssStyle.FONT_SIZE_UNIT_PERCENT:
|
||||
spannedText.setSpan(new RelativeSizeSpan(style.getFontSize() / 100), start, end,
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
addOrReplaceSpan(spannedText, new RelativeSizeSpan(style.getFontSize() / 100), start, end);
|
||||
break;
|
||||
case WebvttCssStyle.UNSPECIFIED:
|
||||
// Do nothing.
|
||||
|
|
@ -537,6 +531,26 @@ public final class WebvttCueParser {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds {@code span} to {@code spannedText} between {@code start} and {@code end}, removing any
|
||||
* existing spans of the same type and with the same indices.
|
||||
*
|
||||
* <p>This is useful for types of spans that don't make sense to duplicate and where the
|
||||
* evaluation order might have an unexpected impact on the final text, e.g. {@link
|
||||
* ForegroundColorSpan}.
|
||||
*/
|
||||
private static void addOrReplaceSpan(
|
||||
SpannableStringBuilder spannedText, Object span, int start, int end) {
|
||||
Object[] existingSpans = spannedText.getSpans(start, end, span.getClass());
|
||||
for (Object existingSpan : existingSpans) {
|
||||
if (spannedText.getSpanStart(existingSpan) == start
|
||||
&& spannedText.getSpanEnd(existingSpan) == end) {
|
||||
spannedText.removeSpan(existingSpan);
|
||||
}
|
||||
}
|
||||
spannedText.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag name for the given tag contents.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ public class WebvttDecoderTest {
|
|||
Spanned s4 = getUniqueSpanTextAt(subtitle, /* timeUs= */ 25000000);
|
||||
assertThat(s1.getSpans(/* start= */ 0, s1.length(), ForegroundColorSpan.class)).hasLength(1);
|
||||
assertThat(s1.getSpans(/* start= */ 0, s1.length(), BackgroundColorSpan.class)).hasLength(1);
|
||||
assertThat(s2.getSpans(/* start= */ 0, s2.length(), ForegroundColorSpan.class)).hasLength(2);
|
||||
assertThat(s2.getSpans(/* start= */ 0, s2.length(), ForegroundColorSpan.class)).hasLength(1);
|
||||
assertThat(s3.getSpans(/* start= */ 10, s3.length(), UnderlineSpan.class)).hasLength(1);
|
||||
assertThat(s4.getSpans(/* start= */ 0, /* end= */ 16, BackgroundColorSpan.class)).hasLength(2);
|
||||
assertThat(s4.getSpans(/* start= */ 17, s4.length(), StyleSpan.class)).hasLength(1);
|
||||
|
|
|
|||
Loading…
Reference in a new issue