mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
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:
parent
f39b1d0f90
commit
391f9b923e
@ -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;
|
||||||
|
@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
11
testdata/src/test/assets/ttml/vertical_text.xml
vendored
11
testdata/src/test/assets/ttml/vertical_text.xml
vendored
@ -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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user