public void AssSimpleFontColorAndItalic() { var target = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); target.LoadSubtitle(subtitle, GetAssLines(@"{\1c&HFFFF00&\i1}CYAN{\i0}"), null); string actual = subtitle.Paragraphs[0].Text; const string expected = "<font color=\"#00ffff\"><i>CYAN</i></font>"; Assert.AreEqual(expected, actual); }
public void AssSimpleFontSizeMultiple() { var target = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); target.LoadSubtitle(subtitle, GetAssLines(@"{\fs1}T{\fs2}E{\fs3}S{\fs4}T"), null); string actual = subtitle.Paragraphs[0].Text; const string expected = "<font size=\"1\">T</font><font size=\"2\">E</font><font size=\"3\">S</font><font size=\"4\">T</font>"; Assert.AreEqual(expected, actual); }
public void AssSimpleFontName() { var target = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); target.LoadSubtitle(subtitle, GetAssLines(@"{\fnArial}Font"), null); string actual = subtitle.Paragraphs[0].Text; const string expected = "<font face=\"Arial\">Font</font>"; Assert.AreEqual(expected, actual); }
public void AssSimpleBold() { var target = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); target.LoadSubtitle(subtitle, GetAssLines(@"{\b1}Bold{\b0}"), null); string actual = subtitle.Paragraphs[0].Text; const string expected = "<b>Bold</b>"; Assert.AreEqual(expected, actual); }
public void AssSimpleUnderline() { var target = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); target.LoadSubtitle(subtitle, GetAssLines(@"{\u1}Underline{\u0}"), null); string actual = subtitle.Paragraphs[0].Text; const string expected = "<u>Underline</u>"; Assert.AreEqual(expected, actual); }
public void AssSimpleItalic() { var target = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); target.LoadSubtitle(subtitle, GetAssLines(@"{\i1}Italic{\i0}"), null); string actual = subtitle.Paragraphs[0].Text; const string expected = "<i>Italic</i>"; Assert.AreEqual(expected, actual); }
public void AssSizeAndOtherTags() { var target = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); target.LoadSubtitle(subtitle, GetAssLines(@"{\fs20\pos(1,1)\blur5}Bla-bla-bla"), null); string actual = subtitle.Paragraphs[0].Text; const string expected = @"{\fs20\pos(1,1)\blur5}Bla-bla-bla"; Assert.AreEqual(expected, actual); }
public void AssFontNameAndSize() { var target = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); target.LoadSubtitle(subtitle, GetAssLines(@"{\fnViner Hand ITC\fs28}Testing"), null); string actual = subtitle.Paragraphs[0].Text; const string expected = "<font face=\"Viner Hand ITC\" size=\"28\">Testing</font>"; Assert.AreEqual(expected, actual); }
public void AssSimpleFontColor4() { var target = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); target.LoadSubtitle(subtitle, GetAssLines(@"{\c&HFFFFFF&}Font"), null); string actual = subtitle.Paragraphs[0].Text; const string expected = "<font color=\"#ffffff\">Font</font>"; Assert.AreEqual(expected, actual); }
private static bool IsStyleDifferent(string styleName, Subtitle newSubtitle, string oldHeader) { var newStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, newSubtitle.Header); var oldStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, oldHeader); if (oldStyle == null || newStyle == null) { return(true); } return(newStyle.ToRawAss() != oldStyle.ToRawAss()); }
private void FillStyles() { listViewStyles.AutoSizeLastColumn(); var styles = AdvancedSubStationAlpha.GetStylesFromHeader(_subtitle.Header); var oldLoading = _loading; _loading = true; listViewStyles.Items.Clear(); listViewStyles.Items.AddRange(styles.OrderBy(p => p).Select(p => new ListViewItem { Text = p }).ToArray()); _loading = oldLoading; }
public ResolutionResampler(Subtitle subtitle, string videoFileName, VideoInfo videoInfo, bool showNeverButton) { UiUtil.PreInitialize(this); InitializeComponent(); UiUtil.FixFonts(this); var l = LanguageSettings.Current.AssaResulationChanger; Text = l.Title; labelSourceRes.Text = l.SourceVideoRes; labelTargetRes.Text = l.TargetVideoRes; checkBoxMargins.Text = l.ChangeResolutionMargins; checkBoxFontSize.Text = l.ChangeResolutionFontSize; checkBoxPosition.Text = l.ChangeResolutionPositions; checkBoxDrawing.Text = l.ChangeResolutionDrawing; buttonOK.Text = LanguageSettings.Current.General.Ok; buttonCancel.Text = LanguageSettings.Current.General.Cancel; UiUtil.FixLargeFonts(this, buttonOK); _subtitle = subtitle; _videoFileName = videoFileName; var videoInfo1 = videoInfo; if (string.IsNullOrEmpty(_subtitle.Header)) { _subtitle.Header = AdvancedSubStationAlpha.DefaultHeader; } var oldPlayResX = AdvancedSubStationAlpha.GetTagValueFromHeader("PlayResX", "[Script Info]", _subtitle.Header); if (int.TryParse(oldPlayResX, out var w)) { numericUpDownSourceWidth.Value = w; } var oldPlayResY = AdvancedSubStationAlpha.GetTagValueFromHeader("PlayResY", "[Script Info]", _subtitle.Header); if (int.TryParse(oldPlayResY, out var h)) { numericUpDownSourceHeight.Value = h; } if (videoInfo1 != null && videoInfo1.Width > 0 && videoInfo1.Height > 0) { numericUpDownTargetWidth.Value = videoInfo1.Width; numericUpDownTargetHeight.Value = videoInfo1.Height; } buttonNever.Text = LanguageSettings.Current.TimedTextSmpteTiming.NoNever; buttonNever.Visible = showNeverButton; }
private void InitializeListView() { var styles = AdvancedSubStationAlpha.GetStylesFromHeader(_subtitle.Header); listViewStyles.Items.Clear(); foreach (string style in styles) { SsaStyle ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(style, _subtitle.Header); SubStationAlphaStyles.AddStyle(listViewStyles, ssaStyle, _subtitle, _isSubStationAlpha); } if (listViewStyles.Items.Count > 0) { listViewStyles.Items[0].Selected = true; } }
private void ShowStyleAlignment() { var indices = GetIndices(); if (indices.Length == 0) { labelStyleAlignment.Text = string.Format(LanguageSettings.Current.AssaSetPosition.StyleAlignmentX, "{\\an2}"); return; } var p = _subtitleWithNewHeader.Paragraphs[indices[0]]; var style = AdvancedSubStationAlpha.GetSsaStyle(p.Extra, _subtitleWithNewHeader.Header); labelStyleAlignment.Text = string.Format(LanguageSettings.Current.AssaSetPosition.StyleAlignmentX, "{\\an" + style.Alignment + "} (" + p.Extra + ")"); }
private void LoadExistingProgressBarSettings() { //TODO: splitter height + width foreach (var p in _subtitle.Paragraphs) { if (p.Extra == "SE-progress-bar-text") { var newParagraph = new Paragraph(p) { Text = Utilities.RemoveSsaTags(p.Text) }; if (double.TryParse(p.Actor, NumberStyles.None, CultureInfo.InvariantCulture, out var number)) { newParagraph.StartTime.TotalMilliseconds = number; } _chapters.Paragraphs.Add(newParagraph); } } foreach (var style in AdvancedSubStationAlpha.GetSsaStylesFromHeader(_subtitle.Header)) { if (style.Name == "SE-progress-bar-text") { comboBoxFontName.Text = style.FontName; numericUpDownFontSize.Value = (decimal)style.FontSize; panelTextColor.BackColor = style.Primary; } else if (style.Name == "SE-progress-bar-bg") { panelPrimaryColor.BackColor = style.Primary; panelSecondaryColor.BackColor = style.Secondary; if (style.Alignment != "7") { radioButtonPosBottom.Checked = true; } else { radioButtonPosTop.Checked = true; } } } RefreshListView(); }
private void VideoLoaded(object sender, EventArgs e) { var format = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); var indices = GetIndices(); var styleToApply = $"{{\\pos({_x},{_y})}}"; var p = indices.Length > 0 ? new Paragraph(_subtitleWithNewHeader.Paragraphs[indices[0]]) : new Paragraph(Configuration.Settings.General.PreviewAssaText, 0, 1000); RemoveOldPosTags(p); // remove fade tags p.Text = Regex.Replace(p.Text, @"{\\fad\([\d\.,]*\)}", string.Empty); p.Text = Regex.Replace(p.Text, @"\\fad\([\d\.,]*\)", string.Empty); p.Text = Regex.Replace(p.Text, @"{\\fade\([\d\.,]*\)}", string.Empty); p.Text = Regex.Replace(p.Text, @"\\fade\([\d\.,]*\)", string.Empty); if (panelAdvanced.Visible) { RemoveAdvancedTags(p); styleToApply = AddAdvancedTags(styleToApply); } p.Text = styleToApply + p.Text; subtitle.Paragraphs.Add(p); subtitle.Header = _subtitleWithNewHeader.Header ?? AdvancedSubStationAlpha.DefaultHeader; var text = subtitle.ToText(format); _mpvTextFileName = FileUtil.GetTempFileName(format.Extension); File.WriteAllText(_mpvTextFileName, text); _mpv.LoadSubtitle(_mpvTextFileName); if (!_videoLoaded) { Application.DoEvents(); _mpv.Pause(); _mpv.CurrentPosition = p.StartTime.TotalSeconds + 0.05; Application.DoEvents(); _videoLoaded = true; timer1.Start(); } }
private void ResetHeader() { SubtitleFormat format; if (_isSubStationAlpha) { format = new SubStationAlpha(); } else { format = new AdvancedSubStationAlpha(); } var sub = new Subtitle(); string text = format.ToText(sub, string.Empty); var lines = text.SplitToLines(); format.LoadSubtitle(sub, lines, string.Empty); _header = sub.Header; }
private string GetDefaultHeader() { SubtitleFormat format; if (_isSubStationAlpha) { format = new SubStationAlpha(); } else { format = new AdvancedSubStationAlpha(); } var sub = new Subtitle(); string text = format.ToText(sub, string.Empty); var lines = text.SplitToLines(); format.LoadSubtitle(sub, lines, string.Empty); return(sub.Header.Trim()); }
private void SetPosition_Shown(object sender, EventArgs e) { ShowStyleAlignment(); ShowCurrentPosition(); var playResX = AdvancedSubStationAlpha.GetTagFromHeader("PlayResX", "[Script Info]", _subtitleWithNewHeader.Header); var playResY = AdvancedSubStationAlpha.GetTagFromHeader("PlayResY", "[Script Info]", _subtitleWithNewHeader.Header); if (string.IsNullOrEmpty(playResX) || string.IsNullOrEmpty(playResY)) { var dialogResult = MessageBox.Show(LanguageSettings.Current.AssaSetPosition.ResolutionMissing, "Subtitle Edit", MessageBoxButtons.YesNoCancel); if (dialogResult == DialogResult.OK || dialogResult == DialogResult.Yes) { _subtitleWithNewHeader.Header = AdvancedSubStationAlpha.AddTagToHeader("PlayResX", "PlayResX: " + _videoInfo.Width.ToString(CultureInfo.InvariantCulture), "[Script Info]", _subtitleWithNewHeader.Header); _subtitleWithNewHeader.Header = AdvancedSubStationAlpha.AddTagToHeader("PlayResY", "PlayResY: " + _videoInfo.Height.ToString(CultureInfo.InvariantCulture), "[Script Info]", _subtitleWithNewHeader.Header); } } GeneratePreviewViaMpv(); _loading = false; }
public static string SubStationAlphaHeaderToTimedText(Subtitle subtitle) { var x = new XmlDocument(); x.LoadXml(new TimedText10().ToText(new Subtitle(), "tt")); // load default xml var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); var styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); styleHead.SelectSingleNode("ttml:styling", xnsmgr).RemoveAll(); foreach (string styleName in AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header)) { try { var ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, subtitle.Header); if (ssaStyle != null) { string fontStyle = "normal"; if (ssaStyle.Italic) { fontStyle = "italic"; } string fontWeight = "normal"; if (ssaStyle.Bold) { fontWeight = "bold"; } AddStyleToXml(x, styleHead, xnsmgr, ssaStyle.Name, ssaStyle.FontName, fontWeight, fontStyle, Utilities.ColorToHex(ssaStyle.Primary), ssaStyle.FontSize.ToString(CultureInfo.InvariantCulture)); } } catch { // ignored } } return(x.OuterXml); }
private void VideoLoaded(object sender, EventArgs e) { var format = new AdvancedSubStationAlpha(); var subtitle = new Subtitle(); var indices = GetIndices(subtitle); var styleToApply = seTextBox1.Text; if (indices.Length > 0) { var p = new Paragraph(_subtitle.Paragraphs[indices[0]]) { StartTime = { TotalMilliseconds = 0 }, EndTime = { TotalMilliseconds = 2000 } }; p.Text = styleToApply + p.Text; subtitle.Paragraphs.Add(p); } else { var p = new Paragraph(Configuration.Settings.General.PreviewAssaText, 0, 1000); p.Text = styleToApply + p.Text; subtitle.Paragraphs.Add(p); } subtitle.Header = _subtitle.Header ?? AdvancedSubStationAlpha.DefaultHeader; var text = subtitle.ToText(format); _mpvTextFileName = FileUtil.GetTempFileName(format.Extension); File.WriteAllText(_mpvTextFileName, text); _mpv.LoadSubtitle(_mpvTextFileName); _mpv.Play(); if (!_videoLoaded) { timer1.Start(); _videoLoaded = true; } }
public SubStationAlphaStylesExport(string header, bool isSubStationAlpha, SubtitleFormat format) { InitializeComponent(); _header = header; _isSubStationAlpha = isSubStationAlpha; _format = format; _styles = AdvancedSubStationAlpha.GetStylesFromHeader(_header); listViewExportStyles.Columns[0].Width = listViewExportStyles.Width - 20; foreach (var style in _styles) { listViewExportStyles.Items.Add(new ListViewItem(style) { Checked = true }); } Text = Configuration.Settings.Language.SubStationAlphaStyles.Export; labelStyles.Text = Configuration.Settings.Language.SubStationAlphaStyles.Styles; buttonOK.Text = Configuration.Settings.Language.General.Ok; buttonCancel.Text = Configuration.Settings.Language.General.Cancel; }
private void FillStyles() { listViewStyles.Columns[listViewStyles.Columns.Count - 1].Width = -2; var styles = new List <string>(); var formatType = _format.GetType(); if (formatType == typeof(AdvancedSubStationAlpha) || formatType == typeof(SubStationAlpha)) { styles = AdvancedSubStationAlpha.GetStylesFromHeader(_subtitle.Header); } else if (formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText)) { styles = TimedText10.GetStylesFromHeader(_subtitle.Header); } else if (formatType == typeof(Sami) || formatType == typeof(SamiModern)) { styles = _subtitle.Header == null?Sami.GetStylesFromSubtitle(_subtitle) : Sami.GetStylesFromHeader(_subtitle.Header); } foreach (var style in styles) { listViewStyles.Items.Add(style); } }
public override string ToText(Subtitle subtitle, string title) { bool convertedFromSubStationAlpha = false; if (subtitle.Header != null) { XmlNode styleHead = null; try { var x = new XmlDocument(); x.LoadXml(subtitle.Header); var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); if (x.DocumentElement != null) { styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); } } catch { styleHead = null; } if (styleHead == null && (subtitle.Header.Contains("[V4+ Styles]") || subtitle.Header.Contains("[V4 Styles]"))) { var x = new XmlDocument(); x.LoadXml(new ItunesTimedText().ToText(new Subtitle(), "tt")); // load default xml var xnsmgr = new XmlNamespaceManager(x.NameTable); xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); if (x.DocumentElement != null) { styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr); styleHead.SelectSingleNode("ttml:styling", xnsmgr).RemoveAll(); foreach (string styleName in AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header)) { try { var ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, subtitle.Header); string fontStyle = "normal"; if (ssaStyle.Italic) { fontStyle = "italic"; } string fontWeight = "normal"; if (ssaStyle.Bold) { fontWeight = "bold"; } AddStyleToXml(x, styleHead, xnsmgr, ssaStyle.Name, ssaStyle.FontName, fontWeight, fontStyle, Utilities.ColorToHex(ssaStyle.Primary), ssaStyle.FontSize.ToString()); convertedFromSubStationAlpha = true; } catch { // ignored } } } subtitle.Header = x.OuterXml; // save new xml with styles in header } } var xml = new XmlDocument { XmlResolver = null }; var nsmgr = new XmlNamespaceManager(xml.NameTable); nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml"); nsmgr.AddNamespace("ttp", "http://www.w3.org/ns/10/ttml#parameter"); nsmgr.AddNamespace("tts", "http://www.w3.org/ns/10/ttml#style"); nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata"); nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata"); nsmgr.AddNamespace("smpte", "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt"); nsmgr.AddNamespace("m608", "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608"); const string xmlStructure = @"<?xml version='1.0' encoding='utf-8'?> <tt xml:lang='[LANG]' xmlns='http://www.w3.org/ns/ttml' xmlns:tts='http://www.w3.org/ns/ttml#styling' xmlns:ttm='http://www.w3.org/ns/ttml#metadata' xmlns:ttp='http://www.w3.org/ns/ttml#parameter' ttp:timeBase='media' ttp:frameRate='24' ttp:frameRateMultiplier='1000 1001' xmlns:smpte='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt' xmlns:m608='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608'> <head> <metadata> <ttm:title>SMPTE-TT 2052 subtitle</ttm:title> <ttm:desc>SMPTE Timed Text document created by Subtitle Edit</ttm:desc> <smpte:information xmlns:m608='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608' origin='http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt#cea608' mode='Preserved' m608:channel='CC1' m608:programName='Demo' m608:captionService='F1C1CC'/> </metadata> <styling> <style xml:id='basic' tts:color='white' tts:fontFamily='Arial' tts:backgroundColor='transparent' tts:fontSize='21' tts:fontWeight='normal' tts:fontStyle='normal' /> </styling> <layout> <region xml:id='bottom' tts:backgroundColor='transparent' tts:showBackground='whenActive' tts:origin='80% 80%' tts:extent='80% 80%' tts:displayAlign='after' /> </layout> </head> <body> <div></div> </body> </tt>"; var languageCode = LanguageAutoDetect.AutoDetectGoogleLanguage(subtitle); xml.LoadXml(xmlStructure.Replace("[LANG]", languageCode)); if (!string.IsNullOrWhiteSpace(title)) { var headNode = xml.DocumentElement.SelectSingleNode("//ttml:head", nsmgr); var metadataNode = headNode?.SelectSingleNode("ttml:metadata", nsmgr); var titleNode = metadataNode?.FirstChild; if (titleNode != null) { titleNode.InnerText = title; } } var div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).SelectSingleNode("ttml:div", nsmgr); bool hasBottomCenterRegion = false; bool hasTopCenterRegion = false; foreach (XmlNode node in xml.DocumentElement.SelectNodes("//ttml:head/ttml:layout/ttml:region", nsmgr)) { string id = null; if (node.Attributes["xml:id"] != null) { id = node.Attributes["xml:id"].Value; } else if (node.Attributes["id"] != null) { id = node.Attributes["id"].Value; } if (id != null && id == "bottom") { hasBottomCenterRegion = true; } if (id != null && id == "topCenter") { hasTopCenterRegion = true; } } foreach (var p in subtitle.Paragraphs) { XmlNode paragraph = xml.CreateElement("p", "http://www.w3.org/ns/ttml"); string text = p.Text; XmlAttribute start = xml.CreateAttribute("begin"); start.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00}:{3:00}", p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, MillisecondsToFramesMaxFrameRate(p.StartTime.Milliseconds)); paragraph.Attributes.Append(start); XmlAttribute end = xml.CreateAttribute("end"); end.InnerText = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}:{2:00}:{3:00}", p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, MillisecondsToFramesMaxFrameRate(p.EndTime.Milliseconds)); paragraph.Attributes.Append(end); XmlAttribute style = xml.CreateAttribute("style"); style.InnerText = "basic"; paragraph.Attributes.Append(style); XmlAttribute regionP = xml.CreateAttribute("region"); if (text.StartsWith("{\\an7}", StringComparison.Ordinal) || text.StartsWith("{\\an8}", StringComparison.Ordinal) || text.StartsWith("{\\an9}", StringComparison.Ordinal)) { if (hasTopCenterRegion) { regionP.InnerText = "top"; paragraph.Attributes.Append(regionP); } } else if (hasBottomCenterRegion) { regionP.InnerText = "bottom"; paragraph.Attributes.Append(regionP); } if (text.StartsWith("{\\an", StringComparison.Ordinal) && text.Length > 6 && text[5] == '}') { text = text.Remove(0, 6); } XmlAttribute styleAttribute = xml.CreateAttribute("style"); styleAttribute.InnerText = "basic"; paragraph.Attributes.Append(styleAttribute); if (convertedFromSubStationAlpha) { if (string.IsNullOrEmpty(p.Style)) { p.Style = p.Extra; } } bool first = true; bool italicOn = false; foreach (string line in text.SplitToLines()) { if (!first) { XmlNode br = xml.CreateElement("br", "http://www.w3.org/ns/ttml"); paragraph.AppendChild(br); } var styles = new Stack <XmlNode>(); XmlNode currentStyle = xml.CreateTextNode(string.Empty); paragraph.AppendChild(currentStyle); int skipCount = 0; for (int i = 0; i < line.Length; i++) { if (skipCount > 0) { skipCount--; } else if (line.Substring(i).StartsWith("<i>", StringComparison.Ordinal)) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); skipCount = 2; italicOn = true; } else if (line.Substring(i).StartsWith("<b>", StringComparison.Ordinal)) { currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontWeight", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "bold"; currentStyle.Attributes.Append(attr); skipCount = 2; } else if (line.Substring(i).StartsWith("<font ", StringComparison.Ordinal)) { int endIndex = line.Substring(i + 1).IndexOf('>'); if (endIndex > 0) { skipCount = endIndex + 1; string fontContent = line.Substring(i, skipCount); if (fontContent.Contains(" color=")) { var arr = fontContent.Substring(fontContent.IndexOf(" color=", StringComparison.Ordinal) + 7).Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (arr.Length > 0) { string fontColor = arr[0].Trim('\'').Trim('"').Trim('\''); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:color", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = fontColor; currentStyle.Attributes.Append(attr); } } } else { skipCount = line.Length; } } else if (line.Substring(i).StartsWith("</i>", StringComparison.Ordinal) || line.Substring(i).StartsWith("</b>", StringComparison.Ordinal) || line.Substring(i).StartsWith("</font>", StringComparison.Ordinal)) { currentStyle = xml.CreateTextNode(string.Empty); if (styles.Count > 0) { currentStyle = styles.Pop().CloneNode(true); currentStyle.InnerText = string.Empty; } paragraph.AppendChild(currentStyle); if (line.Substring(i).StartsWith("</font>", StringComparison.Ordinal)) { skipCount = 6; } else { skipCount = 3; } italicOn = false; } else { if (i == 0 && italicOn && !(line.Substring(i).StartsWith("<i>", StringComparison.Ordinal))) { styles.Push(currentStyle); currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null); paragraph.AppendChild(currentStyle); XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style"); attr.InnerText = "italic"; currentStyle.Attributes.Append(attr); } currentStyle.InnerText = currentStyle.InnerText + line[i]; } } first = false; } div.AppendChild(paragraph); } string xmlString = ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty).Replace(" xmlns:tts=\"http://www.w3.org/ns/10/ttml#style\">", ">").Replace("<br />", "<br/>"); if (subtitle.Header == null) { subtitle.Header = xmlString; } return(xmlString); }
public string ToRawAss(string styleFormat = DefaultAssStyleFormat) { var sb = new StringBuilder(); sb.Append("Style: "); var format = styleFormat.ToLowerInvariant().Substring(8).Split(','); for (int i = 0; i < format.Length; i++) { string f = format[i].Trim(); if (f == "name") { sb.Append(Name); } else if (f == "fontname") { sb.Append(FontName); } else if (f == "fontsize") { sb.Append(FontSize.ToString(CultureInfo.InvariantCulture)); } else if (f == "primarycolour") { sb.Append(AdvancedSubStationAlpha.GetSsaColorString(Primary)); } else if (f == "secondarycolour") { sb.Append(AdvancedSubStationAlpha.GetSsaColorString(Secondary)); } else if (f == "outlinecolour") { sb.Append(AdvancedSubStationAlpha.GetSsaColorString(Outline)); } else if (f == "backcolour") { sb.Append(AdvancedSubStationAlpha.GetSsaColorString(Background)); } else if (f == "bold") { sb.Append(BoolToRawSsa(Bold)); } else if (f == "italic") { sb.Append(BoolToRawSsa(Italic)); } else if (f == "underline") { sb.Append(BoolToRawSsa(Underline)); } else if (f == "strikeout") { sb.Append(BoolToRawSsa(Strikeout)); } else if (f == "outline") { sb.Append(OutlineWidth.ToString(CultureInfo.InvariantCulture)); } else if (f == "shadow") { sb.Append(ShadowWidth.ToString(CultureInfo.InvariantCulture)); } else if (f == "alignment") { sb.Append(Alignment); } else if (f == "marginl") { sb.Append(MarginLeft); } else if (f == "marginr") { sb.Append(MarginRight); } else if (f == "marginv") { sb.Append(MarginVertical); } else if (f == "borderstyle") { sb.Append(BorderStyle); } else if (f == "encoding") { sb.Append('1'); } else if (f == "strikeout") { sb.Append('0'); } else if (f == "scalex") { sb.Append(ScaleX.ToString(CultureInfo.InvariantCulture)); } else if (f == "scaley") { sb.Append(ScaleY.ToString(CultureInfo.InvariantCulture)); } else if (f == "spacing") { sb.Append(Spacing.ToString(CultureInfo.InvariantCulture)); } else if (f == "angle") { sb.Append(Angle.ToString(CultureInfo.InvariantCulture)); } sb.Append(','); } var s = sb.ToString().Trim(); return(s.Substring(0, s.Length - 1)); }
private void buttonOK_Click(object sender, EventArgs e) { ExportedStyles = new List <string>(); foreach (ListViewItem item in listViewExportStyles.Items) { if (item.Checked) { ExportedStyles.Add(item.Text); } } if (ExportedStyles.Count == 0) { return; } saveFileDialogStyle.Title = LanguageSettings.Current.SubStationAlphaStyles.ExportStyleToFile; saveFileDialogStyle.InitialDirectory = Configuration.DataDirectory; if (_isSubStationAlpha) { saveFileDialogStyle.Filter = SubStationAlpha.NameOfFormat + "|*.ssa|" + LanguageSettings.Current.General.AllFiles + "|*.*"; saveFileDialogStyle.FileName = "my_styles.ssa"; } else { saveFileDialogStyle.Filter = AdvancedSubStationAlpha.NameOfFormat + "|*.ass|" + LanguageSettings.Current.General.AllFiles + "|*.*"; saveFileDialogStyle.FileName = "my_styles.ass"; } if (saveFileDialogStyle.ShowDialog(this) == DialogResult.OK) { if (File.Exists(saveFileDialogStyle.FileName)) { var s = new Subtitle(); var format = s.LoadSubtitle(saveFileDialogStyle.FileName, out _, null); if (format == null) { MessageBox.Show("Not subtitle format: " + _format.Name); return; } if (format.Name != _format.Name) { MessageBox.Show(string.Format("Cannot save {1} style in {0} file!", format.Name, _format.Name)); } else { var sb = new StringBuilder(); bool stylesOn = false; bool done = false; string styleFormat = SsaStyle.DefaultAssStyleFormat; foreach (string line in File.ReadAllLines(saveFileDialogStyle.FileName)) { if (line.StartsWith("format:", StringComparison.OrdinalIgnoreCase)) { styleFormat = line; } else if (line.StartsWith("style:", StringComparison.OrdinalIgnoreCase)) { stylesOn = true; } else if (stylesOn && !done) { done = true; foreach (var styleName in ExportedStyles) { SsaStyle style = AdvancedSubStationAlpha.GetSsaStyle(styleName, _header); if (_isSubStationAlpha) { sb.AppendLine(style.ToRawSsa(styleFormat)); } else { sb.AppendLine(style.ToRawAss(styleFormat)); } } } sb.AppendLine(line); foreach (var styleName in ExportedStyles) { var toLower = line.Trim().ToLowerInvariant(); while (toLower.Contains(": ")) { toLower = toLower.Replace(": ", ":"); } while (toLower.Contains(" :")) { toLower = toLower.Replace(" :", ":"); } if (stylesOn && toLower.StartsWith("style:" + styleName.Trim() + ",", StringComparison.OrdinalIgnoreCase)) { MessageBox.Show(string.Format(LanguageSettings.Current.SubStationAlphaStyles.StyleAlreadyExits, styleName)); return; } } } File.WriteAllText(saveFileDialogStyle.FileName, sb.ToString(), Encoding.UTF8); } } else { var sb = new StringBuilder(); foreach (var line in _header.Replace(Environment.NewLine, "\n").Split('\n')) { if (line.StartsWith("style:", StringComparison.OrdinalIgnoreCase)) { foreach (var styleName in ExportedStyles) { var toLower = line.Trim().ToLowerInvariant(); while (toLower.Contains(": ")) { toLower = toLower.Replace(": ", ":"); } while (toLower.Contains(" :")) { toLower = toLower.Replace(" :", ":"); } if (toLower.StartsWith("style:" + styleName.ToLowerInvariant().Trim(), StringComparison.Ordinal)) { sb.AppendLine(line); } } } else { sb.AppendLine(line); } } string content = sb.ToString(); if (content.TrimEnd().EndsWith("[Events]", StringComparison.Ordinal)) { content = content.Trim() + Environment.NewLine + "Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text" + Environment.NewLine + "Dialogue: 0,0:00:31.91,0:00:33.91,Default,,0,0,0,,My Styles :)"; } else if (!content.Contains("[Events]", StringComparison.OrdinalIgnoreCase)) { content = content.Trim() + Environment.NewLine + Environment.NewLine + "[Events]" + Environment.NewLine + "Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text" + Environment.NewLine + "Dialogue: 0,0:00:31.91,0:00:33.91,Default,,0,0,0,,My Styles :)"; } File.WriteAllText(saveFileDialogStyle.FileName, content, Encoding.UTF8); DialogResult = DialogResult.OK; } } }
private SsaStyle GetSsaStyle(string styleName) { return(AdvancedSubStationAlpha.GetSsaStyle(styleName, _header)); }
public override string ToText(Subtitle subtitle, string title) { const string header = @"[Script Info] ; This is a Sub Station Alpha v4 script. Title: {0} ScriptType: v4.00 Collisions: Normal PlayDepth: 0 [V4 Styles] Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding Style: Default,{1},{2},{3},65535,65535,-2147483640,-1,0,1,{4},{5},2,10,10,10,0,1 [Events] Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text"; const string headerNoStyles = @"[Script Info] ; This is a Sub Station Alpha v4 script. Title: {0} ScriptType: v4.00 Collisions: Normal PlayDepth: 0 [V4 Styles] Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding {1} [Events] Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text"; const string timeCodeFormat = "{0}:{1:00}:{2:00}.{3:00}"; // h:mm:ss.cc const string paragraphWriteFormat = "Dialogue: Marked={4},{0},{1},{3},{5},0000,0000,0000,{6},{2}"; const string commentWriteFormat = "Comment: Marked={4},{0},{1},{3},{5},0000,0000,0000,{6},{2}"; var sb = new StringBuilder(); Color fontColor = Color.White; bool isValidAssHeader = !string.IsNullOrEmpty(subtitle.Header) && subtitle.Header.Contains("[V4 Styles]"); var styles = new List <string>(); if (isValidAssHeader) { sb.AppendLine(subtitle.Header.Trim()); const string formatLine = "Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text"; if (!subtitle.Header.Contains(formatLine)) { sb.AppendLine(formatLine); } styles = AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header); } else if (!string.IsNullOrEmpty(subtitle.Header) && subtitle.Header.Contains("[V4+ Styles]")) { LoadStylesFromAdvancedSubstationAlpha(subtitle, title, subtitle.Header, headerNoStyles, sb); } else { sb.AppendLine(string.Format(header, title, "Arial", 20, ColorTranslator.ToWin32(fontColor), 2, 1 )); } foreach (Paragraph p in subtitle.Paragraphs) { string start = string.Format(timeCodeFormat, p.StartTime.Hours, p.StartTime.Minutes, p.StartTime.Seconds, p.StartTime.Milliseconds / 10); string end = string.Format(timeCodeFormat, p.EndTime.Hours, p.EndTime.Minutes, p.EndTime.Seconds, p.EndTime.Milliseconds / 10); string style = "Default"; string actor = "NTP"; if (!string.IsNullOrEmpty(p.Actor)) { actor = p.Actor; } string effect = ""; if (!string.IsNullOrEmpty(p.Effect)) { effect = p.Effect; } if (!string.IsNullOrEmpty(p.Extra) && isValidAssHeader && styles.Contains(p.Extra)) { style = p.Extra; } if (style == "Default") { style = "*Default"; } if (p.IsComment) { sb.AppendLine(string.Format(commentWriteFormat, start, end, AdvancedSubStationAlpha.FormatText(p), style, p.Layer, actor, effect)); } else { sb.AppendLine(string.Format(paragraphWriteFormat, start, end, AdvancedSubStationAlpha.FormatText(p), style, p.Layer, actor, effect)); } } return(sb.ToString().Trim()); }
public override void LoadSubtitle(Subtitle subtitle, List <string> lines, string fileName) { _errorCount = 0; Errors = null; bool eventsStarted = false; subtitle.Paragraphs.Clear(); string[] format = { "Marked", " Start", " End", " Style", " Name", " MarginL", " MarginR", " MarginV", " Effect", " Text" }; int indexLayer = 0; int indexStart = 1; int indexEnd = 2; int indexStyle = 3; const int indexName = 4; int indexEffect = 8; int indexText = 9; var errors = new StringBuilder(); int lineNumber = 0; var header = new StringBuilder(); foreach (string line in lines) { lineNumber++; if (!eventsStarted) { header.AppendLine(line); } if (line.Trim().Equals("[events]", StringComparison.OrdinalIgnoreCase)) { eventsStarted = true; } else if (!string.IsNullOrEmpty(line) && line.TrimStart().StartsWith(';')) { // skip comment lines } else if (eventsStarted && !string.IsNullOrWhiteSpace(line)) { string s = line.Trim().ToLower(); if (s.StartsWith("format:", StringComparison.Ordinal)) { if (line.Length > 10) { format = line.ToLower().Substring(8).Split(','); for (int i = 0; i < format.Length; i++) { if (format[i].Trim().Equals("layer", StringComparison.OrdinalIgnoreCase)) { indexLayer = i; } else if (format[i].Trim().Equals("start", StringComparison.OrdinalIgnoreCase)) { indexStart = i; } else if (format[i].Trim().Equals("end", StringComparison.OrdinalIgnoreCase)) { indexEnd = i; } else if (format[i].Trim().Equals("text", StringComparison.OrdinalIgnoreCase)) { indexText = i; } else if (format[i].Trim().Equals("effect", StringComparison.OrdinalIgnoreCase)) { indexEffect = i; } else if (format[i].Trim().Equals("style", StringComparison.OrdinalIgnoreCase)) { indexStyle = i; } } } } else if (!string.IsNullOrEmpty(s)) { string text = string.Empty; string start = string.Empty; string end = string.Empty; string style = string.Empty; var layer = 0; string effect = string.Empty; string name = string.Empty; string[] splittedLine; if (s.StartsWith("dialog:", StringComparison.Ordinal)) { splittedLine = line.Remove(0, 7).Split(','); } else if (s.StartsWith("dialogue:", StringComparison.Ordinal)) { splittedLine = line.Remove(0, 9).Split(','); } else { splittedLine = line.Split(','); } for (int i = 0; i < splittedLine.Length; i++) { if (i == indexStart) { start = splittedLine[i].Trim(); } else if (i == indexEnd) { end = splittedLine[i].Trim(); } else if (i == indexLayer) { int.TryParse(splittedLine[i], out layer); } else if (i == indexEffect) { effect = splittedLine[i]; } else if (i == indexText) { text = splittedLine[i]; } else if (i == indexStyle) { style = splittedLine[i]; } else if (i == indexName) { name = splittedLine[i]; } else if (i > indexText) { text += "," + splittedLine[i]; } } try { var p = new Paragraph { StartTime = GetTimeCodeFromString(start), EndTime = GetTimeCodeFromString(end), Text = AdvancedSubStationAlpha.GetFormattedText(text) }; if (!string.IsNullOrEmpty(style)) { p.Extra = style; } if (!string.IsNullOrEmpty(effect)) { p.Effect = effect; } p.Layer = layer; if (!string.IsNullOrEmpty(name)) { p.Actor = name; } p.IsComment = s.StartsWith("comment:", StringComparison.Ordinal); subtitle.Paragraphs.Add(p); } catch { _errorCount++; } } } } if (header.Length > 0) { subtitle.Header = header.ToString(); } subtitle.Renumber(1); Errors = errors.ToString(); }
private static void LoadStylesFromAdvancedSubstationAlpha(Subtitle subtitle, string title, string header, string headerNoStyles, StringBuilder sb) { try { bool styleFound = false; var ttStyles = new StringBuilder(); foreach (string styleName in AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header)) { try { var ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, subtitle.Header); if (ssaStyle != null) { string bold = "-1"; if (ssaStyle.Bold) { bold = "1"; } string italic = "0"; if (ssaStyle.Italic) { italic = "1"; } string newAlignment = "2"; switch (ssaStyle.Alignment) { case "1": newAlignment = "1"; break; case "3": newAlignment = "3"; break; case "4": newAlignment = "9"; break; case "5": newAlignment = "10"; break; case "6": newAlignment = "11"; break; case "7": newAlignment = "5"; break; case "8": newAlignment = "6"; break; case "9": newAlignment = "7"; break; } //Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding const string styleFormat = "Style: {0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},0,1"; // N FN FS PC SC TC BC Bo It BS O Sh Ali ML MR MV A Encoding ttStyles.AppendLine(string.Format(styleFormat, ssaStyle.Name, ssaStyle.FontName, ssaStyle.FontSize, ssaStyle.Primary.ToArgb(), ssaStyle.Secondary.ToArgb(), ssaStyle.Outline.ToArgb(), ssaStyle.Background.ToArgb(), bold, italic, ssaStyle.BorderStyle, ssaStyle.OutlineWidth, ssaStyle.ShadowWidth, newAlignment, ssaStyle.MarginLeft, ssaStyle.MarginRight, ssaStyle.MarginVertical)); styleFound = true; } } catch { } } if (styleFound) { sb.AppendLine(string.Format(headerNoStyles, title, ttStyles)); subtitle.Header = sb.ToString(); } else { sb.AppendLine(string.Format(header, title)); } } catch { sb.AppendLine(string.Format(header, title)); } }
internal static SubtitleFormat LoadMatroskaTextSubtitle(MatroskaTrackInfo matroskaSubtitleInfo, MatroskaFile matroska, List<MatroskaSubtitle> sub, Subtitle subtitle) { if (subtitle == null) { throw new ArgumentNullException("subtitle"); } subtitle.Paragraphs.Clear(); var isSsa = false; SubtitleFormat format = new SubRip(); if (matroskaSubtitleInfo.CodecPrivate.Contains("[script info]", StringComparison.OrdinalIgnoreCase)) { if (matroskaSubtitleInfo.CodecPrivate.Contains("[V4 Styles]", StringComparison.OrdinalIgnoreCase)) { format = new SubStationAlpha(); } else { format = new AdvancedSubStationAlpha(); } isSsa = true; } if (isSsa) { foreach (var p in LoadMatroskaSSA(matroskaSubtitleInfo, matroska.Path, format, sub).Paragraphs) { subtitle.Paragraphs.Add(p); } if (!string.IsNullOrEmpty(matroskaSubtitleInfo.CodecPrivate)) { bool eventsStarted = false; bool fontsStarted = false; bool graphicsStarted = false; var header = new StringBuilder(); foreach (string line in matroskaSubtitleInfo.CodecPrivate.Replace(Environment.NewLine, "\n").Split('\n')) { if (!eventsStarted && !fontsStarted && !graphicsStarted) { header.AppendLine(line); } if (line.TrimStart().StartsWith("dialog:", StringComparison.OrdinalIgnoreCase)) { eventsStarted = true; fontsStarted = false; graphicsStarted = false; } else if (line.Trim().Equals("[events]", StringComparison.OrdinalIgnoreCase)) { eventsStarted = true; fontsStarted = false; graphicsStarted = false; } else if (line.Trim().Equals("[fonts]", StringComparison.OrdinalIgnoreCase)) { eventsStarted = false; fontsStarted = true; graphicsStarted = false; } else if (line.Trim().Equals("[graphics]", StringComparison.OrdinalIgnoreCase)) { eventsStarted = false; fontsStarted = false; graphicsStarted = true; } } subtitle.Header = header.ToString().TrimEnd(); if (!subtitle.Header.Contains("[events]", StringComparison.OrdinalIgnoreCase)) { subtitle.Header += Environment.NewLine + Environment.NewLine + "[Events]" + Environment.NewLine; } } } else { foreach (var p in sub) { subtitle.Paragraphs.Add(new Paragraph(p.Text, p.Start, p.End)); } } subtitle.Renumber(); return format; }
private void ButtonRemoveAll_Click(object sender, EventArgs e) { this.listViewStyles.Items.Clear(); var sub = new Subtitle(); if (this.isSubStationAlpha) { var ssa = new SubStationAlpha(); string text = ssa.ToText(sub, string.Empty); string[] lineArray = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); var lines = new List<string>(); foreach (string line in lineArray) { lines.Add(line); } ssa.LoadSubtitle(sub, lines, string.Empty); this.header = this.header.Remove(this.header.IndexOf("[V4 Styles]", StringComparison.Ordinal)) + sub.Header.Substring(sub.Header.IndexOf("[V4 Styles]", StringComparison.Ordinal)); } else { var ass = new AdvancedSubStationAlpha(); string text = ass.ToText(sub, string.Empty); string[] lineArray = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); var lines = new List<string>(); foreach (string line in lineArray) { lines.Add(line); } ass.LoadSubtitle(sub, lines, string.Empty); this.header = this.header.Remove(this.header.IndexOf("[V4+ Styles]", StringComparison.Ordinal)) + sub.Header.Substring(sub.Header.IndexOf("[V4+ Styles]", StringComparison.Ordinal)); } this.InitializeListView(); }