TTML: Fix writingDirection to be parsed from regions not styles

It applies only to regions:
https://www.w3.org/TR/2018/REC-ttml2-20181108/#style-attribute-writingMode

PiperOrigin-RevId: 319515547
This commit is contained in:
ibaker 2020-07-03 15:16:58 +01:00 committed by Ian Baker
parent f39b1d0f90
commit 391f9b923e
6 changed files with 44 additions and 53 deletions

View File

@ -444,6 +444,26 @@ public final class TtmlDecoder extends SimpleSubtitleDecoder {
} }
float regionTextHeight = 1.0f / cellResolution.rows; float regionTextHeight = 1.0f / cellResolution.rows;
@Cue.VerticalType int verticalType = Cue.TYPE_UNSET;
@Nullable
String writingDirection =
XmlPullParserUtil.getAttributeValue(xmlParser, TtmlNode.ATTR_TTS_WRITING_MODE);
if (writingDirection != null) {
switch (Util.toLowerInvariant(writingDirection)) {
// TODO: Support horizontal RTL modes.
case TtmlNode.VERTICAL:
case TtmlNode.VERTICAL_LR:
verticalType = Cue.VERTICAL_TYPE_LR;
break;
case TtmlNode.VERTICAL_RL:
verticalType = Cue.VERTICAL_TYPE_RL;
break;
default:
// ignore
break;
}
}
return new TtmlRegion( return new TtmlRegion(
regionId, regionId,
position, position,
@ -453,7 +473,8 @@ public final class TtmlDecoder extends SimpleSubtitleDecoder {
width, width,
height, height,
/* textSizeType= */ Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING, /* textSizeType= */ Cue.TEXT_SIZE_TYPE_FRACTIONAL_IGNORE_PADDING,
/* textSize= */ regionTextHeight); /* textSize= */ regionTextHeight,
verticalType);
} }
private static String[] parseStyleIds(String parentStyleIds) { private static String[] parseStyleIds(String parentStyleIds) {
@ -588,21 +609,6 @@ public final class TtmlDecoder extends SimpleSubtitleDecoder {
break; break;
} }
break; break;
case TtmlNode.ATTR_TTS_WRITING_MODE:
switch (Util.toLowerInvariant(attributeValue)) {
// TODO: Support horizontal RTL modes.
case TtmlNode.VERTICAL:
case TtmlNode.VERTICAL_LR:
style = createIfNull(style).setVerticalType(Cue.VERTICAL_TYPE_LR);
break;
case TtmlNode.VERTICAL_RL:
style = createIfNull(style).setVerticalType(Cue.VERTICAL_TYPE_RL);
break;
default:
// ignore
break;
}
break;
default: default:
// ignore // ignore
break; break;

View File

@ -268,6 +268,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
.setLineAnchor(region.lineAnchor) .setLineAnchor(region.lineAnchor)
.setSize(region.width) .setSize(region.width)
.setBitmapHeight(region.height) .setBitmapHeight(region.height)
.setVerticalType(region.verticalType)
.build()); .build());
} }
@ -281,6 +282,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
regionOutput.setPosition(region.position); regionOutput.setPosition(region.position);
regionOutput.setSize(region.width); regionOutput.setSize(region.width);
regionOutput.setTextSize(region.textSize, region.textSizeType); regionOutput.setTextSize(region.textSize, region.textSizeType);
regionOutput.setVerticalType(region.verticalType);
cues.add(regionOutput.build()); cues.add(regionOutput.build());
} }
@ -380,9 +382,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
if (resolvedStyle != null) { if (resolvedStyle != null) {
TtmlRenderUtil.applyStylesToSpan(text, start, end, resolvedStyle, parent, globalStyles); TtmlRenderUtil.applyStylesToSpan(text, start, end, resolvedStyle, parent, globalStyles);
regionOutput regionOutput.setTextAlignment(resolvedStyle.getTextAlign());
.setTextAlignment(resolvedStyle.getTextAlign())
.setVerticalType(resolvedStyle.getVerticalType());
} }
} }

View File

@ -25,12 +25,13 @@ import com.google.android.exoplayer2.text.Cue;
public final String id; public final String id;
public final float position; public final float position;
public final float line; public final float line;
public final @Cue.LineType int lineType; @Cue.LineType public final int lineType;
public final @Cue.AnchorType int lineAnchor; @Cue.AnchorType public final int lineAnchor;
public final float width; public final float width;
public final float height; public final float height;
public final @Cue.TextSizeType int textSizeType; @Cue.TextSizeType public final int textSizeType;
public final float textSize; public final float textSize;
@Cue.VerticalType public final int verticalType;
public TtmlRegion(String id) { public TtmlRegion(String id) {
this( this(
@ -42,7 +43,8 @@ import com.google.android.exoplayer2.text.Cue;
/* width= */ Cue.DIMEN_UNSET, /* width= */ Cue.DIMEN_UNSET,
/* height= */ Cue.DIMEN_UNSET, /* height= */ Cue.DIMEN_UNSET,
/* textSizeType= */ Cue.TYPE_UNSET, /* textSizeType= */ Cue.TYPE_UNSET,
/* textSize= */ Cue.DIMEN_UNSET); /* textSize= */ Cue.DIMEN_UNSET,
/* verticalType= */ Cue.TYPE_UNSET);
} }
public TtmlRegion( public TtmlRegion(
@ -54,7 +56,8 @@ import com.google.android.exoplayer2.text.Cue;
float width, float width,
float height, float height,
int textSizeType, int textSizeType,
float textSize) { float textSize,
@Cue.VerticalType int verticalType) {
this.id = id; this.id = id;
this.position = position; this.position = position;
this.line = line; this.line = line;
@ -64,6 +67,7 @@ import com.google.android.exoplayer2.text.Cue;
this.height = height; this.height = height;
this.textSizeType = textSizeType; this.textSizeType = textSizeType;
this.textSize = textSize; this.textSize = textSize;
this.verticalType = verticalType;
} }
} }

View File

@ -19,8 +19,6 @@ import android.graphics.Typeface;
import android.text.Layout; import android.text.Layout;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.Cue.VerticalType;
import com.google.android.exoplayer2.text.span.RubySpan; import com.google.android.exoplayer2.text.span.RubySpan;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@ -88,7 +86,6 @@ import java.lang.annotation.RetentionPolicy;
@RubySpan.Position private int rubyPosition; @RubySpan.Position private int rubyPosition;
@Nullable private Layout.Alignment textAlign; @Nullable private Layout.Alignment textAlign;
@OptionalBoolean private int textCombine; @OptionalBoolean private int textCombine;
@Cue.VerticalType private int verticalType;
public TtmlStyle() { public TtmlStyle() {
linethrough = UNSPECIFIED; linethrough = UNSPECIFIED;
@ -99,7 +96,6 @@ import java.lang.annotation.RetentionPolicy;
rubyType = UNSPECIFIED; rubyType = UNSPECIFIED;
rubyPosition = RubySpan.POSITION_UNKNOWN; rubyPosition = RubySpan.POSITION_UNKNOWN;
textCombine = UNSPECIFIED; textCombine = UNSPECIFIED;
verticalType = Cue.TYPE_UNSET;
} }
/** /**
@ -249,9 +245,6 @@ import java.lang.annotation.RetentionPolicy;
if (chaining && rubyType == UNSPECIFIED && ancestor.rubyType != UNSPECIFIED) { if (chaining && rubyType == UNSPECIFIED && ancestor.rubyType != UNSPECIFIED) {
rubyType = ancestor.rubyType; rubyType = ancestor.rubyType;
} }
if (chaining && verticalType == Cue.TYPE_UNSET && ancestor.verticalType != Cue.TYPE_UNSET) {
setVerticalType(ancestor.verticalType);
}
} }
return this; return this;
} }
@ -323,14 +316,4 @@ import java.lang.annotation.RetentionPolicy;
public float getFontSize() { public float getFontSize() {
return fontSize; return fontSize;
} }
public TtmlStyle setVerticalType(@VerticalType int verticalType) {
this.verticalType = verticalType;
return this;
}
@VerticalType
public int getVerticalType() {
return verticalType;
}
} }

View File

@ -28,7 +28,6 @@ import android.graphics.Color;
import android.text.Layout; import android.text.Layout;
import androidx.annotation.ColorInt; import androidx.annotation.ColorInt;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.span.RubySpan; import com.google.android.exoplayer2.text.span.RubySpan;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -47,7 +46,6 @@ public final class TtmlStyleTest {
private static final int RUBY_POSITION = RubySpan.POSITION_UNDER; private static final int RUBY_POSITION = RubySpan.POSITION_UNDER;
private static final Layout.Alignment TEXT_ALIGN = Layout.Alignment.ALIGN_CENTER; private static final Layout.Alignment TEXT_ALIGN = Layout.Alignment.ALIGN_CENTER;
private static final boolean TEXT_COMBINE = true; private static final boolean TEXT_COMBINE = true;
@Cue.VerticalType private static final int VERTICAL_TYPE = Cue.VERTICAL_TYPE_RL;
private final TtmlStyle populatedStyle = private final TtmlStyle populatedStyle =
new TtmlStyle() new TtmlStyle()
@ -64,8 +62,7 @@ public final class TtmlStyleTest {
.setRubyType(RUBY_TYPE) .setRubyType(RUBY_TYPE)
.setRubyPosition(RUBY_POSITION) .setRubyPosition(RUBY_POSITION)
.setTextAlign(TEXT_ALIGN) .setTextAlign(TEXT_ALIGN)
.setTextCombine(TEXT_COMBINE) .setTextCombine(TEXT_COMBINE);
.setVerticalType(VERTICAL_TYPE);
@Test @Test
public void inheritStyle() { public void inheritStyle() {
@ -89,9 +86,6 @@ public final class TtmlStyleTest {
assertWithMessage("backgroundColor should not be inherited") assertWithMessage("backgroundColor should not be inherited")
.that(style.hasBackgroundColor()) .that(style.hasBackgroundColor())
.isFalse(); .isFalse();
assertWithMessage("verticalType should not be inherited")
.that(style.getVerticalType())
.isEqualTo(Cue.TYPE_UNSET);
} }
@Test @Test
@ -115,9 +109,6 @@ public final class TtmlStyleTest {
.that(style.getBackgroundColor()) .that(style.getBackgroundColor())
.isEqualTo(BACKGROUND_COLOR); .isEqualTo(BACKGROUND_COLOR);
assertWithMessage("rubyType should be chained").that(style.getRubyType()).isEqualTo(RUBY_TYPE); assertWithMessage("rubyType should be chained").that(style.getRubyType()).isEqualTo(RUBY_TYPE);
assertWithMessage("verticalType should be chained")
.that(style.getVerticalType())
.isEqualTo(VERTICAL_TYPE);
} }
@Test @Test

View File

@ -3,12 +3,19 @@
xmlns:tts="http://www.w3.org/2006/10/ttaf1#style" xmlns:tts="http://www.w3.org/2006/10/ttaf1#style"
xmlns="http://www.w3.org/ns/ttml" xmlns="http://www.w3.org/ns/ttml"
xmlns="http://www.w3.org/2006/10/ttaf1"> xmlns="http://www.w3.org/2006/10/ttaf1">
<head>
<layout>
<region id="right-to-left" tts:extent="80% 80%" tts:origin="10% 10%" tts:writingMode="tbrl" />
<region id="left-to-right" tts:extent="80% 80%" tts:origin="10% 10%" tts:writingMode="tblr" />
</layout>
</head>
<body> <body>
<div> <div>
<p begin="10s" end="18s" tts:writingMode="tbrl">Vertical right-to-left (e.g. Japanese)</p> <p begin="10s" end="18s" region="right-to-left">Vertical right-to-left (e.g. Japanese)</p>
</div> </div>
<div> <div>
<p begin="20s" end="28s" tts:writingMode="tblr">Vertical left-to-right (e.g. Mongolian)</p> <p begin="20s" end="28s" region="left-to-right">Vertical left-to-right (e.g. Mongolian)</p>
</div> </div>
<div> <div>
<p begin="30s" end="38s">Horizontal text</p> <p begin="30s" end="38s">Horizontal text</p>