diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 39ef439f40..ddc5d06fdb 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -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 ### diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlNode.java b/library/core/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlNode.java index 43fa7a1bd9..1facb73567 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlNode.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/ttml/TtmlNode.java @@ -175,7 +175,7 @@ import java.util.TreeSet; Map regionMap) { TreeMap regionOutputs = new TreeMap<>(); traverseForText(timeUs, false, regionId, regionOutputs); - traverseForStyle(globalStyles, regionOutputs); + traverseForStyle(timeUs, globalStyles, regionOutputs); List cues = new ArrayList<>(); for (Entry 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 regionOutputs) { + private void traverseForText( + long timeUs, + boolean descendsPNode, + String inheritedRegion, + Map 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 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 entry : regionOutputs.entrySet()) { nodeEndsByRegion.put(entry.getKey(), entry.getValue().length()); } } } - private static SpannableStringBuilder getRegionOutput(String resolvedRegionId, - Map regionOutputs) { + private static SpannableStringBuilder getRegionOutput( + String resolvedRegionId, Map regionOutputs) { if (!regionOutputs.containsKey(resolvedRegionId)) { regionOutputs.put(resolvedRegionId, new SpannableStringBuilder()); } return regionOutputs.get(resolvedRegionId); } - private void traverseForStyle(Map globalStyles, + private void traverseForStyle( + long timeUs, + Map globalStyles, Map regionOutputs) { + if (!isActive(timeUs)) { + return; + } for (Entry 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 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 globalStyles, + SpannableStringBuilder regionOutput, + int start, + int end) { + TtmlStyle resolvedStyle = TtmlRenderUtil.resolveStyle(style, styleIds, globalStyles); + if (resolvedStyle != null) { + TtmlRenderUtil.applyStylesToSpan(regionOutput, start, end, resolvedStyle); } }