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
276788bc
authored
Feb 20, 2017
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge branch 'drhill-dev-v2_imagesubs' into dev-v2
parents
edae29df
e27a6eca
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
116 additions
and
34 deletions
library/src/main/java/com/google/android/exoplayer2/text/Cue.java
library/src/main/java/com/google/android/exoplayer2/ui/SubtitlePainter.java
library/src/main/java/com/google/android/exoplayer2/text/Cue.java
View file @
276788bc
...
...
@@ -16,6 +16,7 @@
package
com
.
google
.
android
.
exoplayer2
.
text
;
import
android.graphics.Color
;
import
android.graphics.Bitmap
;
import
android.support.annotation.IntDef
;
import
android.text.Layout.Alignment
;
import
java.lang.annotation.Retention
;
...
...
@@ -78,7 +79,8 @@ public class Cue {
public
static
final
int
LINE_TYPE_NUMBER
=
1
;
/**
* The cue text. Note the {@link CharSequence} may be decorated with styling spans.
* The cue text, or null if this is an image cue. Note the {@link CharSequence} may be decorated
* with styling spans.
*/
public
final
CharSequence
text
;
...
...
@@ -88,6 +90,11 @@ public class Cue {
public
final
Alignment
textAlignment
;
/**
* The cue image, or null if this is a text cue.
*/
public
final
Bitmap
bitmap
;
/**
* The position of the {@link #lineAnchor} of the cue box within the viewport in the direction
* orthogonal to the writing direction, or {@link #DIMEN_UNSET}. When set, the interpretation of
* the value depends on the value of {@link #lineType}.
...
...
@@ -95,8 +102,8 @@ public class Cue {
* For horizontal text and {@link #lineType} equal to {@link #LINE_TYPE_FRACTION}, this is the
* fractional vertical position relative to the top of the viewport.
*/
public
final
float
line
;
/**
* The type of the {@link #line} value.
* <p>
...
...
@@ -122,9 +129,8 @@ public class Cue {
* {@code (line == -2 && lineAnchor == ANCHOR_TYPE_START)} position a cue so that only its first
* line is visible at the bottom of the viewport.
*/
@LineType
public
final
int
lineType
;
@LineType
public
final
int
lineType
;
/**
* The cue box anchor positioned by {@link #line}. One of {@link #ANCHOR_TYPE_START},
* {@link #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}.
...
...
@@ -133,9 +139,8 @@ public class Cue {
* and {@link #ANCHOR_TYPE_END} correspond to the top, middle and bottom of the cue box
* respectively.
*/
@AnchorType
public
final
int
lineAnchor
;
@AnchorType
public
final
int
lineAnchor
;
/**
* The fractional position of the {@link #positionAnchor} of the cue box within the viewport in
* the direction orthogonal to {@link #line}, or {@link #DIMEN_UNSET}.
...
...
@@ -154,8 +159,7 @@ public class Cue {
* and {@link #ANCHOR_TYPE_END} correspond to the left, middle and right of the cue box
* respectively.
*/
@AnchorType
public
final
int
positionAnchor
;
@AnchorType
public
final
int
positionAnchor
;
/**
* The size of the cue box in the writing direction specified as a fraction of the viewport size
...
...
@@ -174,7 +178,36 @@ public class Cue {
public
final
int
windowColor
;
/**
* Constructs a cue whose {@link #textAlignment} is null, whose type parameters are set to
* Constructs an image cue whose type parameters are set to {@link #TYPE_UNSET} and whose
* dimension parameters are set to {@link #DIMEN_UNSET}.
*
* @param bitmap See {@link #bitmap}.
*/
public
Cue
(
Bitmap
bitmap
)
{
this
(
bitmap
,
DIMEN_UNSET
,
TYPE_UNSET
,
DIMEN_UNSET
,
TYPE_UNSET
,
DIMEN_UNSET
);
}
/**
* Creates an image cue.
*
* @param horizontalPosition The position of the horizontal anchor within the viewport, expressed
* as a fraction of the viewport width.
* @param horizontalPositionAnchor The horizontal anchor. One of {@link #ANCHOR_TYPE_START},
* {@link #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}.
* @param verticalPosition The position of the vertical anchor within the viewport, expressed as a
* fraction of the viewport height.
* @param verticalPositionAnchor The vertical anchor. One of {@link #ANCHOR_TYPE_START},
* {@link #ANCHOR_TYPE_MIDDLE}, {@link #ANCHOR_TYPE_END} and {@link #TYPE_UNSET}.
* @param width The width of the cue, expressed as a fraction of the viewport width.
*/
public
Cue
(
Bitmap
bitmap
,
float
horizontalPosition
,
@AnchorType
int
horizontalPositionAnchor
,
float
verticalPosition
,
@AnchorType
int
verticalPositionAnchor
,
float
width
)
{
this
(
null
,
null
,
bitmap
,
verticalPosition
,
LINE_TYPE_FRACTION
,
verticalPositionAnchor
,
horizontalPosition
,
horizontalPositionAnchor
,
width
,
false
,
Color
.
BLACK
);
}
/**
* Constructs 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}.
*
* @param text See {@link #text}.
...
...
@@ -184,6 +217,8 @@ public class Cue {
}
/**
* Creates a text cue.
*
* @param text See {@link #text}.
* @param textAlignment See {@link #textAlignment}.
* @param line See {@link #line}.
...
...
@@ -200,6 +235,8 @@ public class Cue {
}
/**
* Creates a text cue.
*
* @param text See {@link #text}.
* @param textAlignment See {@link #textAlignment}.
* @param line See {@link #line}.
...
...
@@ -214,8 +251,16 @@ public class Cue {
public
Cue
(
CharSequence
text
,
Alignment
textAlignment
,
float
line
,
@LineType
int
lineType
,
@AnchorType
int
lineAnchor
,
float
position
,
@AnchorType
int
positionAnchor
,
float
size
,
boolean
windowColorSet
,
int
windowColor
)
{
this
(
text
,
textAlignment
,
null
,
line
,
lineType
,
lineAnchor
,
position
,
positionAnchor
,
size
,
windowColorSet
,
windowColor
);
}
private
Cue
(
CharSequence
text
,
Alignment
textAlignment
,
Bitmap
bitmap
,
float
line
,
@LineType
int
lineType
,
@AnchorType
int
lineAnchor
,
float
position
,
@AnchorType
int
positionAnchor
,
float
size
,
boolean
windowColorSet
,
int
windowColor
)
{
this
.
text
=
text
;
this
.
textAlignment
=
textAlignment
;
this
.
bitmap
=
bitmap
;
this
.
line
=
line
;
this
.
lineType
=
lineType
;
this
.
lineAnchor
=
lineAnchor
;
...
...
library/src/main/java/com/google/android/exoplayer2/ui/SubtitlePainter.java
View file @
276788bc
...
...
@@ -18,11 +18,13 @@ package com.google.android.exoplayer2.ui;
import
android.content.Context
;
import
android.content.res.Resources
;
import
android.content.res.TypedArray
;
import
android.graphics.Bitmap
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.graphics.Paint.Join
;
import
android.graphics.Paint.Style
;
import
android.graphics.Rect
;
import
android.graphics.RectF
;
import
android.text.Layout.Alignment
;
import
android.text.StaticLayout
;
...
...
@@ -63,6 +65,7 @@ import com.google.android.exoplayer2.util.Util;
private
final
Paint
paint
;
// Previous input variables.
private
Bitmap
cueBitmap
;
private
CharSequence
cueText
;
private
Alignment
cueTextAlignment
;
private
float
cueLine
;
...
...
@@ -93,6 +96,7 @@ import com.google.android.exoplayer2.util.Util;
private
int
textLeft
;
private
int
textTop
;
private
int
textPaddingX
;
private
Rect
bitmapRect
;
@SuppressWarnings
(
"ResourceType"
)
public
SubtitlePainter
(
Context
context
)
{
...
...
@@ -141,21 +145,25 @@ import com.google.android.exoplayer2.util.Util;
public
void
draw
(
Cue
cue
,
boolean
applyEmbeddedStyles
,
CaptionStyleCompat
style
,
float
textSizePx
,
float
bottomPaddingFraction
,
Canvas
canvas
,
int
cueBoxLeft
,
int
cueBoxTop
,
int
cueBoxRight
,
int
cueBoxBottom
)
{
CharSequence
cueText
=
cue
.
text
;
if
(
TextUtils
.
isEmpty
(
cueText
))
{
// Nothing to draw.
return
;
}
int
windowColor
=
cue
.
windowColorSet
?
cue
.
windowColor
:
style
.
windowColor
;
if
(!
applyEmbeddedStyles
)
{
// Strip out any embedded styling.
cueText
=
cueText
.
toString
();
windowColor
=
style
.
windowColor
;
boolean
isTextCue
=
cue
.
bitmap
==
null
;
CharSequence
cueText
=
null
;
Bitmap
cueBitmap
=
null
;
if
(
isTextCue
)
{
cueText
=
cue
.
text
;
if
(
TextUtils
.
isEmpty
(
cueText
))
{
// Nothing to draw.
return
;
}
if
(!
applyEmbeddedStyles
)
{
// Strip out any embedded styling.
cueText
=
cueText
.
toString
();
}
}
else
{
cueBitmap
=
cue
.
bitmap
;
}
if
(
areCharSequencesEqual
(
this
.
cueText
,
cueText
)
&&
Util
.
areEqual
(
this
.
cueTextAlignment
,
cue
.
textAlignment
)
&&
this
.
cueBitmap
==
cueBitmap
&&
this
.
cueLine
==
cue
.
line
&&
this
.
cueLineType
==
cue
.
lineType
&&
Util
.
areEqual
(
this
.
cueLineAnchor
,
cue
.
lineAnchor
)
...
...
@@ -165,7 +173,7 @@ import com.google.android.exoplayer2.util.Util;
&&
this
.
applyEmbeddedStyles
==
applyEmbeddedStyles
&&
this
.
foregroundColor
==
style
.
foregroundColor
&&
this
.
backgroundColor
==
style
.
backgroundColor
&&
this
.
windowColor
==
windowColor
&&
this
.
windowColor
==
style
.
windowColor
&&
this
.
edgeType
==
style
.
edgeType
&&
this
.
edgeColor
==
style
.
edgeColor
&&
Util
.
areEqual
(
this
.
textPaint
.
getTypeface
(),
style
.
typeface
)
...
...
@@ -176,12 +184,13 @@ import com.google.android.exoplayer2.util.Util;
&&
this
.
parentRight
==
cueBoxRight
&&
this
.
parentBottom
==
cueBoxBottom
)
{
// We can use the cached layout.
drawLayout
(
canvas
);
drawLayout
(
canvas
,
isTextCue
);
return
;
}
this
.
cueText
=
cueText
;
this
.
cueTextAlignment
=
cue
.
textAlignment
;
this
.
cueBitmap
=
cue
.
bitmap
;
this
.
cueLine
=
cue
.
line
;
this
.
cueLineType
=
cue
.
lineType
;
this
.
cueLineAnchor
=
cue
.
lineAnchor
;
...
...
@@ -191,7 +200,7 @@ import com.google.android.exoplayer2.util.Util;
this
.
applyEmbeddedStyles
=
applyEmbeddedStyles
;
this
.
foregroundColor
=
style
.
foregroundColor
;
this
.
backgroundColor
=
style
.
backgroundColor
;
this
.
windowColor
=
windowColor
;
this
.
windowColor
=
style
.
windowColor
;
this
.
edgeType
=
style
.
edgeType
;
this
.
edgeColor
=
style
.
edgeColor
;
this
.
textPaint
.
setTypeface
(
style
.
typeface
);
...
...
@@ -202,6 +211,15 @@ import com.google.android.exoplayer2.util.Util;
this
.
parentRight
=
cueBoxRight
;
this
.
parentBottom
=
cueBoxBottom
;
if
(
isTextCue
)
{
setupTextLayout
();
}
else
{
setupBitmapLayout
();
}
drawLayout
(
canvas
,
isTextCue
);
}
private
void
setupTextLayout
()
{
int
parentWidth
=
parentRight
-
parentLeft
;
int
parentHeight
=
parentBottom
-
parentTop
;
...
...
@@ -237,7 +255,7 @@ import com.google.android.exoplayer2.util.Util;
int
anchorPosition
=
Math
.
round
(
parentWidth
*
cuePosition
)
+
parentLeft
;
textLeft
=
cuePositionAnchor
==
Cue
.
ANCHOR_TYPE_END
?
anchorPosition
-
textWidth
:
cuePositionAnchor
==
Cue
.
ANCHOR_TYPE_MIDDLE
?
(
anchorPosition
*
2
-
textWidth
)
/
2
:
anchorPosition
;
:
anchorPosition
;
textLeft
=
Math
.
max
(
textLeft
,
parentLeft
);
textRight
=
Math
.
min
(
textLeft
+
textWidth
,
parentRight
);
}
else
{
...
...
@@ -256,12 +274,12 @@ import com.google.android.exoplayer2.util.Util;
if
(
cueLine
>=
0
)
{
anchorPosition
=
Math
.
round
(
cueLine
*
firstLineHeight
)
+
parentTop
;
}
else
{
anchorPosition
=
Math
.
round
(
(
cueLine
+
1
)
*
firstLineHeight
)
+
parentBottom
;
anchorPosition
=
Math
.
round
(
cueLine
*
firstLineHeight
)
+
parentBottom
;
}
}
textTop
=
cueLineAnchor
==
Cue
.
ANCHOR_TYPE_END
?
anchorPosition
-
textHeight
:
cueLineAnchor
==
Cue
.
ANCHOR_TYPE_MIDDLE
?
(
anchorPosition
*
2
-
textHeight
)
/
2
:
anchorPosition
;
:
anchorPosition
;
if
(
textTop
+
textHeight
>
parentBottom
)
{
textTop
=
parentBottom
-
textHeight
;
}
else
if
(
textTop
<
parentTop
)
{
...
...
@@ -279,16 +297,31 @@ import com.google.android.exoplayer2.util.Util;
this
.
textLeft
=
textLeft
;
this
.
textTop
=
textTop
;
this
.
textPaddingX
=
textPaddingX
;
}
drawLayout
(
canvas
);
private
void
setupBitmapLayout
()
{
int
parentWidth
=
parentRight
-
parentLeft
;
int
parentHeight
=
parentBottom
-
parentTop
;
float
anchorX
=
parentLeft
+
(
parentWidth
*
cuePosition
);
float
anchorY
=
parentTop
+
(
parentHeight
*
cueLine
);
int
width
=
(
int
)
(
parentWidth
*
cueSize
);
int
height
=
(
int
)
(
width
*
((
float
)
cueBitmap
.
getHeight
()
/
cueBitmap
.
getWidth
()));
int
x
=
(
int
)
(
cueLineAnchor
==
Cue
.
ANCHOR_TYPE_END
?
(
anchorX
-
width
)
:
cueLineAnchor
==
Cue
.
ANCHOR_TYPE_MIDDLE
?
(
anchorX
-
(
width
/
2
))
:
anchorX
);
int
y
=
(
int
)
(
cuePositionAnchor
==
Cue
.
ANCHOR_TYPE_END
?
(
anchorY
-
width
)
:
cuePositionAnchor
==
Cue
.
ANCHOR_TYPE_MIDDLE
?
(
anchorY
-
(
width
/
2
))
:
anchorY
);
bitmapRect
=
new
Rect
(
x
,
y
,
x
+
width
,
y
+
height
);
}
/**
* Draws {@link #textLayout} into the provided canvas.
*
* @param canvas The canvas into which to draw.
*/
private
void
drawLayout
(
Canvas
canvas
)
{
private
void
drawLayout
(
Canvas
canvas
,
boolean
isTextCue
)
{
if
(
isTextCue
)
{
drawTextLayout
(
canvas
);
}
else
{
drawBitmapLayout
(
canvas
);
}
}
private
void
drawTextLayout
(
Canvas
canvas
)
{
final
StaticLayout
layout
=
textLayout
;
if
(
layout
==
null
)
{
// Nothing to draw.
...
...
@@ -347,6 +380,10 @@ import com.google.android.exoplayer2.util.Util;
canvas
.
restoreToCount
(
saveCount
);
}
private
void
drawBitmapLayout
(
Canvas
canvas
)
{
canvas
.
drawBitmap
(
cueBitmap
,
null
,
bitmapRect
,
null
);
}
/**
* This method is used instead of {@link TextUtils#equals(CharSequence, CharSequence)} because the
* latter only checks the text of each sequence, and does not check for equality of styling that
...
...
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