mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Address code review comments
- Refactor TextEmphasis class to support different ordering of styles - Merge RubySpan.Position and TextEmphasisSpan.Position - Remove TTML constructs from Spanned classes
This commit is contained in:
parent
fcda8d47ff
commit
4ad6454713
19 changed files with 417 additions and 452 deletions
|
|
@ -16,12 +16,6 @@
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.text.span;
|
package com.google.android.exoplayer2.text.span;
|
||||||
|
|
||||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
|
||||||
|
|
||||||
import androidx.annotation.IntDef;
|
|
||||||
import java.lang.annotation.Documented;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A styling span for ruby text.
|
* A styling span for ruby text.
|
||||||
*
|
*
|
||||||
|
|
@ -38,48 +32,14 @@ import java.lang.annotation.Retention;
|
||||||
// rubies (e.g. HTML <rp> tag).
|
// rubies (e.g. HTML <rp> tag).
|
||||||
public final class RubySpan {
|
public final class RubySpan {
|
||||||
|
|
||||||
/** The ruby position is unknown. */
|
|
||||||
public static final int POSITION_UNKNOWN = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The ruby text should be positioned above the base text.
|
|
||||||
*
|
|
||||||
* <p>For vertical text it should be positioned to the right, same as CSS's <a
|
|
||||||
* href="https://developer.mozilla.org/en-US/docs/Web/CSS/ruby-position">ruby-position</a>.
|
|
||||||
*/
|
|
||||||
public static final int POSITION_OVER = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The ruby text should be positioned below the base text.
|
|
||||||
*
|
|
||||||
* <p>For vertical text it should be positioned to the left, same as CSS's <a
|
|
||||||
* href="https://developer.mozilla.org/en-US/docs/Web/CSS/ruby-position">ruby-position</a>.
|
|
||||||
*/
|
|
||||||
public static final int POSITION_UNDER = 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The possible positions of the ruby text relative to the base text.
|
|
||||||
*
|
|
||||||
* <p>One of:
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>{@link #POSITION_UNKNOWN}
|
|
||||||
* <li>{@link #POSITION_OVER}
|
|
||||||
* <li>{@link #POSITION_UNDER}
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
@Documented
|
|
||||||
@Retention(SOURCE)
|
|
||||||
@IntDef({POSITION_UNKNOWN, POSITION_OVER, POSITION_UNDER})
|
|
||||||
public @interface Position {}
|
|
||||||
|
|
||||||
/** The ruby text, i.e. the smaller explanatory characters. */
|
/** The ruby text, i.e. the smaller explanatory characters. */
|
||||||
public final String rubyText;
|
public final String rubyText;
|
||||||
|
|
||||||
/** The position of the ruby text relative to the base text. */
|
/** The position of the ruby text relative to the base text. */
|
||||||
@Position public final int position;
|
@TextAnnotation.Position
|
||||||
|
public final int position;
|
||||||
|
|
||||||
public RubySpan(String rubyText, @Position int position) {
|
public RubySpan(String rubyText, @TextAnnotation.Position int position) {
|
||||||
this.rubyText = rubyText;
|
this.rubyText = rubyText;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.google.android.exoplayer2.text.span;
|
||||||
|
|
||||||
|
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||||
|
|
||||||
|
import androidx.annotation.IntDef;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to describe properties of a text annotation (i.e. ruby, text emphasis marks)
|
||||||
|
*/
|
||||||
|
public class TextAnnotation {
|
||||||
|
/** The text annotation position is unknown. */
|
||||||
|
public static final int POSITION_UNKNOWN = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For horizontal text, the text annotation should be positioned above the base text.
|
||||||
|
*
|
||||||
|
* <p>For vertical text it should be positioned to the right, same as CSS's <a
|
||||||
|
* href="https://developer.mozilla.org/en-US/docs/Web/CSS/ruby-position">ruby-position</a>.
|
||||||
|
*/
|
||||||
|
public static final int POSITION_BEFORE = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For horizontal text, the text annotation should be positioned below the base text.
|
||||||
|
*
|
||||||
|
* <p>For vertical text it should be positioned to the left, same as CSS's <a
|
||||||
|
* href="https://developer.mozilla.org/en-US/docs/Web/CSS/ruby-position">ruby-position</a>.
|
||||||
|
*/
|
||||||
|
public static final int POSITION_AFTER = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The possible positions of the annotation text relative to the base text.
|
||||||
|
*
|
||||||
|
* <p>One of:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link #POSITION_UNKNOWN}
|
||||||
|
* <li>{@link #POSITION_BEFORE}
|
||||||
|
* <li>{@link #POSITION_AFTER}
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Retention(SOURCE)
|
||||||
|
@IntDef({POSITION_UNKNOWN, POSITION_BEFORE, POSITION_AFTER})
|
||||||
|
public @interface Position {}
|
||||||
|
}
|
||||||
|
|
@ -23,72 +23,22 @@ import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
|
|
||||||
public final class TextEmphasisSpan {
|
public final class TextEmphasisSpan {
|
||||||
/**
|
// Bits [1:0] are used for typical mark types
|
||||||
* <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-emphasis-position">Text Emphasis Position</a>
|
public static final int MARK_FLAG_CIRCLE = 1;
|
||||||
*/
|
public static final int MARK_FLAG_DOT = 2;
|
||||||
|
public static final int MARK_FLAG_SESAME = 3;
|
||||||
|
|
||||||
/**
|
// Bit 2 is used for filled/open
|
||||||
* The text emphasis position is unknown. If an implementation does not recognize or otherwise
|
public static final int MARK_FLAG_FILLED = 0;
|
||||||
* distinguish an annotation position value, then it must be interpreted as if a position of
|
public static final int MARK_FLAG_OPEN = 4;
|
||||||
* before were specified; as such, an implementation that supports text annotation marks must
|
|
||||||
* minimally support the before value.
|
|
||||||
*/
|
|
||||||
public static final int POSITION_UNKNOWN = -1;
|
|
||||||
|
|
||||||
/**
|
// Below are the mark style constants
|
||||||
* The emphasis marks should be positioned above the base text in horizontal writing mode The
|
public static final int MARK_FILLED_CIRCLE = MARK_FLAG_CIRCLE | MARK_FLAG_FILLED;
|
||||||
* emphasis marks should be positioned to the right of the base text in vertical writing mode
|
public static final int MARK_FILLED_DOT = MARK_FLAG_DOT | MARK_FLAG_FILLED;
|
||||||
*/
|
public static final int MARK_FILLED_SESAME = MARK_FLAG_SESAME | MARK_FLAG_FILLED;
|
||||||
public static final int POSITION_BEFORE = 1;
|
public static final int MARK_OPEN_CIRCLE = MARK_FLAG_CIRCLE | MARK_FLAG_OPEN;
|
||||||
|
public static final int MARK_OPEN_DOT = MARK_FLAG_DOT | MARK_FLAG_OPEN;
|
||||||
/**
|
public static final int MARK_OPEN_SESAME = MARK_FLAG_SESAME | MARK_FLAG_OPEN;
|
||||||
* The emphasis marks should be positioned below the base text in horizontal writing mode The
|
|
||||||
* emphasis marks should be positioned to the left of the base text in vertical writing mode
|
|
||||||
*/
|
|
||||||
public static final int POSITION_AFTER = 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The text emphasis should be positioned in following way:
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>Equivalent to {@link #POSITION_BEFORE} for (1) the only line area of or (2) the first line
|
|
||||||
* area of the last block area generated by a p element which contains annotated text
|
|
||||||
* <li>otherwise, equivalent to {@link #POSITION_AFTER}
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
public static final int POSITION_OUTSIDE = 3;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The possible positions of the emphasis marks relative to the base text.
|
|
||||||
*
|
|
||||||
* <p>One of:
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>{@link #POSITION_UNKNOWN}
|
|
||||||
* <li>{@link #POSITION_BEFORE}
|
|
||||||
* <li>{@link #POSITION_AFTER}
|
|
||||||
* <li>{@link #POSITION_OUTSIDE}
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
@Documented
|
|
||||||
@Retention(SOURCE)
|
|
||||||
@IntDef({POSITION_UNKNOWN, POSITION_BEFORE, POSITION_AFTER, POSITION_OUTSIDE})
|
|
||||||
public @interface Position {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The text emphasis position is unknown.
|
|
||||||
*/
|
|
||||||
public static final int MARK_UNKNOWN = -1;
|
|
||||||
|
|
||||||
public static final int MARK_AUTO = 1;
|
|
||||||
public static final int MARK_FILLED_CIRCLE = 2;
|
|
||||||
public static final int MARK_FILLED_DOT = 3;
|
|
||||||
public static final int MARK_FILLED_SESAME = 4;
|
|
||||||
public static final int MARK_OPEN_CIRCLE = 5;
|
|
||||||
public static final int MARK_OPEN_DOT = 6;
|
|
||||||
public static final int MARK_OPEN_SESAME = 7;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The possible types of annotations used.
|
* The possible types of annotations used.
|
||||||
|
|
@ -96,8 +46,6 @@ public final class TextEmphasisSpan {
|
||||||
* <p>One of:
|
* <p>One of:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link #MARK_UNKNOWN}
|
|
||||||
* <li>{@link #MARK_AUTO}
|
|
||||||
* <li>{@link #MARK_FILLED_CIRCLE}
|
* <li>{@link #MARK_FILLED_CIRCLE}
|
||||||
* <li>{@link #MARK_FILLED_DOT}
|
* <li>{@link #MARK_FILLED_DOT}
|
||||||
* <li>{@link #MARK_FILLED_SESAME}
|
* <li>{@link #MARK_FILLED_SESAME}
|
||||||
|
|
@ -105,29 +53,31 @@ public final class TextEmphasisSpan {
|
||||||
* <li>{@link #MARK_OPEN_DOT}
|
* <li>{@link #MARK_OPEN_DOT}
|
||||||
* <li>{@link #MARK_OPEN_SESAME}
|
* <li>{@link #MARK_OPEN_SESAME}
|
||||||
* </ul>
|
* </ul>
|
||||||
|
*
|
||||||
|
* Note: We are intentionally excluding MARK_AUTO here since the auto value should
|
||||||
|
* be resolved
|
||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(SOURCE)
|
@Retention(SOURCE)
|
||||||
@IntDef({MARK_UNKNOWN, MARK_AUTO, MARK_FILLED_CIRCLE, MARK_FILLED_DOT, MARK_FILLED_SESAME,
|
@IntDef({MARK_FILLED_CIRCLE, MARK_FILLED_DOT, MARK_FILLED_SESAME,
|
||||||
MARK_OPEN_CIRCLE, MARK_OPEN_DOT, MARK_OPEN_SESAME})
|
MARK_OPEN_CIRCLE, MARK_OPEN_DOT, MARK_OPEN_SESAME})
|
||||||
public @interface Mark {
|
public @interface Mark {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mark used to emphasis text
|
||||||
|
*/
|
||||||
|
public @TextEmphasisSpan.Mark int mark;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The position of the text emphasis relative to the base text
|
* The position of the text emphasis relative to the base text
|
||||||
*/
|
*/
|
||||||
@TextEmphasisSpan.Position
|
@TextAnnotation.Position
|
||||||
public final int position;
|
public final int position;
|
||||||
|
|
||||||
/**
|
|
||||||
* The text emphasis mark
|
|
||||||
*/
|
|
||||||
@TextEmphasisSpan.Mark
|
|
||||||
public final int mark;
|
|
||||||
|
|
||||||
public TextEmphasisSpan(@TextEmphasisSpan.Mark int mark,
|
public TextEmphasisSpan(@TextEmphasisSpan.Mark int mark,
|
||||||
@TextEmphasisSpan.Position int position) {
|
@TextAnnotation.Position int position) {
|
||||||
this.mark = mark;
|
this.mark = mark;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,21 +16,17 @@
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.text.ttml;
|
package com.google.android.exoplayer2.text.ttml;
|
||||||
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_AUTO;
|
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_FILLED_CIRCLE;
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_FILLED_DOT;
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_FILLED_SESAME;
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_OPEN_CIRCLE;
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_OPEN_DOT;
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_OPEN_SESAME;
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.POSITION_AFTER;
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.POSITION_BEFORE;
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.POSITION_OUTSIDE;
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.POSITION_UNKNOWN;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to emphasize text using markers above or below the text. For example, markers
|
* This class is used to emphasize text using markers above or below the text. For example, markers
|
||||||
|
|
@ -42,18 +38,73 @@ import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||||
/* package */ final class TextEmphasis {
|
/* package */ final class TextEmphasis {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The position of the text emphasis relative to the base text.
|
* Mark style to be resolved at rendering time. Hence, it is not defined in
|
||||||
|
* {@link TextEmphasisSpan.Mark}
|
||||||
*/
|
*/
|
||||||
@TextEmphasisSpan.Position
|
public static final int MARK_AUTO = 1 << 8;
|
||||||
public final int position;
|
|
||||||
|
@Documented
|
||||||
|
@Retention(SOURCE)
|
||||||
|
@IntDef({TextEmphasisSpan.MARK_FILLED_CIRCLE,
|
||||||
|
TextEmphasisSpan.MARK_FILLED_DOT,
|
||||||
|
TextEmphasisSpan.MARK_FILLED_SESAME,
|
||||||
|
TextEmphasisSpan.MARK_OPEN_CIRCLE,
|
||||||
|
TextEmphasisSpan.MARK_OPEN_DOT,
|
||||||
|
TextEmphasisSpan.MARK_OPEN_SESAME,
|
||||||
|
// Extending the definition in TextEmphasisSpan for intermediate values
|
||||||
|
MARK_AUTO
|
||||||
|
})
|
||||||
|
|
||||||
|
/* package */ @interface Mark {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The desired emphasis mark
|
* The mark style of the text emphasis.
|
||||||
*/
|
*/
|
||||||
@TextEmphasisSpan.Mark
|
/* package */@Mark
|
||||||
public final int mark;
|
final int mark;
|
||||||
|
|
||||||
private TextEmphasis(@TextEmphasisSpan.Mark int mark, @TextEmphasisSpan.Position int position) {
|
/**
|
||||||
|
* Position to be resolved at rendering time. Hence, it is not defined in
|
||||||
|
* {@link TextAnnotation.Position}
|
||||||
|
*/
|
||||||
|
public static final int POSITION_OUTSIDE = 1 << 8;
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
@Retention(SOURCE)
|
||||||
|
@IntDef({TextAnnotation.POSITION_UNKNOWN,
|
||||||
|
TextAnnotation.POSITION_BEFORE,
|
||||||
|
TextAnnotation.POSITION_AFTER,
|
||||||
|
// Extending the definition in TextAnnotation.Position for intermediate values
|
||||||
|
POSITION_OUTSIDE
|
||||||
|
})
|
||||||
|
public @interface Position {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position of the text emphasis relative to the base text.
|
||||||
|
*/
|
||||||
|
@Position
|
||||||
|
public final int position;
|
||||||
|
|
||||||
|
private static Set markValues = ImmutableSet.of(
|
||||||
|
TtmlNode.TEXT_EMPHASIS_AUTO,
|
||||||
|
TtmlNode.TEXT_EMPHASIS_MARK_DOT,
|
||||||
|
TtmlNode.TEXT_EMPHASIS_MARK_SESAME,
|
||||||
|
TtmlNode.TEXT_EMPHASIS_MARK_CIRCLE
|
||||||
|
);
|
||||||
|
|
||||||
|
private static Set markStyles = ImmutableSet.of(
|
||||||
|
TtmlNode.TEXT_EMPHASIS_MARK_FILLED,
|
||||||
|
TtmlNode.TEXT_EMPHASIS_MARK_OPEN
|
||||||
|
);
|
||||||
|
|
||||||
|
private static Set positionValues = ImmutableSet.of(
|
||||||
|
TtmlNode.TEXT_EMPHASIS_POSITION_AFTER,
|
||||||
|
TtmlNode.TEXT_EMPHASIS_POSITION_BEFORE,
|
||||||
|
TtmlNode.TEXT_EMPHASIS_POSITION_OUTSIDE
|
||||||
|
);
|
||||||
|
|
||||||
|
private TextEmphasis(@Mark int mark, @TextAnnotation.Position int position) {
|
||||||
this.mark = mark;
|
this.mark = mark;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
@ -76,126 +127,65 @@ import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] nodes = parsingValue.split("\\s+");
|
Set<String> nodes = Sets.newHashSet(parsingValue.split("\\s+"));
|
||||||
|
|
||||||
switch (nodes.length) {
|
if (nodes.size() == 0 || TtmlNode.TEXT_EMPHASIS_NONE.equals(nodes.iterator().next())) {
|
||||||
case 0:
|
|
||||||
return null;
|
|
||||||
case 1:
|
|
||||||
return handleOneNode(nodes[0]);
|
|
||||||
case 2:
|
|
||||||
return handleTwoNodes(nodes[0], nodes[1]);
|
|
||||||
default:
|
|
||||||
// We ignore anything after third entry in value
|
|
||||||
return handleThreeNodes(nodes[0], nodes[1], nodes[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @Nullable
|
|
||||||
TextEmphasis handleOneNode(@NonNull String value) {
|
|
||||||
|
|
||||||
if (TtmlNode.TEXT_EMPHASIS_NONE.equals(value)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return parseNodes(nodes);
|
||||||
// Handle "auto" or unknown value
|
|
||||||
// If an implementation does not recognize or otherwise distinguish an emphasis style value,
|
|
||||||
// then it must be interpreted as if a style of auto were specified; as such, an implementation
|
|
||||||
// that supports text emphasis marks must minimally support the auto value.
|
|
||||||
return new TextEmphasis(MARK_AUTO, POSITION_UNKNOWN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @Nullable
|
private static @Nullable TextEmphasis parseNodes(Set<String> nodes) {
|
||||||
TextEmphasis handleTwoNodes(@NonNull String mark, @NonNull String position) {
|
Set styleSet = Sets.intersection(markStyles, nodes).immutableCopy();
|
||||||
|
Set markSet = Sets.intersection(markValues, nodes).immutableCopy();
|
||||||
|
Set positionSet = Sets.intersection(positionValues, nodes).immutableCopy();
|
||||||
|
|
||||||
@TextEmphasisSpan.Position int positionEntry = getPosition(position);
|
@Mark int mark = 0;
|
||||||
@TextEmphasisSpan.Mark int markEntry;
|
if (styleSet.size() == 1) {
|
||||||
switch (mark) {
|
mark |= TtmlNode.TEXT_EMPHASIS_MARK_OPEN.equals(styleSet.iterator().next())
|
||||||
case TtmlNode.TEXT_EMPHASIS_AUTO:
|
? TextEmphasisSpan.MARK_FLAG_OPEN
|
||||||
markEntry = MARK_AUTO;
|
: TextEmphasisSpan.MARK_FLAG_FILLED;
|
||||||
break;
|
}
|
||||||
// If only circle, dot, or sesame is specified, then it is equivalent to filled circle,
|
if (markSet.size() == 1) {
|
||||||
// filled dot, and filled sesame, respectively.
|
switch ((String) markSet.iterator().next()) {
|
||||||
case TtmlNode.TEXT_EMPHASIS_MARK_DOT:
|
case TtmlNode.TEXT_EMPHASIS_AUTO:
|
||||||
markEntry = MARK_FILLED_DOT;
|
mark |= MARK_AUTO;
|
||||||
break;
|
break;
|
||||||
case TtmlNode.TEXT_EMPHASIS_MARK_SESAME:
|
case TtmlNode.TEXT_EMPHASIS_MARK_DOT:
|
||||||
markEntry = MARK_FILLED_SESAME;
|
mark |= TextEmphasisSpan.MARK_FLAG_DOT;
|
||||||
break;
|
break;
|
||||||
case TtmlNode.TEXT_EMPHASIS_MARK_CIRCLE:
|
case TtmlNode.TEXT_EMPHASIS_MARK_SESAME:
|
||||||
markEntry = MARK_FILLED_CIRCLE;
|
mark |= TextEmphasisSpan.MARK_FLAG_SESAME;
|
||||||
break;
|
break;
|
||||||
default:
|
case TtmlNode.TEXT_EMPHASIS_MARK_CIRCLE:
|
||||||
// This is use case for: "filled dot" when position is not specified.
|
default:
|
||||||
return handleWithPosition(mark, position, POSITION_UNKNOWN);
|
mark |= TextEmphasisSpan.MARK_FLAG_CIRCLE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mark |= TextEmphasisSpan.MARK_FLAG_CIRCLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new TextEmphasis(markEntry, positionEntry);
|
/**
|
||||||
}
|
* If no emphasis position is specified, then the emphasis position must be interpreted as if
|
||||||
|
* a position of outside were specified.
|
||||||
private static @Nullable
|
* <p>
|
||||||
TextEmphasis handleWithPosition(@NonNull String markStyle, @Nullable String mark,
|
* More information on
|
||||||
@TextEmphasisSpan.Position int position) {
|
* <a href="https://www.w3.org/TR/2018/REC-ttml2-20181108/#style-attribute-textEmphasis">tts:textEmphasis</a>
|
||||||
|
*/
|
||||||
switch (mark) {
|
@Position int position = POSITION_OUTSIDE;
|
||||||
|
if (positionSet.size() == 1) {
|
||||||
case TtmlNode.TEXT_EMPHASIS_MARK_DOT:
|
switch ((String) positionSet.iterator().next()) {
|
||||||
if (TtmlNode.TEXT_EMPHASIS_MARK_FILLED.equals(markStyle)) {
|
case TtmlNode.TEXT_EMPHASIS_POSITION_AFTER:
|
||||||
return new TextEmphasis(MARK_FILLED_DOT, position);
|
position = TextAnnotation.POSITION_AFTER;
|
||||||
} else if (TtmlNode.TEXT_EMPHASIS_MARK_OPEN.equals(markStyle)) {
|
break;
|
||||||
return new TextEmphasis(MARK_OPEN_DOT, position);
|
case TtmlNode.TEXT_EMPHASIS_POSITION_OUTSIDE:
|
||||||
} else {
|
position = POSITION_OUTSIDE;
|
||||||
return new TextEmphasis(MARK_FILLED_DOT, position);
|
break;
|
||||||
}
|
case TtmlNode.TEXT_EMPHASIS_POSITION_BEFORE:
|
||||||
|
default:
|
||||||
case TtmlNode.TEXT_EMPHASIS_MARK_SESAME:
|
position = TextAnnotation.POSITION_BEFORE;
|
||||||
if (TtmlNode.TEXT_EMPHASIS_MARK_FILLED.equals(markStyle)) {
|
}
|
||||||
return new TextEmphasis(MARK_FILLED_SESAME, position);
|
|
||||||
} else if (TtmlNode.TEXT_EMPHASIS_MARK_OPEN.equals(markStyle)) {
|
|
||||||
return new TextEmphasis(MARK_OPEN_SESAME, position);
|
|
||||||
} else {
|
|
||||||
return new TextEmphasis(MARK_FILLED_SESAME, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
case TtmlNode.TEXT_EMPHASIS_MARK_CIRCLE:
|
|
||||||
if (TtmlNode.TEXT_EMPHASIS_MARK_FILLED.equals(markStyle)) {
|
|
||||||
return new TextEmphasis(MARK_FILLED_CIRCLE, position);
|
|
||||||
} else if (TtmlNode.TEXT_EMPHASIS_MARK_OPEN.equals(markStyle)) {
|
|
||||||
return new TextEmphasis(MARK_OPEN_CIRCLE, position);
|
|
||||||
} else {
|
|
||||||
return new TextEmphasis(MARK_FILLED_CIRCLE, position);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Not supported, default to AUTO.
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return new TextEmphasis(mark, position);
|
||||||
return new TextEmphasis(MARK_AUTO, POSITION_UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @Nullable
|
|
||||||
TextEmphasis handleThreeNodes(@NonNull String markStyle, @NonNull String mark,
|
|
||||||
@NonNull String position) {
|
|
||||||
|
|
||||||
@TextEmphasisSpan.Position int positionEntry = getPosition(position);
|
|
||||||
return handleWithPosition(markStyle, mark, positionEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static @TextEmphasisSpan.Position
|
|
||||||
int getPosition(@NonNull String value) {
|
|
||||||
|
|
||||||
switch (value) {
|
|
||||||
case TtmlNode.TEXT_EMPHASIS_POSITION_AFTER:
|
|
||||||
return POSITION_AFTER;
|
|
||||||
case TtmlNode.TEXT_EMPHASIS_POSITION_BEFORE:
|
|
||||||
return POSITION_BEFORE;
|
|
||||||
case TtmlNode.TEXT_EMPHASIS_POSITION_OUTSIDE:
|
|
||||||
return POSITION_OUTSIDE;
|
|
||||||
default:
|
|
||||||
// ignore
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return POSITION_UNKNOWN;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import com.google.android.exoplayer2.text.Cue;
|
||||||
import com.google.android.exoplayer2.text.SimpleSubtitleDecoder;
|
import com.google.android.exoplayer2.text.SimpleSubtitleDecoder;
|
||||||
import com.google.android.exoplayer2.text.Subtitle;
|
import com.google.android.exoplayer2.text.Subtitle;
|
||||||
import com.google.android.exoplayer2.text.SubtitleDecoderException;
|
import com.google.android.exoplayer2.text.SubtitleDecoderException;
|
||||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.ColorParser;
|
import com.google.android.exoplayer2.util.ColorParser;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
|
|
@ -583,10 +583,10 @@ public final class TtmlDecoder extends SimpleSubtitleDecoder {
|
||||||
case TtmlNode.ATTR_TTS_RUBY_POSITION:
|
case TtmlNode.ATTR_TTS_RUBY_POSITION:
|
||||||
switch (Util.toLowerInvariant(attributeValue)) {
|
switch (Util.toLowerInvariant(attributeValue)) {
|
||||||
case TtmlNode.RUBY_BEFORE:
|
case TtmlNode.RUBY_BEFORE:
|
||||||
style = createIfNull(style).setRubyPosition(RubySpan.POSITION_OVER);
|
style = createIfNull(style).setRubyPosition(TextAnnotation.POSITION_BEFORE);
|
||||||
break;
|
break;
|
||||||
case TtmlNode.RUBY_AFTER:
|
case TtmlNode.RUBY_AFTER:
|
||||||
style = createIfNull(style).setRubyPosition(RubySpan.POSITION_UNDER);
|
style = createIfNull(style).setRubyPosition(TextAnnotation.POSITION_AFTER);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// ignore
|
// ignore
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import com.google.android.exoplayer2.text.Cue;
|
||||||
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
||||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||||
import com.google.android.exoplayer2.text.span.SpanUtil;
|
import com.google.android.exoplayer2.text.span.SpanUtil;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
|
@ -124,21 +125,36 @@ import java.util.Map;
|
||||||
}
|
}
|
||||||
if (style.getTextEmphasis() != null) {
|
if (style.getTextEmphasis() != null) {
|
||||||
TextEmphasis textEmphasis = style.getTextEmphasis();
|
TextEmphasis textEmphasis = style.getTextEmphasis();
|
||||||
// https://www.w3.org/TR/ttml2/#style-value-emphasis-style
|
/**
|
||||||
// If an implementation does not recognize or otherwise distinguish an emphasis style value,
|
* If an implementation does not recognize or otherwise distinguish an emphasis style value,
|
||||||
// then it must be interpreted as if a style of auto were specified; as such, an
|
* then it must be interpreted as if a style of auto were specified; as such, an
|
||||||
// implementation that supports text emphasis marks must minimally support the auto value.
|
* implementation that supports text emphasis marks must minimally support the auto value.
|
||||||
// If a vertical writing mode applies, then equivalent to filled sesame; otherwise, equivalent
|
* If a vertical writing mode applies, then equivalent to filled sesame; otherwise, equivalent
|
||||||
// to filled circle.
|
* to filled circle.
|
||||||
@TextEmphasisSpan.Mark int mark = textEmphasis.mark;
|
* See https://www.w3.org/TR/ttml2/#style-value-emphasis-style
|
||||||
if (textEmphasis.mark == TextEmphasisSpan.MARK_AUTO
|
*/
|
||||||
|| textEmphasis.mark == TextEmphasisSpan.MARK_UNKNOWN) {
|
@TextEmphasis.Mark int mark = textEmphasis.mark;
|
||||||
|
if (textEmphasis.mark == TextEmphasis.MARK_AUTO) {
|
||||||
mark = (verticalType == Cue.VERTICAL_TYPE_LR || verticalType == Cue.VERTICAL_TYPE_RL) ?
|
mark = (verticalType == Cue.VERTICAL_TYPE_LR || verticalType == Cue.VERTICAL_TYPE_RL) ?
|
||||||
TextEmphasisSpan.MARK_FILLED_SESAME : TextEmphasisSpan.MARK_FILLED_CIRCLE;
|
TextEmphasisSpan.MARK_FILLED_SESAME : TextEmphasisSpan.MARK_FILLED_CIRCLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TextEmphasis.Position int position = textEmphasis.position;
|
||||||
|
if (textEmphasis.position == TextEmphasis.POSITION_OUTSIDE) {
|
||||||
|
/**
|
||||||
|
* Not supported in current implementation
|
||||||
|
* If an implementation does not recognize or otherwise distinguish an annotation position
|
||||||
|
* value, then it must be interpreted as if a position of before were specified; as such,
|
||||||
|
* an implementation that supports text annotation marks must minimally support the before
|
||||||
|
* value.
|
||||||
|
* See https://www.w3.org/TR/ttml2/#style-value-annotation-position
|
||||||
|
*/
|
||||||
|
position = TextAnnotation.POSITION_BEFORE;
|
||||||
|
}
|
||||||
|
|
||||||
SpanUtil.addOrReplaceSpan(
|
SpanUtil.addOrReplaceSpan(
|
||||||
builder,
|
builder,
|
||||||
new TextEmphasisSpan(mark, textEmphasis.position),
|
new TextEmphasisSpan(mark, position),
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
@ -165,11 +181,11 @@ import java.util.Map;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Get rubyPosition from `textNode` when TTML inheritance is implemented.
|
// TODO: Get rubyPosition from `textNode` when TTML inheritance is implemented.
|
||||||
@RubySpan.Position
|
@TextAnnotation.Position
|
||||||
int rubyPosition =
|
int rubyPosition =
|
||||||
containerNode.style != null
|
containerNode.style != null
|
||||||
? containerNode.style.getRubyPosition()
|
? containerNode.style.getRubyPosition()
|
||||||
: RubySpan.POSITION_UNKNOWN;
|
: TextAnnotation.POSITION_UNKNOWN;
|
||||||
builder.setSpan(
|
builder.setSpan(
|
||||||
new RubySpan(rubyText, rubyPosition), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
new RubySpan(rubyText, rubyPosition), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ 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.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
@ -83,7 +84,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
private float fontSize;
|
private float fontSize;
|
||||||
@Nullable private String id;
|
@Nullable private String id;
|
||||||
@RubyType private int rubyType;
|
@RubyType private int rubyType;
|
||||||
@RubySpan.Position private int rubyPosition;
|
@TextAnnotation.Position private int rubyPosition;
|
||||||
@Nullable private Layout.Alignment textAlign;
|
@Nullable private Layout.Alignment textAlign;
|
||||||
@OptionalBoolean private int textCombine;
|
@OptionalBoolean private int textCombine;
|
||||||
|
|
||||||
|
|
@ -96,7 +97,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
italic = UNSPECIFIED;
|
italic = UNSPECIFIED;
|
||||||
fontSizeUnit = UNSPECIFIED;
|
fontSizeUnit = UNSPECIFIED;
|
||||||
rubyType = UNSPECIFIED;
|
rubyType = UNSPECIFIED;
|
||||||
rubyPosition = RubySpan.POSITION_UNKNOWN;
|
rubyPosition = TextAnnotation.POSITION_UNKNOWN;
|
||||||
textCombine = UNSPECIFIED;
|
textCombine = UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,7 +228,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
if (underline == UNSPECIFIED) {
|
if (underline == UNSPECIFIED) {
|
||||||
underline = ancestor.underline;
|
underline = ancestor.underline;
|
||||||
}
|
}
|
||||||
if (rubyPosition == RubySpan.POSITION_UNKNOWN) {
|
if (rubyPosition == TextAnnotation.POSITION_UNKNOWN) {
|
||||||
rubyPosition = ancestor.rubyPosition;
|
rubyPosition = ancestor.rubyPosition;
|
||||||
}
|
}
|
||||||
if (textAlign == null && ancestor.textAlign != null) {
|
if (textAlign == null && ancestor.textAlign != null) {
|
||||||
|
|
@ -274,12 +275,12 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
return rubyType;
|
return rubyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TtmlStyle setRubyPosition(@RubySpan.Position int position) {
|
public TtmlStyle setRubyPosition(@TextAnnotation.Position int position) {
|
||||||
this.rubyPosition = position;
|
this.rubyPosition = position;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RubySpan.Position
|
@TextAnnotation.Position
|
||||||
public int getRubyPosition() {
|
public int getRubyPosition() {
|
||||||
return rubyPosition;
|
return rubyPosition;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer2.text.webvtt;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.ColorParser;
|
import com.google.android.exoplayer2.util.ColorParser;
|
||||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||||
|
|
@ -195,9 +196,9 @@ import java.util.regex.Pattern;
|
||||||
style.setBackgroundColor(ColorParser.parseCssColor(value));
|
style.setBackgroundColor(ColorParser.parseCssColor(value));
|
||||||
} else if (PROPERTY_RUBY_POSITION.equals(property)) {
|
} else if (PROPERTY_RUBY_POSITION.equals(property)) {
|
||||||
if (VALUE_OVER.equals(value)) {
|
if (VALUE_OVER.equals(value)) {
|
||||||
style.setRubyPosition(RubySpan.POSITION_OVER);
|
style.setRubyPosition(TextAnnotation.POSITION_BEFORE);
|
||||||
} else if (VALUE_UNDER.equals(value)) {
|
} else if (VALUE_UNDER.equals(value)) {
|
||||||
style.setRubyPosition(RubySpan.POSITION_UNDER);
|
style.setRubyPosition(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
} else if (PROPERTY_TEXT_COMBINE_UPRIGHT.equals(property)) {
|
} else if (PROPERTY_TEXT_COMBINE_UPRIGHT.equals(property)) {
|
||||||
style.setCombineUpright(VALUE_ALL.equals(value) || value.startsWith(VALUE_DIGITS));
|
style.setCombineUpright(VALUE_ALL.equals(value) || value.startsWith(VALUE_DIGITS));
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import androidx.annotation.ColorInt;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
|
|
@ -95,7 +96,7 @@ public final class WebvttCssStyle {
|
||||||
@OptionalBoolean private int italic;
|
@OptionalBoolean private int italic;
|
||||||
@FontSizeUnit private int fontSizeUnit;
|
@FontSizeUnit private int fontSizeUnit;
|
||||||
private float fontSize;
|
private float fontSize;
|
||||||
@RubySpan.Position private int rubyPosition;
|
@TextAnnotation.Position private int rubyPosition;
|
||||||
private boolean combineUpright;
|
private boolean combineUpright;
|
||||||
|
|
||||||
public WebvttCssStyle() {
|
public WebvttCssStyle() {
|
||||||
|
|
@ -111,7 +112,7 @@ public final class WebvttCssStyle {
|
||||||
bold = UNSPECIFIED;
|
bold = UNSPECIFIED;
|
||||||
italic = UNSPECIFIED;
|
italic = UNSPECIFIED;
|
||||||
fontSizeUnit = UNSPECIFIED;
|
fontSizeUnit = UNSPECIFIED;
|
||||||
rubyPosition = RubySpan.POSITION_UNKNOWN;
|
rubyPosition = TextAnnotation.POSITION_UNKNOWN;
|
||||||
combineUpright = false;
|
combineUpright = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -272,12 +273,12 @@ public final class WebvttCssStyle {
|
||||||
return fontSize;
|
return fontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WebvttCssStyle setRubyPosition(@RubySpan.Position int rubyPosition) {
|
public WebvttCssStyle setRubyPosition(@TextAnnotation.Position int rubyPosition) {
|
||||||
this.rubyPosition = rubyPosition;
|
this.rubyPosition = rubyPosition;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RubySpan.Position
|
@TextAnnotation.Position
|
||||||
public int getRubyPosition() {
|
public int getRubyPosition() {
|
||||||
return rubyPosition;
|
return rubyPosition;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.text.Cue;
|
import com.google.android.exoplayer2.text.Cue;
|
||||||
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
||||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||||
|
|
@ -572,7 +573,7 @@ public final class WebvttCueParser {
|
||||||
StartTag startTag,
|
StartTag startTag,
|
||||||
List<Element> nestedElements,
|
List<Element> nestedElements,
|
||||||
List<WebvttCssStyle> styles) {
|
List<WebvttCssStyle> styles) {
|
||||||
@RubySpan.Position int rubyTagPosition = getRubyPosition(styles, cueId, startTag);
|
@TextAnnotation.Position int rubyTagPosition = getRubyPosition(styles, cueId, startTag);
|
||||||
List<Element> sortedNestedElements = new ArrayList<>(nestedElements.size());
|
List<Element> sortedNestedElements = new ArrayList<>(nestedElements.size());
|
||||||
sortedNestedElements.addAll(nestedElements);
|
sortedNestedElements.addAll(nestedElements);
|
||||||
Collections.sort(sortedNestedElements, Element.BY_START_POSITION_ASC);
|
Collections.sort(sortedNestedElements, Element.BY_START_POSITION_ASC);
|
||||||
|
|
@ -585,12 +586,12 @@ public final class WebvttCueParser {
|
||||||
Element rubyTextElement = sortedNestedElements.get(i);
|
Element rubyTextElement = sortedNestedElements.get(i);
|
||||||
// Use the <rt> element's ruby-position if set, otherwise the <ruby> element's and otherwise
|
// Use the <rt> element's ruby-position if set, otherwise the <ruby> element's and otherwise
|
||||||
// default to OVER.
|
// default to OVER.
|
||||||
@RubySpan.Position
|
@TextAnnotation.Position
|
||||||
int rubyPosition =
|
int rubyPosition =
|
||||||
firstKnownRubyPosition(
|
firstKnownRubyPosition(
|
||||||
getRubyPosition(styles, cueId, rubyTextElement.startTag),
|
getRubyPosition(styles, cueId, rubyTextElement.startTag),
|
||||||
rubyTagPosition,
|
rubyTagPosition,
|
||||||
RubySpan.POSITION_OVER);
|
TextAnnotation.POSITION_BEFORE);
|
||||||
// Move the rubyText from spannedText into the RubySpan.
|
// Move the rubyText from spannedText into the RubySpan.
|
||||||
int adjustedRubyTextStart = rubyTextElement.startTag.position - deletedCharCount;
|
int adjustedRubyTextStart = rubyTextElement.startTag.position - deletedCharCount;
|
||||||
int adjustedRubyTextEnd = rubyTextElement.endPosition - deletedCharCount;
|
int adjustedRubyTextEnd = rubyTextElement.endPosition - deletedCharCount;
|
||||||
|
|
@ -607,31 +608,31 @@ public final class WebvttCueParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RubySpan.Position
|
@TextAnnotation.Position
|
||||||
private static int getRubyPosition(
|
private static int getRubyPosition(
|
||||||
List<WebvttCssStyle> styles, @Nullable String cueId, StartTag startTag) {
|
List<WebvttCssStyle> styles, @Nullable String cueId, StartTag startTag) {
|
||||||
List<StyleMatch> styleMatches = getApplicableStyles(styles, cueId, startTag);
|
List<StyleMatch> styleMatches = getApplicableStyles(styles, cueId, startTag);
|
||||||
for (int i = 0; i < styleMatches.size(); i++) {
|
for (int i = 0; i < styleMatches.size(); i++) {
|
||||||
WebvttCssStyle style = styleMatches.get(i).style;
|
WebvttCssStyle style = styleMatches.get(i).style;
|
||||||
if (style.getRubyPosition() != RubySpan.POSITION_UNKNOWN) {
|
if (style.getRubyPosition() != TextAnnotation.POSITION_UNKNOWN) {
|
||||||
return style.getRubyPosition();
|
return style.getRubyPosition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return RubySpan.POSITION_UNKNOWN;
|
return TextAnnotation.POSITION_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RubySpan.Position
|
@TextAnnotation.Position
|
||||||
private static int firstKnownRubyPosition(
|
private static int firstKnownRubyPosition(
|
||||||
@RubySpan.Position int position1,
|
@TextAnnotation.Position int position1,
|
||||||
@RubySpan.Position int position2,
|
@TextAnnotation.Position int position2,
|
||||||
@RubySpan.Position int position3) {
|
@TextAnnotation.Position int position3) {
|
||||||
if (position1 != RubySpan.POSITION_UNKNOWN) {
|
if (position1 != TextAnnotation.POSITION_UNKNOWN) {
|
||||||
return position1;
|
return position1;
|
||||||
}
|
}
|
||||||
if (position2 != RubySpan.POSITION_UNKNOWN) {
|
if (position2 != TextAnnotation.POSITION_UNKNOWN) {
|
||||||
return position2;
|
return position2;
|
||||||
}
|
}
|
||||||
if (position3 != RubySpan.POSITION_UNKNOWN) {
|
if (position3 != TextAnnotation.POSITION_UNKNOWN) {
|
||||||
return position3;
|
return position3;
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import static com.google.common.truth.Truth.assertThat;
|
||||||
import static com.google.common.truth.Truth.assertWithMessage;
|
import static com.google.common.truth.Truth.assertWithMessage;
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
|
@ -21,7 +21,6 @@ public class TextEmphasisTest {
|
||||||
String value = null;
|
String value = null;
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must be null").that(textEmphasis).isNull();
|
assertWithMessage("Text Emphasis must be null").that(textEmphasis).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,7 +29,6 @@ public class TextEmphasisTest {
|
||||||
String value = "";
|
String value = "";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must be null").that(textEmphasis).isNull();
|
assertWithMessage("Text Emphasis must be null").that(textEmphasis).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,7 +37,6 @@ public class TextEmphasisTest {
|
||||||
String value = "none";
|
String value = "none";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must be null").that(textEmphasis).isNull();
|
assertWithMessage("Text Emphasis must be null").that(textEmphasis).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,10 +45,9 @@ public class TextEmphasisTest {
|
||||||
String value = "auto";
|
String value = "auto";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_AUTO);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasis.MARK_AUTO);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_UNKNOWN);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -59,26 +55,57 @@ public class TextEmphasisTest {
|
||||||
String value = "auto outside";
|
String value = "auto outside";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_AUTO);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasis.MARK_AUTO);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_OUTSIDE);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If only filled or open is specified, then it is equivalent to filled circle and open circle,
|
||||||
|
* respectively.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testFilled() {
|
||||||
|
String value = "filled";
|
||||||
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
||||||
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOpen() {
|
||||||
|
String value = "open";
|
||||||
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_CIRCLE);
|
||||||
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOpenAfter() {
|
||||||
|
String value = "open after";
|
||||||
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_CIRCLE);
|
||||||
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If only circle, dot, or sesame is specified, then it is equivalent to filled circle, filled dot,
|
* If only circle, dot, or sesame is specified, then it is equivalent to filled circle, filled dot,
|
||||||
* and filled sesame, respectively.
|
* and filled sesame, respectively.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDotBefore() {
|
public void testDotBefore() {
|
||||||
String value = "dot before";
|
String value = "dot before";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_BEFORE);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -86,10 +113,9 @@ public class TextEmphasisTest {
|
||||||
String value = "circle before";
|
String value = "circle before";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_BEFORE);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -97,10 +123,9 @@ public class TextEmphasisTest {
|
||||||
String value = "sesame before";
|
String value = "sesame before";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_BEFORE);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -108,10 +133,9 @@ public class TextEmphasisTest {
|
||||||
String value = "dot AFTER";
|
String value = "dot AFTER";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_AFTER);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -119,10 +143,9 @@ public class TextEmphasisTest {
|
||||||
String value = "circle after";
|
String value = "circle after";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_AFTER);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -130,10 +153,9 @@ public class TextEmphasisTest {
|
||||||
String value = "sesame aFter";
|
String value = "sesame aFter";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_AFTER);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -141,10 +163,9 @@ public class TextEmphasisTest {
|
||||||
String value = "dot outside";
|
String value = "dot outside";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_OUTSIDE);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -152,10 +173,9 @@ public class TextEmphasisTest {
|
||||||
String value = "circle outside";
|
String value = "circle outside";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_OUTSIDE);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -163,10 +183,9 @@ public class TextEmphasisTest {
|
||||||
String value = "sesame outside";
|
String value = "sesame outside";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_OUTSIDE);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -174,10 +193,9 @@ public class TextEmphasisTest {
|
||||||
String value = "open dot AFTER";
|
String value = "open dot AFTER";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_DOT);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_DOT);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_AFTER);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -185,10 +203,9 @@ public class TextEmphasisTest {
|
||||||
String value = "Open circle after";
|
String value = "Open circle after";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_CIRCLE);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_CIRCLE);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_AFTER);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -196,10 +213,9 @@ public class TextEmphasisTest {
|
||||||
String value = "open sesame aFter";
|
String value = "open sesame aFter";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_SESAME);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_SESAME);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_AFTER);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -207,10 +223,9 @@ public class TextEmphasisTest {
|
||||||
String value = "open dot before";
|
String value = "open dot before";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_DOT);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_DOT);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_BEFORE);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -218,10 +233,9 @@ public class TextEmphasisTest {
|
||||||
String value = "Open circle Before";
|
String value = "Open circle Before";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_CIRCLE);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_CIRCLE);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_BEFORE);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -229,10 +243,9 @@ public class TextEmphasisTest {
|
||||||
String value = "open sesame Before";
|
String value = "open sesame Before";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_SESAME);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_SESAME);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_BEFORE);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -240,10 +253,9 @@ public class TextEmphasisTest {
|
||||||
String value = "open dot Outside";
|
String value = "open dot Outside";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_DOT);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_DOT);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_OUTSIDE);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -251,10 +263,9 @@ public class TextEmphasisTest {
|
||||||
String value = "Open circle Outside";
|
String value = "Open circle Outside";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_CIRCLE);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_CIRCLE);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_OUTSIDE);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -262,10 +273,9 @@ public class TextEmphasisTest {
|
||||||
String value = "open sesame outside";
|
String value = "open sesame outside";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_SESAME);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_SESAME);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_OUTSIDE);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -273,10 +283,9 @@ public class TextEmphasisTest {
|
||||||
String value = "filled dot outside";
|
String value = "filled dot outside";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_OUTSIDE);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -284,10 +293,9 @@ public class TextEmphasisTest {
|
||||||
String value = "filled circle outside";
|
String value = "filled circle outside";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_OUTSIDE);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -295,10 +303,9 @@ public class TextEmphasisTest {
|
||||||
String value = "filled sesame outside";
|
String value = "filled sesame outside";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_OUTSIDE);
|
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -306,10 +313,9 @@ public class TextEmphasisTest {
|
||||||
String value = "filled dot After";
|
String value = "filled dot After";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_AFTER);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -317,10 +323,9 @@ public class TextEmphasisTest {
|
||||||
String value = "filled circle after";
|
String value = "filled circle after";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_AFTER);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -328,10 +333,9 @@ public class TextEmphasisTest {
|
||||||
String value = "filled sesame After";
|
String value = "filled sesame After";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_AFTER);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -339,10 +343,9 @@ public class TextEmphasisTest {
|
||||||
String value = "filled dot before";
|
String value = "filled dot before";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_BEFORE);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -350,10 +353,9 @@ public class TextEmphasisTest {
|
||||||
String value = "filled circle Before";
|
String value = "filled circle Before";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_BEFORE);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -361,9 +363,28 @@ public class TextEmphasisTest {
|
||||||
String value = "filled sesame Before";
|
String value = "filled sesame Before";
|
||||||
TextEmphasis textEmphasis = createTextEmphasis(value);
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
Log.d(TAG, "textEmphasis: " + textEmphasis);
|
|
||||||
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
||||||
assertThat(textEmphasis.position).isEqualTo(TextEmphasisSpan.POSITION_BEFORE);
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBeforeFilledSesame() {
|
||||||
|
String value = "before filled sesame";
|
||||||
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
||||||
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBeforeSesameFilled() {
|
||||||
|
String value = "before sesame filled";
|
||||||
|
TextEmphasis textEmphasis = createTextEmphasis(value);
|
||||||
|
|
||||||
|
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
|
||||||
|
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
|
||||||
|
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import com.google.android.exoplayer2.text.Cue;
|
||||||
import com.google.android.exoplayer2.text.Subtitle;
|
import com.google.android.exoplayer2.text.Subtitle;
|
||||||
import com.google.android.exoplayer2.text.SubtitleDecoderException;
|
import com.google.android.exoplayer2.text.SubtitleDecoderException;
|
||||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.ColorParser;
|
import com.google.android.exoplayer2.util.ColorParser;
|
||||||
|
|
@ -648,16 +649,16 @@ public final class TtmlDecoderTest {
|
||||||
assertThat(firstCue.toString()).isEqualTo("Cue with annotated text.");
|
assertThat(firstCue.toString()).isEqualTo("Cue with annotated text.");
|
||||||
assertThat(firstCue)
|
assertThat(firstCue)
|
||||||
.hasRubySpanBetween("Cue with ".length(), "Cue with annotated".length())
|
.hasRubySpanBetween("Cue with ".length(), "Cue with annotated".length())
|
||||||
.withTextAndPosition("1st rubies", RubySpan.POSITION_OVER);
|
.withTextAndPosition("1st rubies", TextAnnotation.POSITION_BEFORE);
|
||||||
assertThat(firstCue)
|
assertThat(firstCue)
|
||||||
.hasRubySpanBetween("Cue with annotated ".length(), "Cue with annotated text".length())
|
.hasRubySpanBetween("Cue with annotated ".length(), "Cue with annotated text".length())
|
||||||
.withTextAndPosition("2nd rubies", RubySpan.POSITION_UNKNOWN);
|
.withTextAndPosition("2nd rubies", TextAnnotation.POSITION_UNKNOWN);
|
||||||
|
|
||||||
Spanned secondCue = getOnlyCueTextAtTimeUs(subtitle, 20_000_000);
|
Spanned secondCue = getOnlyCueTextAtTimeUs(subtitle, 20_000_000);
|
||||||
assertThat(secondCue.toString()).isEqualTo("Cue with annotated text.");
|
assertThat(secondCue.toString()).isEqualTo("Cue with annotated text.");
|
||||||
assertThat(secondCue)
|
assertThat(secondCue)
|
||||||
.hasRubySpanBetween("Cue with ".length(), "Cue with annotated".length())
|
.hasRubySpanBetween("Cue with ".length(), "Cue with annotated".length())
|
||||||
.withTextAndPosition("rubies", RubySpan.POSITION_UNKNOWN);
|
.withTextAndPosition("rubies", TextAnnotation.POSITION_UNKNOWN);
|
||||||
|
|
||||||
Spanned thirdCue = getOnlyCueTextAtTimeUs(subtitle, 30_000_000);
|
Spanned thirdCue = getOnlyCueTextAtTimeUs(subtitle, 30_000_000);
|
||||||
assertThat(thirdCue.toString()).isEqualTo("Cue with annotated text.");
|
assertThat(thirdCue.toString()).isEqualTo("Cue with annotated text.");
|
||||||
|
|
@ -681,69 +682,68 @@ public final class TtmlDecoderTest {
|
||||||
TtmlSubtitle subtitle = getSubtitle(TEXT_EMPHASIS_FILE);
|
TtmlSubtitle subtitle = getSubtitle(TEXT_EMPHASIS_FILE);
|
||||||
|
|
||||||
Spanned firstCue = getOnlyCueTextAtTimeUs(subtitle, 10_000_000);
|
Spanned firstCue = getOnlyCueTextAtTimeUs(subtitle, 10_000_000);
|
||||||
assertThat(firstCue)
|
assertThat(firstCue).hasNoSpans();
|
||||||
.hasNoTextEmphasisSpanBetween("None ".length(), "None おはよ".length());
|
|
||||||
|
|
||||||
Spanned secondCue = getOnlyCueTextAtTimeUs(subtitle, 20_000_000);
|
Spanned secondCue = getOnlyCueTextAtTimeUs(subtitle, 20_000_000);
|
||||||
assertThat(secondCue)
|
assertThat(secondCue)
|
||||||
.hasTextEmphasisSpanBetween("Auto ".length(), "Auto ございます".length())
|
.hasTextEmphasisSpanBetween("Auto ".length(), "Auto ございます".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
|
||||||
TextEmphasisSpan.POSITION_UNKNOWN);
|
TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned thirdCue = getOnlyCueTextAtTimeUs(subtitle, 30_000_000);
|
Spanned thirdCue = getOnlyCueTextAtTimeUs(subtitle, 30_000_000);
|
||||||
assertThat(thirdCue)
|
assertThat(thirdCue)
|
||||||
.hasTextEmphasisSpanBetween("Filled circle ".length(), "Filled circle こんばんは".length())
|
.hasTextEmphasisSpanBetween("Filled circle ".length(), "Filled circle こんばんは".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
|
||||||
TextEmphasisSpan.POSITION_UNKNOWN);
|
TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned fourthCue = getOnlyCueTextAtTimeUs(subtitle, 40_000_000);
|
Spanned fourthCue = getOnlyCueTextAtTimeUs(subtitle, 40_000_000);
|
||||||
assertThat(fourthCue)
|
assertThat(fourthCue)
|
||||||
.hasTextEmphasisSpanBetween("Filled dot ".length(), "Filled dot ございます".length())
|
.hasTextEmphasisSpanBetween("Filled dot ".length(), "Filled dot ございます".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_DOT, TextEmphasisSpan.POSITION_UNKNOWN);
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_DOT, TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned fifthCue = getOnlyCueTextAtTimeUs(subtitle, 50_000_000);
|
Spanned fifthCue = getOnlyCueTextAtTimeUs(subtitle, 50_000_000);
|
||||||
assertThat(fifthCue)
|
assertThat(fifthCue)
|
||||||
.hasTextEmphasisSpanBetween("Filled sesame ".length(), "Filled sesame おはよ".length())
|
.hasTextEmphasisSpanBetween("Filled sesame ".length(), "Filled sesame おはよ".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
|
||||||
TextEmphasisSpan.POSITION_UNKNOWN);
|
TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned sixthCue = getOnlyCueTextAtTimeUs(subtitle, 60_000_000);
|
Spanned sixthCue = getOnlyCueTextAtTimeUs(subtitle, 60_000_000);
|
||||||
assertThat(sixthCue)
|
assertThat(sixthCue)
|
||||||
.hasTextEmphasisSpanBetween("Open circle before ".length(),
|
.hasTextEmphasisSpanBetween("Open circle before ".length(),
|
||||||
"Open circle before ございます".length())
|
"Open circle before ございます".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_OPEN_CIRCLE, TextEmphasisSpan.POSITION_BEFORE);
|
.withMarkAndPosition(TextEmphasisSpan.MARK_OPEN_CIRCLE, TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned seventhCue = getOnlyCueTextAtTimeUs(subtitle, 70_000_000);
|
Spanned seventhCue = getOnlyCueTextAtTimeUs(subtitle, 70_000_000);
|
||||||
assertThat(seventhCue)
|
assertThat(seventhCue)
|
||||||
.hasTextEmphasisSpanBetween("Open dot after ".length(), "Open dot after おはよ".length())
|
.hasTextEmphasisSpanBetween("Open dot after ".length(), "Open dot after おはよ".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_OPEN_DOT, TextEmphasisSpan.POSITION_AFTER);
|
.withMarkAndPosition(TextEmphasisSpan.MARK_OPEN_DOT, TextAnnotation.POSITION_AFTER);
|
||||||
|
|
||||||
Spanned eighthCue = getOnlyCueTextAtTimeUs(subtitle, 80_000_000);
|
Spanned eighthCue = getOnlyCueTextAtTimeUs(subtitle, 80_000_000);
|
||||||
assertThat(eighthCue)
|
assertThat(eighthCue)
|
||||||
.hasTextEmphasisSpanBetween("Open sesame outside ".length(),
|
.hasTextEmphasisSpanBetween("Open sesame outside ".length(),
|
||||||
"Open sesame outside ございます".length())
|
"Open sesame outside ございます".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_OPEN_SESAME, TextEmphasisSpan.POSITION_OUTSIDE);
|
.withMarkAndPosition(TextEmphasisSpan.MARK_OPEN_SESAME, TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned ninthCue = getOnlyCueTextAtTimeUs(subtitle, 90_000_000);
|
Spanned ninthCue = getOnlyCueTextAtTimeUs(subtitle, 90_000_000);
|
||||||
assertThat(ninthCue)
|
assertThat(ninthCue)
|
||||||
.hasTextEmphasisSpanBetween("Auto outside ".length(), "Auto outside おはよ".length())
|
.hasTextEmphasisSpanBetween("Auto outside ".length(), "Auto outside おはよ".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
|
||||||
TextEmphasisSpan.POSITION_OUTSIDE);
|
TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned tenthCue = getOnlyCueTextAtTimeUs(subtitle, 100_000_000);
|
Spanned tenthCue = getOnlyCueTextAtTimeUs(subtitle, 100_000_000);
|
||||||
assertThat(tenthCue)
|
assertThat(tenthCue)
|
||||||
.hasTextEmphasisSpanBetween("Circle before ".length(), "Circle before ございます".length())
|
.hasTextEmphasisSpanBetween("Circle before ".length(), "Circle before ございます".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE, TextEmphasisSpan.POSITION_BEFORE);
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE, TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned eleventhCue = getOnlyCueTextAtTimeUs(subtitle, 110_000_000);
|
Spanned eleventhCue = getOnlyCueTextAtTimeUs(subtitle, 110_000_000);
|
||||||
assertThat(eleventhCue)
|
assertThat(eleventhCue)
|
||||||
.hasTextEmphasisSpanBetween("Sesame after ".length(), "Sesame after おはよ".length())
|
.hasTextEmphasisSpanBetween("Sesame after ".length(), "Sesame after おはよ".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME, TextEmphasisSpan.POSITION_AFTER);
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME, TextAnnotation.POSITION_AFTER);
|
||||||
|
|
||||||
Spanned twelfthCue = getOnlyCueTextAtTimeUs(subtitle, 120_000_000);
|
Spanned twelfthCue = getOnlyCueTextAtTimeUs(subtitle, 120_000_000);
|
||||||
assertThat(twelfthCue)
|
assertThat(twelfthCue)
|
||||||
.hasTextEmphasisSpanBetween("Dot outside ".length(), "Dot outside ございます".length())
|
.hasTextEmphasisSpanBetween("Dot outside ".length(), "Dot outside ございます".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_DOT, TextEmphasisSpan.POSITION_OUTSIDE);
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_DOT, TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned thirteenthCue = getOnlyCueTextAtTimeUs(subtitle, 130_000_000);
|
Spanned thirteenthCue = getOnlyCueTextAtTimeUs(subtitle, 130_000_000);
|
||||||
assertThat(thirteenthCue)
|
assertThat(thirteenthCue)
|
||||||
|
|
@ -754,25 +754,25 @@ public final class TtmlDecoderTest {
|
||||||
assertThat(fourteenthCue)
|
assertThat(fourteenthCue)
|
||||||
.hasTextEmphasisSpanBetween("Auto (TBLR) ".length(), "Auto (TBLR) ございます".length())
|
.hasTextEmphasisSpanBetween("Auto (TBLR) ".length(), "Auto (TBLR) ございます".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
|
||||||
TextEmphasisSpan.POSITION_UNKNOWN);
|
TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned fifteenthCue = getOnlyCueTextAtTimeUs(subtitle, 150_000_000);
|
Spanned fifteenthCue = getOnlyCueTextAtTimeUs(subtitle, 150_000_000);
|
||||||
assertThat(fifteenthCue)
|
assertThat(fifteenthCue)
|
||||||
.hasTextEmphasisSpanBetween("Auto (TBRL) ".length(), "Auto (TBRL) おはよ".length())
|
.hasTextEmphasisSpanBetween("Auto (TBRL) ".length(), "Auto (TBRL) おはよ".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
|
||||||
TextEmphasisSpan.POSITION_UNKNOWN);
|
TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned sixteenthCue = getOnlyCueTextAtTimeUs(subtitle, 160_000_000);
|
Spanned sixteenthCue = getOnlyCueTextAtTimeUs(subtitle, 160_000_000);
|
||||||
assertThat(sixteenthCue)
|
assertThat(sixteenthCue)
|
||||||
.hasTextEmphasisSpanBetween("Auto (TB) ".length(), "Auto (TB) ございます".length())
|
.hasTextEmphasisSpanBetween("Auto (TB) ".length(), "Auto (TB) ございます".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
|
||||||
TextEmphasisSpan.POSITION_UNKNOWN);
|
TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
Spanned seventeenthCue = getOnlyCueTextAtTimeUs(subtitle, 170_000_000);
|
Spanned seventeenthCue = getOnlyCueTextAtTimeUs(subtitle, 170_000_000);
|
||||||
assertThat(seventeenthCue)
|
assertThat(seventeenthCue)
|
||||||
.hasTextEmphasisSpanBetween("Auto (LR) ".length(), "Auto (LR) おはよ".length())
|
.hasTextEmphasisSpanBetween("Auto (LR) ".length(), "Auto (LR) おはよ".length())
|
||||||
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
|
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
|
||||||
TextEmphasisSpan.POSITION_UNKNOWN);
|
TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Spanned getOnlyCueTextAtTimeUs(Subtitle subtitle, long timeUs) {
|
private static Spanned getOnlyCueTextAtTimeUs(Subtitle subtitle, long timeUs) {
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,9 @@
|
||||||
package com.google.android.exoplayer2.text.ttml;
|
package com.google.android.exoplayer2.text.ttml;
|
||||||
|
|
||||||
import static android.graphics.Color.BLACK;
|
import static android.graphics.Color.BLACK;
|
||||||
|
import static com.google.android.exoplayer2.text.span.TextAnnotation.POSITION_BEFORE;
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_FILLED_DOT;
|
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_FILLED_DOT;
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_OPEN_SESAME;
|
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.MARK_OPEN_SESAME;
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.POSITION_AFTER;
|
|
||||||
import static com.google.android.exoplayer2.text.span.TextEmphasisSpan.POSITION_BEFORE;
|
|
||||||
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_BOLD;
|
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_BOLD;
|
||||||
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_BOLD_ITALIC;
|
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_BOLD_ITALIC;
|
||||||
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_ITALIC;
|
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_ITALIC;
|
||||||
|
|
@ -32,7 +31,7 @@ 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.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
|
@ -47,7 +46,7 @@ public final class TtmlStyleTest {
|
||||||
@TtmlStyle.FontSizeUnit private static final int FONT_SIZE_UNIT = TtmlStyle.FONT_SIZE_UNIT_EM;
|
@TtmlStyle.FontSizeUnit private static final int FONT_SIZE_UNIT = TtmlStyle.FONT_SIZE_UNIT_EM;
|
||||||
@ColorInt private static final int BACKGROUND_COLOR = Color.BLACK;
|
@ColorInt private static final int BACKGROUND_COLOR = Color.BLACK;
|
||||||
private static final int RUBY_TYPE = TtmlStyle.RUBY_TYPE_TEXT;
|
private static final int RUBY_TYPE = TtmlStyle.RUBY_TYPE_TEXT;
|
||||||
private static final int RUBY_POSITION = RubySpan.POSITION_UNDER;
|
private static final int RUBY_POSITION = TextAnnotation.POSITION_AFTER;
|
||||||
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";
|
||||||
|
|
@ -233,9 +232,9 @@ public final class TtmlStyleTest {
|
||||||
public void rubyPosition() {
|
public void rubyPosition() {
|
||||||
TtmlStyle style = new TtmlStyle();
|
TtmlStyle style = new TtmlStyle();
|
||||||
|
|
||||||
assertThat(style.getRubyPosition()).isEqualTo(RubySpan.POSITION_UNKNOWN);
|
assertThat(style.getRubyPosition()).isEqualTo(TextAnnotation.POSITION_UNKNOWN);
|
||||||
style.setRubyPosition(RubySpan.POSITION_OVER);
|
style.setRubyPosition(POSITION_BEFORE);
|
||||||
assertThat(style.getRubyPosition()).isEqualTo(RubySpan.POSITION_OVER);
|
assertThat(style.getRubyPosition()).isEqualTo(POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -264,6 +263,6 @@ public final class TtmlStyleTest {
|
||||||
assertThat(style.getTextEmphasis()).isNull();
|
assertThat(style.getTextEmphasis()).isNull();
|
||||||
style.setTextEmphasis(TextEmphasis.createTextEmphasis("open sesame after"));
|
style.setTextEmphasis(TextEmphasis.createTextEmphasis("open sesame after"));
|
||||||
assertThat(style.getTextEmphasis().mark).isEqualTo(MARK_OPEN_SESAME);
|
assertThat(style.getTextEmphasis().mark).isEqualTo(MARK_OPEN_SESAME);
|
||||||
assertThat(style.getTextEmphasis().position).isEqualTo(POSITION_AFTER);
|
assertThat(style.getTextEmphasis().position).isEqualTo(TextAnnotation.POSITION_AFTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import com.google.android.exoplayer2.testutil.TestUtil;
|
||||||
import com.google.android.exoplayer2.text.Cue;
|
import com.google.android.exoplayer2.text.Cue;
|
||||||
import com.google.android.exoplayer2.text.SubtitleDecoderException;
|
import com.google.android.exoplayer2.text.SubtitleDecoderException;
|
||||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.ColorParser;
|
import com.google.android.exoplayer2.util.ColorParser;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
@ -349,7 +350,7 @@ public class WebvttDecoderTest {
|
||||||
assertThat(firstCue.text.toString()).isEqualTo("Some text with over-ruby.");
|
assertThat(firstCue.text.toString()).isEqualTo("Some text with over-ruby.");
|
||||||
assertThat((Spanned) firstCue.text)
|
assertThat((Spanned) firstCue.text)
|
||||||
.hasRubySpanBetween("Some ".length(), "Some text with over-ruby".length())
|
.hasRubySpanBetween("Some ".length(), "Some text with over-ruby".length())
|
||||||
.withTextAndPosition("over", RubySpan.POSITION_OVER);
|
.withTextAndPosition("over", TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
// Check that `under` is read from CSS and unspecified defaults to `over`.
|
// Check that `under` is read from CSS and unspecified defaults to `over`.
|
||||||
Cue secondCue = Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(2)));
|
Cue secondCue = Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(2)));
|
||||||
|
|
@ -357,25 +358,25 @@ public class WebvttDecoderTest {
|
||||||
.isEqualTo("Some text with under-ruby and over-ruby (default).");
|
.isEqualTo("Some text with under-ruby and over-ruby (default).");
|
||||||
assertThat((Spanned) secondCue.text)
|
assertThat((Spanned) secondCue.text)
|
||||||
.hasRubySpanBetween("Some ".length(), "Some text with under-ruby".length())
|
.hasRubySpanBetween("Some ".length(), "Some text with under-ruby".length())
|
||||||
.withTextAndPosition("under", RubySpan.POSITION_UNDER);
|
.withTextAndPosition("under", TextAnnotation.POSITION_AFTER);
|
||||||
assertThat((Spanned) secondCue.text)
|
assertThat((Spanned) secondCue.text)
|
||||||
.hasRubySpanBetween(
|
.hasRubySpanBetween(
|
||||||
"Some text with under-ruby and ".length(),
|
"Some text with under-ruby and ".length(),
|
||||||
"Some text with under-ruby and over-ruby (default)".length())
|
"Some text with under-ruby and over-ruby (default)".length())
|
||||||
.withTextAndPosition("over", RubySpan.POSITION_OVER);
|
.withTextAndPosition("over", TextAnnotation.POSITION_BEFORE);
|
||||||
|
|
||||||
// Check many <rt> tags with different positions nested in a single <ruby> span.
|
// Check many <rt> tags with different positions nested in a single <ruby> span.
|
||||||
Cue thirdCue = Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(4)));
|
Cue thirdCue = Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(4)));
|
||||||
assertThat(thirdCue.text.toString()).isEqualTo("base1base2base3.");
|
assertThat(thirdCue.text.toString()).isEqualTo("base1base2base3.");
|
||||||
assertThat((Spanned) thirdCue.text)
|
assertThat((Spanned) thirdCue.text)
|
||||||
.hasRubySpanBetween(/* start= */ 0, "base1".length())
|
.hasRubySpanBetween(/* start= */ 0, "base1".length())
|
||||||
.withTextAndPosition("over1", RubySpan.POSITION_OVER);
|
.withTextAndPosition("over1", TextAnnotation.POSITION_BEFORE);
|
||||||
assertThat((Spanned) thirdCue.text)
|
assertThat((Spanned) thirdCue.text)
|
||||||
.hasRubySpanBetween("base1".length(), "base1base2".length())
|
.hasRubySpanBetween("base1".length(), "base1base2".length())
|
||||||
.withTextAndPosition("under2", RubySpan.POSITION_UNDER);
|
.withTextAndPosition("under2", TextAnnotation.POSITION_AFTER);
|
||||||
assertThat((Spanned) thirdCue.text)
|
assertThat((Spanned) thirdCue.text)
|
||||||
.hasRubySpanBetween("base1base2".length(), "base1base2base3".length())
|
.hasRubySpanBetween("base1base2".length(), "base1base2base3".length())
|
||||||
.withTextAndPosition("under3", RubySpan.POSITION_UNDER);
|
.withTextAndPosition("under3", TextAnnotation.POSITION_AFTER);
|
||||||
|
|
||||||
// Check a <ruby> span with no <rt> tags.
|
// Check a <ruby> span with no <rt> tags.
|
||||||
Cue fourthCue = Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(6)));
|
Cue fourthCue = Iterables.getOnlyElement(subtitle.getCues(subtitle.getEventTime(6)));
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import android.util.SparseArray;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
||||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
|
@ -187,11 +188,11 @@ import java.util.regex.Pattern;
|
||||||
} else if (span instanceof RubySpan) {
|
} else if (span instanceof RubySpan) {
|
||||||
RubySpan rubySpan = (RubySpan) span;
|
RubySpan rubySpan = (RubySpan) span;
|
||||||
switch (rubySpan.position) {
|
switch (rubySpan.position) {
|
||||||
case RubySpan.POSITION_OVER:
|
case TextAnnotation.POSITION_BEFORE:
|
||||||
return "<ruby style='ruby-position:over;'>";
|
return "<ruby style='ruby-position:over;'>";
|
||||||
case RubySpan.POSITION_UNDER:
|
case TextAnnotation.POSITION_AFTER:
|
||||||
return "<ruby style='ruby-position:under;'>";
|
return "<ruby style='ruby-position:under;'>";
|
||||||
case RubySpan.POSITION_UNKNOWN:
|
case TextAnnotation.POSITION_UNKNOWN:
|
||||||
return "<ruby style='ruby-position:unset;'>";
|
return "<ruby style='ruby-position:unset;'>";
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -256,23 +257,17 @@ import java.util.regex.Pattern;
|
||||||
return "open dot";
|
return "open dot";
|
||||||
case TextEmphasisSpan.MARK_OPEN_SESAME:
|
case TextEmphasisSpan.MARK_OPEN_SESAME:
|
||||||
return "open sesame";
|
return "open sesame";
|
||||||
case TextEmphasisSpan.MARK_AUTO: // TODO
|
|
||||||
// https://www.w3.org/TR/ttml2/#style-value-emphasis-style
|
|
||||||
// If a vertical writing mode applies, then equivalent to filled sesame; otherwise,
|
|
||||||
// equivalent to filled circle.
|
|
||||||
case TextEmphasisSpan.MARK_UNKNOWN:
|
|
||||||
default:
|
default:
|
||||||
return "unset";
|
return "unset";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getTextEmphasisPosition(@TextEmphasisSpan.Position int position){
|
private static String getTextEmphasisPosition(@TextAnnotation.Position int position){
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case TextEmphasisSpan.POSITION_AFTER:
|
case TextAnnotation.POSITION_AFTER:
|
||||||
return "under left";
|
return "under left";
|
||||||
case TextEmphasisSpan.POSITION_UNKNOWN:
|
case TextAnnotation.POSITION_UNKNOWN:
|
||||||
case TextEmphasisSpan.POSITION_BEFORE:
|
case TextAnnotation.POSITION_BEFORE:
|
||||||
case TextEmphasisSpan.POSITION_OUTSIDE: /* Not supported, fallback to "before" */
|
|
||||||
default:
|
default:
|
||||||
// https://www.w3.org/TR/ttml2/#style-value-annotation-position
|
// https://www.w3.org/TR/ttml2/#style-value-annotation-position
|
||||||
// If an implementation does not recognize or otherwise distinguish an annotation position
|
// If an implementation does not recognize or otherwise distinguish an annotation position
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
||||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
@ -251,12 +252,12 @@ public class SpannedToHtmlConverterTest {
|
||||||
SpannableString spanned =
|
SpannableString spanned =
|
||||||
new SpannableString("String with over-annotated and under-annotated section");
|
new SpannableString("String with over-annotated and under-annotated section");
|
||||||
spanned.setSpan(
|
spanned.setSpan(
|
||||||
new RubySpan("ruby-text", RubySpan.POSITION_OVER),
|
new RubySpan("ruby-text", TextAnnotation.POSITION_BEFORE),
|
||||||
"String with ".length(),
|
"String with ".length(),
|
||||||
"String with over-annotated".length(),
|
"String with over-annotated".length(),
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
spanned.setSpan(
|
spanned.setSpan(
|
||||||
new RubySpan("non-àscìì-text", RubySpan.POSITION_UNDER),
|
new RubySpan("non-àscìì-text", TextAnnotation.POSITION_AFTER),
|
||||||
"String with over-annotated and ".length(),
|
"String with over-annotated and ".length(),
|
||||||
"String with over-annotated and under-annotated".length(),
|
"String with over-annotated and under-annotated".length(),
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
@ -284,13 +285,13 @@ public class SpannedToHtmlConverterTest {
|
||||||
public void convert_supportsTextEmphasisSpan() {
|
public void convert_supportsTextEmphasisSpan() {
|
||||||
SpannableString spanned = new SpannableString("Text emphasis おはよ ございます ");
|
SpannableString spanned = new SpannableString("Text emphasis おはよ ございます ");
|
||||||
spanned.setSpan(
|
spanned.setSpan(
|
||||||
new TextEmphasisSpan(TextEmphasisSpan.MARK_FILLED_CIRCLE, TextEmphasisSpan.POSITION_BEFORE),
|
new TextEmphasisSpan(TextEmphasisSpan.MARK_FILLED_CIRCLE, TextAnnotation.POSITION_BEFORE),
|
||||||
"Text emphasis ".length(),
|
"Text emphasis ".length(),
|
||||||
"Text emphasis おはよ".length(),
|
"Text emphasis おはよ".length(),
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
spanned.setSpan(
|
spanned.setSpan(
|
||||||
new TextEmphasisSpan(TextEmphasisSpan.MARK_OPEN_SESAME, TextEmphasisSpan.POSITION_AFTER),
|
new TextEmphasisSpan(TextEmphasisSpan.MARK_OPEN_SESAME, TextAnnotation.POSITION_AFTER),
|
||||||
"Text emphasis おはよ ".length(),
|
"Text emphasis おはよ ".length(),
|
||||||
"Text emphasis おはよ ございます ".length(),
|
"Text emphasis おはよ ございます ".length(),
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
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">
|
||||||
<head>
|
<head>
|
||||||
<region xml:id="region1" tts:extent="80.000% 80.000%" tts:origin="10.000% 10.000%" tts:writingMode="tbrl"/>
|
<region xml:id="region_tbrl" tts:extent="80.000% 80.000%" tts:origin="10.000% 10.000%" tts:writingMode="tbrl"/>
|
||||||
<region xml:id="region2" tts:extent="80.000% 80.000%" tts:origin="10.000% 10.000%" tts:writingMode="tblr"/>
|
<region xml:id="region_tblr" tts:extent="80.000% 80.000%" tts:origin="10.000% 10.000%" tts:writingMode="tblr"/>
|
||||||
<region xml:id="region3" tts:extent="80.000% 80.000%" tts:origin="10.000% 10.000%" tts:writingMode="tb"/>
|
<region xml:id="region_tb" tts:extent="80.000% 80.000%" tts:origin="10.000% 10.000%" tts:writingMode="tb"/>
|
||||||
<region xml:id="region4" tts:extent="80.000% 80.000%" tts:origin="10.000% 10.000%" tts:writingMode="lr"/>
|
<region xml:id="region_lr" tts:extent="80.000% 80.000%" tts:origin="10.000% 10.000%" tts:writingMode="lr"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -49,16 +49,16 @@
|
||||||
<p begin="130s" end="138s">No textEmphasis property <span>おはよ</span></p>
|
<p begin="130s" end="138s">No textEmphasis property <span>おはよ</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p begin="140s" end="148s" region="region1">Auto (TBLR) <span tts:textEmphasis="auto">ございます</span></p>
|
<p begin="140s" end="148s" region="region_tbrl">Auto (TBLR) <span tts:textEmphasis="auto">ございます</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p begin="150s" end="158s" region="region2">Auto (TBRL) <span tts:textEmphasis="auto">おはよ</span></p>
|
<p begin="150s" end="158s" region="region_tblr">Auto (TBRL) <span tts:textEmphasis="auto">おはよ</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p begin="160s" end="168s" region="region3">Auto (TB) <span tts:textEmphasis="auto">ございます</span></p>
|
<p begin="160s" end="168s" region="region_tb">Auto (TB) <span tts:textEmphasis="auto">ございます</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p begin="170s" end="178s" region="region4">Auto (LR) <span tts:textEmphasis="auto">おはよ</span></p>
|
<p begin="170s" end="178s" region="region_lr">Auto (LR) <span tts:textEmphasis="auto">おはよ</span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ import androidx.annotation.ColorInt;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
import com.google.android.exoplayer2.text.span.HorizontalTextInVerticalContextSpan;
|
||||||
import com.google.android.exoplayer2.text.span.RubySpan;
|
import com.google.android.exoplayer2.text.span.RubySpan;
|
||||||
|
import com.google.android.exoplayer2.text.span.TextAnnotation;
|
||||||
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.common.truth.Fact;
|
import com.google.common.truth.Fact;
|
||||||
|
|
@ -1075,7 +1076,7 @@ public final class SpannedSubject extends Subject {
|
||||||
* @param position The expected position of the text.
|
* @param position The expected position of the text.
|
||||||
* @return A {@link WithSpanFlags} object for optional additional assertions on the flags.
|
* @return A {@link WithSpanFlags} object for optional additional assertions on the flags.
|
||||||
*/
|
*/
|
||||||
AndSpanFlags withTextAndPosition(String text, @RubySpan.Position int position);
|
AndSpanFlags withTextAndPosition(String text, @TextAnnotation.Position int position);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final RubyText ALREADY_FAILED_WITH_TEXT =
|
private static final RubyText ALREADY_FAILED_WITH_TEXT =
|
||||||
|
|
@ -1099,7 +1100,7 @@ public final class SpannedSubject extends Subject {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AndSpanFlags withTextAndPosition(String text, @RubySpan.Position int position) {
|
public AndSpanFlags withTextAndPosition(String text, @TextAnnotation.Position int position) {
|
||||||
List<Integer> matchingSpanFlags = new ArrayList<>();
|
List<Integer> matchingSpanFlags = new ArrayList<>();
|
||||||
List<TextAndPosition> spanTextsAndPositions = new ArrayList<>();
|
List<TextAndPosition> spanTextsAndPositions = new ArrayList<>();
|
||||||
for (RubySpan span : actualSpans) {
|
for (RubySpan span : actualSpans) {
|
||||||
|
|
@ -1116,7 +1117,7 @@ public final class SpannedSubject extends Subject {
|
||||||
|
|
||||||
private static final class TextAndPosition {
|
private static final class TextAndPosition {
|
||||||
private final String text;
|
private final String text;
|
||||||
@RubySpan.Position private final int position;
|
@TextAnnotation.Position private final int position;
|
||||||
|
|
||||||
private TextAndPosition(String text, int position) {
|
private TextAndPosition(String text, int position) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
|
|
@ -1164,7 +1165,7 @@ public final class SpannedSubject extends Subject {
|
||||||
* @return A {@link WithSpanFlags} object for optional additional assertions on the flags.
|
* @return A {@link WithSpanFlags} object for optional additional assertions on the flags.
|
||||||
*/
|
*/
|
||||||
AndSpanFlags withMarkAndPosition(@TextEmphasisSpan.Mark int mark,
|
AndSpanFlags withMarkAndPosition(@TextEmphasisSpan.Mark int mark,
|
||||||
@TextEmphasisSpan.Position int position);
|
@TextAnnotation.Position int position);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final TextEmphasisDescription ALREADY_FAILED_WITH_MARK =
|
private static final TextEmphasisDescription ALREADY_FAILED_WITH_MARK =
|
||||||
|
|
@ -1189,7 +1190,7 @@ public final class SpannedSubject extends Subject {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AndSpanFlags withMarkAndPosition(@TextEmphasisSpan.Mark int mark,
|
public AndSpanFlags withMarkAndPosition(@TextEmphasisSpan.Mark int mark,
|
||||||
@TextEmphasisSpan.Position int position) {
|
@TextAnnotation.Position int position) {
|
||||||
List<Integer> matchingSpanFlags = new ArrayList<>();
|
List<Integer> matchingSpanFlags = new ArrayList<>();
|
||||||
List<MarkAndPosition> textEmphasisMarksAndPositions = new ArrayList<>();
|
List<MarkAndPosition> textEmphasisMarksAndPositions = new ArrayList<>();
|
||||||
for (TextEmphasisSpan span : actualSpans) {
|
for (TextEmphasisSpan span : actualSpans) {
|
||||||
|
|
@ -1208,39 +1209,19 @@ public final class SpannedSubject extends Subject {
|
||||||
|
|
||||||
@TextEmphasisSpan.Mark
|
@TextEmphasisSpan.Mark
|
||||||
private final int mark;
|
private final int mark;
|
||||||
@TextEmphasisSpan.Position
|
@TextAnnotation.Position
|
||||||
private final int position;
|
private final int position;
|
||||||
|
|
||||||
private MarkAndPosition(@TextEmphasisSpan.Mark int mark,
|
private MarkAndPosition(@TextEmphasisSpan.Mark int mark,
|
||||||
@TextEmphasisSpan.Position int position) {
|
@TextAnnotation.Position int position) {
|
||||||
this.mark = mark;
|
this.mark = mark;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(@Nullable Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextEmphasisSubject.MarkAndPosition that = (TextEmphasisSubject.MarkAndPosition) o;
|
|
||||||
return (position == that.position) && (mark == that.mark);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = 34613 * mark + position;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("{mark=%s,position=%s}", mark, position);
|
return String.format("{mark=%s,position=%s}", mark, position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -609,23 +609,23 @@ public class SpannedSubjectTest {
|
||||||
public void rubySpan_success() {
|
public void rubySpan_success() {
|
||||||
SpannableString spannable =
|
SpannableString spannable =
|
||||||
createSpannable(
|
createSpannable(
|
||||||
new RubySpan("ruby text", RubySpan.POSITION_OVER), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
new RubySpan("ruby text", TextAnnotation.POSITION_BEFORE), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
assertThat(spannable)
|
assertThat(spannable)
|
||||||
.hasRubySpanBetween(SPAN_START, SPAN_END)
|
.hasRubySpanBetween(SPAN_START, SPAN_END)
|
||||||
.withTextAndPosition("ruby text", RubySpan.POSITION_OVER)
|
.withTextAndPosition("ruby text", TextAnnotation.POSITION_BEFORE)
|
||||||
.andFlags(Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
.andFlags(Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rubySpan_wrongEndIndex() {
|
public void rubySpan_wrongEndIndex() {
|
||||||
checkHasSpanFailsDueToIndexMismatch(
|
checkHasSpanFailsDueToIndexMismatch(
|
||||||
new RubySpan("ruby text", RubySpan.POSITION_OVER), SpannedSubject::hasRubySpanBetween);
|
new RubySpan("ruby text", TextAnnotation.POSITION_BEFORE), SpannedSubject::hasRubySpanBetween);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rubySpan_wrongText() {
|
public void rubySpan_wrongText() {
|
||||||
SpannableString spannable = createSpannable(new RubySpan("ruby text", RubySpan.POSITION_OVER));
|
SpannableString spannable = createSpannable(new RubySpan("ruby text", TextAnnotation.POSITION_BEFORE));
|
||||||
|
|
||||||
AssertionError expected =
|
AssertionError expected =
|
||||||
expectFailure(
|
expectFailure(
|
||||||
|
|
@ -633,7 +633,7 @@ public class SpannedSubjectTest {
|
||||||
whenTesting
|
whenTesting
|
||||||
.that(spannable)
|
.that(spannable)
|
||||||
.hasRubySpanBetween(SPAN_START, SPAN_END)
|
.hasRubySpanBetween(SPAN_START, SPAN_END)
|
||||||
.withTextAndPosition("incorrect text", RubySpan.POSITION_OVER));
|
.withTextAndPosition("incorrect text", TextAnnotation.POSITION_BEFORE));
|
||||||
|
|
||||||
assertThat(expected).factValue("value of").contains("rubyTextAndPosition");
|
assertThat(expected).factValue("value of").contains("rubyTextAndPosition");
|
||||||
assertThat(expected).factValue("expected").contains("text='incorrect text'");
|
assertThat(expected).factValue("expected").contains("text='incorrect text'");
|
||||||
|
|
@ -642,7 +642,7 @@ public class SpannedSubjectTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rubySpan_wrongPosition() {
|
public void rubySpan_wrongPosition() {
|
||||||
SpannableString spannable = createSpannable(new RubySpan("ruby text", RubySpan.POSITION_OVER));
|
SpannableString spannable = createSpannable(new RubySpan("ruby text", TextAnnotation.POSITION_BEFORE));
|
||||||
|
|
||||||
AssertionError expected =
|
AssertionError expected =
|
||||||
expectFailure(
|
expectFailure(
|
||||||
|
|
@ -650,27 +650,27 @@ public class SpannedSubjectTest {
|
||||||
whenTesting
|
whenTesting
|
||||||
.that(spannable)
|
.that(spannable)
|
||||||
.hasRubySpanBetween(SPAN_START, SPAN_END)
|
.hasRubySpanBetween(SPAN_START, SPAN_END)
|
||||||
.withTextAndPosition("ruby text", RubySpan.POSITION_UNDER));
|
.withTextAndPosition("ruby text", TextAnnotation.POSITION_AFTER));
|
||||||
|
|
||||||
assertThat(expected).factValue("value of").contains("rubyTextAndPosition");
|
assertThat(expected).factValue("value of").contains("rubyTextAndPosition");
|
||||||
assertThat(expected).factValue("expected").contains("position=" + RubySpan.POSITION_UNDER);
|
assertThat(expected).factValue("expected").contains("position=" + TextAnnotation.POSITION_AFTER);
|
||||||
assertThat(expected).factValue("but was").contains("position=" + RubySpan.POSITION_OVER);
|
assertThat(expected).factValue("but was").contains("position=" + TextAnnotation.POSITION_BEFORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rubySpan_wrongFlags() {
|
public void rubySpan_wrongFlags() {
|
||||||
checkHasSpanFailsDueToFlagMismatch(
|
checkHasSpanFailsDueToFlagMismatch(
|
||||||
new RubySpan("ruby text", RubySpan.POSITION_OVER),
|
new RubySpan("ruby text", TextAnnotation.POSITION_BEFORE),
|
||||||
(subject, start, end) ->
|
(subject, start, end) ->
|
||||||
subject
|
subject
|
||||||
.hasRubySpanBetween(start, end)
|
.hasRubySpanBetween(start, end)
|
||||||
.withTextAndPosition("ruby text", RubySpan.POSITION_OVER));
|
.withTextAndPosition("ruby text", TextAnnotation.POSITION_BEFORE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noRubySpan_success() {
|
public void noRubySpan_success() {
|
||||||
SpannableString spannable =
|
SpannableString spannable =
|
||||||
createSpannableWithUnrelatedSpanAnd(new RubySpan("ruby text", RubySpan.POSITION_OVER));
|
createSpannableWithUnrelatedSpanAnd(new RubySpan("ruby text", TextAnnotation.POSITION_BEFORE));
|
||||||
|
|
||||||
assertThat(spannable).hasNoRubySpanBetween(UNRELATED_SPAN_START, UNRELATED_SPAN_END);
|
assertThat(spannable).hasNoRubySpanBetween(UNRELATED_SPAN_START, UNRELATED_SPAN_END);
|
||||||
}
|
}
|
||||||
|
|
@ -678,7 +678,7 @@ public class SpannedSubjectTest {
|
||||||
@Test
|
@Test
|
||||||
public void noRubySpan_failure() {
|
public void noRubySpan_failure() {
|
||||||
checkHasNoSpanFails(
|
checkHasNoSpanFails(
|
||||||
new RubySpan("ruby text", RubySpan.POSITION_OVER), SpannedSubject::hasNoRubySpanBetween);
|
new RubySpan("ruby text", TextAnnotation.POSITION_BEFORE), SpannedSubject::hasNoRubySpanBetween);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue