private Map<String, TtmlStyle> parseHeader( XmlPullParser xmlParser, Map<String, TtmlStyle> globalStyles) throws IOException, XmlPullParserException { do { xmlParser.next(); if (ParserUtil.isStartTag(xmlParser, TtmlNode.TAG_STYLE)) { String parentStyleId = xmlParser.getAttributeValue(null, ATTR_STYLE); TtmlStyle style = parseStyleAttributes(xmlParser, new TtmlStyle()); if (parentStyleId != null) { String[] ids = parseStyleIds(parentStyleId); for (int i = 0; i < ids.length; i++) { style.chain(globalStyles.get(ids[i])); } } if (style.getId() != null) { globalStyles.put(style.getId(), style); } } } while (!ParserUtil.isEndTag(xmlParser, TtmlNode.TAG_HEAD)); return globalStyles; }
private TtmlNode parseNode(XmlPullParser parser, TtmlNode parent) throws ParserException { long duration = 0; long startTime = TtmlNode.UNDEFINED_TIME; long endTime = TtmlNode.UNDEFINED_TIME; String[] styleIds = null; int attributeCount = parser.getAttributeCount(); TtmlStyle style = parseStyleAttributes(parser, null); for (int i = 0; i < attributeCount; i++) { String attr = ParserUtil.removeNamespacePrefix(parser.getAttributeName(i)); String value = parser.getAttributeValue(i); if (attr.equals(ATTR_BEGIN)) { startTime = parseTimeExpression(value, DEFAULT_FRAMERATE, DEFAULT_SUBFRAMERATE, DEFAULT_TICKRATE); } else if (attr.equals(ATTR_END)) { endTime = parseTimeExpression(value, DEFAULT_FRAMERATE, DEFAULT_SUBFRAMERATE, DEFAULT_TICKRATE); } else if (attr.equals(ATTR_DURATION)) { duration = parseTimeExpression(value, DEFAULT_FRAMERATE, DEFAULT_SUBFRAMERATE, DEFAULT_TICKRATE); } else if (attr.equals(ATTR_STYLE)) { // IDREFS: potentially multiple space delimited ids String[] ids = parseStyleIds(value); if (ids.length > 0) { styleIds = ids; } } else { // Do nothing. } } if (parent != null && parent.startTimeUs != TtmlNode.UNDEFINED_TIME) { if (startTime != TtmlNode.UNDEFINED_TIME) { startTime += parent.startTimeUs; } if (endTime != TtmlNode.UNDEFINED_TIME) { endTime += parent.startTimeUs; } } if (endTime == TtmlNode.UNDEFINED_TIME) { if (duration > 0) { // Infer the end time from the duration. endTime = startTime + duration; } else if (parent != null && parent.endTimeUs != TtmlNode.UNDEFINED_TIME) { // If the end time remains unspecified, then it should be inherited from the parent. endTime = parent.endTimeUs; } } return TtmlNode.buildNode(parser.getName(), startTime, endTime, style, styleIds); }
private TtmlStyle parseStyleAttributes(XmlPullParser parser, TtmlStyle style) { int attributeCount = parser.getAttributeCount(); for (int i = 0; i < attributeCount; i++) { String attributeName = parser.getAttributeName(i); String attributeValue = parser.getAttributeValue(i); switch (ParserUtil.removeNamespacePrefix(attributeName)) { case TtmlNode.ATTR_ID: if (TtmlNode.TAG_STYLE.equals(parser.getName())) { style = createIfNull(style).setId(attributeValue); } break; case TtmlNode.ATTR_TTS_BACKGROUND_COLOR: style = createIfNull(style); try { style.setBackgroundColor(TtmlColorParser.parseColor(attributeValue)); } catch (IllegalArgumentException e) { Log.w(TAG, "failed parsing background value: '" + attributeValue + "'"); } break; case TtmlNode.ATTR_TTS_COLOR: style = createIfNull(style); try { style.setColor(TtmlColorParser.parseColor(attributeValue)); } catch (IllegalArgumentException e) { Log.w(TAG, "failed parsing color value: '" + attributeValue + "'"); } break; case TtmlNode.ATTR_TTS_FONT_FAMILY: style = createIfNull(style).setFontFamily(attributeValue); break; case TtmlNode.ATTR_TTS_FONT_SIZE: // TODO: handle size break; case TtmlNode.ATTR_TTS_FONT_WEIGHT: style = createIfNull(style).setBold(TtmlNode.BOLD.equalsIgnoreCase(attributeValue)); break; case TtmlNode.ATTR_TTS_FONT_STYLE: style = createIfNull(style).setItalic(TtmlNode.ITALIC.equalsIgnoreCase(attributeValue)); break; case TtmlNode.ATTR_TTS_TEXT_ALIGN: switch (Util.toLowerInvariant(attributeValue)) { case TtmlNode.LEFT: style = createIfNull(style).setTextAlign(Layout.Alignment.ALIGN_NORMAL); break; case TtmlNode.START: style = createIfNull(style).setTextAlign(Layout.Alignment.ALIGN_NORMAL); break; case TtmlNode.RIGHT: style = createIfNull(style).setTextAlign(Layout.Alignment.ALIGN_OPPOSITE); break; case TtmlNode.END: style = createIfNull(style).setTextAlign(Layout.Alignment.ALIGN_OPPOSITE); break; case TtmlNode.CENTER: style = createIfNull(style).setTextAlign(Layout.Alignment.ALIGN_CENTER); break; } break; case TtmlNode.ATTR_TTS_TEXT_DECORATION: switch (Util.toLowerInvariant(attributeValue)) { case TtmlNode.LINETHROUGH: style = createIfNull(style).setLinethrough(true); break; case TtmlNode.NO_LINETHROUGH: style = createIfNull(style).setLinethrough(false); break; case TtmlNode.UNDERLINE: style = createIfNull(style).setUnderline(true); break; case TtmlNode.NO_UNDERLINE: style = createIfNull(style).setUnderline(false); break; } break; default: // ignore break; } } return style; }