public void DcinemaSmpteColorAndItalic()
 {
     var target = new DCinemaSmpte2010();
     var subtitle = new Subtitle();
     subtitle.Paragraphs.Add(new Paragraph("<font color=\"#ff0000\"><i>Red</i></font>", 1000, 5000));
     string text = target.ToText(subtitle, "title");
     Assert.IsTrue(text.Contains("<dcst:Font Italic=\"yes\" Color=\"FFFF0000\">Red</dcst:Font>"));
 }
 public void DcinemaSmpteItalic()
 {
     var target = new DCinemaSmpte2010();
     var subtitle = new Subtitle();
     subtitle.Paragraphs.Add(new Paragraph("<i>Italic</i>", 1000, 5000));
     string text = target.ToText(subtitle, "title");
     Assert.IsTrue(text.Contains("<dcst:Font Italic=\"yes\">Italic</dcst:Font>"));
 }
Example #3
0
        public override string ToText(Subtitle subtitle, string title)
        {
            Errors = null;
            var ss = Configuration.Settings.SubtitleSettings;

            if (!string.IsNullOrEmpty(ss.CurrentDCinemaEditRate))
            {
                string[] temp = ss.CurrentDCinemaEditRate.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                double   d1, d2;
                if (temp.Length == 2 && double.TryParse(temp[0], out d1) && double.TryParse(temp[1], out d2))
                {
                    _frameRate = d1 / d2;
                }
            }

            string xmlStructure =
                "<dcst:SubtitleReel xmlns:dcst=\"http://www.smpte-ra.org/schemas/428-7/2007/DCST\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">" + Environment.NewLine +
                "  <dcst:Id>urn:uuid:7be835a3-cfb4-43d0-bb4b-f0b4c95e962e</dcst:Id>" + Environment.NewLine +
                "  <dcst:ContentTitleText></dcst:ContentTitleText> " + Environment.NewLine +
                "  <dcst:AnnotationText>This is a subtitle file</dcst:AnnotationText>" + Environment.NewLine +
                "  <dcst:IssueDate>2012-06-26T12:33:59.000-00:00</dcst:IssueDate>" + Environment.NewLine +
                "  <dcst:ReelNumber>1</dcst:ReelNumber>" + Environment.NewLine +
                "  <dcst:Language>en</dcst:Language>" + Environment.NewLine +
                "  <dcst:EditRate>25 1</dcst:EditRate>" + Environment.NewLine +
                "  <dcst:TimeCodeRate>25</dcst:TimeCodeRate>" + Environment.NewLine +
                "  <dcst:StartTime>00:00:00:00</dcst:StartTime> " + Environment.NewLine +
                "  <dcst:LoadFont ID=\"theFontId\">urn:uuid:3dec6dc0-39d0-498d-97d0-928d2eb78391</dcst:LoadFont>" + Environment.NewLine +
                "  <dcst:SubtitleList>" + Environment.NewLine +
                "    <dcst:Font ID=\"theFontId\" Size=\"39\" Weight=\"normal\" Color=\"FFFFFFFF\" Effect=\"border\" EffectColor=\"FF000000\">" + Environment.NewLine +
                "    </dcst:Font>" + Environment.NewLine +
                "  </dcst:SubtitleList>" + Environment.NewLine +
                "</dcst:SubtitleReel>";

            var xml = new XmlDocument();

            xml.LoadXml(xmlStructure);
            xml.PreserveWhitespace = true;
            var nsmgr = new XmlNamespaceManager(xml.NameTable);

            nsmgr.AddNamespace("dcst", xml.DocumentElement.NamespaceURI);

            if (string.IsNullOrEmpty(ss.CurrentDCinemaMovieTitle))
            {
                ss.CurrentDCinemaMovieTitle = title;
            }

            if (ss.CurrentDCinemaFontSize == 0 || string.IsNullOrEmpty(ss.CurrentDCinemaFontEffect))
            {
                Configuration.Settings.SubtitleSettings.InitializeDCinameSettings(true);
            }

            xml.DocumentElement.SelectSingleNode("dcst:ContentTitleText", nsmgr).InnerText = ss.CurrentDCinemaMovieTitle;
            if (string.IsNullOrEmpty(ss.CurrentDCinemaSubtitleId) || !ss.CurrentDCinemaSubtitleId.StartsWith("urn:uuid:"))
            {
                ss.CurrentDCinemaSubtitleId = "urn:uuid:" + Guid.NewGuid();
            }

            xml.DocumentElement.SelectSingleNode("dcst:Id", nsmgr).InnerText         = ss.CurrentDCinemaSubtitleId;
            xml.DocumentElement.SelectSingleNode("dcst:ReelNumber", nsmgr).InnerText = ss.CurrentDCinemaReelNumber;
            xml.DocumentElement.SelectSingleNode("dcst:IssueDate", nsmgr).InnerText  = ss.CurrentDCinemaIssueDate;
            if (string.IsNullOrEmpty(ss.CurrentDCinemaLanguage))
            {
                ss.CurrentDCinemaLanguage = "en";
            }

            xml.DocumentElement.SelectSingleNode("dcst:Language", nsmgr).InnerText = ss.CurrentDCinemaLanguage;
            if (ss.CurrentDCinemaEditRate == null && ss.CurrentDCinemaTimeCodeRate == null)
            {
                if (Configuration.Settings.General.CurrentFrameRate == 24)
                {
                    ss.CurrentDCinemaEditRate     = "24 1";
                    ss.CurrentDCinemaTimeCodeRate = "24";
                }
                else
                {
                    ss.CurrentDCinemaEditRate     = "25 1";
                    ss.CurrentDCinemaTimeCodeRate = "25";
                }
            }
            xml.DocumentElement.SelectSingleNode("dcst:EditRate", nsmgr).InnerText     = ss.CurrentDCinemaEditRate;
            xml.DocumentElement.SelectSingleNode("dcst:TimeCodeRate", nsmgr).InnerText = ss.CurrentDCinemaTimeCodeRate;
            if (string.IsNullOrEmpty(ss.CurrentDCinemaStartTime))
            {
                ss.CurrentDCinemaStartTime = "00:00:00:00";
            }

            xml.DocumentElement.SelectSingleNode("dcst:StartTime", nsmgr).InnerText = ss.CurrentDCinemaStartTime;
            xml.DocumentElement.SelectSingleNode("dcst:LoadFont", nsmgr).InnerText  = ss.CurrentDCinemaFontUri;
            int    fontSize     = ss.CurrentDCinemaFontSize;
            string loadedFontId = "Font1";

            if (!string.IsNullOrEmpty(ss.CurrentDCinemaFontId))
            {
                loadedFontId = ss.CurrentDCinemaFontId;
            }

            xml.DocumentElement.SelectSingleNode("dcst:LoadFont", nsmgr).Attributes["ID"].Value = loadedFontId;
            xml.DocumentElement.SelectSingleNode("dcst:SubtitleList/dcst:Font", nsmgr).Attributes["Size"].Value        = fontSize.ToString();
            xml.DocumentElement.SelectSingleNode("dcst:SubtitleList/dcst:Font", nsmgr).Attributes["Color"].Value       = "FF" + Utilities.ColorToHex(ss.CurrentDCinemaFontColor).TrimStart('#').ToUpperInvariant();
            xml.DocumentElement.SelectSingleNode("dcst:SubtitleList/dcst:Font", nsmgr).Attributes["ID"].Value          = loadedFontId;
            xml.DocumentElement.SelectSingleNode("dcst:SubtitleList/dcst:Font", nsmgr).Attributes["Effect"].Value      = ss.CurrentDCinemaFontEffect;
            xml.DocumentElement.SelectSingleNode("dcst:SubtitleList/dcst:Font", nsmgr).Attributes["EffectColor"].Value = "FF" + Utilities.ColorToHex(ss.CurrentDCinemaFontEffectColor).TrimStart('#').ToUpperInvariant();

            XmlNode mainListFont = xml.DocumentElement.SelectSingleNode("dcst:SubtitleList/dcst:Font", nsmgr);
            int     no           = 0;

            foreach (Paragraph p in subtitle.Paragraphs)
            {
                if (p.Text != null)
                {
                    XmlNode subNode = xml.CreateElement("dcst:Subtitle", "dcst");

                    XmlAttribute id = xml.CreateAttribute("SpotNumber");
                    id.InnerText = (no + 1).ToString();
                    subNode.Attributes.Append(id);

                    XmlAttribute fadeUpTime = xml.CreateAttribute("FadeUpTime");
                    fadeUpTime.InnerText = "00:00:00:00";
                    subNode.Attributes.Append(fadeUpTime);

                    XmlAttribute fadeDownTime = xml.CreateAttribute("FadeDownTime");
                    fadeDownTime.InnerText = "00:00:00:00";
                    subNode.Attributes.Append(fadeDownTime);

                    XmlAttribute start = xml.CreateAttribute("TimeIn");
                    start.InnerText = ConvertToTimeString(p.StartTime);
                    subNode.Attributes.Append(start);

                    XmlAttribute end = xml.CreateAttribute("TimeOut");
                    end.InnerText = ConvertToTimeString(p.EndTime);
                    subNode.Attributes.Append(end);

                    bool alignLeft = p.Text.StartsWith("{\\a1}", StringComparison.Ordinal) || p.Text.StartsWith("{\\a5}", StringComparison.Ordinal) || p.Text.StartsWith("{\\a9}", StringComparison.Ordinal) ||      // sub station alpha
                                     p.Text.StartsWith("{\\an1}", StringComparison.Ordinal) || p.Text.StartsWith("{\\an4}", StringComparison.Ordinal) || p.Text.StartsWith("{\\an7}", StringComparison.Ordinal);     // advanced sub station alpha

                    bool alignRight = p.Text.StartsWith("{\\a3}", StringComparison.Ordinal) || p.Text.StartsWith("{\\a7}", StringComparison.Ordinal) || p.Text.StartsWith("{\\a11}", StringComparison.Ordinal) ||    // sub station alpha
                                      p.Text.StartsWith("{\\an3}", StringComparison.Ordinal) || p.Text.StartsWith("{\\an6}", StringComparison.Ordinal) || p.Text.StartsWith("{\\an9}", StringComparison.Ordinal);    // advanced sub station alpha

                    bool alignVTop = p.Text.StartsWith("{\\a5}", StringComparison.Ordinal) || p.Text.StartsWith("{\\a6}", StringComparison.Ordinal) || p.Text.StartsWith("{\\a7}", StringComparison.Ordinal) ||      // sub station alpha
                                     p.Text.StartsWith("{\\an7}", StringComparison.Ordinal) || p.Text.StartsWith("{\\an8}", StringComparison.Ordinal) || p.Text.StartsWith("{\\an9}", StringComparison.Ordinal);     // advanced sub station alpha

                    bool alignVCenter = p.Text.StartsWith("{\\a9}", StringComparison.Ordinal) || p.Text.StartsWith("{\\a10}", StringComparison.Ordinal) || p.Text.StartsWith("{\\a11}", StringComparison.Ordinal) || // sub station alpha
                                        p.Text.StartsWith("{\\an4}", StringComparison.Ordinal) || p.Text.StartsWith("{\\an5}", StringComparison.Ordinal) || p.Text.StartsWith("{\\an6}", StringComparison.Ordinal);  // advanced sub station alpha

                    string text = Utilities.RemoveSsaTags(p.Text);

                    var lines      = text.SplitToLines();
                    int vPos       = 1 + lines.Count * 7;
                    int vPosFactor = (int)Math.Round(fontSize / 7.4);
                    if (alignVTop)
                    {
                        vPos = Configuration.Settings.SubtitleSettings.DCinemaBottomMargin; // Bottom margin is normally 8
                    }
                    else if (alignVCenter)
                    {
                        vPos = (int)Math.Round((lines.Count * vPosFactor * -1) / 2.0);
                    }
                    else
                    {
                        vPos = lines.Count * vPosFactor - vPosFactor + Configuration.Settings.SubtitleSettings.DCinemaBottomMargin; // Bottom margin is normally 8
                    }

                    bool           isItalic   = false;
                    int            fontNo     = 0;
                    Stack <string> fontColors = new Stack <string>();
                    foreach (string line in lines)
                    {
                        XmlNode textNode = xml.CreateElement("dcst:Text", "dcst");

                        XmlAttribute vPosition = xml.CreateAttribute("Vposition");
                        vPosition.InnerText = vPos.ToString();
                        textNode.Attributes.Append(vPosition);

                        XmlAttribute vAlign = xml.CreateAttribute("Valign");
                        if (alignVTop)
                        {
                            vAlign.InnerText = "top";
                        }
                        else if (alignVCenter)
                        {
                            vAlign.InnerText = "center";
                        }
                        else
                        {
                            vAlign.InnerText = "bottom";
                        }

                        textNode.Attributes.Append(vAlign); textNode.Attributes.Append(vAlign);

                        XmlAttribute hAlign = xml.CreateAttribute("Halign");
                        if (alignLeft)
                        {
                            hAlign.InnerText = "left";
                        }
                        else if (alignRight)
                        {
                            hAlign.InnerText = "right";
                        }
                        else
                        {
                            hAlign.InnerText = "center";
                        }

                        textNode.Attributes.Append(hAlign);

                        XmlAttribute direction = xml.CreateAttribute("Direction");
                        direction.InnerText = "ltr";
                        textNode.Attributes.Append(direction);

                        int     i        = 0;
                        var     txt      = new StringBuilder();
                        var     html     = new StringBuilder();
                        XmlNode nodeTemp = xml.CreateElement("temp");
                        while (i < line.Length)
                        {
                            if (!isItalic && line.Substring(i).StartsWith("<i>"))
                            {
                                if (txt.Length > 0)
                                {
                                    nodeTemp.InnerText = txt.ToString();
                                    html.Append(nodeTemp.InnerXml);
                                    txt.Clear();
                                }
                                isItalic = true;
                                i       += 2;
                            }
                            else if (isItalic && line.Substring(i).StartsWith("</i>"))
                            {
                                if (txt.Length > 0)
                                {
                                    XmlNode fontNode = xml.CreateElement("dcst:Font", "dcst");

                                    XmlAttribute italic = xml.CreateAttribute("Italic");
                                    italic.InnerText = "yes";
                                    fontNode.Attributes.Append(italic);

                                    if (line.Length > i + 5 && line.Substring(i + 4).StartsWith("</font>"))
                                    {
                                        XmlAttribute fontColor = xml.CreateAttribute("Color");
                                        fontColor.InnerText = fontColors.Pop();
                                        fontNode.Attributes.Append(fontColor);
                                        fontNo--;
                                        i += 7;
                                    }

                                    fontNode.InnerText = HtmlUtil.RemoveHtmlTags(txt.ToString());
                                    html.Append(fontNode.OuterXml);
                                    txt.Clear();
                                }
                                isItalic = false;
                                i       += 3;
                            }
                            else if (line.Substring(i).StartsWith("<font color=") && line.Substring(i + 3).Contains('>'))
                            {
                                int endOfFont = line.IndexOf('>', i);
                                if (txt.Length > 0)
                                {
                                    nodeTemp.InnerText = txt.ToString();
                                    html.Append(nodeTemp.InnerXml);
                                    txt.Clear();
                                }
                                string c = line.Substring(i + 12, endOfFont - (i + 12));
                                c = c.Trim('"').Trim('\'').Trim();
                                if (c.StartsWith('#'))
                                {
                                    c = c.TrimStart('#').ToUpperInvariant().PadLeft(8, 'F');
                                }

                                fontColors.Push(c);
                                fontNo++;
                                i = endOfFont;
                            }
                            else if (fontNo > 0 && line.Substring(i).StartsWith("</font>"))
                            {
                                if (txt.Length > 0)
                                {
                                    XmlNode fontNode = xml.CreateElement("dcst:Font", "dcst");

                                    XmlAttribute fontColor = xml.CreateAttribute("Color");
                                    fontColor.InnerText = fontColors.Pop();
                                    fontNode.Attributes.Append(fontColor);

                                    if (line.Length > i + 9 && line.Substring(i + 7).StartsWith("</i>"))
                                    {
                                        XmlAttribute italic = xml.CreateAttribute("Italic");
                                        italic.InnerText = "yes";
                                        fontNode.Attributes.Append(italic);
                                        isItalic = false;
                                        i       += 4;
                                    }

                                    fontNode.InnerText = HtmlUtil.RemoveHtmlTags(txt.ToString());
                                    html.Append(fontNode.OuterXml);
                                    txt.Clear();
                                }
                                fontNo--;
                                i += 6;
                            }
                            else
                            {
                                txt.Append(line[i]);
                            }
                            i++;
                        }

                        if (fontNo > 0)
                        {
                            if (txt.Length > 0)
                            {
                                XmlNode fontNode = xml.CreateElement("dcst:Font", "dcst");

                                XmlAttribute fontColor = xml.CreateAttribute("Color");
                                fontColor.InnerText = fontColors.Peek();
                                fontNode.Attributes.Append(fontColor);

                                if (isItalic)
                                {
                                    XmlAttribute italic = xml.CreateAttribute("Italic");
                                    italic.InnerText = "yes";
                                    fontNode.Attributes.Append(italic);
                                }

                                fontNode.InnerText = HtmlUtil.RemoveHtmlTags(txt.ToString());
                                html.Append(fontNode.OuterXml);
                            }
                            else if (html.Length > 0 && html.ToString().StartsWith("<dcst:Font "))
                            {
                                XmlDocument temp = new XmlDocument();
                                temp.LoadXml("<root>" + html.ToString().Replace("dcst:Font", "Font") + "</root>");
                                XmlNode fontNode = xml.CreateElement("dcst:Font");
                                fontNode.InnerXml = temp.DocumentElement.SelectSingleNode("Font").InnerXml;
                                foreach (XmlAttribute a in temp.DocumentElement.SelectSingleNode("Font").Attributes)
                                {
                                    XmlAttribute newA = xml.CreateAttribute(a.Name);
                                    newA.InnerText = a.InnerText;
                                    fontNode.Attributes.Append(newA);
                                }

                                XmlAttribute fontColor = xml.CreateAttribute("Color");
                                fontColor.InnerText = fontColors.Peek();
                                fontNode.Attributes.Append(fontColor);

                                html.Clear();
                                html.Append(fontNode.OuterXml);
                            }
                        }
                        else if (isItalic)
                        {
                            if (txt.Length > 0)
                            {
                                XmlNode fontNode = xml.CreateElement("dcst:Font", "dcst");

                                XmlAttribute italic = xml.CreateAttribute("Italic");
                                italic.InnerText = "yes";
                                fontNode.Attributes.Append(italic);

                                fontNode.InnerText = HtmlUtil.RemoveHtmlTags(line);
                                html.Append(fontNode.OuterXml);
                            }
                        }
                        else
                        {
                            if (txt.Length > 0)
                            {
                                nodeTemp.InnerText = txt.ToString();
                                html.Append(nodeTemp.InnerXml);
                            }
                        }
                        textNode.InnerXml = html.ToString();

                        subNode.AppendChild(textNode);
                        if (alignVTop)
                        {
                            vPos += vPosFactor;
                        }
                        else
                        {
                            vPos -= vPosFactor;
                        }
                    }
                    if (subNode.InnerXml.Length == 0)
                    { // Empty text is just one space
                        XmlNode textNode = xml.CreateElement("dcst:Text", "dcst");
                        textNode.InnerXml = " ";
                        subNode.AppendChild(textNode);

                        XmlAttribute vPosition = xml.CreateAttribute("Vposition");
                        vPosition.InnerText = vPos.ToString();
                        textNode.Attributes.Append(vPosition);

                        XmlAttribute vAlign = xml.CreateAttribute("Valign");
                        vAlign.InnerText = "bottom";
                        textNode.Attributes.Append(vAlign);
                    }
                    mainListFont.AppendChild(subNode);
                    no++;
                }
            }
            string result = ToUtf8XmlString(xml).Replace("encoding=\"utf-8\"", "encoding=\"UTF-8\"").Replace(" xmlns:dcst=\"dcst\"", string.Empty);

            const string res = "Nikse.SubtitleEdit.Resources.SMPTE-428-7-2007-DCST.xsd.gz";

            System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();
            Stream strm = asm.GetManifestResourceStream(res);

            if (strm != null)
            {
                try
                {
                    var xmld = new XmlDocument();
                    var rdr  = new StreamReader(strm);
                    var zip  = new GZipStream(rdr.BaseStream, CompressionMode.Decompress);
                    xmld.LoadXml(result);
                    using (var xr = XmlReader.Create(zip))
                    {
                        xmld.Schemas.Add(null, xr);
                        xmld.Validate(ValidationCallBack);
                    }
                }
                catch (Exception exception)
                {
                    Errors = "Error validating xml via SMPTE - 428 - 7 - 2007 - DCST.xsd: " + exception.Message;
                }
            }
            return(DCinemaSmpte2010.FixDcsTextSameLine(result));
        }
Example #4
0
 private string ConvertToTimeString(TimeCode time)
 {
     return($"{time.Hours:00}:{time.Minutes:00}:{time.Seconds:00}:{DCinemaSmpte2010.MsToFramesMaxFrameRate(time.Milliseconds, _frameRate):00}");
 }
 private string ConvertToTimeString(TimeCode time)
 {
     return(string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, DCinemaSmpte2010.MsToFramesMaxFrameRate(time.Milliseconds, _frameRate)));
 }