mirror of
https://github.com/samsonjs/media.git
synced 2026-04-02 10:45:51 +00:00
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
This commit is contained in:
parent
9a45d504d3
commit
17abab455e
2 changed files with 42 additions and 22 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue