Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
4be774aa
authored
Mar 24, 2021
by
Denise LaFayette
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Support tts:shear in TTML parser and WebView output
parent
f19ab4aa
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
180 additions
and
11 deletions
library/common/src/main/java/com/google/android/exoplayer2/text/Cue.java
library/core/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlDecoder.java
library/core/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlNode.java
library/core/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlStyle.java
library/core/src/test/java/com/google/android/exoplayer2/text/CueTest.java
library/core/src/test/java/com/google/android/exoplayer2/text/ttml/TtmlDecoderTest.java
library/core/src/test/java/com/google/android/exoplayer2/text/ttml/TtmlStyleTest.java
library/ui/src/main/java/com/google/android/exoplayer2/ui/WebViewSubtitleOutput.java
testdata/src/test/assets/media/ttml/shear.xml
library/common/src/main/java/com/google/android/exoplayer2/text/Cue.java
View file @
4be774aa
...
@@ -270,6 +270,12 @@ public final class Cue {
...
@@ -270,6 +270,12 @@ public final class Cue {
public
final
@VerticalType
int
verticalType
;
public
final
@VerticalType
int
verticalType
;
/**
/**
* The shear angle in degrees expressed in graphics coordinates to be applied to this block. This
* results in a skew transform for the block along the inline progression axis.
*/
public
final
float
shearDegrees
;
/**
* Creates a text cue whose {@link #textAlignment} is null, whose type parameters are set to
* Creates a text cue whose {@link #textAlignment} is null, whose type parameters are set to
* {@link #TYPE_UNSET} and whose dimension parameters are set to {@link #DIMEN_UNSET}.
* {@link #TYPE_UNSET} and whose dimension parameters are set to {@link #DIMEN_UNSET}.
*
*
...
@@ -370,7 +376,8 @@ public final class Cue {
...
@@ -370,7 +376,8 @@ public final class Cue {
/* bitmapHeight= */
DIMEN_UNSET
,
/* bitmapHeight= */
DIMEN_UNSET
,
/* windowColorSet= */
false
,
/* windowColorSet= */
false
,
/* windowColor= */
Color
.
BLACK
,
/* windowColor= */
Color
.
BLACK
,
/* verticalType= */
TYPE_UNSET
);
/* verticalType= */
TYPE_UNSET
,
0
f
);
}
}
/**
/**
...
@@ -415,7 +422,8 @@ public final class Cue {
...
@@ -415,7 +422,8 @@ public final class Cue {
/* bitmapHeight= */
DIMEN_UNSET
,
/* bitmapHeight= */
DIMEN_UNSET
,
windowColorSet
,
windowColorSet
,
windowColor
,
windowColor
,
/* verticalType= */
TYPE_UNSET
);
/* verticalType= */
TYPE_UNSET
,
0
f
);
}
}
private
Cue
(
private
Cue
(
...
@@ -433,7 +441,8 @@ public final class Cue {
...
@@ -433,7 +441,8 @@ public final class Cue {
float
bitmapHeight
,
float
bitmapHeight
,
boolean
windowColorSet
,
boolean
windowColorSet
,
int
windowColor
,
int
windowColor
,
@VerticalType
int
verticalType
)
{
@VerticalType
int
verticalType
,
float
shearDegrees
)
{
// Exactly one of text or bitmap should be set.
// Exactly one of text or bitmap should be set.
if
(
text
==
null
)
{
if
(
text
==
null
)
{
Assertions
.
checkNotNull
(
bitmap
);
Assertions
.
checkNotNull
(
bitmap
);
...
@@ -455,6 +464,7 @@ public final class Cue {
...
@@ -455,6 +464,7 @@ public final class Cue {
this
.
textSizeType
=
textSizeType
;
this
.
textSizeType
=
textSizeType
;
this
.
textSize
=
textSize
;
this
.
textSize
=
textSize
;
this
.
verticalType
=
verticalType
;
this
.
verticalType
=
verticalType
;
this
.
shearDegrees
=
shearDegrees
;
}
}
/** Returns a new {@link Cue.Builder} initialized with the same values as this Cue. */
/** Returns a new {@link Cue.Builder} initialized with the same values as this Cue. */
...
@@ -479,6 +489,7 @@ public final class Cue {
...
@@ -479,6 +489,7 @@ public final class Cue {
private
boolean
windowColorSet
;
private
boolean
windowColorSet
;
@ColorInt
private
int
windowColor
;
@ColorInt
private
int
windowColor
;
@VerticalType
private
int
verticalType
;
@VerticalType
private
int
verticalType
;
private
float
shearDegrees
;
public
Builder
()
{
public
Builder
()
{
text
=
null
;
text
=
null
;
...
@@ -514,6 +525,7 @@ public final class Cue {
...
@@ -514,6 +525,7 @@ public final class Cue {
windowColorSet
=
cue
.
windowColorSet
;
windowColorSet
=
cue
.
windowColorSet
;
windowColor
=
cue
.
windowColor
;
windowColor
=
cue
.
windowColor
;
verticalType
=
cue
.
verticalType
;
verticalType
=
cue
.
verticalType
;
shearDegrees
=
cue
.
shearDegrees
;
}
}
/**
/**
...
@@ -795,6 +807,14 @@ public final class Cue {
...
@@ -795,6 +807,14 @@ public final class Cue {
}
}
/**
/**
* Sets the shear angle for this Cue
*/
public
Builder
setShearDegrees
(
float
shearDegrees
)
{
this
.
shearDegrees
=
shearDegrees
;
return
this
;
}
/**
* Gets the vertical formatting for this Cue.
* Gets the vertical formatting for this Cue.
*
*
* @see Cue#verticalType
* @see Cue#verticalType
...
@@ -821,7 +841,8 @@ public final class Cue {
...
@@ -821,7 +841,8 @@ public final class Cue {
bitmapHeight
,
bitmapHeight
,
windowColorSet
,
windowColorSet
,
windowColor
,
windowColor
,
verticalType
);
verticalType
,
shearDegrees
);
}
}
}
}
}
}
library/core/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlDecoder.java
View file @
4be774aa
...
@@ -81,7 +81,9 @@ public final class TtmlDecoder extends SimpleSubtitleDecoder {
...
@@ -81,7 +81,9 @@ public final class TtmlDecoder extends SimpleSubtitleDecoder {
private
static
final
Pattern
OFFSET_TIME
=
private
static
final
Pattern
OFFSET_TIME
=
Pattern
.
compile
(
"^([0-9]+(?:\\.[0-9]+)?)(h|m|s|ms|f|t)$"
);
Pattern
.
compile
(
"^([0-9]+(?:\\.[0-9]+)?)(h|m|s|ms|f|t)$"
);
private
static
final
Pattern
FONT_SIZE
=
Pattern
.
compile
(
"^(([0-9]*.)?[0-9]+)(px|em|%)$"
);
private
static
final
Pattern
FONT_SIZE
=
Pattern
.
compile
(
"^(([0-9]*.)?[0-9]+)(px|em|%)$"
);
private
static
final
Pattern
PERCENTAGE_COORDINATES
=
static
final
Pattern
SIGNED_PERCENTAGE
=
Pattern
.
compile
(
"^([-+]?\\d+\\.?\\d*?)%$"
);
static
final
Pattern
PERCENTAGE_COORDINATES
=
Pattern
.
compile
(
"^(\\d+\\.?\\d*?)% (\\d+\\.?\\d*?)%$"
);
Pattern
.
compile
(
"^(\\d+\\.?\\d*?)% (\\d+\\.?\\d*?)%$"
);
private
static
final
Pattern
PIXEL_COORDINATES
=
private
static
final
Pattern
PIXEL_COORDINATES
=
Pattern
.
compile
(
"^(\\d+\\.?\\d*?)px (\\d+\\.?\\d*?)px$"
);
Pattern
.
compile
(
"^(\\d+\\.?\\d*?)px (\\d+\\.?\\d*?)px$"
);
...
@@ -613,6 +615,13 @@ public final class TtmlDecoder extends SimpleSubtitleDecoder {
...
@@ -613,6 +615,13 @@ public final class TtmlDecoder extends SimpleSubtitleDecoder {
style
=
style
=
createIfNull
(
style
)
createIfNull
(
style
)
.
setTextEmphasis
(
TextEmphasis
.
parse
(
Util
.
toLowerInvariant
(
attributeValue
)));
.
setTextEmphasis
(
TextEmphasis
.
parse
(
Util
.
toLowerInvariant
(
attributeValue
)));
case
TtmlNode
.
ATTR_TTS_SHEAR
:
style
=
createIfNull
(
style
);
try
{
parseShear
(
attributeValue
,
style
);
}
catch
(
SubtitleDecoderException
e
)
{
Log
.
w
(
TAG
,
"Failed parsing shear value: "
+
attributeValue
);
}
break
;
break
;
default
:
default
:
// ignore
// ignore
...
@@ -755,6 +764,27 @@ public final class TtmlDecoder extends SimpleSubtitleDecoder {
...
@@ -755,6 +764,27 @@ public final class TtmlDecoder extends SimpleSubtitleDecoder {
}
}
}
}
private
static
void
parseShear
(
String
expression
,
TtmlStyle
out
)
throws
SubtitleDecoderException
{
Matcher
matcher
=
SIGNED_PERCENTAGE
.
matcher
(
expression
);
if
(
matcher
.
matches
())
{
try
{
float
value
=
Float
.
parseFloat
(
matcher
.
group
(
1
));
// https://www.w3.org/TR/2018/REC-ttml2-20181108/#semantics-style-procedures-shear
// If the absolute value of the specified percentage is greater than 100%, then it must be
// interpreted as if 100% were specified with the appropriate sign.
value
=
Math
.
max
(-
100
f
,
value
);
value
=
Math
.
min
(
100
f
,
value
);
out
.
setShearPercentage
(
value
);
}
catch
(
NumberFormatException
e
)
{
throw
new
SubtitleDecoderException
(
"Invalid expression for shear: '"
+
expression
+
"'."
,
e
);
}
}
else
{
throw
new
SubtitleDecoderException
(
"Invalid expression for shear: '"
+
expression
+
"'."
);
}
}
/**
/**
* Parses a time expression, returning the parsed timestamp.
* Parses a time expression, returning the parsed timestamp.
* <p>
* <p>
...
...
library/core/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlNode.java
View file @
4be774aa
...
@@ -71,6 +71,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
...
@@ -71,6 +71,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public
static
final
String
ATTR_TTS_TEXT_COMBINE
=
"textCombine"
;
public
static
final
String
ATTR_TTS_TEXT_COMBINE
=
"textCombine"
;
public
static
final
String
ATTR_TTS_TEXT_EMPHASIS
=
"textEmphasis"
;
public
static
final
String
ATTR_TTS_TEXT_EMPHASIS
=
"textEmphasis"
;
public
static
final
String
ATTR_TTS_WRITING_MODE
=
"writingMode"
;
public
static
final
String
ATTR_TTS_WRITING_MODE
=
"writingMode"
;
public
static
final
String
ATTR_TTS_SHEAR
=
"shear"
;
// Values for ruby
// Values for ruby
public
static
final
String
RUBY_CONTAINER
=
"container"
;
public
static
final
String
RUBY_CONTAINER
=
"container"
;
...
@@ -408,6 +409,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
...
@@ -408,6 +409,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
if
(
resolvedStyle
!=
null
)
{
if
(
resolvedStyle
!=
null
)
{
TtmlRenderUtil
.
applyStylesToSpan
(
TtmlRenderUtil
.
applyStylesToSpan
(
text
,
start
,
end
,
resolvedStyle
,
parent
,
globalStyles
,
verticalType
);
text
,
start
,
end
,
resolvedStyle
,
parent
,
globalStyles
,
verticalType
);
if
(
resolvedStyle
.
getShearPercentage
()
!=
0.0f
&&
TAG_P
.
equals
(
tag
))
{
// Shear style should only be applied to P nodes
// https://www.w3.org/TR/2018/REC-ttml2-20181108/#style-attribute-shear
// The spec doesn't specify the coordinate system to use for block shear
// however the spec shows examples of how different values are expected to be rendered.
// See: https://www.w3.org/TR/2018/REC-ttml2-20181108/#style-attribute-shear
// https://www.w3.org/TR/2018/REC-ttml2-20181108/#style-attribute-fontShear
// This maps the shear percentage to shear angle in graphics coordinates
regionOutput
.
setShearDegrees
(
resolvedStyle
.
getShearPercentage
()
*
-
90
/
100
);
}
regionOutput
.
setTextAlignment
(
resolvedStyle
.
getTextAlign
());
regionOutput
.
setTextAlignment
(
resolvedStyle
.
getTextAlign
());
}
}
}
}
...
...
library/core/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlStyle.java
View file @
4be774aa
...
@@ -87,6 +87,8 @@ import java.lang.annotation.RetentionPolicy;
...
@@ -87,6 +87,8 @@ import java.lang.annotation.RetentionPolicy;
@Nullable
private
Layout
.
Alignment
textAlign
;
@Nullable
private
Layout
.
Alignment
textAlign
;
@OptionalBoolean
private
int
textCombine
;
@OptionalBoolean
private
int
textCombine
;
@Nullable
private
TextEmphasis
textEmphasis
;
@Nullable
private
TextEmphasis
textEmphasis
;
private
float
shearPercentage
;
public
TtmlStyle
()
{
public
TtmlStyle
()
{
linethrough
=
UNSPECIFIED
;
linethrough
=
UNSPECIFIED
;
...
@@ -185,6 +187,15 @@ import java.lang.annotation.RetentionPolicy;
...
@@ -185,6 +187,15 @@ import java.lang.annotation.RetentionPolicy;
return
hasBackgroundColor
;
return
hasBackgroundColor
;
}
}
public
TtmlStyle
setShearPercentage
(
Float
shearPercentage
)
{
this
.
shearPercentage
=
shearPercentage
;
return
this
;
}
public
float
getShearPercentage
()
{
return
shearPercentage
;
}
/**
/**
* Chains this style to referential style. Local properties which are already set are never
* Chains this style to referential style. Local properties which are already set are never
* overridden.
* overridden.
...
@@ -242,6 +253,9 @@ import java.lang.annotation.RetentionPolicy;
...
@@ -242,6 +253,9 @@ import java.lang.annotation.RetentionPolicy;
if
(
textEmphasis
==
null
)
{
if
(
textEmphasis
==
null
)
{
textEmphasis
=
ancestor
.
textEmphasis
;
textEmphasis
=
ancestor
.
textEmphasis
;
}
}
if
(
shearPercentage
==
0.0f
)
{
shearPercentage
=
ancestor
.
shearPercentage
;
}
// attributes not inherited as of http://www.w3.org/TR/ttml1/
// attributes not inherited as of http://www.w3.org/TR/ttml1/
if
(
chaining
&&
!
hasBackgroundColor
&&
ancestor
.
hasBackgroundColor
)
{
if
(
chaining
&&
!
hasBackgroundColor
&&
ancestor
.
hasBackgroundColor
)
{
setBackgroundColor
(
ancestor
.
backgroundColor
);
setBackgroundColor
(
ancestor
.
backgroundColor
);
...
...
library/core/src/test/java/com/google/android/exoplayer2/text/CueTest.java
View file @
4be774aa
...
@@ -45,6 +45,7 @@ public class CueTest {
...
@@ -45,6 +45,7 @@ public class CueTest {
.
setSize
(
0.8f
)
.
setSize
(
0.8f
)
.
setWindowColor
(
Color
.
CYAN
)
.
setWindowColor
(
Color
.
CYAN
)
.
setVerticalType
(
Cue
.
VERTICAL_TYPE_RL
)
.
setVerticalType
(
Cue
.
VERTICAL_TYPE_RL
)
.
setShearDegrees
(-
15
f
)
.
build
();
.
build
();
Cue
modifiedCue
=
cue
.
buildUpon
().
build
();
Cue
modifiedCue
=
cue
.
buildUpon
().
build
();
...
@@ -61,6 +62,7 @@ public class CueTest {
...
@@ -61,6 +62,7 @@ public class CueTest {
assertThat
(
cue
.
windowColor
).
isEqualTo
(
Color
.
CYAN
);
assertThat
(
cue
.
windowColor
).
isEqualTo
(
Color
.
CYAN
);
assertThat
(
cue
.
windowColorSet
).
isTrue
();
assertThat
(
cue
.
windowColorSet
).
isTrue
();
assertThat
(
cue
.
verticalType
).
isEqualTo
(
Cue
.
VERTICAL_TYPE_RL
);
assertThat
(
cue
.
verticalType
).
isEqualTo
(
Cue
.
VERTICAL_TYPE_RL
);
assertThat
(
cue
.
shearDegrees
).
isEqualTo
(-
15
f
);
assertThat
(
modifiedCue
.
text
).
isSameInstanceAs
(
cue
.
text
);
assertThat
(
modifiedCue
.
text
).
isSameInstanceAs
(
cue
.
text
);
assertThat
(
modifiedCue
.
textAlignment
).
isEqualTo
(
cue
.
textAlignment
);
assertThat
(
modifiedCue
.
textAlignment
).
isEqualTo
(
cue
.
textAlignment
);
...
@@ -74,6 +76,7 @@ public class CueTest {
...
@@ -74,6 +76,7 @@ public class CueTest {
assertThat
(
modifiedCue
.
windowColor
).
isEqualTo
(
cue
.
windowColor
);
assertThat
(
modifiedCue
.
windowColor
).
isEqualTo
(
cue
.
windowColor
);
assertThat
(
modifiedCue
.
windowColorSet
).
isEqualTo
(
cue
.
windowColorSet
);
assertThat
(
modifiedCue
.
windowColorSet
).
isEqualTo
(
cue
.
windowColorSet
);
assertThat
(
modifiedCue
.
verticalType
).
isEqualTo
(
cue
.
verticalType
);
assertThat
(
modifiedCue
.
verticalType
).
isEqualTo
(
cue
.
verticalType
);
assertThat
(
modifiedCue
.
shearDegrees
).
isEqualTo
(
cue
.
shearDegrees
);
}
}
@Test
@Test
...
...
library/core/src/test/java/com/google/android/exoplayer2/text/ttml/TtmlDecoderTest.java
View file @
4be774aa
...
@@ -69,6 +69,7 @@ public final class TtmlDecoderTest {
...
@@ -69,6 +69,7 @@ public final class TtmlDecoderTest {
private
static
final
String
TEXT_COMBINE_FILE
=
"media/ttml/text_combine.xml"
;
private
static
final
String
TEXT_COMBINE_FILE
=
"media/ttml/text_combine.xml"
;
private
static
final
String
RUBIES_FILE
=
"media/ttml/rubies.xml"
;
private
static
final
String
RUBIES_FILE
=
"media/ttml/rubies.xml"
;
private
static
final
String
TEXT_EMPHASIS_FILE
=
"media/ttml/text_emphasis.xml"
;
private
static
final
String
TEXT_EMPHASIS_FILE
=
"media/ttml/text_emphasis.xml"
;
private
static
final
String
SHEAR_FILE
=
"media/ttml/shear.xml"
;
@Test
@Test
public
void
inlineAttributes
()
throws
IOException
,
SubtitleDecoderException
{
public
void
inlineAttributes
()
throws
IOException
,
SubtitleDecoderException
{
...
@@ -816,6 +817,37 @@ public final class TtmlDecoderTest {
...
@@ -816,6 +817,37 @@ public final class TtmlDecoderTest {
TextAnnotation
.
POSITION_BEFORE
);
TextAnnotation
.
POSITION_BEFORE
);
}
}
@Test
public
void
shear
()
throws
IOException
,
SubtitleDecoderException
{
TtmlSubtitle
subtitle
=
getSubtitle
(
SHEAR_FILE
);
final
float
TOLERANCE
=
0.01f
;
Cue
firstCue
=
getOnlyCueAtTimeUs
(
subtitle
,
10_000_000
);
assertThat
(
firstCue
.
shearDegrees
).
isEqualTo
(
0
f
);
Cue
secondCue
=
getOnlyCueAtTimeUs
(
subtitle
,
20_000_000
);
assertThat
(
secondCue
.
shearDegrees
).
isWithin
(
TOLERANCE
).
of
(-
15
f
);
Cue
thirdCue
=
getOnlyCueAtTimeUs
(
subtitle
,
30_000_000
);
assertThat
(
thirdCue
.
shearDegrees
).
isWithin
(
TOLERANCE
).
of
(
15
f
);
Cue
fourthCue
=
getOnlyCueAtTimeUs
(
subtitle
,
40_000_000
);
assertThat
(
fourthCue
.
shearDegrees
).
isWithin
(
TOLERANCE
).
of
(-
15
f
);
Cue
fifthCue
=
getOnlyCueAtTimeUs
(
subtitle
,
50_000_000
);
assertThat
(
fifthCue
.
shearDegrees
).
isWithin
(
TOLERANCE
).
of
(-
22.5f
);
Cue
sixthCue
=
getOnlyCueAtTimeUs
(
subtitle
,
60_000_000
);
assertThat
(
sixthCue
.
shearDegrees
).
isWithin
(
TOLERANCE
).
of
(
0
f
);
Cue
seventhCue
=
getOnlyCueAtTimeUs
(
subtitle
,
70_000_000
);
assertThat
(
seventhCue
.
shearDegrees
).
isWithin
(
TOLERANCE
).
of
(-
90
f
);
Cue
eighthCue
=
getOnlyCueAtTimeUs
(
subtitle
,
80_000_000
);
assertThat
(
eighthCue
.
shearDegrees
).
isWithin
(
TOLERANCE
).
of
(
90
f
);
}
private
static
Spanned
getOnlyCueTextAtTimeUs
(
Subtitle
subtitle
,
long
timeUs
)
{
private
static
Spanned
getOnlyCueTextAtTimeUs
(
Subtitle
subtitle
,
long
timeUs
)
{
Cue
cue
=
getOnlyCueAtTimeUs
(
subtitle
,
timeUs
);
Cue
cue
=
getOnlyCueAtTimeUs
(
subtitle
,
timeUs
);
assertThat
(
cue
.
text
).
isInstanceOf
(
Spanned
.
class
);
assertThat
(
cue
.
text
).
isInstanceOf
(
Spanned
.
class
);
...
...
library/core/src/test/java/com/google/android/exoplayer2/text/ttml/TtmlStyleTest.java
View file @
4be774aa
...
@@ -49,6 +49,7 @@ public final class TtmlStyleTest {
...
@@ -49,6 +49,7 @@ public final class TtmlStyleTest {
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
;
public
static
final
String
TEXT_EMPHASIS_STYLE
=
"dot before"
;
public
static
final
String
TEXT_EMPHASIS_STYLE
=
"dot before"
;
public
static
final
float
SHEAR_PERCENTAGE
=
16
f
;
private
final
TtmlStyle
populatedStyle
=
private
final
TtmlStyle
populatedStyle
=
new
TtmlStyle
()
new
TtmlStyle
()
...
@@ -66,7 +67,8 @@ public final class TtmlStyleTest {
...
@@ -66,7 +67,8 @@ public final class TtmlStyleTest {
.
setRubyPosition
(
RUBY_POSITION
)
.
setRubyPosition
(
RUBY_POSITION
)
.
setTextAlign
(
TEXT_ALIGN
)
.
setTextAlign
(
TEXT_ALIGN
)
.
setTextCombine
(
TEXT_COMBINE
)
.
setTextCombine
(
TEXT_COMBINE
)
.
setTextEmphasis
(
TextEmphasis
.
parse
(
TEXT_EMPHASIS_STYLE
));
.
setTextEmphasis
(
TextEmphasis
.
parse
(
TEXT_EMPHASIS_STYLE
))
.
setShearPercentage
(
SHEAR_PERCENTAGE
);
@Test
@Test
public
void
inheritStyle
()
{
public
void
inheritStyle
()
{
...
@@ -94,6 +96,7 @@ public final class TtmlStyleTest {
...
@@ -94,6 +96,7 @@ public final class TtmlStyleTest {
assertThat
(
style
.
getTextEmphasis
().
markShape
).
isEqualTo
(
TextEmphasisSpan
.
MARK_SHAPE_DOT
);
assertThat
(
style
.
getTextEmphasis
().
markShape
).
isEqualTo
(
TextEmphasisSpan
.
MARK_SHAPE_DOT
);
assertThat
(
style
.
getTextEmphasis
().
markFill
).
isEqualTo
(
TextEmphasisSpan
.
MARK_FILL_FILLED
);
assertThat
(
style
.
getTextEmphasis
().
markFill
).
isEqualTo
(
TextEmphasisSpan
.
MARK_FILL_FILLED
);
assertThat
(
style
.
getTextEmphasis
().
position
).
isEqualTo
(
POSITION_BEFORE
);
assertThat
(
style
.
getTextEmphasis
().
position
).
isEqualTo
(
POSITION_BEFORE
);
assertWithMessage
(
"shear"
).
that
(
style
.
getShearPercentage
()).
isEqualTo
(
SHEAR_PERCENTAGE
);
}
}
@Test
@Test
...
@@ -121,6 +124,7 @@ public final class TtmlStyleTest {
...
@@ -121,6 +124,7 @@ public final class TtmlStyleTest {
assertThat
(
style
.
getTextEmphasis
().
markShape
).
isEqualTo
(
TextEmphasisSpan
.
MARK_SHAPE_DOT
);
assertThat
(
style
.
getTextEmphasis
().
markShape
).
isEqualTo
(
TextEmphasisSpan
.
MARK_SHAPE_DOT
);
assertThat
(
style
.
getTextEmphasis
().
markFill
).
isEqualTo
(
TextEmphasisSpan
.
MARK_FILL_FILLED
);
assertThat
(
style
.
getTextEmphasis
().
markFill
).
isEqualTo
(
TextEmphasisSpan
.
MARK_FILL_FILLED
);
assertThat
(
style
.
getTextEmphasis
().
position
).
isEqualTo
(
POSITION_BEFORE
);
assertThat
(
style
.
getTextEmphasis
().
position
).
isEqualTo
(
POSITION_BEFORE
);
assertWithMessage
(
"shear"
).
that
(
style
.
getShearPercentage
()).
isEqualTo
(
SHEAR_PERCENTAGE
);
}
}
@Test
@Test
...
@@ -267,4 +271,15 @@ public final class TtmlStyleTest {
...
@@ -267,4 +271,15 @@ public final class TtmlStyleTest {
assertThat
(
style
.
getTextEmphasis
().
markFill
).
isEqualTo
(
TextEmphasisSpan
.
MARK_FILL_OPEN
);
assertThat
(
style
.
getTextEmphasis
().
markFill
).
isEqualTo
(
TextEmphasisSpan
.
MARK_FILL_OPEN
);
assertThat
(
style
.
getTextEmphasis
().
position
).
isEqualTo
(
TextAnnotation
.
POSITION_AFTER
);
assertThat
(
style
.
getTextEmphasis
().
position
).
isEqualTo
(
TextAnnotation
.
POSITION_AFTER
);
}
}
public
void
shear
()
{
TtmlStyle
style
=
new
TtmlStyle
();
assertThat
(
style
.
getShearPercentage
()).
isEqualTo
(
0
f
);
style
.
setShearPercentage
(
101
f
);
assertThat
(
style
.
getShearPercentage
()).
isEqualTo
(
101
f
);
style
.
setShearPercentage
(-
200
f
);
assertThat
(
style
.
getShearPercentage
()).
isEqualTo
(-
200
f
);
style
.
setShearPercentage
(
0.1f
);
assertThat
(
style
.
getShearPercentage
()).
isEqualTo
(
0.1f
);
}
}
}
library/ui/src/main/java/com/google/android/exoplayer2/ui/WebViewSubtitleOutput.java
View file @
4be774aa
...
@@ -262,9 +262,8 @@ import java.util.Map;
...
@@ -262,9 +262,8 @@ import java.util.Map;
verticalTranslatePercent
=
lineAnchorTranslatePercent
;
verticalTranslatePercent
=
lineAnchorTranslatePercent
;
}
}
SpannedToHtmlConverter
.
HtmlAndCss
htmlAndCss
=
SpannedToHtmlConverter
.
HtmlAndCss
htmlAndCss
=
SpannedToHtmlConverter
SpannedToHtmlConverter
.
convert
(
.
convert
(
cue
.
text
,
getContext
().
getResources
().
getDisplayMetrics
().
density
);
cue
.
text
,
getContext
().
getResources
().
getDisplayMetrics
().
density
);
for
(
String
cssSelector
:
cssRuleSets
.
keySet
())
{
for
(
String
cssSelector
:
cssRuleSets
.
keySet
())
{
@Nullable
@Nullable
String
previousCssDeclarationBlock
=
String
previousCssDeclarationBlock
=
...
@@ -285,7 +284,8 @@ import java.util.Map;
...
@@ -285,7 +284,8 @@ import java.util.Map;
+
"writing-mode:%s;"
+
"writing-mode:%s;"
+
"font-size:%s;"
+
"font-size:%s;"
+
"background-color:%s;"
+
"background-color:%s;"
+
"transform:translate(%s%%,%s%%);"
+
"transform:translate(%s%%,%s%%)"
+
"%s;"
+
"'>"
,
+
"'>"
,
positionProperty
,
positionProperty
,
positionPercent
,
positionPercent
,
...
@@ -298,7 +298,8 @@ import java.util.Map;
...
@@ -298,7 +298,8 @@ import java.util.Map;
cueTextSizeCssPx
,
cueTextSizeCssPx
,
windowCssColor
,
windowCssColor
,
horizontalTranslatePercent
,
horizontalTranslatePercent
,
verticalTranslatePercent
))
verticalTranslatePercent
,
getBlockShear
(
cue
)))
.
append
(
Util
.
formatInvariant
(
"<span class='%s'>"
,
DEFAULT_BACKGROUND_CSS_CLASS
))
.
append
(
Util
.
formatInvariant
(
"<span class='%s'>"
,
DEFAULT_BACKGROUND_CSS_CLASS
))
.
append
(
htmlAndCss
.
html
)
.
append
(
htmlAndCss
.
html
)
.
append
(
"</span>"
)
.
append
(
"</span>"
)
...
@@ -320,6 +321,16 @@ import java.util.Map;
...
@@ -320,6 +321,16 @@ import java.util.Map;
"base64"
);
"base64"
);
}
}
private
static
String
getBlockShear
(
Cue
cue
)
{
if
(
cue
.
shearDegrees
!=
0.0f
)
{
String
direction
=
(
cue
.
verticalType
==
Cue
.
VERTICAL_TYPE_LR
||
cue
.
verticalType
==
Cue
.
VERTICAL_TYPE_RL
)
?
"skewY"
:
"skewX"
;
return
Util
.
formatInvariant
(
" %s(%.2fdeg)"
,
direction
,
cue
.
shearDegrees
);
}
return
""
;
}
/**
/**
* Converts a text size to a CSS px value.
* Converts a text size to a CSS px value.
*
*
...
...
testdata/src/test/assets/media/ttml/shear.xml
0 → 100644
View file @
4be774aa
<tt
xmlns:ttm=
"http://www.w3.org/2006/10/ttaf1#metadata"
xmlns:ttp=
"http://www.w3.org/2006/10/ttaf1#parameter"
xmlns:tts=
"http://www.w3.org/2006/10/ttaf1#style"
xmlns=
"http://www.w3.org/ns/ttml"
xmlns=
"http://www.w3.org/2006/10/ttaf1"
>
<body>
<div>
<p
begin=
"10s"
end=
"18s"
tts:shear=
"0%"
>
0%
</p>
</div>
<div>
<p
begin=
"20s"
end=
"28s"
tts:shear=
"16.67%"
>
16.67%
</p>
</div>
<div>
<p
begin=
"30s"
end=
"38s"
tts:shear=
"-16.67%"
>
-16.67%
</p>
</div>
<div>
<p
begin=
"40s"
end=
"48s"
tts:shear=
"+16.67%"
>
+16.67%
</p>
</div>
<div>
<p
begin=
"50s"
end=
"58s"
tts:shear=
"+25%"
>
+25%
</p>
</div>
<div>
<p
begin=
"60s"
end=
"68s"
tts:shear=
"Invalid"
>
Invalid
</p>
</div>
<div>
<p
begin=
"70s"
end=
"78s"
tts:shear=
"100.01%"
>
100.01%
</p>
</div>
<div>
<p
begin=
"80s"
end=
"88s"
tts:shear=
"-101.1%"
>
-101.1%
</p>
</div>
</body>
</tt>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment