Do TTML color parsing directly in Exoplayer.
- Added TtmlColorParser to workaround JellyBean issues with named colors. - Support rgb and rgba expressions as well.
This commit is contained in:
parent
414ad05314
commit
20e05a31b2
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer.text.ttml;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.test.InstrumentationTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for <code>TtmlColorParser</code>.
|
||||||
|
*/
|
||||||
|
public class TtmlColorParserTest extends InstrumentationTestCase {
|
||||||
|
|
||||||
|
public void testHexCodeParsing() {
|
||||||
|
assertEquals(Color.WHITE, TtmlColorParser.parseColor("#ffffff"));
|
||||||
|
assertEquals(Color.WHITE, TtmlColorParser.parseColor("#ffffffff"));
|
||||||
|
assertEquals(Color.parseColor("#00ffffff"), TtmlColorParser.parseColor("#00ffffff"));
|
||||||
|
assertEquals(Color.parseColor("#12341234"), TtmlColorParser.parseColor("#12341234"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testColorNameParsing() {
|
||||||
|
assertEquals(TtmlColorParser.TRANSPARENT, TtmlColorParser.parseColor("transparent"));
|
||||||
|
assertEquals(TtmlColorParser.BLACK, TtmlColorParser.parseColor("black"));
|
||||||
|
assertEquals(TtmlColorParser.GRAY, TtmlColorParser.parseColor("gray"));
|
||||||
|
assertEquals(TtmlColorParser.SILVER, TtmlColorParser.parseColor("silver"));
|
||||||
|
assertEquals(TtmlColorParser.WHITE, TtmlColorParser.parseColor("white"));
|
||||||
|
assertEquals(TtmlColorParser.MAROON, TtmlColorParser.parseColor("maroon"));
|
||||||
|
assertEquals(TtmlColorParser.RED, TtmlColorParser.parseColor("red"));
|
||||||
|
assertEquals(TtmlColorParser.PURPLE, TtmlColorParser.parseColor("purple"));
|
||||||
|
assertEquals(TtmlColorParser.FUCHSIA, TtmlColorParser.parseColor("fuchsia"));
|
||||||
|
assertEquals(TtmlColorParser.MAGENTA, TtmlColorParser.parseColor("magenta"));
|
||||||
|
assertEquals(TtmlColorParser.GREEN, TtmlColorParser.parseColor("green"));
|
||||||
|
assertEquals(TtmlColorParser.LIME, TtmlColorParser.parseColor("lime"));
|
||||||
|
assertEquals(TtmlColorParser.OLIVE, TtmlColorParser.parseColor("olive"));
|
||||||
|
assertEquals(TtmlColorParser.YELLOW, TtmlColorParser.parseColor("yellow"));
|
||||||
|
assertEquals(TtmlColorParser.NAVY, TtmlColorParser.parseColor("navy"));
|
||||||
|
assertEquals(TtmlColorParser.BLUE, TtmlColorParser.parseColor("blue"));
|
||||||
|
assertEquals(TtmlColorParser.TEAL, TtmlColorParser.parseColor("teal"));
|
||||||
|
assertEquals(TtmlColorParser.AQUA, TtmlColorParser.parseColor("aqua"));
|
||||||
|
assertEquals(TtmlColorParser.CYAN, TtmlColorParser.parseColor("cyan"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testParseUnknownColor() {
|
||||||
|
try {
|
||||||
|
TtmlColorParser.parseColor("colorOfAnElectron");
|
||||||
|
fail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testParseNull() {
|
||||||
|
try {
|
||||||
|
TtmlColorParser.parseColor(null);
|
||||||
|
fail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testParseEmpty() {
|
||||||
|
try {
|
||||||
|
TtmlColorParser.parseColor("");
|
||||||
|
fail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRgbColorParsing() {
|
||||||
|
assertEquals(Color.WHITE, TtmlColorParser.parseColor("rgb(255,255,255)"));
|
||||||
|
// spaces do not matter
|
||||||
|
assertEquals(Color.WHITE, TtmlColorParser.parseColor(" rgb ( 255, 255, 255)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRgbColorParsing_rgbValuesOutOfBounds() {
|
||||||
|
int outOfBounds = TtmlColorParser.parseColor("rgb(999, 999, 999)");
|
||||||
|
int color = Color.rgb(999, 999, 999);
|
||||||
|
// behave like framework Color behaves
|
||||||
|
assertEquals(color, outOfBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRgbColorParsing_rgbValuesNegative() {
|
||||||
|
try {
|
||||||
|
TtmlColorParser.parseColor("rgb(-4, 55, 209)");
|
||||||
|
fail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRgbaColorParsing() {
|
||||||
|
assertEquals(Color.WHITE, TtmlColorParser.parseColor("rgba(255,255,255,0)"));
|
||||||
|
assertEquals(Color.argb(0, 255, 255, 255), TtmlColorParser.parseColor("rgba(255,255,255,255)"));
|
||||||
|
assertEquals(Color.BLACK, TtmlColorParser.parseColor("rgba(0, 0, 0, 0)"));
|
||||||
|
assertEquals(Color.argb(0, 0, 0, 0), TtmlColorParser.parseColor("rgba(0, 0, 0, 255)"));
|
||||||
|
assertEquals(Color.RED, TtmlColorParser.parseColor("rgba(255, 0, 0, 0)"));
|
||||||
|
assertEquals(Color.argb(0, 255, 0, 0), TtmlColorParser.parseColor("rgba(255, 0, 0, 255)"));
|
||||||
|
assertEquals(Color.argb(205, 255, 0, 0), TtmlColorParser.parseColor("rgba(255, 0, 0, 50)"));
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,6 @@ package com.google.android.exoplayer.text.ttml;
|
|||||||
|
|
||||||
import com.google.android.exoplayer.text.Cue;
|
import com.google.android.exoplayer.text.Cue;
|
||||||
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.test.InstrumentationTestCase;
|
import android.test.InstrumentationTestCase;
|
||||||
import android.text.Layout;
|
import android.text.Layout;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
@ -67,8 +66,8 @@ public final class TtmlParserTest extends InstrumentationTestCase {
|
|||||||
TtmlNode body = queryChildrenForTag(root, TtmlNode.TAG_BODY, 0);
|
TtmlNode body = queryChildrenForTag(root, TtmlNode.TAG_BODY, 0);
|
||||||
TtmlNode firstDiv = queryChildrenForTag(body, TtmlNode.TAG_DIV, 0);
|
TtmlNode firstDiv = queryChildrenForTag(body, TtmlNode.TAG_DIV, 0);
|
||||||
TtmlStyle firstPStyle = queryChildrenForTag(firstDiv, TtmlNode.TAG_P, 0).style;
|
TtmlStyle firstPStyle = queryChildrenForTag(firstDiv, TtmlNode.TAG_P, 0).style;
|
||||||
assertEquals(Color.parseColor("yellow"), firstPStyle.getColor());
|
assertEquals(TtmlColorParser.parseColor("yellow"), firstPStyle.getColor());
|
||||||
assertEquals(Color.parseColor("blue"), firstPStyle.getBackgroundColor());
|
assertEquals(TtmlColorParser.parseColor("blue"), firstPStyle.getBackgroundColor());
|
||||||
assertEquals("serif", firstPStyle.getFontFamily());
|
assertEquals("serif", firstPStyle.getFontFamily());
|
||||||
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, firstPStyle.getStyle());
|
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, firstPStyle.getStyle());
|
||||||
assertTrue(firstPStyle.isUnderline());
|
assertTrue(firstPStyle.isUnderline());
|
||||||
@ -78,24 +77,43 @@ public final class TtmlParserTest extends InstrumentationTestCase {
|
|||||||
TtmlSubtitle subtitle = getSubtitle(INLINE_ATTRIBUTES_TTML_FILE);
|
TtmlSubtitle subtitle = getSubtitle(INLINE_ATTRIBUTES_TTML_FILE);
|
||||||
assertEquals(4, subtitle.getEventTimeCount());
|
assertEquals(4, subtitle.getEventTimeCount());
|
||||||
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_ITALIC,
|
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_ITALIC,
|
||||||
Color.CYAN, Color.parseColor("lime"), false, true, null);
|
TtmlColorParser.CYAN, TtmlColorParser.parseColor("lime"), false, true, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* regression test for devices on JellyBean where some named colors are not correctly defined
|
||||||
|
* on framework level. Tests that <i>lime</i> resolves to <code>#FF00FF00</code> not
|
||||||
|
* <code>#00FF00</code>.
|
||||||
|
*
|
||||||
|
* See: https://github.com/android/platform_frameworks_base/blob/jb-mr2-release/
|
||||||
|
* graphics/java/android/graphics/Color.java#L414
|
||||||
|
* https://github.com/android/platform_frameworks_base/blob/kitkat-mr2.2-release/
|
||||||
|
* graphics/java/android/graphics/Color.java#L414
|
||||||
|
*
|
||||||
|
* @throws IOException thrown if reading subtitle file fails.
|
||||||
|
*/
|
||||||
|
public void testLime() throws IOException {
|
||||||
|
TtmlSubtitle subtitle = getSubtitle(INLINE_ATTRIBUTES_TTML_FILE);
|
||||||
|
assertEquals(4, subtitle.getEventTimeCount());
|
||||||
|
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_ITALIC,
|
||||||
|
TtmlColorParser.CYAN, TtmlColorParser.LIME, false, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInheritGlobalStyle() throws IOException {
|
public void testInheritGlobalStyle() throws IOException {
|
||||||
TtmlSubtitle subtitle = getSubtitle(INHERIT_STYLE_TTML_FILE);
|
TtmlSubtitle subtitle = getSubtitle(INHERIT_STYLE_TTML_FILE);
|
||||||
assertEquals(2, subtitle.getEventTimeCount());
|
assertEquals(2, subtitle.getEventTimeCount());
|
||||||
assertSpans(subtitle, 10, "text 1", "serif", TtmlStyle.STYLE_BOLD_ITALIC,
|
assertSpans(subtitle, 10, "text 1", "serif", TtmlStyle.STYLE_BOLD_ITALIC,
|
||||||
Color.BLUE, Color.YELLOW, true, false, null);
|
TtmlColorParser.BLUE, TtmlColorParser.YELLOW, true, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInheritGlobalStyleOverriddenByInlineAttributes() throws IOException {
|
public void testInheritGlobalStyleOverriddenByInlineAttributes() throws IOException {
|
||||||
TtmlSubtitle subtitle = getSubtitle(INHERIT_STYLE_OVERRIDE_TTML_FILE);
|
TtmlSubtitle subtitle = getSubtitle(INHERIT_STYLE_OVERRIDE_TTML_FILE);
|
||||||
assertEquals(4, subtitle.getEventTimeCount());
|
assertEquals(4, subtitle.getEventTimeCount());
|
||||||
|
|
||||||
assertSpans(subtitle, 10, "text 1", "serif", TtmlStyle.STYLE_BOLD_ITALIC, Color.BLUE,
|
assertSpans(subtitle, 10, "text 1", "serif", TtmlStyle.STYLE_BOLD_ITALIC, TtmlColorParser.BLUE,
|
||||||
Color.YELLOW, true, false, null);
|
TtmlColorParser.YELLOW, true, false, null);
|
||||||
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_ITALIC, Color.RED,
|
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_ITALIC, TtmlColorParser.RED,
|
||||||
Color.YELLOW, true, false, null);
|
TtmlColorParser.YELLOW, true, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInheritGlobalAndParent() throws IOException {
|
public void testInheritGlobalAndParent() throws IOException {
|
||||||
@ -103,9 +121,10 @@ public final class TtmlParserTest extends InstrumentationTestCase {
|
|||||||
assertEquals(4, subtitle.getEventTimeCount());
|
assertEquals(4, subtitle.getEventTimeCount());
|
||||||
|
|
||||||
assertSpans(subtitle, 10, "text 1", "sansSerif", TtmlStyle.STYLE_NORMAL,
|
assertSpans(subtitle, 10, "text 1", "sansSerif", TtmlStyle.STYLE_NORMAL,
|
||||||
Color.RED, Color.parseColor("lime"), false, true, Layout.Alignment.ALIGN_CENTER);
|
TtmlColorParser.RED, TtmlColorParser.parseColor("lime"), false, true,
|
||||||
|
Layout.Alignment.ALIGN_CENTER);
|
||||||
assertSpans(subtitle, 20, "text 2", "serif", TtmlStyle.STYLE_BOLD_ITALIC,
|
assertSpans(subtitle, 20, "text 2", "serif", TtmlStyle.STYLE_BOLD_ITALIC,
|
||||||
Color.BLUE, Color.YELLOW, true, true, Layout.Alignment.ALIGN_CENTER);
|
TtmlColorParser.BLUE, TtmlColorParser.YELLOW, true, true, Layout.Alignment.ALIGN_CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInheritMultipleStyles() throws IOException {
|
public void testInheritMultipleStyles() throws IOException {
|
||||||
@ -113,7 +132,7 @@ public final class TtmlParserTest extends InstrumentationTestCase {
|
|||||||
assertEquals(12, subtitle.getEventTimeCount());
|
assertEquals(12, subtitle.getEventTimeCount());
|
||||||
|
|
||||||
assertSpans(subtitle, 10, "text 1", "sansSerif", TtmlStyle.STYLE_BOLD_ITALIC,
|
assertSpans(subtitle, 10, "text 1", "sansSerif", TtmlStyle.STYLE_BOLD_ITALIC,
|
||||||
Color.BLUE, Color.YELLOW, false, true, null);
|
TtmlColorParser.BLUE, TtmlColorParser.YELLOW, false, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInheritMultipleStylesWithoutLocalAttributes() throws IOException {
|
public void testInheritMultipleStylesWithoutLocalAttributes() throws IOException {
|
||||||
@ -121,7 +140,7 @@ public final class TtmlParserTest extends InstrumentationTestCase {
|
|||||||
assertEquals(12, subtitle.getEventTimeCount());
|
assertEquals(12, subtitle.getEventTimeCount());
|
||||||
|
|
||||||
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_BOLD_ITALIC,
|
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_BOLD_ITALIC,
|
||||||
Color.BLUE, Color.BLACK, false, true, null);
|
TtmlColorParser.BLUE, TtmlColorParser.BLACK, false, true, null);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +149,7 @@ public final class TtmlParserTest extends InstrumentationTestCase {
|
|||||||
assertEquals(12, subtitle.getEventTimeCount());
|
assertEquals(12, subtitle.getEventTimeCount());
|
||||||
|
|
||||||
assertSpans(subtitle, 30, "text 2.5", "sansSerifInline", TtmlStyle.STYLE_ITALIC,
|
assertSpans(subtitle, 30, "text 2.5", "sansSerifInline", TtmlStyle.STYLE_ITALIC,
|
||||||
Color.RED, Color.YELLOW, true, true, null);
|
TtmlColorParser.RED, TtmlColorParser.YELLOW, true, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEmptyStyleAttribute() throws IOException {
|
public void testEmptyStyleAttribute() throws IOException {
|
||||||
@ -175,16 +194,16 @@ public final class TtmlParserTest extends InstrumentationTestCase {
|
|||||||
|
|
||||||
TtmlStyle style = globalStyles.get("s2");
|
TtmlStyle style = globalStyles.get("s2");
|
||||||
assertEquals("serif", style.getFontFamily());
|
assertEquals("serif", style.getFontFamily());
|
||||||
assertEquals(Color.RED, style.getBackgroundColor());
|
assertEquals(TtmlColorParser.RED, style.getBackgroundColor());
|
||||||
assertEquals(Color.BLACK, style.getColor());
|
assertEquals(TtmlColorParser.BLACK, style.getColor());
|
||||||
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, style.getStyle());
|
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, style.getStyle());
|
||||||
assertTrue(style.isLinethrough());
|
assertTrue(style.isLinethrough());
|
||||||
|
|
||||||
style = globalStyles.get("s3");
|
style = globalStyles.get("s3");
|
||||||
// only difference: color must be RED
|
// only difference: color must be RED
|
||||||
assertEquals(Color.RED, style.getColor());
|
assertEquals(TtmlColorParser.RED, style.getColor());
|
||||||
assertEquals("serif", style.getFontFamily());
|
assertEquals("serif", style.getFontFamily());
|
||||||
assertEquals(Color.RED, style.getBackgroundColor());
|
assertEquals(TtmlColorParser.RED, style.getBackgroundColor());
|
||||||
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, style.getStyle());
|
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, style.getStyle());
|
||||||
assertTrue(style.isLinethrough());
|
assertTrue(style.isLinethrough());
|
||||||
}
|
}
|
||||||
@ -224,8 +243,8 @@ public final class TtmlParserTest extends InstrumentationTestCase {
|
|||||||
TtmlStyle style = queryChildrenForTag(div, TtmlNode.TAG_P, 0).style;
|
TtmlStyle style = queryChildrenForTag(div, TtmlNode.TAG_P, 0).style;
|
||||||
|
|
||||||
assertNotNull(style);
|
assertNotNull(style);
|
||||||
assertEquals(Color.BLACK, style.getBackgroundColor());
|
assertEquals(TtmlColorParser.BLACK, style.getBackgroundColor());
|
||||||
assertEquals(Color.YELLOW, style.getColor());
|
assertEquals(TtmlColorParser.YELLOW, style.getColor());
|
||||||
assertEquals(TtmlStyle.STYLE_ITALIC, style.getStyle());
|
assertEquals(TtmlStyle.STYLE_ITALIC, style.getStyle());
|
||||||
assertEquals("sansSerif", style.getFontFamily());
|
assertEquals("sansSerif", style.getFontFamily());
|
||||||
assertFalse(style.isUnderline());
|
assertFalse(style.isUnderline());
|
||||||
@ -243,8 +262,8 @@ public final class TtmlParserTest extends InstrumentationTestCase {
|
|||||||
TtmlStyle style = queryChildrenForTag(div, TtmlNode.TAG_P, 0).style;
|
TtmlStyle style = queryChildrenForTag(div, TtmlNode.TAG_P, 0).style;
|
||||||
|
|
||||||
assertNotNull(style);
|
assertNotNull(style);
|
||||||
assertEquals(Color.BLACK, style.getBackgroundColor());
|
assertEquals(TtmlColorParser.BLACK, style.getBackgroundColor());
|
||||||
assertEquals(Color.YELLOW, style.getColor());
|
assertEquals(TtmlColorParser.YELLOW, style.getColor());
|
||||||
assertEquals(TtmlStyle.STYLE_ITALIC, style.getStyle());
|
assertEquals(TtmlStyle.STYLE_ITALIC, style.getStyle());
|
||||||
assertEquals("sansSerif", style.getFontFamily());
|
assertEquals("sansSerif", style.getFontFamily());
|
||||||
assertFalse(style.isUnderline());
|
assertFalse(style.isUnderline());
|
||||||
|
@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer.text.ttml;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer.util.Assertions;
|
||||||
|
import com.google.android.exoplayer.util.Util;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser to parse ttml color value expression
|
||||||
|
* (http://www.w3.org/TR/ttml1/#style-value-color)
|
||||||
|
*/
|
||||||
|
/*package*/ final class TtmlColorParser {
|
||||||
|
|
||||||
|
private static final String RGB = "rgb";
|
||||||
|
private static final String RGBA = "rgba";
|
||||||
|
|
||||||
|
private static final Pattern RGB_PATTERN = Pattern.compile(
|
||||||
|
"^rgb\\((\\d{1,3}),(\\d{1,3}),(\\d{1,3})\\)$");
|
||||||
|
|
||||||
|
private static final Pattern RGBA_PATTERN = Pattern.compile(
|
||||||
|
"^rgba\\((\\d{1,3}),(\\d{1,3}),(\\d{1,3}),(\\d{1,3})\\)$");
|
||||||
|
|
||||||
|
|
||||||
|
static final int TRANSPARENT = 0x00000000;
|
||||||
|
static final int BLACK = 0xFF000000;
|
||||||
|
static final int SILVER = 0xFFC0C0C0;
|
||||||
|
static final int GRAY = 0xFF808080;
|
||||||
|
static final int WHITE = 0xFFFFFFFF;
|
||||||
|
static final int MAROON = 0xFF800000;
|
||||||
|
static final int RED = 0xFFFF0000;
|
||||||
|
static final int PURPLE = 0xFF800080;
|
||||||
|
static final int FUCHSIA = 0xFFFF00FF;
|
||||||
|
static final int MAGENTA = FUCHSIA;
|
||||||
|
static final int GREEN = 0xFF008000;
|
||||||
|
static final int LIME = 0xFF00FF00;
|
||||||
|
static final int OLIVE = 0xFF808000;
|
||||||
|
static final int YELLOW = 0xFFFFFF00;
|
||||||
|
static final int NAVY = 0xFF000080;
|
||||||
|
static final int BLUE = 0xFF0000FF;
|
||||||
|
static final int TEAL = 0xFF008080;
|
||||||
|
static final int AQUA = 0x00FFFFFF;
|
||||||
|
static final int CYAN = 0xFF00FFFF;
|
||||||
|
|
||||||
|
private static final Map<String, Integer> COLOR_NAME_MAP;
|
||||||
|
static {
|
||||||
|
COLOR_NAME_MAP = new HashMap<>();
|
||||||
|
COLOR_NAME_MAP.put("transparent", TRANSPARENT);
|
||||||
|
COLOR_NAME_MAP.put("black", BLACK);
|
||||||
|
COLOR_NAME_MAP.put("silver", SILVER);
|
||||||
|
COLOR_NAME_MAP.put("gray", GRAY);
|
||||||
|
COLOR_NAME_MAP.put("white", WHITE);
|
||||||
|
COLOR_NAME_MAP.put("maroon", MAROON);
|
||||||
|
COLOR_NAME_MAP.put("red", RED);
|
||||||
|
COLOR_NAME_MAP.put("purple", PURPLE);
|
||||||
|
COLOR_NAME_MAP.put("fuchsia", FUCHSIA);
|
||||||
|
COLOR_NAME_MAP.put("magenta", MAGENTA);
|
||||||
|
COLOR_NAME_MAP.put("green", GREEN);
|
||||||
|
COLOR_NAME_MAP.put("lime", LIME);
|
||||||
|
COLOR_NAME_MAP.put("olive", OLIVE);
|
||||||
|
COLOR_NAME_MAP.put("yellow", YELLOW);
|
||||||
|
COLOR_NAME_MAP.put("navy", NAVY);
|
||||||
|
COLOR_NAME_MAP.put("blue", BLUE);
|
||||||
|
COLOR_NAME_MAP.put("teal", TEAL);
|
||||||
|
COLOR_NAME_MAP.put("aqua", AQUA);
|
||||||
|
COLOR_NAME_MAP.put("cyan", CYAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int parseColor(String colorExpression) {
|
||||||
|
Assertions.checkArgument(!TextUtils.isEmpty(colorExpression));
|
||||||
|
colorExpression = colorExpression.replace(" ", "");
|
||||||
|
if (colorExpression.charAt(0) == '#') {
|
||||||
|
// Use a long to avoid rollovers on #ffXXXXXX
|
||||||
|
long color = Long.parseLong(colorExpression.substring(1), 16);
|
||||||
|
if (colorExpression.length() == 7) {
|
||||||
|
// Set the alpha value
|
||||||
|
color |= 0x00000000ff000000;
|
||||||
|
} else if (colorExpression.length() != 9) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
return (int) color;
|
||||||
|
} else if (colorExpression.startsWith(RGBA)) {
|
||||||
|
Matcher matcher = RGBA_PATTERN.matcher(colorExpression);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
return argb(
|
||||||
|
255 - Integer.parseInt(matcher.group(4), 10),
|
||||||
|
Integer.parseInt(matcher.group(1), 10),
|
||||||
|
Integer.parseInt(matcher.group(2), 10),
|
||||||
|
Integer.parseInt(matcher.group(3), 10)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (colorExpression.startsWith(RGB)) {
|
||||||
|
Matcher matcher = RGB_PATTERN.matcher(colorExpression);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
return rgb(
|
||||||
|
Integer.parseInt(matcher.group(1), 10),
|
||||||
|
Integer.parseInt(matcher.group(2), 10),
|
||||||
|
Integer.parseInt(matcher.group(3), 10)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we use our own color map
|
||||||
|
Integer color = COLOR_NAME_MAP.get(Util.toLowerInvariant(colorExpression));
|
||||||
|
if (color != null) {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int argb(int alpha, int red, int green, int blue) {
|
||||||
|
return (alpha << 24) | (red << 16) | (green << 8) | blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int rgb(int red, int green, int blue) {
|
||||||
|
return argb(0xFF, red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,7 +23,6 @@ import com.google.android.exoplayer.util.MimeTypes;
|
|||||||
import com.google.android.exoplayer.util.ParserUtil;
|
import com.google.android.exoplayer.util.ParserUtil;
|
||||||
import com.google.android.exoplayer.util.Util;
|
import com.google.android.exoplayer.util.Util;
|
||||||
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.text.Layout;
|
import android.text.Layout;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -207,7 +206,7 @@ public final class TtmlParser implements SubtitleParser {
|
|||||||
case TtmlNode.ATTR_TTS_BACKGROUND_COLOR:
|
case TtmlNode.ATTR_TTS_BACKGROUND_COLOR:
|
||||||
style = createIfNull(style);
|
style = createIfNull(style);
|
||||||
try {
|
try {
|
||||||
style.setBackgroundColor(Color.parseColor(attributeValue));
|
style.setBackgroundColor(TtmlColorParser.parseColor(attributeValue));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
Log.w(TAG, "failed parsing background value: '" + attributeValue + "'");
|
Log.w(TAG, "failed parsing background value: '" + attributeValue + "'");
|
||||||
}
|
}
|
||||||
@ -215,7 +214,7 @@ public final class TtmlParser implements SubtitleParser {
|
|||||||
case TtmlNode.ATTR_TTS_COLOR:
|
case TtmlNode.ATTR_TTS_COLOR:
|
||||||
style = createIfNull(style);
|
style = createIfNull(style);
|
||||||
try {
|
try {
|
||||||
style.setColor(Color.parseColor(attributeValue));
|
style.setColor(TtmlColorParser.parseColor(attributeValue));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
Log.w(TAG, "failed parsing color value: '" + attributeValue + "'");
|
Log.w(TAG, "failed parsing color value: '" + attributeValue + "'");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user