CuePainter fixes for caption styling.

- Don't allow "nothing has changed" optimization in the case
  that only styling has changed (TextUtils.equals will return
  true in this case, but we shouldn't optimize).
- Add functionality to suppress embedded styling; seems useful
  to have.
- Added "this." for clarity.
This commit is contained in:
Oliver Woodman 2015-09-10 18:22:44 +01:00
parent 68f2dc5998
commit 7d38d2ef3c
2 changed files with 69 additions and 33 deletions

View file

@ -71,6 +71,7 @@ import android.util.Log;
private CharSequence cueText;
private int cuePosition;
private Alignment cueAlignment;
private boolean applyEmbeddedStyles;
private int foregroundColor;
private int backgroundColor;
private int windowColor;
@ -121,6 +122,7 @@ import android.util.Log;
* which the same parameters are passed.
*
* @param cue The cue to draw.
* @param applyEmbeddedStyles Whether styling embedded within the cue should be applied.
* @param style The style to use when drawing the cue text.
* @param fontScale The font scale.
* @param bottomPaddingFraction The bottom padding fraction to apply when {@link Cue#line} is
@ -131,48 +133,55 @@ import android.util.Log;
* @param cueBoxRight The right position of the enclosing cue box.
* @param cueBoxBottom The bottom position of the enclosing cue box.
*/
public void draw(Cue cue, CaptionStyleCompat style, float fontScale, float bottomPaddingFraction,
Canvas canvas, int cueBoxLeft, int cueBoxTop, int cueBoxRight, int cueBoxBottom) {
if (TextUtils.isEmpty(cue.text)) {
public void draw(Cue cue, boolean applyEmbeddedStyles, CaptionStyleCompat style, float fontScale,
float bottomPaddingFraction, Canvas canvas, int cueBoxLeft, int cueBoxTop, int cueBoxRight,
int cueBoxBottom) {
CharSequence cueText = cue.text;
if (TextUtils.isEmpty(cueText)) {
// Nothing to draw.
return;
}
if (TextUtils.equals(cueText, cue.text)
&& cuePosition == cue.position
&& Util.areEqual(cueAlignment, cue.alignment)
&& foregroundColor == style.foregroundColor
&& backgroundColor == style.backgroundColor
&& windowColor == style.windowColor
&& edgeType == style.edgeType
&& edgeColor == style.edgeColor
&& Util.areEqual(textPaint.getTypeface(), style.typeface)
if (!applyEmbeddedStyles) {
// Strip out any embedded styling.
cueText = cueText.toString();
}
if (areCharSequencesEqual(this.cueText, cueText)
&& this.cuePosition == cue.position
&& Util.areEqual(this.cueAlignment, cue.alignment)
&& this.applyEmbeddedStyles == applyEmbeddedStyles
&& this.foregroundColor == style.foregroundColor
&& this.backgroundColor == style.backgroundColor
&& this.windowColor == style.windowColor
&& this.edgeType == style.edgeType
&& this.edgeColor == style.edgeColor
&& Util.areEqual(this.textPaint.getTypeface(), style.typeface)
&& this.fontScale == fontScale
&& this.bottomPaddingFraction == bottomPaddingFraction
&& parentLeft == cueBoxLeft
&& parentTop == cueBoxTop
&& parentRight == cueBoxRight
&& parentBottom == cueBoxBottom) {
&& this.parentLeft == cueBoxLeft
&& this.parentTop == cueBoxTop
&& this.parentRight == cueBoxRight
&& this.parentBottom == cueBoxBottom) {
// We can use the cached layout.
drawLayout(canvas);
return;
}
cueText = cue.text;
cuePosition = cue.position;
cueAlignment = cue.alignment;
foregroundColor = style.foregroundColor;
backgroundColor = style.backgroundColor;
windowColor = style.windowColor;
edgeType = style.edgeType;
edgeColor = style.edgeColor;
textPaint.setTypeface(style.typeface);
this.cueText = cueText;
this.cuePosition = cue.position;
this.cueAlignment = cue.alignment;
this.applyEmbeddedStyles = applyEmbeddedStyles;
this.foregroundColor = style.foregroundColor;
this.backgroundColor = style.backgroundColor;
this.windowColor = style.windowColor;
this.edgeType = style.edgeType;
this.edgeColor = style.edgeColor;
this.textPaint.setTypeface(style.typeface);
this.fontScale = fontScale;
this.bottomPaddingFraction = bottomPaddingFraction;
parentLeft = cueBoxLeft;
parentTop = cueBoxTop;
parentRight = cueBoxRight;
parentBottom = cueBoxBottom;
this.parentLeft = cueBoxLeft;
this.parentTop = cueBoxTop;
this.parentRight = cueBoxRight;
this.parentBottom = cueBoxBottom;
int parentWidth = parentRight - parentLeft;
int parentHeight = parentBottom - parentTop;
@ -297,4 +306,15 @@ import android.util.Log;
canvas.restoreToCount(saveCount);
}
/**
* This method is used instead of {@link TextUtils#equals(CharSequence, CharSequence)} because the
* latter only checks the text of each sequence, and does not check for equality of styling that
* may be embedded within the {@link CharSequence}s.
*/
private static boolean areCharSequencesEqual(CharSequence first, CharSequence second) {
// Some CharSequence implementations don't perform a cheap referential equality check in their
// equals methods, so we perform one explicitly here.
return first == second || (first != null && first.equals(second));
}
}

View file

@ -38,6 +38,7 @@ public final class SubtitleLayout extends View {
private List<Cue> cues;
private float fontScale;
private boolean applyEmbeddedStyles;
private CaptionStyleCompat style;
private float bottomPaddingFraction;
@ -49,6 +50,7 @@ public final class SubtitleLayout extends View {
super(context, attrs);
painters = new ArrayList<>();
fontScale = 1;
applyEmbeddedStyles = true;
style = CaptionStyleCompat.DEFAULT;
bottomPaddingFraction = DEFAULT_BOTTOM_PADDING_FRACTION;
}
@ -87,7 +89,21 @@ public final class SubtitleLayout extends View {
}
/**
* Configures the view according to the given style.
* Sets whether styling embedded within the cues should be applied. Enabled by default.
*
* @param applyEmbeddedStyles Whether styling embedded within the cues should be applied.
*/
public void setApplyEmbeddedStyles(boolean applyEmbeddedStyles) {
if (this.applyEmbeddedStyles == applyEmbeddedStyles) {
return;
}
this.applyEmbeddedStyles = applyEmbeddedStyles;
// Invalidate to trigger drawing.
invalidate();
}
/**
* Sets the caption style.
*
* @param style A style for the view.
*/
@ -119,8 +135,8 @@ public final class SubtitleLayout extends View {
public void dispatchDraw(Canvas canvas) {
int cueCount = (cues == null) ? 0 : cues.size();
for (int i = 0; i < cueCount; i++) {
painters.get(i).draw(cues.get(i), style, fontScale, bottomPaddingFraction, canvas, getLeft(),
getTop(), getRight(), getBottom());
painters.get(i).draw(cues.get(i), applyEmbeddedStyles, style, fontScale,
bottomPaddingFraction, canvas, getLeft(), getTop(), getRight(), getBottom());
}
}