Add format "Timed Text IMSC 1.1"

This commit is contained in:
Nikolaj Olsson 2024-03-14 12:55:46 +01:00
parent 471d278fea
commit 723160beb3
7 changed files with 571 additions and 12 deletions

View File

@ -42,6 +42,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Stbl/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tahoma/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tesseract/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ttml/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Ukranian/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unbreak/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Undocked/@EntryIndexedValue">True</s:Boolean>

View File

@ -8,7 +8,7 @@ using System.Xml;
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
{
/// <summary>
/// IMSC 1.1 Viewer: http://sandflow.com/imsc1_1/
/// IMSC 1.1 Viewer: https://www.sandflow.com/imsc1_1/
/// More about bouten/furigana: https://www.japanesewithanime.com/2018/03/furigana-dots-bouten.html
/// Netflix blog entry: https://medium.com/netflix-techblog/implementing-japanese-subtitles-on-netflix-c165fbe61989
/// </summary>

View File

@ -223,6 +223,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
new TimedText200604CData(),
new TimedText200604Ooyala(),
new TimedText(),
new TimedTextImsc11(),
new TitleExchangePro(),
new Titra(),
new TmpegEncText(),

View File

@ -31,7 +31,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
{
var sb = new StringBuilder();
lines.ForEach(line => sb.AppendLine(line));
string xmlAsString = sb.ToString().Trim();
var xmlAsString = sb.ToString().Trim();
if (xmlAsString.Contains("xmlns:tts=\"http://www.w3.org/2006/04"))
{
@ -41,6 +41,16 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
if (xmlAsString.Contains("http://www.w3.org/ns/ttml"))
{
xmlAsString = xmlAsString.RemoveControlCharactersButWhiteSpace();
if (xmlAsString.Contains("profile/imsc1"))
{
var f = new TimedTextImsc11();
if (f.IsMine(lines, fileName))
{
return false;
}
}
var xml = new XmlDocument { XmlResolver = null };
try
{
@ -79,6 +89,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
}
}
}
return false;
}

View File

@ -19,7 +19,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats
{
var sb = new StringBuilder();
lines.ForEach(line => sb.AppendLine(line));
string xmlAsString = sb.ToString().Replace("http://www.w3.org/2006/04/ttaf1#styling\"xml:lang", "http://www.w3.org/2006/04/ttaf1#styling\" xml:lang").Trim();
var xmlAsString = sb.ToString().Replace("http://www.w3.org/2006/04/ttaf1#styling\"xml:lang", "http://www.w3.org/2006/04/ttaf1#styling\" xml:lang").Trim();
if (xmlAsString.Contains("http://www.w3.org/2006/10"))
{

View File

@ -0,0 +1,546 @@
using Nikse.SubtitleEdit.Core.Common;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
namespace Nikse.SubtitleEdit.Core.SubtitleFormats
{
/// <summary>
/// IMSC 1.1 Viewer: https://www.sandflow.com/imsc1_1/
/// </summary>
public class TimedTextImsc11 : SubtitleFormat
{
public override string Extension => ".xml";
public override string Name => "Timed Text IMSC 1.1";
private static string GetXmlStructure()
{
return @"<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<tt xml:lang='en' xmlns='http://www.w3.org/ns/ttml' ttp:contentProfiles='http://www.w3.org/ns/ttml/profile/imsc1.1/text' 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' ttp:tickRate='10000000' xmlns:ebutts='urn:ebu:tt:style' xmlns:itts='http://www.w3.org/ns/ttml/profile/imsc1#styling' xmlns:ittp='http://www.w3.org/ns/ttml/profile/imsc1#parameter' xmlns:ittm='http://www.w3.org/ns/ttml/profile/imsc1#metadata' ittp:aspectRatio='16 9'>
<head>
<styling>
<style xml:id='style.center' tts:backgroundColor='transparent' tts:color='white' tts:fontFamily='Arial' tts:fontSize='100%' tts:textAlign='center' tts:textOutline='black 2px' />
<style xml:id='style.italic' tts:shear='16.6667%' tts:backgroundColor='transparent' tts:color='white' tts:fontFamily='Arial' tts:fontSize='100%' tts:textAlign='center' tts:textOutline='black 2px' />
</styling>
<layout>
<region xml:id='region.topLeft' tts:extent='80% 40%' tts:origin='10% 10%' tts:displayAlign='before' tts:textAlign='start' />
<region xml:id='region.centerLeft' tts:extent='80% 40%' tts:origin='10% 30%' tts:displayAlign='center' tts:textAlign='start' />
<region xml:id='region.bottomLeft' tts:extent='80% 40%' tts:origin='10% 50%' tts:displayAlign='after' tts:textAlign='start' />
<region xml:id='region.topCenter' tts:extent='80% 40%' tts:origin='10% 10%' tts:displayAlign='before' tts:textAlign='center' />
<region xml:id='region.centerCenter' tts:extent='80% 40%' tts:origin='10% 30%' tts:displayAlign='center' tts:textAlign='center' />
<region xml:id='region.bottomCenter' tts:extent='80% 40%' tts:origin='10% 50%' tts:displayAlign='after' tts:textAlign='center' />
<region xml:id='region.topRight' tts:extent='80% 40%' tts:origin='10% 10%' tts:displayAlign='before' tts:textAlign='end' />
<region xml:id='region.centerRight' tts:extent='80% 40%' tts:origin='10% 30%' tts:displayAlign='center' tts:textAlign='end' />
<region xml:id='region.bottomRight' tts:extent='80% 40%' tts:origin='10% 50%' tts:displayAlign='after' tts:textAlign='end' />
</layout>
</head>
<body>
<div>
</div>
</body>
</tt>
".Replace('\'', '"');
}
public override bool IsMine(List<string> lines, string fileName)
{
if (fileName != null && !(fileName.EndsWith(Extension, StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)))
{
return false;
}
var sb = new StringBuilder();
lines.ForEach(line => sb.AppendLine(line));
var text = sb.ToString();
if (text.Contains("lang=\"ja\"", StringComparison.Ordinal) && text.Contains("bouten-", StringComparison.Ordinal))
{
return false;
}
return text.Contains("profile/imsc1") && base.IsMine(lines, fileName);
}
public override string ToText(Subtitle subtitle, string title)
{
var xml = new XmlDocument { XmlResolver = null };
xml.LoadXml(GetXmlStructure());
var namespaceManager = new XmlNamespaceManager(xml.NameTable);
namespaceManager.AddNamespace("ttml", "http://www.w3.org/ns/ttml");
var div = xml.DocumentElement.SelectSingleNode("ttml:body", namespaceManager).SelectSingleNode("ttml:div", namespaceManager);
foreach (var p in subtitle.Paragraphs)
{
var paragraphNode = MakeParagraph(xml, p);
div.AppendChild(paragraphNode);
}
var xmlString = ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty);
subtitle.Header = xmlString;
return xmlString;
}
private static XmlNode MakeParagraph(XmlDocument xml, Paragraph p)
{
XmlNode paragraph = xml.CreateElement("p", "http://www.w3.org/ns/ttml");
string text = p.Text.RemoveControlCharactersButWhiteSpace();
XmlAttribute start = xml.CreateAttribute("begin");
start.InnerText = TimedText10.ConvertToTimeString(p.StartTime);
paragraph.Attributes.Append(start);
XmlAttribute dur = xml.CreateAttribute("dur");
dur.InnerText = TimedText10.ConvertToTimeString(p.Duration);
paragraph.Attributes.Append(dur);
XmlAttribute region = xml.CreateAttribute("region");
region.InnerText = GetRegionFromText(p.Text);
paragraph.Attributes.Append(region);
// Trying to parse and convert paragraph content
try
{
text = Utilities.RemoveSsaTags(text);
text = string.Join("<br/>", text.SplitToLines());
var paragraphContent = new XmlDocument();
paragraphContent.LoadXml($"<root>{text.Replace("&", "&amp;")}</root>");
ConvertParagraphNodeToTtmlNode(paragraphContent.DocumentElement, xml, paragraph);
}
catch // Wrong markup, clear it
{
text = Regex.Replace(text, "[<>]", "");
paragraph.AppendChild(xml.CreateTextNode(text));
}
return paragraph;
}
internal static void ConvertParagraphNodeToTtmlNode(XmlNode node, XmlDocument ttmlXml, XmlNode ttmlNode)
{
foreach (XmlNode child in node.ChildNodes)
{
if (child is XmlText)
{
ttmlNode.AppendChild(ttmlXml.CreateTextNode(child.Value));
}
else if (child.Name == "br")
{
XmlNode br = ttmlXml.CreateElement("br");
ttmlNode.AppendChild(br);
ConvertParagraphNodeToTtmlNode(child, ttmlXml, br);
}
else if (child.Name == "i")
{
XmlNode span = ttmlXml.CreateElement("span");
XmlAttribute attr = ttmlXml.CreateAttribute("style");
attr.InnerText = "italic";
span.Attributes.Append(attr);
ttmlNode.AppendChild(span);
ConvertParagraphNodeToTtmlNode(child, ttmlXml, span);
}
else // Default - skip node
{
ConvertParagraphNodeToTtmlNode(child, ttmlXml, ttmlNode);
}
}
}
private static string GetRegionFromText(string text)
{
if (text.StartsWith(@"{\an7", StringComparison.Ordinal))
{
return "region.topLeft";
}
if (text.StartsWith(@"{\an8", StringComparison.Ordinal))
{
return "region.topCenter";
}
if (text.StartsWith(@"{\an9", StringComparison.Ordinal))
{
return "region.topRight";
}
if (text.StartsWith(@"{\an4", StringComparison.Ordinal))
{
return "region.centerLeft";
}
if (text.StartsWith(@"{\an5", StringComparison.Ordinal))
{
return "region.centerCenter";
}
if (text.StartsWith(@"{\an6", StringComparison.Ordinal))
{
return "region.centerRight";
}
if (text.StartsWith(@"{\an1", StringComparison.Ordinal))
{
return "region.bottomLeft";
}
if (text.StartsWith(@"{\an3", StringComparison.Ordinal))
{
return "region.bottomRight";
}
return "region.bottomCenter";
}
private static string GetAssStyleFromRegion(string region)
{
switch (region)
{
case "region.topLeft": return @"{\an7}";
case "region.topCenter": return @"{\an8}";
case "region.topRight": return @"{\an9}";
case "region.centerLeft": return @"{\an4}";
case "region.centerCenter": return @"{\an5}";
case "region.centerRight": return @"{\an6}";
case "region.bottomLeft": return @"{\an1}";
case "region.bottomRight": return @"{\an3}";
default: return string.Empty;
}
}
private static List<string> GetStyles()
{
return TimedText10.GetStylesFromHeader(GetXmlStructure());
}
public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
{
_errorCount = 0;
var sb = new StringBuilder();
lines.ForEach(line => sb.AppendLine(line));
var xml = new XmlDocument { XmlResolver = null, PreserveWhitespace = true };
try
{
xml.LoadXml(sb.ToString().RemoveControlCharactersButWhiteSpace().Trim());
}
catch
{
xml.LoadXml(sb.ToString().Replace(" & ", " &amp; ").Replace("Q&A", "Q&amp;A").RemoveControlCharactersButWhiteSpace().Trim());
}
var frameRateAttr = xml.DocumentElement.Attributes["ttp:frameRate"];
if (frameRateAttr != null)
{
if (double.TryParse(frameRateAttr.Value, out var fr))
{
if (fr > 20 && fr < 100)
{
Configuration.Settings.General.CurrentFrameRate = fr;
}
var frameRateMultiplier = xml.DocumentElement.Attributes["ttp:frameRateMultiplier"];
if (frameRateMultiplier != null)
{
if (frameRateMultiplier.InnerText == "999 1000" && Math.Abs(fr - 30) < 0.01)
{
Configuration.Settings.General.CurrentFrameRate = 29.97;
}
else if (frameRateMultiplier.InnerText == "999 1000" && Math.Abs(fr - 24) < 0.01)
{
Configuration.Settings.General.CurrentFrameRate = 23.976;
}
else
{
var arr = frameRateMultiplier.InnerText.Split();
if (arr.Length == 2 && Utilities.IsInteger(arr[0]) && Utilities.IsInteger(arr[1]) && int.Parse(arr[1]) > 0)
{
fr = double.Parse(arr[0]) / double.Parse(arr[1]);
if (fr > 20 && fr < 100)
{
Configuration.Settings.General.CurrentFrameRate = fr;
}
}
}
}
}
}
if (BatchSourceFrameRate.HasValue)
{
Configuration.Settings.General.CurrentFrameRate = BatchSourceFrameRate.Value;
}
Configuration.Settings.SubtitleSettings.TimedText10TimeCodeFormatSource = null;
subtitle.Header = sb.ToString();
var namespaceManager = new XmlNamespaceManager(xml.NameTable);
namespaceManager.AddNamespace("ttml", "http://www.w3.org/ns/ttml");
var body = xml.DocumentElement.SelectSingleNode("ttml:body", namespaceManager);
foreach (XmlNode node in body.SelectNodes("//ttml:p", namespaceManager))
{
TimedText10.ExtractTimeCodes(node, subtitle, out var begin, out var end);
var assStyle = string.Empty;
var region = node.Attributes?["region"];
if (region != null)
{
assStyle = GetAssStyleFromRegion(region.InnerText);
}
var text = assStyle + ReadParagraph(node, xml);
var p = new Paragraph(begin, end, text);
subtitle.Paragraphs.Add(p);
}
subtitle.Renumber();
}
private static string ReadParagraph(XmlNode node, XmlDocument xml)
{
var pText = new StringBuilder();
var styles = GetStyles();
foreach (XmlNode child in node.ChildNodes)
{
if (child.NodeType == XmlNodeType.Text)
{
pText.Append(child.Value);
}
else if (child.Name == "br" || child.Name == "tt:br")
{
pText.AppendLine();
}
else if (child.Name == "#significant-whitespace" || child.Name == "tt:#significant-whitespace")
{
pText.Append(child.InnerText);
}
else if (child.Name == "span" || child.Name == "tt:span")
{
var isItalic = false;
var isBold = false;
var isUnderlined = false;
string fontFamily = null;
string color = null;
// Composing styles
if (child.Attributes["style"] != null)
{
var styleName = child.Attributes["style"].Value;
if (styles.Contains(styleName))
{
try
{
var nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml");
XmlNode head = xml.DocumentElement.SelectSingleNode("ttml:head", nsmgr);
foreach (XmlNode styleNode in head.SelectNodes("//ttml:style", nsmgr))
{
string currentStyle = null;
if (styleNode.Attributes["xml:id"] != null)
{
currentStyle = styleNode.Attributes["xml:id"].Value;
}
else if (styleNode.Attributes["id"] != null)
{
currentStyle = styleNode.Attributes["id"].Value;
}
if (currentStyle == styleName)
{
if (styleNode.Attributes["tts:fontStyle"] != null && styleNode.Attributes["tts:fontStyle"].Value == "italic")
{
isItalic = true;
}
if (styleNode.Attributes["tts:fontWeight"] != null && styleNode.Attributes["tts:fontWeight"].Value == "bold")
{
isBold = true;
}
if (styleNode.Attributes["tts:textDecoration"] != null && styleNode.Attributes["tts:textDecoration"].Value == "underline")
{
isUnderlined = true;
}
if (styleNode.Attributes["tts:fontFamily"] != null)
{
fontFamily = styleNode.Attributes["tts:fontFamily"].Value;
}
if (styleNode.Attributes["tts:color"] != null)
{
color = styleNode.Attributes["tts:color"].Value;
}
}
}
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e);
}
}
}
if (child.Attributes["tts:fontStyle"] != null && child.Attributes["tts:fontStyle"].Value == "italic")
{
isItalic = true;
}
else if (child.Attributes["style"] != null && child.Attributes["style"].Value == "italic")
{
isItalic = true;
}
if (child.Attributes["tts:fontWeight"] != null && child.Attributes["tts:fontWeight"].Value == "bold")
{
isBold = true;
}
if (child.Attributes["tts:textDecoration"] != null && child.Attributes["tts:textDecoration"].Value == "underline")
{
isUnderlined = true;
}
if (child.Attributes["tts:fontFamily"] != null)
{
fontFamily = child.Attributes["tts:fontFamily"].Value;
}
if (child.Attributes["tts:color"] != null)
{
color = child.Attributes["tts:color"].Value;
}
// Applying styles
if (isItalic)
{
pText.Append("<i>");
}
if (isBold)
{
pText.Append("<b>");
}
if (isUnderlined)
{
pText.Append("<u>");
}
if (!string.IsNullOrEmpty(fontFamily) || !string.IsNullOrEmpty(color))
{
pText.Append("<font");
if (!string.IsNullOrEmpty(fontFamily))
{
pText.Append($" face=\"{fontFamily}\"");
}
if (!string.IsNullOrEmpty(color))
{
pText.Append($" color=\"{color}\"");
}
pText.Append(">");
}
pText.Append(ReadParagraph(child, xml));
if (!string.IsNullOrEmpty(fontFamily) || !string.IsNullOrEmpty(color))
{
pText.Append("</font>");
}
if (isUnderlined)
{
pText.Append("</u>");
}
if (isBold)
{
pText.Append("</b>");
}
if (isItalic)
{
pText.Append("</i>");
}
}
}
return pText.ToString().TrimEnd();
}
public static string RemoveTags(string text)
{
return text
.Replace("<bouten-dot-before>", string.Empty)
.Replace("</bouten-dot-before>", string.Empty)
.Replace("<bouten-dot-after>", string.Empty)
.Replace("</bouten-dot-after>", string.Empty)
.Replace("<bouten-dot-outside>", string.Empty)
.Replace("</bouten-dot-outside>", string.Empty)
.Replace("<bouten-filled-circle-outside>", string.Empty)
.Replace("</bouten-filled-circle-outside>", string.Empty)
.Replace("<bouten-open-circle-outside>", string.Empty)
.Replace("</bouten-open-circle-outside>", string.Empty)
.Replace("<bouten-open-dot-outside>", string.Empty)
.Replace("</bouten-open-dot-outside>", string.Empty)
.Replace("<bouten-filled-sesame-outside>", string.Empty)
.Replace("</bouten-filled-sesame-outside>", string.Empty)
.Replace("<bouten-open-sesame-outside>", string.Empty)
.Replace("</bouten-open-sesame-outside>", string.Empty)
.Replace("<bouten-auto-outside>", string.Empty)
.Replace("</bouten-auto-outside>", string.Empty)
.Replace("<bouten-auto>", string.Empty)
.Replace("</bouten-auto>", string.Empty)
.Replace("<horizontalDigit>", string.Empty)
.Replace("</horizontalDigit>", string.Empty)
.Replace("<ruby-container>", string.Empty)
.Replace("</ruby-container>", string.Empty)
.Replace("<ruby-base>", string.Empty)
.Replace("</ruby-base>", string.Empty)
.Replace("<ruby-base-italic>", string.Empty)
.Replace("</ruby-base-italic>", string.Empty)
.Replace("<ruby-text>", string.Empty)
.Replace("</ruby-text>", string.Empty)
.Replace("<ruby-text-after>", string.Empty)
.Replace("</ruby-text-after>", string.Empty)
.Replace("<ruby-text-italic>", string.Empty)
.Replace("</ruby-text-italic>", string.Empty);
}
public override void RemoveNativeFormatting(Subtitle subtitle, SubtitleFormat newFormat)
{
foreach (var p in subtitle.Paragraphs)
{
p.Text = RemoveTags(p.Text);
}
}
}
}

View File

@ -2337,7 +2337,7 @@ namespace Nikse.SubtitleEdit.Forms
styles = AdvancedSubStationAlpha.GetStylesFromHeader(AdvancedSubStationAlpha.DefaultHeader);
}
}
else if (formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText))
else if (formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText) || formatType == typeof(TimedTextImsc11))
{
styles = TimedText10.GetStylesFromHeader(_subtitle.Header);
}
@ -2373,7 +2373,7 @@ namespace Nikse.SubtitleEdit.Forms
{
SubtitleListview1.ShowExtraColumn(_languageGeneral.Class);
}
else if (formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText))
else if (formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText) || formatType == typeof(TimedTextImsc11))
{
SubtitleListview1.ShowExtraColumn(_languageGeneral.StyleLanguage);
}
@ -9294,7 +9294,7 @@ namespace Nikse.SubtitleEdit.Forms
}
}
}
else if (((formatType == typeof(TimedText10) && Configuration.Settings.SubtitleSettings.TimedText10ShowStyleAndLanguage) || formatType == typeof(ItunesTimedText)) && SubtitleListview1.SelectedItems.Count > 0)
else if (((formatType == typeof(TimedText10) && Configuration.Settings.SubtitleSettings.TimedText10ShowStyleAndLanguage) || formatType == typeof(ItunesTimedText) || formatType == typeof(TimedTextImsc11)) && SubtitleListview1.SelectedItems.Count > 0)
{
toolStripMenuItemWebVTT.Visible = false;
toolStripMenuItemAssStyles.Text = _language.Menu.ContextMenu.TimedTextStyles;
@ -9857,7 +9857,7 @@ namespace Nikse.SubtitleEdit.Forms
var format = GetCurrentSubtitleFormat();
var formatType = format.GetType();
if ((formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText)))
if ((formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText) || formatType == typeof(TimedTextImsc11)))
{
foreach (int index in SubtitleListview1.SelectedIndices)
{
@ -10684,7 +10684,7 @@ namespace Nikse.SubtitleEdit.Forms
{
styles = AdvancedSubStationAlpha.GetStylesFromHeader(_subtitle.Header);
}
else if (formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText))
else if (formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText) || formatType == typeof(TimedTextImsc11))
{
styles = TimedText10.GetStylesFromHeader(_subtitle.Header);
}
@ -10702,7 +10702,7 @@ namespace Nikse.SubtitleEdit.Forms
if (useExtraForStyle)
{
newParagraph.Extra = style;
if (format.GetType() == typeof(TimedText10) || format.GetType() == typeof(ItunesTimedText))
if (format.GetType() == typeof(TimedText10) || format.GetType() == typeof(ItunesTimedText) || formatType == typeof(TimedTextImsc11))
{
if (styles.Count > 0)
{
@ -25451,7 +25451,7 @@ namespace Nikse.SubtitleEdit.Forms
toolStripMenuItemFileFormatProperties.Text = string.Format(_language.Menu.File.FormatXProperties, format.Name);
}
if (ft == typeof(TimedText10) || ft == typeof(ItunesTimedText))
if (ft == typeof(TimedText10) || ft == typeof(ItunesTimedText) || ft == typeof(TimedTextImsc11))
{
toolStripMenuItemFileFormatProperties.Visible = true;
toolStripMenuItemFileFormatProperties.Text = string.Format(_language.Menu.File.FormatXProperties, format.Name);
@ -31995,7 +31995,7 @@ namespace Nikse.SubtitleEdit.Forms
}
}
}
else if (formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText))
else if (formatType == typeof(TimedText10) || formatType == typeof(ItunesTimedText) || formatType == typeof(TimedTextImsc11))
{
using (var styles = new TimedTextStyles(_subtitle))
{
@ -32435,7 +32435,7 @@ namespace Nikse.SubtitleEdit.Forms
return;
}
if (ft == typeof(TimedText10))
if (ft == typeof(TimedText10) || ft == typeof(TimedTextImsc11))
{
using (var properties = new TimedTextProperties(_subtitle))
{