Address code review comments

- Split text emphasis mark and style into two IntDefs
- Represent textEmphasis="none" with a span rather than null
- Fixed bugs in the style parsing logic
This commit is contained in:
Denise LaFayette 2021-03-05 12:23:34 -08:00
parent 60a3af8d77
commit f7f40bcb25
9 changed files with 560 additions and 308 deletions

View File

@ -23,51 +23,60 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
public final class TextEmphasisSpan {
// Bits [1:0] are used for typical mark types
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
public static final int MARK_FLAG_FILLED = 0;
public static final int MARK_FLAG_OPEN = 4;
// Below are the mark style constants
public static final int MARK_FILLED_CIRCLE = MARK_FLAG_CIRCLE | MARK_FLAG_FILLED;
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 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;
public static final int MARK_SHAPE_NONE = 0;
public static final int MARK_SHAPE_CIRCLE = 1;
public static final int MARK_SHAPE_DOT = 2;
public static final int MARK_SHAPE_SESAME = 3;
/**
* The possible types of annotations used.
* The possible mark shapes that can be used.
*
* <p>One of:
*
* <ul>
* <li>{@link #MARK_FILLED_CIRCLE}
* <li>{@link #MARK_FILLED_DOT}
* <li>{@link #MARK_FILLED_SESAME}
* <li>{@link #MARK_OPEN_CIRCLE}
* <li>{@link #MARK_OPEN_DOT}
* <li>{@link #MARK_OPEN_SESAME}
* <li>{@link #MARK_SHAPE_NONE}
* <li>{@link #MARK_SHAPE_CIRCLE}
* <li>{@link #MARK_SHAPE_DOT}
* <li>{@link #MARK_SHAPE_SESAME}
* </ul>
*
* Note: We are intentionally excluding MARK_AUTO here since the auto value should
* be resolved
*/
@Documented
@Retention(SOURCE)
@IntDef({MARK_FILLED_CIRCLE, MARK_FILLED_DOT, MARK_FILLED_SESAME,
MARK_OPEN_CIRCLE, MARK_OPEN_DOT, MARK_OPEN_SESAME})
public @interface Mark {
@IntDef({MARK_SHAPE_NONE, MARK_SHAPE_CIRCLE, MARK_SHAPE_DOT, MARK_SHAPE_SESAME})
public @interface MarkShape {
}
public static final int MARK_FILL_UNSPECIFIED = 0;
public static final int MARK_FILL_FILLED = 1;
public static final int MARK_FILL_OPEN = 2;
/**
* The mark used to emphasis text
* The possible mark fills that can be used.
*
* <p>One of:
*
* <ul>
* <li>{@link #MARK_FILL_UNSPECIFIED}
* <li>{@link #MARK_FILL_FILLED}
* <li>{@link #MARK_FILL_OPEN}
* </ul>
*/
public @TextEmphasisSpan.Mark int mark;
@Documented
@Retention(SOURCE)
@IntDef({MARK_FILL_UNSPECIFIED, MARK_FILL_FILLED, MARK_FILL_OPEN})
public @interface MarkFill {
}
/**
* The mark shape used for text emphasis
*/
public @MarkShape int markShape;
/**
* The mark fill for the text emphasis mark
*/
public @MarkShape int markFill;
/**
* The position of the text emphasis relative to the base text
@ -76,9 +85,10 @@ public final class TextEmphasisSpan {
public final int position;
public TextEmphasisSpan(@TextEmphasisSpan.Mark int mark,
public TextEmphasisSpan(@MarkShape int shape, @MarkFill int fill,
@TextAnnotation.Position int position) {
this.mark = mark;
this.markShape = shape;
this.markFill = fill;
this.position = position;
}
}

View File

@ -38,33 +38,35 @@ import java.util.Set;
/* package */ final class TextEmphasis {
/**
* Mark style to be resolved at rendering time. Hence, it is not defined in
* {@link TextEmphasisSpan.Mark}
* Mark shape AUTO is to be resolved at rendering time. Hence, it is not defined in
* {@link TextEmphasisSpan.MarkShape}
*/
public static final int MARK_AUTO = 1 << 8;
public static final int MARK_SHAPE_AUTO = 1 << 8;
@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
@IntDef({TextEmphasisSpan.MARK_SHAPE_NONE,
TextEmphasisSpan.MARK_SHAPE_CIRCLE,
TextEmphasisSpan.MARK_SHAPE_DOT,
TextEmphasisSpan.MARK_SHAPE_SESAME,
// Extending the definition in TextEmphasisSpan.MarkShape for intermediate values
MARK_SHAPE_AUTO
})
@interface Mark {
@interface MarkShape {
}
@MarkShape
final int markShape;
/**
* The mark style of the text emphasis.
*/
@Mark final int mark;
@TextEmphasisSpan.MarkFill
final int markFill;
/**
* Position to be resolved at rendering time. Hence, it is not defined in
* Position OUTSIDE is to be resolved at rendering time. Hence, it is not defined in
* {@link TextAnnotation.Position}
*/
static final int POSITION_OUTSIDE = 1 << 8;
@ -84,26 +86,32 @@ import java.util.Set;
*/
@Position final int position;
private static Set markValues = ImmutableSet.of(
private static final Set<String> singleStyleValues = ImmutableSet.of(
TtmlNode.TEXT_EMPHASIS_AUTO,
TtmlNode.TEXT_EMPHASIS_NONE
);
private static final Set<String> markShapeValues = ImmutableSet.of(
TtmlNode.TEXT_EMPHASIS_MARK_DOT,
TtmlNode.TEXT_EMPHASIS_MARK_SESAME,
TtmlNode.TEXT_EMPHASIS_MARK_CIRCLE
);
);
private static Set markStyles = ImmutableSet.of(
private static final Set<String> markFillValues = ImmutableSet.of(
TtmlNode.TEXT_EMPHASIS_MARK_FILLED,
TtmlNode.TEXT_EMPHASIS_MARK_OPEN
);
private static Set positionValues = ImmutableSet.of(
private static final Set<String> positionValues = ImmutableSet.of(
TtmlNode.ANNOTATION_POSITION_AFTER,
TtmlNode.ANNOTATION_POSITION_BEFORE,
TtmlNode.ANNOTATION_POSITION_OUTSIDE
);
private TextEmphasis(@Mark int mark, @TextAnnotation.Position int position) {
this.mark = mark;
private TextEmphasis(@MarkShape int shape, @TextEmphasisSpan.MarkFill int fill,
@TextAnnotation.Position int position) {
this.markShape = shape;
this.markFill = fill;
this.position = position;
}
@ -111,68 +119,83 @@ import java.util.Set;
public String toString() {
return "TextEmphasis{" +
"position=" + position +
", mark=" + mark +
", markShape=" + markShape +
", markFill=" + markFill +
'}';
}
public static TextEmphasis createTextEmphasis(@Nullable String value) {
@Nullable public static TextEmphasis createTextEmphasis(@Nullable String value) {
if (value == null) {
return null;
}
String parsingValue = value.toLowerCase().trim();
if ("".equals(parsingValue)) {
if (parsingValue.isEmpty()) {
return null;
}
Set<String> nodes = Sets.newHashSet(parsingValue.split("\\s+"));
if (nodes.size() == 0 || TtmlNode.TEXT_EMPHASIS_NONE.equals(nodes.iterator().next())) {
if (nodes.size() == 0) {
return null;
}
return parseNodes(nodes);
}
private static @Nullable TextEmphasis parseNodes(Set<String> nodes) {
Set styleSet = Sets.intersection(markStyles, nodes).immutableCopy();
Set markSet = Sets.intersection(markValues, nodes).immutableCopy();
Set positionSet = Sets.intersection(positionValues, nodes).immutableCopy();
@Mark int mark = 0;
if (styleSet.size() == 1) {
mark |= TtmlNode.TEXT_EMPHASIS_MARK_OPEN.equals(styleSet.iterator().next())
? TextEmphasisSpan.MARK_FLAG_OPEN
: TextEmphasisSpan.MARK_FLAG_FILLED;
}
if (markSet.size() == 1) {
switch ((String) markSet.iterator().next()) {
case TtmlNode.TEXT_EMPHASIS_AUTO:
mark |= MARK_AUTO;
break;
case TtmlNode.TEXT_EMPHASIS_MARK_DOT:
mark |= TextEmphasisSpan.MARK_FLAG_DOT;
break;
case TtmlNode.TEXT_EMPHASIS_MARK_SESAME:
mark |= TextEmphasisSpan.MARK_FLAG_SESAME;
break;
case TtmlNode.TEXT_EMPHASIS_MARK_CIRCLE:
default:
mark |= TextEmphasisSpan.MARK_FLAG_CIRCLE;
}
@MarkShape int markShape;
@TextEmphasisSpan.MarkFill int markFill = TextEmphasisSpan.MARK_FILL_UNSPECIFIED;
Set<String> styleSet = Sets.intersection(singleStyleValues, nodes).immutableCopy();
if (styleSet.size() > 0) {
// If "none" or "auto" are found in the description, ignore the other style (fill, shape)
// attributes.
markShape = TtmlNode.TEXT_EMPHASIS_NONE.equals(styleSet.iterator().next())
? TextEmphasisSpan.MARK_SHAPE_NONE : MARK_SHAPE_AUTO;
// markFill is ignored when markShape is NONE or AUTO
} else {
mark |= TextEmphasisSpan.MARK_FLAG_CIRCLE;
Set<String> fillSet = Sets.intersection(markFillValues, nodes).immutableCopy();
Set<String> shapeSet = Sets.intersection(markShapeValues, nodes).immutableCopy();
if (fillSet.size() == 0 && shapeSet.size() == 0) {
// 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.
// https://www.w3.org/TR/ttml2/#style-value-emphasis-style
markShape = MARK_SHAPE_AUTO;
} else {
if (fillSet.size() > 0) {
markFill = TtmlNode.TEXT_EMPHASIS_MARK_OPEN.equals(fillSet.iterator().next())
? TextEmphasisSpan.MARK_FILL_OPEN
: TextEmphasisSpan.MARK_FILL_FILLED;
} else {
markFill = TextEmphasisSpan.MARK_FILL_FILLED;
}
if (shapeSet.size() > 0) {
switch (shapeSet.iterator().next()) {
case TtmlNode.TEXT_EMPHASIS_MARK_DOT:
markShape = TextEmphasisSpan.MARK_SHAPE_DOT;
break;
case TtmlNode.TEXT_EMPHASIS_MARK_SESAME:
markShape = TextEmphasisSpan.MARK_SHAPE_SESAME;
break;
case TtmlNode.TEXT_EMPHASIS_MARK_CIRCLE:
default:
markShape = TextEmphasisSpan.MARK_SHAPE_CIRCLE;
}
} else {
markShape = TextEmphasisSpan.MARK_SHAPE_CIRCLE;
}
}
}
/**
* If no emphasis position is specified, then the emphasis position must be interpreted as if
* a position of outside were specified.
* <p>
* More information on
* <a href="https://www.w3.org/TR/2018/REC-ttml2-20181108/#style-attribute-textEmphasis">tts:textEmphasis</a>
*/
Set<String> positionSet = Sets.intersection(positionValues, nodes).immutableCopy();
// If no emphasis position is specified, then the emphasis position must be interpreted as if
// a position of outside were specified.
// https://www.w3.org/TR/2018/REC-ttml2-20181108/#style-attribute-textEmphasis
@Position int position = POSITION_OUTSIDE;
if (positionSet.size() == 1) {
switch ((String) positionSet.iterator().next()) {
if (positionSet.size() > 0) {
switch (positionSet.iterator().next()) {
case TtmlNode.ANNOTATION_POSITION_AFTER:
position = TextAnnotation.POSITION_AFTER;
break;
@ -184,6 +207,6 @@ import java.util.Set;
position = TextAnnotation.POSITION_BEFORE;
}
}
return new TextEmphasis(mark, position);
return new TextEmphasis(markShape, markFill, position);
}
}

View File

@ -129,14 +129,14 @@ import java.util.Map;
* 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.
* If a vertical writing mode applies, then equivalent to filled sesame; otherwise, equivalent
* to filled circle.
* See 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.
* See https://www.w3.org/TR/ttml2/#style-value-emphasis-style
*/
@TextEmphasis.Mark int mark = textEmphasis.mark;
if (textEmphasis.mark == TextEmphasis.MARK_AUTO) {
mark = (verticalType == Cue.VERTICAL_TYPE_LR || verticalType == Cue.VERTICAL_TYPE_RL) ?
TextEmphasisSpan.MARK_FILLED_SESAME : TextEmphasisSpan.MARK_FILLED_CIRCLE;
@TextEmphasis.MarkShape int markShape = textEmphasis.markShape;
if (textEmphasis.markShape == TextEmphasis.MARK_SHAPE_AUTO) {
markShape = (verticalType == Cue.VERTICAL_TYPE_LR || verticalType == Cue.VERTICAL_TYPE_RL) ?
TextEmphasisSpan.MARK_SHAPE_SESAME : TextEmphasisSpan.MARK_SHAPE_CIRCLE;
}
@TextEmphasis.Position int position = textEmphasis.position;
@ -154,7 +154,7 @@ import java.util.Map;
SpanUtil.addOrReplaceSpan(
builder,
new TextEmphasisSpan(mark, position),
new TextEmphasisSpan(markShape, textEmphasis.markFill, position),
start,
end,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

View File

@ -1,16 +1,20 @@
package com.google.android.exoplayer2.text.ttml;
import static com.google.android.exoplayer2.text.ttml.TextEmphasis.MARK_SHAPE_AUTO;
import static com.google.android.exoplayer2.text.ttml.TextEmphasis.POSITION_OUTSIDE;
import static com.google.android.exoplayer2.text.ttml.TextEmphasis.createTextEmphasis;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import androidx.annotation.Nullable;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.text.span.TextAnnotation;
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link TextEmphasis}. */
/**
* Unit test for {@link TextEmphasis}.
*/
@RunWith(AndroidJUnit4.class)
public class TextEmphasisTest {
@ -18,373 +22,542 @@ public class TextEmphasisTest {
@Test
public void testNull() {
String value = null;
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(null);
assertWithMessage("Text Emphasis must be null").that(textEmphasis).isNull();
}
@Test
public void testEmpty() {
String value = "";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis("");
assertWithMessage("Text Emphasis must be null").that(textEmphasis).isNull();
}
@Test
public void testEmptyWithWhitespace() {
@Nullable TextEmphasis textEmphasis = createTextEmphasis(" ");
assertWithMessage("Text Emphasis must be null").that(textEmphasis).isNull();
}
@Test
public void testNone() {
String value = "none";
TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must be null").that(textEmphasis).isNull();
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_NONE);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testAuto() {
String value = "auto";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasis.MARK_AUTO);
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
assertWithMessage("markShape").that(textEmphasis.markShape).isEqualTo(MARK_SHAPE_AUTO);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_UNSPECIFIED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testInvalid() {
String value = "invalid";
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertWithMessage("markShape").that(textEmphasis.markShape).isEqualTo(MARK_SHAPE_AUTO);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_UNSPECIFIED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testAutoOutside() {
String value = "auto outside";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasis.MARK_AUTO);
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
assertWithMessage("markShape").that(textEmphasis.markShape).isEqualTo(MARK_SHAPE_AUTO);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_UNSPECIFIED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testAutoAfter() {
String value = "auto after";
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertWithMessage("markShape").that(textEmphasis.markShape).isEqualTo(MARK_SHAPE_AUTO);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_UNSPECIFIED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
/**
* If only filled or open is specified, then it is equivalent to filled circle and open circle,
* respectively.
* 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);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testOpen() {
String value = "open";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testOpenAfter() {
String value = "open after";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
/**
* If only circle, dot, or sesame is specified, then it is equivalent to filled circle, filled dot,
* and filled sesame, respectively.
* If only circle, dot, or sesame is specified, then it is equivalent to filled circle, filled
* dot, and filled sesame, respectively.
*/
@Test
public void testDotBefore() {
String value = "dot before";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testCircleBefore() {
String value = "circle before";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testSesameBefore() {
String value = "sesame before";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testDotAfter() {
String value = "dot AFTER";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
@Test
public void testCircleAfter() {
String value = "circle after";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
@Test
public void testSesameAfter() {
String value = "sesame aFter";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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_AFTER);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
@Test
public void testDotOutside() {
String value = "dot outside";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testCircleOutside() {
String value = "circle outside";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testSesameOutside() {
String value = "sesame outside";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testOpenDotAfter() {
String value = "open dot AFTER";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_DOT);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
@Test
public void testOpenCircleAfter() {
String value = "Open circle after";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
@Test
public void testOpenSesameAfter() {
String value = "open sesame aFter";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_SESAME);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
@Test
public void testOpenDotBefore() {
String value = "open dot before";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_DOT);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testOpenCircleBefore() {
String value = "Open circle Before";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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_BEFORE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testOpenSesameBefore() {
String value = "open sesame Before";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_SESAME);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testOpenDotOutside() {
String value = "open dot Outside";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_DOT);
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testOpenCircleOutside() {
String value = "Open circle Outside";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testOpenSesameOutside() {
String value = "open sesame outside";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_OPEN_SESAME);
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testFilledDotOutside() {
String value = "filled dot outside";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testFilledCircleOutside() {
String value = "filled circle outside";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testFilledSesameOutside() {
String value = "filled sesame outside";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_SESAME);
assertThat(textEmphasis.position).isEqualTo(TextEmphasis.POSITION_OUTSIDE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextEmphasis.POSITION_OUTSIDE);
}
@Test
public void testFilledDotAfter() {
String value = "filled dot After";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
@Test
public void testFilledCircleAfter() {
String value = "filled circle after";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_AFTER);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
@Test
public void testFilledSesameAfter() {
String value = "filled sesame After";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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_AFTER);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_AFTER);
}
@Test
public void testFilledDotBefore() {
String value = "filled dot before";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_DOT);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testFilledCircleBefore() {
String value = "filled circle Before";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertThat(textEmphasis.mark).isEqualTo(TextEmphasisSpan.MARK_FILLED_CIRCLE);
assertThat(textEmphasis.position).isEqualTo(TextAnnotation.POSITION_BEFORE);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testFilledSesameBefore() {
String value = "filled sesame Before";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testBeforeFilledSesame() {
String value = "before filled sesame";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testBeforeSesameFilled() {
String value = "before sesame filled";
TextEmphasis textEmphasis = createTextEmphasis(value);
@Nullable 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);
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testInvalidMarkShape() {
String value = "before sesamee filled";
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_CIRCLE);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testInvalidMarkFill() {
String value = "before sesame filed";
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position)
.isEqualTo(TextAnnotation.POSITION_BEFORE);
}
@Test
public void testInvalidPosition() {
String value = "befour sesame filled";
@Nullable TextEmphasis textEmphasis = createTextEmphasis(value);
assertWithMessage("Text Emphasis must exist").that(textEmphasis).isNotNull();
assertWithMessage("markShape").that(textEmphasis.markShape)
.isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertWithMessage("markFill").that(textEmphasis.markFill)
.isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertWithMessage("position").that(textEmphasis.position).isEqualTo(POSITION_OUTSIDE);
}
}

View File

@ -682,68 +682,80 @@ public final class TtmlDecoderTest {
TtmlSubtitle subtitle = getSubtitle(TEXT_EMPHASIS_FILE);
Spanned firstCue = getOnlyCueTextAtTimeUs(subtitle, 10_000_000);
assertThat(firstCue).hasNoSpans();
assertThat(firstCue).hasTextEmphasisSpanBetween("None ".length(), "None おはよ".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_NONE,
TextEmphasisSpan.MARK_FILL_UNSPECIFIED,
TextAnnotation.POSITION_BEFORE);
Spanned secondCue = getOnlyCueTextAtTimeUs(subtitle, 20_000_000);
assertThat(secondCue)
.hasTextEmphasisSpanBetween("Auto ".length(), "Auto ございます".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_CIRCLE,
TextEmphasisSpan.MARK_FILL_UNSPECIFIED,
TextAnnotation.POSITION_BEFORE);
Spanned thirdCue = getOnlyCueTextAtTimeUs(subtitle, 30_000_000);
assertThat(thirdCue)
.hasTextEmphasisSpanBetween("Filled circle ".length(), "Filled circle こんばんは".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_CIRCLE, TextEmphasisSpan.MARK_FILL_FILLED,
TextAnnotation.POSITION_BEFORE);
Spanned fourthCue = getOnlyCueTextAtTimeUs(subtitle, 40_000_000);
assertThat(fourthCue)
.hasTextEmphasisSpanBetween("Filled dot ".length(), "Filled dot ございます".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_DOT, TextAnnotation.POSITION_BEFORE);
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_DOT, TextEmphasisSpan.MARK_FILL_FILLED,
TextAnnotation.POSITION_BEFORE);
Spanned fifthCue = getOnlyCueTextAtTimeUs(subtitle, 50_000_000);
assertThat(fifthCue)
.hasTextEmphasisSpanBetween("Filled sesame ".length(), "Filled sesame おはよ".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_SESAME, TextEmphasisSpan.MARK_FILL_FILLED,
TextAnnotation.POSITION_BEFORE);
Spanned sixthCue = getOnlyCueTextAtTimeUs(subtitle, 60_000_000);
assertThat(sixthCue)
.hasTextEmphasisSpanBetween("Open circle before ".length(),
"Open circle before ございます".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_OPEN_CIRCLE, TextAnnotation.POSITION_BEFORE);
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_CIRCLE, TextEmphasisSpan.MARK_FILL_OPEN,
TextAnnotation.POSITION_BEFORE);
Spanned seventhCue = getOnlyCueTextAtTimeUs(subtitle, 70_000_000);
assertThat(seventhCue)
.hasTextEmphasisSpanBetween("Open dot after ".length(), "Open dot after おはよ".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_OPEN_DOT, TextAnnotation.POSITION_AFTER);
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_DOT, TextEmphasisSpan.MARK_FILL_OPEN,
TextAnnotation.POSITION_AFTER);
Spanned eighthCue = getOnlyCueTextAtTimeUs(subtitle, 80_000_000);
assertThat(eighthCue)
.hasTextEmphasisSpanBetween("Open sesame outside ".length(),
"Open sesame outside ございます".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_OPEN_SESAME, TextAnnotation.POSITION_BEFORE);
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_SESAME, TextEmphasisSpan.MARK_FILL_OPEN,
TextAnnotation.POSITION_BEFORE);
Spanned ninthCue = getOnlyCueTextAtTimeUs(subtitle, 90_000_000);
assertThat(ninthCue)
.hasTextEmphasisSpanBetween("Auto outside ".length(), "Auto outside おはよ".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_CIRCLE,
TextEmphasisSpan.MARK_FILL_UNSPECIFIED,
TextAnnotation.POSITION_BEFORE);
Spanned tenthCue = getOnlyCueTextAtTimeUs(subtitle, 100_000_000);
assertThat(tenthCue)
.hasTextEmphasisSpanBetween("Circle before ".length(), "Circle before ございます".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE, TextAnnotation.POSITION_BEFORE);
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_CIRCLE, TextEmphasisSpan.MARK_FILL_FILLED,
TextAnnotation.POSITION_BEFORE);
Spanned eleventhCue = getOnlyCueTextAtTimeUs(subtitle, 110_000_000);
assertThat(eleventhCue)
.hasTextEmphasisSpanBetween("Sesame after ".length(), "Sesame after おはよ".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME, TextAnnotation.POSITION_AFTER);
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_SESAME, TextEmphasisSpan.MARK_FILL_FILLED,
TextAnnotation.POSITION_AFTER);
Spanned twelfthCue = getOnlyCueTextAtTimeUs(subtitle, 120_000_000);
assertThat(twelfthCue)
.hasTextEmphasisSpanBetween("Dot outside ".length(), "Dot outside ございます".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_DOT, TextAnnotation.POSITION_BEFORE);
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_DOT, TextEmphasisSpan.MARK_FILL_FILLED,
TextAnnotation.POSITION_BEFORE);
Spanned thirteenthCue = getOnlyCueTextAtTimeUs(subtitle, 130_000_000);
assertThat(thirteenthCue)
@ -753,25 +765,29 @@ public final class TtmlDecoderTest {
Spanned fourteenthCue = getOnlyCueTextAtTimeUs(subtitle, 140_000_000);
assertThat(fourteenthCue)
.hasTextEmphasisSpanBetween("Auto (TBLR) ".length(), "Auto (TBLR) ございます".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_SESAME,
TextEmphasisSpan.MARK_FILL_UNSPECIFIED,
TextAnnotation.POSITION_BEFORE);
Spanned fifteenthCue = getOnlyCueTextAtTimeUs(subtitle, 150_000_000);
assertThat(fifteenthCue)
.hasTextEmphasisSpanBetween("Auto (TBRL) ".length(), "Auto (TBRL) おはよ".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_SESAME,
TextEmphasisSpan.MARK_FILL_UNSPECIFIED,
TextAnnotation.POSITION_BEFORE);
Spanned sixteenthCue = getOnlyCueTextAtTimeUs(subtitle, 160_000_000);
assertThat(sixteenthCue)
.hasTextEmphasisSpanBetween("Auto (TB) ".length(), "Auto (TB) ございます".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_SESAME,
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_SESAME,
TextEmphasisSpan.MARK_FILL_UNSPECIFIED,
TextAnnotation.POSITION_BEFORE);
Spanned seventeenthCue = getOnlyCueTextAtTimeUs(subtitle, 170_000_000);
assertThat(seventeenthCue)
.hasTextEmphasisSpanBetween("Auto (LR) ".length(), "Auto (LR) おはよ".length())
.withMarkAndPosition(TextEmphasisSpan.MARK_FILLED_CIRCLE,
.withMarkAndPosition(TextEmphasisSpan.MARK_SHAPE_CIRCLE,
TextEmphasisSpan.MARK_FILL_UNSPECIFIED,
TextAnnotation.POSITION_BEFORE);
}

View File

@ -17,8 +17,6 @@ package com.google.android.exoplayer2.text.ttml;
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_OPEN_SESAME;
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_ITALIC;
@ -32,6 +30,7 @@ import android.text.Layout;
import androidx.annotation.ColorInt;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.text.span.TextAnnotation;
import com.google.android.exoplayer2.text.span.TextEmphasisSpan;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -92,7 +91,8 @@ public final class TtmlStyleTest {
.that(style.hasBackgroundColor())
.isFalse();
assertThat(style.getTextEmphasis()).isNotNull();
assertThat(style.getTextEmphasis().mark).isEqualTo(MARK_FILLED_DOT);
assertThat(style.getTextEmphasis().markShape).isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertThat(style.getTextEmphasis().markFill).isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertThat(style.getTextEmphasis().position).isEqualTo(POSITION_BEFORE);
}
@ -118,7 +118,8 @@ public final class TtmlStyleTest {
.isEqualTo(BACKGROUND_COLOR);
assertWithMessage("rubyType should be chained").that(style.getRubyType()).isEqualTo(RUBY_TYPE);
assertThat(style.getTextEmphasis()).isNotNull();
assertThat(style.getTextEmphasis().mark).isEqualTo(MARK_FILLED_DOT);
assertThat(style.getTextEmphasis().markShape).isEqualTo(TextEmphasisSpan.MARK_SHAPE_DOT);
assertThat(style.getTextEmphasis().markFill).isEqualTo(TextEmphasisSpan.MARK_FILL_FILLED);
assertThat(style.getTextEmphasis().position).isEqualTo(POSITION_BEFORE);
}
@ -262,7 +263,8 @@ public final class TtmlStyleTest {
TtmlStyle style = new TtmlStyle();
assertThat(style.getTextEmphasis()).isNull();
style.setTextEmphasis(TextEmphasis.createTextEmphasis("open sesame after"));
assertThat(style.getTextEmphasis().mark).isEqualTo(MARK_OPEN_SESAME);
assertThat(style.getTextEmphasis().markShape).isEqualTo(TextEmphasisSpan.MARK_SHAPE_SESAME);
assertThat(style.getTextEmphasis().markFill).isEqualTo(TextEmphasisSpan.MARK_FILL_OPEN);
assertThat(style.getTextEmphasis().position).isEqualTo(TextAnnotation.POSITION_AFTER);
}
}

View File

@ -201,12 +201,13 @@ import java.util.regex.Pattern;
return "<u>";
} else if (span instanceof TextEmphasisSpan) {
TextEmphasisSpan textEmphasisSpan = (TextEmphasisSpan) span;
String style = getTextEmphasisStyle(textEmphasisSpan.mark);
String style = getTextEmphasisStyle(textEmphasisSpan.markShape, textEmphasisSpan.markFill);
String position = getTextEmphasisPosition(textEmphasisSpan.position);
return Util
.formatInvariant("<span style='-webkit-text-emphasis-style: %s; text-emphasis-style: %s; "
+ "-webkit-text-emphasis-position: %s; text-emphasis-position: %s;'>",
style, style, position, position);
.formatInvariant(
"<span style='-webkit-text-emphasis-style: %1$s; text-emphasis-style: %1$s; "
+ "-webkit-text-emphasis-position: %2$s; text-emphasis-position: %2$s;'>",
style, position);
} else {
return null;
}
@ -243,23 +244,39 @@ import java.util.regex.Pattern;
return null;
}
private static String getTextEmphasisStyle(@TextEmphasisSpan.Mark int mark) {
switch (mark) {
case TextEmphasisSpan.MARK_FILLED_CIRCLE:
return "filled circle";
case TextEmphasisSpan.MARK_FILLED_DOT:
return "filled dot";
case TextEmphasisSpan.MARK_FILLED_SESAME:
return "filled sesame";
case TextEmphasisSpan.MARK_OPEN_CIRCLE:
return "open circle";
case TextEmphasisSpan.MARK_OPEN_DOT:
return "open dot";
case TextEmphasisSpan.MARK_OPEN_SESAME:
return "open sesame";
private static String getTextEmphasisStyle(@TextEmphasisSpan.MarkShape int shape,
@TextEmphasisSpan.MarkFill int fill) {
StringBuilder builder = new StringBuilder();
switch (fill) {
case TextEmphasisSpan.MARK_FILL_FILLED:
builder.append("filled ");
break;
case TextEmphasisSpan.MARK_FILL_OPEN:
builder.append("open ");
break;
case TextEmphasisSpan.MARK_FILL_UNSPECIFIED:
default:
return "unset";
break;
}
switch (shape) {
case TextEmphasisSpan.MARK_SHAPE_CIRCLE:
builder.append("circle");
break;
case TextEmphasisSpan.MARK_SHAPE_DOT:
builder.append("dot");
break;
case TextEmphasisSpan.MARK_SHAPE_SESAME:
builder.append("sesame");
break;
case TextEmphasisSpan.MARK_SHAPE_NONE:
builder.append("none");
break;
default:
builder.append("unset");
break;
}
return builder.toString();
}
private static String getTextEmphasisPosition(@TextAnnotation.Position int position){

View File

@ -285,13 +285,15 @@ public class SpannedToHtmlConverterTest {
public void convert_supportsTextEmphasisSpan() {
SpannableString spanned = new SpannableString("Text emphasis おはよ ございます ");
spanned.setSpan(
new TextEmphasisSpan(TextEmphasisSpan.MARK_FILLED_CIRCLE, TextAnnotation.POSITION_BEFORE),
new TextEmphasisSpan(TextEmphasisSpan.MARK_SHAPE_CIRCLE, TextEmphasisSpan.MARK_FILL_FILLED,
TextAnnotation.POSITION_BEFORE),
"Text emphasis ".length(),
"Text emphasis おはよ".length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spanned.setSpan(
new TextEmphasisSpan(TextEmphasisSpan.MARK_OPEN_SESAME, TextAnnotation.POSITION_AFTER),
new TextEmphasisSpan(TextEmphasisSpan.MARK_SHAPE_SESAME, TextEmphasisSpan.MARK_FILL_OPEN,
TextAnnotation.POSITION_AFTER),
"Text emphasis おはよ ".length(),
"Text emphasis おはよ ございます ".length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

View File

@ -1156,20 +1156,21 @@ public final class SpannedSubject extends Subject {
/** Allows assertions about a span's textEmphasis mark and its position. */
public interface TextEmphasisDescription {
/**
* Checks that at least one of the matched spans has the expected {@code mark} and {@code position}.
*
* @param mark The expected mark
* @param markShape The expected mark shape
* @param markFill The expected mark fill
* @param position The expected position of the mark
* @return A {@link WithSpanFlags} object for optional additional assertions on the flags.
*/
AndSpanFlags withMarkAndPosition(@TextEmphasisSpan.Mark int mark,
AndSpanFlags withMarkAndPosition(@TextEmphasisSpan.MarkShape int markShape,
@TextEmphasisSpan.MarkFill int markFill,
@TextAnnotation.Position int position);
}
private static final TextEmphasisDescription ALREADY_FAILED_WITH_MARK =
(mark, position) -> ALREADY_FAILED_AND_FLAGS;
(markShape, markFill, position) -> ALREADY_FAILED_AND_FLAGS;
private static Factory<TextEmphasisSubject, List<TextEmphasisSpan>> textEmphasisSubjects(Spanned actualSpanned) {
return (FailureMetadata metadata, List<TextEmphasisSpan> spans) ->
@ -1189,32 +1190,38 @@ public final class SpannedSubject extends Subject {
}
@Override
public AndSpanFlags withMarkAndPosition(@TextEmphasisSpan.Mark int mark,
public AndSpanFlags withMarkAndPosition(@TextEmphasisSpan.MarkShape int markShape,
@TextEmphasisSpan.MarkFill int markFill,
@TextAnnotation.Position int position) {
List<Integer> matchingSpanFlags = new ArrayList<>();
List<MarkAndPosition> textEmphasisMarksAndPositions = new ArrayList<>();
for (TextEmphasisSpan span : actualSpans) {
textEmphasisMarksAndPositions.add(new MarkAndPosition(span.mark, span.position));
if (span.mark == mark && span.position == position) {
textEmphasisMarksAndPositions
.add(new MarkAndPosition(span.markShape, span.markFill, span.position));
if (span.markFill == markFill && span.markShape == markShape && span.position == position) {
matchingSpanFlags.add(actualSpanned.getSpanFlags(span));
}
}
check("textEmphasisMarkAndPosition")
.that(textEmphasisMarksAndPositions)
.containsExactly(new MarkAndPosition(mark, position));
.containsExactly(new MarkAndPosition(markShape, markFill, position));
return check("flags").about(spanFlags()).that(matchingSpanFlags);
}
private static final class MarkAndPosition {
@TextEmphasisSpan.Mark
private final int mark;
@TextEmphasisSpan.MarkShape
private final int markShape;
@TextEmphasisSpan.MarkFill
private final int markFill;
@TextAnnotation.Position
private final int position;
private MarkAndPosition(@TextEmphasisSpan.Mark int mark,
private MarkAndPosition(@TextEmphasisSpan.MarkShape int markShape,
@TextEmphasisSpan.MarkFill int markFill,
@TextAnnotation.Position int position) {
this.mark = mark;
this.markFill = markFill;
this.markShape = markShape;
this.position = position;
}
@ -1228,18 +1235,20 @@ public final class SpannedSubject extends Subject {
}
TextEmphasisSubject.MarkAndPosition that = (TextEmphasisSubject.MarkAndPosition) o;
return (position == that.position) && (mark == that.mark);
return (position == that.position) && (markShape == that.markShape) && (markFill
== that.markFill);
}
@Override
public int hashCode() {
int result = 34613 * mark + position;
int result = 34613 * markFill + 1993 * markShape + position;
return result;
}
@Override
public String toString() {
return String.format("{mark=%s,position=%s}", mark, position);
return String
.format("{markShape=%s, markFill=%s, position=%s}", markShape, markFill, position);
}
}
}