Commit 17abab45 by hoangtc Committed by Andrew Lewis

Fix a bug with TTML font styling.

Due to a bug, for each TTML node, when applying its style to the encompassed
regions, it applies child nodes's styling several time for each region (the
number of time is equal to the number of region). This leads to a styling issue
if there are multiple regions in a node displayed at the same time in TTML file.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=196810046
parent 9a45d504
......@@ -16,6 +16,9 @@
* HLS:
* Fix playback of livestreams with EXT-X-PROGRAM-DATE-TIME tags
([#4239](https://github.com/google/ExoPlayer/issues/4239)).
* Caption:
* Fix a TTML styling issue when there are multiple regions displayed at the
same time that can make text size of each region much smaller than defined.
### 2.8.0 ###
......
......@@ -175,7 +175,7 @@ import java.util.TreeSet;
Map<String, TtmlRegion> regionMap) {
TreeMap<String, SpannableStringBuilder> regionOutputs = new TreeMap<>();
traverseForText(timeUs, false, regionId, regionOutputs);
traverseForStyle(globalStyles, regionOutputs);
traverseForStyle(timeUs, globalStyles, regionOutputs);
List<Cue> cues = new ArrayList<>();
for (Entry<String, SpannableStringBuilder> entry : regionOutputs.entrySet()) {
TtmlRegion region = regionMap.get(entry.getKey());
......@@ -185,25 +185,31 @@ import java.util.TreeSet;
return cues;
}
private void traverseForText(long timeUs, boolean descendsPNode,
String inheritedRegion, Map<String, SpannableStringBuilder> regionOutputs) {
private void traverseForText(
long timeUs,
boolean descendsPNode,
String inheritedRegion,
Map<String, SpannableStringBuilder> regionOutputs) {
nodeStartsByRegion.clear();
nodeEndsByRegion.clear();
String resolvedRegionId = regionId;
if (ANONYMOUS_REGION_ID.equals(resolvedRegionId)) {
resolvedRegionId = inheritedRegion;
if (TAG_METADATA.equals(tag)) {
// Ignore metadata tag.
return;
}
String resolvedRegionId = ANONYMOUS_REGION_ID.equals(regionId) ? inheritedRegion : regionId;
if (isTextNode && descendsPNode) {
getRegionOutput(resolvedRegionId, regionOutputs).append(text);
} else if (TAG_BR.equals(tag) && descendsPNode) {
getRegionOutput(resolvedRegionId, regionOutputs).append('\n');
} else if (TAG_METADATA.equals(tag)) {
// Do nothing.
} else if (isActive(timeUs)) {
boolean isPNode = TAG_P.equals(tag);
// This is a container node, which can contain zero or more children.
for (Entry<String, SpannableStringBuilder> entry : regionOutputs.entrySet()) {
nodeStartsByRegion.put(entry.getKey(), entry.getValue().length());
}
boolean isPNode = TAG_P.equals(tag);
for (int i = 0; i < getChildCount(); i++) {
getChild(i).traverseForText(timeUs, descendsPNode || isPNode, resolvedRegionId,
regionOutputs);
......@@ -211,39 +217,50 @@ import java.util.TreeSet;
if (isPNode) {
TtmlRenderUtil.endParagraph(getRegionOutput(resolvedRegionId, regionOutputs));
}
for (Entry<String, SpannableStringBuilder> entry : regionOutputs.entrySet()) {
nodeEndsByRegion.put(entry.getKey(), entry.getValue().length());
}
}
}
private static SpannableStringBuilder getRegionOutput(String resolvedRegionId,
Map<String, SpannableStringBuilder> regionOutputs) {
private static SpannableStringBuilder getRegionOutput(
String resolvedRegionId, Map<String, SpannableStringBuilder> regionOutputs) {
if (!regionOutputs.containsKey(resolvedRegionId)) {
regionOutputs.put(resolvedRegionId, new SpannableStringBuilder());
}
return regionOutputs.get(resolvedRegionId);
}
private void traverseForStyle(Map<String, TtmlStyle> globalStyles,
private void traverseForStyle(
long timeUs,
Map<String, TtmlStyle> globalStyles,
Map<String, SpannableStringBuilder> regionOutputs) {
if (!isActive(timeUs)) {
return;
}
for (Entry<String, Integer> entry : nodeEndsByRegion.entrySet()) {
String regionId = entry.getKey();
int start = nodeStartsByRegion.containsKey(regionId) ? nodeStartsByRegion.get(regionId) : 0;
applyStyleToOutput(globalStyles, regionOutputs.get(regionId), start, entry.getValue());
for (int i = 0; i < getChildCount(); ++i) {
getChild(i).traverseForStyle(globalStyles, regionOutputs);
int end = entry.getValue();
if (start != end) {
SpannableStringBuilder regionOutput = regionOutputs.get(regionId);
applyStyleToOutput(globalStyles, regionOutput, start, end);
}
}
for (int i = 0; i < getChildCount(); ++i) {
getChild(i).traverseForStyle(timeUs, globalStyles, regionOutputs);
}
}
private void applyStyleToOutput(Map<String, TtmlStyle> globalStyles,
SpannableStringBuilder regionOutput, int start, int end) {
if (start != end) {
TtmlStyle resolvedStyle = TtmlRenderUtil.resolveStyle(style, styleIds, globalStyles);
if (resolvedStyle != null) {
TtmlRenderUtil.applyStylesToSpan(regionOutput, start, end, resolvedStyle);
}
private void applyStyleToOutput(
Map<String, TtmlStyle> globalStyles,
SpannableStringBuilder regionOutput,
int start,
int end) {
TtmlStyle resolvedStyle = TtmlRenderUtil.resolveStyle(style, styleIds, globalStyles);
if (resolvedStyle != null) {
TtmlRenderUtil.applyStylesToSpan(regionOutput, start, end, resolvedStyle);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment