Example #1
0
        /// <summary>
        /// Helper method is meant to take a char array that is representation of a row and split it up to its string columns.
        /// </summary>
        /// <param name="q">The char array we need to convert.</param>
        /// <param name="delimiter">The delimiter we need to break the columns up by.</param>
        /// <param name="wrapper">The wrapper to break apart strings.</param>
        /// <param name="rowDelimiter">The row delimiter to determine exceptions.</param>
        /// <param name="emptyColumns">The lamda expression to get empty columns.</param>
        /// <param name="allAreEmpty">Switch to determine if we want to ignore if the data is empty and just call them all empty no matter what.</param>
        /// <returns></returns>
        public static List <string> Split(Queue <char> q, string delimiter, char?wrapper, string rowDelimiter, Func <int, string> emptyColumns = null, bool allAreEmpty = false)
        {
            if (q == null)
            {
                return(null);
            }

            var escaped = false;
            var results = new List <string>();
            var builder = new StringBuilder();

            while (q.Count > 0)
            {
                var current = q.Dequeue();
                builder.Append(current);

                if (escaped)
                { // Deal with if we are in a wrapper.
                    if (current == wrapper && q.Count > 0 && q.Peek() == wrapper)
                    {
                        q.Dequeue();
                    }
                    else if (current == wrapper)
                    {
                        escaped = false;
                        builder.Remove(builder.Length - 1, 1);
                    }
                }
                else if (current == wrapper)
                { // Escape the value and start parsing as such
                    escaped = true;
                    builder.Remove(builder.Length - 1, 1);
                }
                else if (builder.EndsWith(delimiter))
                { // If we encounter a delmitier we want to put the current string into the results and clear the builder.
                    results.Add(builder.ToString(0, builder.Length - delimiter.Length));
                    builder.Clear();
                }
            }

            if (builder.Length > 0)
            {
                results.Add(builder.EndsWith(rowDelimiter) ? builder.ToString(0, builder.Length - rowDelimiter.Length) : builder.ToString());
            }

            if (emptyColumns != null)
            {
                for (var i = 0; i < results.Count; ++i)
                {
                    if (results[i].Trim().Length == 0 || allAreEmpty)
                    {
                        results[i] = emptyColumns(i);
                    }
                }
            }

            return(results);
        }
        public MainWindow()
        {
            InitializeComponent();

            var sb = new StringBuilder();

            sb.Append("Blake Pell");

            MessageBox.Show(sb.StartsWith('B', false).ToString()); // true
            MessageBox.Show(sb.StartsWith('b', true).ToString());  // true
            MessageBox.Show(sb.StartsWith('b', false).ToString()); // false

            MessageBox.Show(sb.EndsWith('l', false).ToString());   // true
            MessageBox.Show(sb.EndsWith('L', true).ToString());    // true
            MessageBox.Show(sb.EndsWith('L', false).ToString());   // false



            //var op = new ObjectPool<Person>();
            //op.Max = 10;

            //op.ReturnAction = i =>
            //{
            //    i.FirstName = "Cleared!";
            //    i.LastName = "Cleared!";
            //};

            //var p = op.Get();
            //p.FirstName = "Blake";
            //p.LastName = "Pell";
            //op.Return(p);
            //p.FirstName = "Edwardo";
            //op.Return(p);


            //var xy = op.Get();


            //int x = 0;

            //Parallel.For(0, 10000,
            //             index => {
            //                 var newObject = op.Get();
            //                 op.Return(newObject);

            //                 //FileInfo fi = new FileInfo(files[index]);
            //                 //long size = fi.Length;
            //                 //Interlocked.Add(ref totalSize, size);
            //             });

            ////for (int i = 0; i < 100; i++)
            ////{
            ////    var newObject = op.Get();
            ////    op.Return(newObject);
            ////}

            //MessageBox.Show(op.CounterNewObjects + "|" + op.CounterReusedObjects);
        }
Example #3
0
        private static void Step1b(StringBuilder word, StemRegion stemRegion)
        {
            var replacement = word.EndsWith(step1bReplacements);
            var matchedWord = replacement.MatchWord;

            if (matchedWord != null)
            {
                switch (matchedWord)
                {
                case "EEDLY":
                case "EED":
                    if (word.Length - matchedWord.Length >= stemRegion.R1)
                    {
                        word.ReplaceEnd(replacement);
                    }

                    break;

                default:
                    var found = false;
                    for (var j = 0; j < word.Length - matchedWord.Length; ++j)
                    {
                        if (word.IsVowel(j))
                        {
                            word.ReplaceEnd(replacement);
                            found = true;
                            break;
                        }
                    }

                    if (found)
                    {
                        if (word.EndsWith(step1bAppendEEndings) != null)
                        {
                            word.Append('E');
                        }
                        else if (HasDoubleLetterEnding(word))
                        {
                            word.Length -= 1;
                        }
                        else if (word.IsShortWord(stemRegion))
                        {
                            word.Append('E');
                        }
                    }

                    break;
                }
            }
        }
        public void EndsWith_StringNotAtEnd()
        {
            StringBuilder builder = new StringBuilder();

            builder.Append("abcdefg");
            string endString = "bcd";

            bool endsWith = builder.EndsWith(endString);

            Assert.IsFalse(endsWith);

            endString = "BCD";
            endsWith  = builder.EndsWith(endString, StringComparison.OrdinalIgnoreCase);
            Assert.IsFalse(endsWith);
        }
Example #5
0
        private static void Step2(StringBuilder word, StemRegion stemRegion)
        {
            var replacement = word.EndsWith(step2Replacements);
            var length      = word.Length;

            if (replacement.MatchWord != null && length - replacement.MatchWord.Length >= stemRegion.R1)
            {
                switch (replacement.MatchWord)
                {
                case "OGI":
                    if (length > 3 && word[length - replacement.MatchWord.Length - 1] == 'L')
                    {
                        word.ReplaceEnd(replacement);
                    }

                    break;

                case "LI":
                    if (length > 1 && IsRemovableLiEnding(word[length - 3]))
                    {
                        word.Length -= 2;
                    }

                    break;

                default:
                    word.ReplaceEnd(replacement);
                    break;
                }
            }
        }
Example #6
0
        /// <summary>
        ///   <para>Read the data</para>
        /// </summary>
        /// <param name = "result"></param>
        //[DebuggerStepThrough]
        void ReadCallback(IAsyncResult result)
        {
            try
            {
                var readData = Encoding.UTF8.GetString(
                    _readBuffer,
                    0, _networkStream.EndRead(result));
                _data.Append(readData);

                // check for terminator
                if (_data.EndsWith(_terminator))
                {
                    // process data received not including the terminator
                    Process(
                        _data.ToString(0, _data.Length - _terminator.Length));
                }
                else if (_networkStream != null)
                {
                    // read some more data
                    ContinueRead();
                }
            }
            catch (Exception)
            {
                Dispose();
            }
        }
        /// <summary>Reads a line of characters from the current stream and returns the data as a string.</summary>
        /// <returns>The next line from the input stream, or null if the end of the input stream is reached.</returns>
        /// <exception cref="T:System.OutOfMemoryException">There is insufficient memory to allocate a buffer for the returned string. </exception>
        /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
        /// <filterpriority>1</filterpriority>
        public override string ReadLine()
        {
            if (string.IsNullOrEmpty(NewLine))
            {
                return(base.ReadLine());
            }

            StringBuilder bld = new StringBuilder();
            bool          eof = false;

            while (true)
            {
                int tmp = Read();
                if (tmp == -1)
                {
                    eof = true;
                    break;
                }

                bld.Append((char)tmp);
                if (bld.EndsWith(NewLine))
                {
                    bld.Remove(bld.Length - NewLine.Length, NewLine.Length);
                    break;
                }
            }

            if (eof && bld.Length == 0)
            {
                return(null);
            }

            return(bld.ToString());
        }
        static void Main(string[] args)
        {
            StringBuilder str = new StringBuilder();

            str.Append("Hello_World !!!");
            Console.WriteLine("Index is at: " + str.IndexOf("World", 1));
            Console.WriteLine("Index is at: " + str.IndexOf("H"));
            Console.WriteLine("Index is at: " + str.IndexOf("e"));
            Console.WriteLine("Index is at: " + str.IndexOf("l"));
            Console.WriteLine("Index is at: " + str.IndexOf("l", 3));
            Console.WriteLine("Index is at: " + str.IndexOf("o"));
            Console.WriteLine("Index is at: " + str.IndexOf("W"));
            Console.WriteLine("Index is at: " + str.IndexOf("o"));
            Console.WriteLine("Index is at: " + str.IndexOf("r"));
            Console.WriteLine("Index is at: " + str.IndexOf("l"));
            Console.WriteLine("Index is at: " + str.IndexOf("d"));

            Console.WriteLine("Substring 5 to end: " + str.Substring(5));

            Console.WriteLine("Substring 1, length 1: " + str.Substring(1, 1));

            StringBuilder[] strs = str.Split(new String[] { " ", "_" });

            Console.WriteLine("Does string contain Hello? " + str.Contains("Hello"));

            Console.WriteLine("Does string end with !!!? " + str.EndsWith("!!!"));

            Console.WriteLine("Last index of !: " + str.LastIndexOf("!"));

            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        } //end main
Example #9
0
        internal static HtmlElement GetSpecialTag(this TextReader reader, string name)
        {
            reader.AdvanceReaderThroughWhiteSpace();

            var scriptElement = new HtmlElement
            {
                Attributes   = reader.GetElementAttributes(),
                TagName      = name,
                HasEndingTag = true
            };

            var specialTag = new StringBuilder();

            while (true)
            {
                specialTag.Append((char)reader.Read());
                if (specialTag.EndsWith("</" + name + ">"))
                {
                    break;
                }
            }

            var strSpecialTag = specialTag.ToString();

            strSpecialTag      = strSpecialTag.Substring(0, strSpecialTag.Length - ("</" + name + ">").Length).Trim();
            scriptElement.Text = !string.IsNullOrWhiteSpace(strSpecialTag) ? strSpecialTag : null;
            return(scriptElement);
        }
        public void EndsWith_StringBuilderNull()
        {
            StringBuilder builder  = null;
            bool          endsWith = builder.EndsWith("a");

            Assert.IsFalse(endsWith);
        }
Example #11
0
 public static string JoinPath(string root, string[] parts, int start, int count)
 {
     if (root == null)
         throw new ArgumentNullException("root");
     if (parts == null)
         throw new ArgumentNullException("right");
     if (start < 0 || start > parts.Length)
         throw new ArgumentOutOfRangeException("start");
     if (count < 0 || count > parts.Length - start)
         throw new ArgumentOutOfRangeException("count");
     var result = new StringBuilder(root.Trim());
     var trimmed = parts.Skip(start).Take(count).Select(item => item.Trim());
     foreach (var part in trimmed.Where(item => item.Any()))
         // This seems complicated but the idea is to ensure the single separating slashes
         // saving the slash appending operation if not necessary.
         if (part.StartsWith('/')) {
             if (result.Length > 0 && !result.EndsWith('/'))
                 result.Append(part);
             else
                 result.Append(part, 1, part.Length - 1);
         } else {
             if (result.Length > 0 && !result.EndsWith('/'))
                 result.Append('/');
             result.Append(part);
         }
     return result.ToString();
 }
Example #12
0
 private void TrimEndComma(StringBuilder sb)
 {
     if (sb.EndsWith(','))
     {
         sb.Remove(sb.Length - 1);
     }
 }
Example #13
0
        public static string JoinPath(string root, string[] parts, int start, int count)
        {
            if (root == null)
            {
                throw new ArgumentNullException("root");
            }
            if (parts == null)
            {
                throw new ArgumentNullException("right");
            }
            if (start < 0 || start > parts.Length)
            {
                throw new ArgumentOutOfRangeException("start");
            }
            if (count < 0 || count > parts.Length - start)
            {
                throw new ArgumentOutOfRangeException("count");
            }
            var result  = new StringBuilder(root.Trim());
            var trimmed = parts.Skip(start).Take(count).Select(item => item.Trim());

            foreach (var part in trimmed.Where(item => item.Any()))
            {
                // This seems complicated but the idea is to ensure the single separating slashes
                // saving the append slash operation if not necessary.
                if (part.StartsWith('/'))
                {
                    if (result.Length > 0 && !result.EndsWith('/'))
                    {
                        result.Append(part);
                    }
                    else
                    {
                        result.Append(part, 1, part.Length - 1);
                    }
                }
                else
                {
                    if (result.Length > 0 && !result.EndsWith('/'))
                    {
                        result.Append('/');
                    }
                    result.Append(part);
                }
            }
            return(result.ToString());
        }
Example #14
0
 /// <summary>
 /// The ensure ends with.
 /// </summary>
 /// <param name="sb">
 /// The buffer.
 /// </param>
 /// <param name="suffix">
 /// The suffix.
 /// </param>
 public static void EnsureEndsWith(this StringBuilder sb, string suffix)
 {
     if (!sb.EndsWith(suffix))
     {
         // Append suffix, since it's not currently there.
         sb.Append(suffix);
     }
 }
Example #15
0
 public static void AppendPreDelimited(this StringBuilder builder, string text, string preDelimiter)
 {
     if (builder.Length > 0 && !builder.EndsWith(preDelimiter))
     {
         builder.Append(preDelimiter);
     }
     builder.Append(text);
 }
        public void EndsWith_StringNull()
        {
            StringBuilder builder = new StringBuilder();

            builder.Append("abcdefg");
            string endString = null;
            bool   endsWith  = builder.EndsWith(endString);
        }
        public void EndsWith_StringEmpty()
        {
            StringBuilder builder = new StringBuilder();

            builder.Append("abcdefg");
            string endString = string.Empty;
            bool   endsWith  = builder.EndsWith(endString);
        }
Example #18
0
 public static void RemoveLast(this StringBuilder sb, string value)
 {
     if (!sb.EndsWith(value))
     {
         return;
     }
     sb.Remove(sb.Length - value.Length, value.Length);
 }
        public void TestNotContainingCharactersIgnoreCase()
        {
            StringBuilder sb;

            sb = new StringBuilder(incorrectStringToSearch1);
            Assert.AreEqual(sb.EndsWith(TestStrings.Searched, true), incorrectStringToSearch1.EndsWith(TestStrings.Searched, true, CultureInfo.CurrentCulture));
            sb = new StringBuilder(incorrectStringToSearch2);
            Assert.AreEqual(sb.EndsWith(TestStrings.Searched, true), incorrectStringToSearch2.EndsWith(TestStrings.Searched, true, CultureInfo.CurrentCulture));
        }
Example #20
0
        /// <summary>
        /// Reads lines.
        /// </summary>
        public override List <string> ReadLines(int timeout, TextStopCondition stopCond,
                                                out bool stopReceived, out string logText)
        {
            try
            {
                List <string> lines = new List <string>();
                stopReceived = false;
                IPEndPoint endPoint = CreateRemoteEndPoint();
                UdpClient.Client.ReceiveTimeout = DatagramReceiveTimeout;
                Stopwatch stopwatch = Stopwatch.StartNew();

                while (!stopReceived && stopwatch.ElapsedMilliseconds <= timeout)
                {
                    // read data
                    byte[] datagram = ReceiveDatagram(ref endPoint, out int readPos, out bool isNew);

                    if (datagram != null && datagram.Length > 0)
                    {
                        // get lines from the received data
                        int           datagramLen = datagram.Length;
                        StringBuilder sbLine      = new StringBuilder(datagramLen);

                        while (readPos < datagramLen && !stopReceived)
                        {
                            sbLine.Append(Encoding.GetChars(datagram, readPos, 1));
                            readPos++;
                            bool newLineFound = sbLine.EndsWith(NewLine);

                            if (newLineFound || readPos == datagramLen)
                            {
                                string line = newLineFound ?
                                              sbLine.ToString(0, sbLine.Length - NewLine.Length) :
                                              sbLine.ToString();
                                lines.Add(line);
                                sbLine.Clear();
                                stopReceived = stopCond.CheckCondition(lines, line);
                            }
                        }
                    }

                    // accumulate data in the internal connection buffer
                    if (!stopReceived && isNew)
                    {
                        Thread.Sleep(DataAccumDelay);
                    }

                    StoreDatagram(datagram, readPos);
                }

                logText = BuildReadLinesLogText(lines);
                return(lines);
            }
            catch (Exception ex)
            {
                throw new ScadaException(CommPhrases.ReadLinesError + ": " + ex.Message, ex);
            }
        }
Example #21
0
 public static void AppendPostDelimited(this StringBuilder builder, string text, string postDelimiter)
 {
     builder.Append(text);
     if (builder.Length <= 0 || builder.EndsWith(postDelimiter))
     {
         return;
     }
     builder.Append(postDelimiter);
 }
Example #22
0
        public void UpdateTest1()
        {
            StringBuilder str = new StringBuilder("[TestString]");

            Assert.IsTrue(str.StartsWith("["));
            Assert.IsTrue(str.EndsWith("]"));

            Assert.AreEqual("TestString", str.UnBracketing(StringPair.SquareBracket).ToString());
        }
Example #23
0
        public void UpdateTest1()
        {
            StringBuilder str = new StringBuilder("[TestString]");

            Assert.IsTrue(str.StartsWith("["));
            Assert.IsTrue(str.EndsWith("]"));

            Assert.AreEqual("TestString", str.UnBracketing(StringPair.SquareBracket).ToString());
        }
        public void TestContainingCharacters()
        {
            StringBuilder sb;

            sb = new StringBuilder(correctStringToSearch);
            Assert.AreEqual(sb.EndsWith(TestStrings.Searched), correctStringToSearch.EndsWith(TestStrings.Searched));
            sb = new StringBuilder(TestStrings.Searched);
            Assert.AreEqual(sb.EndsWith(TestStrings.Searched), correctStringToSearch.EndsWith(TestStrings.Searched));
        }
Example #25
0
        private static void Step0(StringBuilder word)
        {
            var endsWith = word.EndsWith(apostropheEnds);

            if (endsWith != null)
            {
                word.Length -= endsWith.Length;
            }
        }
        public void TestContainingCharactersIgnoreCase()
        {
            StringBuilder sb;

            sb = new StringBuilder(correctStringToSearchUpperCase);
            Assert.AreEqual(sb.EndsWith(TestStrings.Searched, true), correctStringToSearch.EndsWith(TestStrings.Searched, true, CultureInfo.CurrentCulture));
            sb = new StringBuilder(TestStrings.Searched.ToUpper());
            Assert.AreEqual(sb.EndsWith(TestStrings.Searched, true), correctStringToSearch.EndsWith(TestStrings.Searched, true, CultureInfo.CurrentCulture));
        }
        public void TestNotContainingCharacters()
        {
            StringBuilder sb;

            sb = new StringBuilder(incorrectStringToSearch1);
            Assert.AreEqual(sb.EndsWith(TestStrings.Searched), incorrectStringToSearch1.EndsWith(TestStrings.Searched));
            sb = new StringBuilder(incorrectStringToSearch2);
            Assert.AreEqual(sb.EndsWith(TestStrings.Searched), incorrectStringToSearch2.EndsWith(TestStrings.Searched));
        }
Example #28
0
        /// <summary>
        /// Reads lines.
        /// </summary>
        public override List <string> ReadLines(int timeout, TextStopCondition stopCond,
                                                out bool stopReceived, out string logText)
        {
            try
            {
                List <string> lines = new List <string>();
                stopReceived          = false;
                NetStream.ReadTimeout = OneByteReadTimeout;
                Stopwatch stopwatch = Stopwatch.StartNew();

                StringBuilder sbLine = new StringBuilder(MaxLineLength);
                byte[]        buffer = new byte[1];

                while (!stopReceived && stopwatch.ElapsedMilliseconds <= timeout)
                {
                    // read one byte
                    bool readOk;
                    try { readOk = NetStream.DataAvailable && NetStream.Read(buffer, 0, 1) > 0; }
                    catch (IOException) { readOk = false; }

                    if (readOk)
                    {
                        sbLine.Append(Encoding.GetChars(buffer));
                    }
                    else
                    {
                        Thread.Sleep(DataAccumDelay);
                    }

                    bool newLineFound = sbLine.EndsWith(NewLine);

                    if (newLineFound || sbLine.Length == MaxLineLength)
                    {
                        string line = newLineFound ?
                                      sbLine.ToString(0, sbLine.Length - NewLine.Length) :
                                      sbLine.ToString();
                        lines.Add(line);
                        sbLine.Clear();
                        stopReceived = stopCond.CheckCondition(lines, line);
                    }
                }

                logText = BuildReadLinesLogText(lines);

                if (lines.Count > 0)
                {
                    UpdateActivityTime();
                }

                return(lines);
            }
            catch (Exception ex)
            {
                throw new ScadaException(CommPhrases.ReadLinesError + ": " + ex.Message, ex);
            }
        }
        public void StringBuilderExtensionEndsWith_OnCase_ReturnsTrue(string sbText, string test) {
            // given
            StringBuilder sb = new StringBuilder(sbText);

            // when
            bool result = sb.EndsWith(test);

            // then
            Assert.IsTrue(result);
        }
        public void EndsWith_ContainsNonAsciiCharacters()
        {
            StringBuilder builder = new StringBuilder();

            builder.Append("\u3041\u3042\u3043\u3044");
            string endString = "\u3043\u3044";
            bool   endsWith  = builder.EndsWith(endString);

            Assert.IsTrue(endsWith);
        }
Example #31
0
        public static StringBuilder RemoveEnd(this StringBuilder str, string end)
        {
            str.ThrowIfNullArgument(nameof(str));
            end.ThrowIfNullArgument(nameof(end));

            if (str.EndsWith(end))
            {
                str.Remove(str.Length - end.Length, end.Length);
            }
            return(str);
        }
Example #32
0
 public static StringBuilder AppendWithNewLine(
     this StringBuilder scriptCode,
     String Script)
 {
     if (scriptCode.Length > 0 && !scriptCode.EndsWith(Environment.NewLine))
     {
         scriptCode.Append(Environment.NewLine);
     }
     scriptCode.Append(Script);
     return(scriptCode);
 }
 /// <summary>
 /// 从当前 StringBuilder 对象移除数组中指定的一组字符的所有尾部匹配项。
 /// </summary>
 /// <param name="builder">StringBuilder的引用</param>
 /// <param name="trimStr">要移除的 Unicode 字符数组或 null。</param>
 /// <param name="stringComparison">方法的某些重载要使用的区域、大小写和排序规则。</param>
 /// <returns>返回移除尾部数据后的项</returns>
 /// <example>
 /// <code lang="c#">
 /// <![CDATA[
 ///     StringBuilder strB=new StringBuilder("中国浙江杭州");
 ///     StringBuilder ret=strB.TrimEnd("杭州"); //返回:"中国浙江"
 /// ]]>
 /// </code>
 /// </example>
 public static StringBuilder TrimEnd(this StringBuilder builder, string trimStr, StringComparison stringComparison = StringComparison.Ordinal)
 {
     if (string.IsNullOrEmpty(trimStr))
     {
         return(builder);
     }
     while (builder.EndsWith(trimStr, stringComparison))
     {
         builder = builder.Remove(builder.Length - trimStr.Length, trimStr.Length);
     }
     return(builder);
 }
        public void StringBuilderExtensionEndsWith_ThrowsArgumentNullException_OnNullArg() {
            // given
            StringBuilder sb = new StringBuilder();

            // when
            ArgumentNullException exception =
                Assert.Throws<ArgumentNullException>(() =>
                    sb.EndsWith(null));

            // then
            Assert.That(() => exception.ParamName, Is.EqualTo("text"));
        }
Example #35
0
        public void FixCasing(List<string> namesEtc, bool changeNameCases, bool makeUppercaseAfterBreak, bool checkLastLine, string lastLine)
        {
            var replaceIds = new List<string>();
            var replaceNames = new List<string>();
            var originalNames = new List<string>();
            ReplaceNames1Remove(namesEtc, replaceIds, replaceNames, originalNames);

            if (checkLastLine)
            {
                string s = Utilities.RemoveHtmlTags(lastLine).TrimEnd().TrimEnd('\"').TrimEnd();

                bool startWithUppercase = string.IsNullOrEmpty(s) ||
                                          s.EndsWith('.') ||
                                          s.EndsWith('!') ||
                                          s.EndsWith('?') ||
                                          s.EndsWith(". ♪", StringComparison.Ordinal) ||
                                          s.EndsWith("! ♪", StringComparison.Ordinal) ||
                                          s.EndsWith("? ♪", StringComparison.Ordinal) ||
                                          s.EndsWith(']') ||
                                          s.EndsWith(')') ||
                                          s.EndsWith(':');

                // start with uppercase after music symbol - but only if next line does not start with music symbol
                if (!startWithUppercase && (s.EndsWith('♪') || s.EndsWith('♫')))
                {
                    if (!Pre.Contains('♪') && !Pre.Contains('♫'))
                        startWithUppercase = true;
                }

                if (startWithUppercase && StrippedText.Length > 0 && !Pre.Contains("..."))
                {
                    StrippedText = StrippedText.Remove(0, 1).Insert(0, StrippedText[0].ToString().ToUpper());
                }
            }

            if (makeUppercaseAfterBreak &&
                (StrippedText.Contains('.') ||
                StrippedText.Contains('!') ||
                StrippedText.Contains('?') ||
                StrippedText.Contains(':') ||
                StrippedText.Contains(';') ||
                StrippedText.Contains(')') ||
                StrippedText.Contains(']') ||
                StrippedText.Contains('}') ||
                StrippedText.Contains('(') ||
                StrippedText.Contains('[') ||
                StrippedText.Contains('{')))
            {
                var sb = new StringBuilder();
                bool lastWasBreak = false;
                for (int i = 0; i < StrippedText.Length; i++)
                {
                    string s = StrippedText[i].ToString();
                    if (lastWasBreak)
                    {
                        if (("\"`´'()<>!?.- " + Environment.NewLine).Contains(s))
                        {
                            sb.Append(s);
                        }
                        else if ((sb.EndsWith('<') || sb.ToString().EndsWith("</", StringComparison.Ordinal)) && i + 1 < StrippedText.Length && StrippedText[i + 1] == '>')
                        { // tags
                            sb.Append(s);
                        }
                        else if (sb.EndsWith('<') && s == "/" && i + 2 < StrippedText.Length && StrippedText[i + 2] == '>')
                        { // tags
                            sb.Append(s);
                        }
                        else if (sb.ToString().EndsWith("... ", StringComparison.Ordinal))
                        {
                            sb.Append(s);
                            lastWasBreak = false;
                        }
                        else
                        {
                            if (".!?:;)]}([{".Contains(s))
                            {
                                sb.Append(s);
                            }
                            else
                            {
                                lastWasBreak = false;
                                sb.Append(s.ToUpper());
                            }
                        }
                    }
                    else
                    {
                        sb.Append(s);
                        if (".!?:;)]}([{".Contains(s))
                        {
                            if (s == "]" && sb.ToString().IndexOf('[') > 1)
                            { // I [Motor roaring] love you!
                                string temp = sb.ToString().Substring(0, sb.ToString().IndexOf('[') - 1).Trim();
                                if (temp.Length > 0 && !Utilities.LowercaseLetters.Contains(temp[temp.Length - 1].ToString()))
                                    lastWasBreak = true;
                            }
                            else
                            {
                                lastWasBreak = true;
                            }
                        }
                    }
                }
                StrippedText = sb.ToString();
            }

            if (changeNameCases)
                ReplaceNames2Fix(replaceIds, replaceNames);
            else
                ReplaceNames2Fix(replaceIds, originalNames);
        }
Example #36
0
        /// <summary>
        /// Extracts a collection of field values from the supplied text record.
        /// </summary>
        /// <param name="line">The text record to extract field values from.</param>
        /// <param name="context">The current parser context.</param>
        /// <returns>A collection of string values corresponding to the fields in the file definition.</returns>
        public IEnumerable<string> ReadValues(string line, ParserContext context)
        {
            _parseStrategy.Reset();

            var value = new StringBuilder(line);
            for( int ix = 0; ix < line.Length; ix++ ) {
                char current = line[ix];
                char? next = ix == line.Length - 1 ? default(char?) : line[ix + 1];

                if( _parseStrategy.IncludeChar(current, next) ) {
                    value.Append(current);

                    if( ! _parseStrategy.Escaped && value.EndsWith(_fieldDelimiter) ) {
                        value.Length -= _fieldDelimiter.Length;
                        yield return value.ToString();
                        value.Length = 0;
                    }
                }
            }
            yield return value.ToString();
        }
Example #37
0
        private Bitmap GenerateImageFromTextWithStyle(string text)
        {
            const bool subtitleFontBold = false;
            bool subtitleAlignLeft = comboBoxHAlign.SelectedIndex == 0;

            // remove styles for display text (except italic)
            text = RemoveSubStationAlphaFormatting(text);
            text = text.Replace("<b>", string.Empty);
            text = text.Replace("</b>", string.Empty);
            text = text.Replace("<B>", string.Empty);
            text = text.Replace("</B>", string.Empty);
            text = text.Replace("<u>", string.Empty);
            text = text.Replace("</u>", string.Empty);
            text = text.Replace("<U>", string.Empty);
            text = text.Replace("</U>", string.Empty);

            Font font;
            try
            {
                font = new Font(_subtitleFontName, _subtitleFontSize, FontStyle.Regular);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
                font = new Font(FontFamily.Families[0].Name, _subtitleFontSize);
            }
            var bmp = new Bitmap(400, 200);
            var g = Graphics.FromImage(bmp);

            SizeF textSize = g.MeasureString("Hj!", font);
            var lineHeight = (textSize.Height * 0.64f);

            textSize = g.MeasureString(HtmlUtil.RemoveHtmlTags(text), font);
            g.Dispose();
            bmp.Dispose();
            int sizeX = (int)(textSize.Width * 0.8) + 40;
            int sizeY = (int)(textSize.Height * 0.8) + 30;
            if (sizeX < 1)
                sizeX = 1;
            if (sizeY < 1)
                sizeY = 1;
            bmp = new Bitmap(sizeX, sizeY);
            g = Graphics.FromImage(bmp);

            var lefts = new List<float>();
            foreach (var line in HtmlUtil.RemoveOpenCloseTags(text, HtmlUtil.TagItalic, HtmlUtil.TagFont).SplitToLines())
            {
                if (subtitleAlignLeft)
                    lefts.Add(5);
                else
                    lefts.Add((float)(bmp.Width - g.MeasureString(line, font).Width * 0.8 + 15) / 2);
            }

            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.CompositingQuality = CompositingQuality.HighQuality;

            var sf = new StringFormat();
            sf.Alignment = StringAlignment.Near;
            sf.LineAlignment = StringAlignment.Near;// draw the text to a path
            var path = new GraphicsPath();

            // display italic
            var sb = new StringBuilder();
            int i = 0;
            bool isItalic = false;
            float left = 5;
            if (lefts.Count > 0)
                left = lefts[0];
            float top = 5;
            bool newLine = false;
            int lineNumber = 0;
            float leftMargin = left;
            bool italicFromStart = false;
            int newLinePathPoint = -1;
            Color c = _subtitleColor;
            var colorStack = new Stack<Color>();
            var lastText = new StringBuilder();
            while (i < text.Length)
            {
                if (text.Substring(i).StartsWith("<font ", StringComparison.OrdinalIgnoreCase))
                {
                    float addLeft = 0;
                    int oldPathPointIndex = path.PointCount;
                    if (oldPathPointIndex < 0)
                        oldPathPointIndex = 0;

                    if (sb.Length > 0)
                    {
                        TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                    }
                    if (path.PointCount > 0)
                    {
                        PointF[] list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
                        for (int k = oldPathPointIndex; k < list.Length; k++)
                        {
                            if (list[k].X > addLeft)
                                addLeft = list[k].X;
                        }
                    }
                    if (addLeft == 0)
                        addLeft = left + 2;
                    left = addLeft;

                    if (_borderWidth > 0)
                        g.DrawPath(new Pen(_borderColor, _borderWidth), path);
                    g.FillPath(new SolidBrush(c), path);
                    path.Reset();
                    path = new GraphicsPath();
                    sb = new StringBuilder();

                    int endIndex = text.Substring(i).IndexOf('>');
                    if (endIndex < 0)
                    {
                        i += 9999;
                    }
                    else
                    {
                        string fontContent = text.Substring(i, endIndex);
                        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('\'');
                                try
                                {
                                    colorStack.Push(c); // save old color
                                    if (fontColor.StartsWith("rgb("))
                                    {
                                        arr = fontColor.Remove(0, 4).TrimEnd(')').Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                        c = Color.FromArgb(int.Parse(arr[0]), int.Parse(arr[1]), int.Parse(arr[2]));
                                    }
                                    else
                                    {
                                        c = ColorTranslator.FromHtml(fontColor);
                                    }
                                }
                                catch
                                {
                                    c = _subtitleColor;
                                }
                            }
                        }
                        i += endIndex;
                    }
                }
                else if (text.Substring(i).StartsWith("</font>", StringComparison.OrdinalIgnoreCase))
                {
                    if (text.Substring(i).ToLower().Replace("</font>", string.Empty).Length > 0)
                    {
                        if (lastText.EndsWith(' ') && !sb.StartsWith(' '))
                        {
                            string t = sb.ToString();
                            sb.Clear();
                            sb.Append(' ');
                            sb.Append(t);
                        }

                        float addLeft = 0;
                        int oldPathPointIndex = path.PointCount - 1;
                        if (oldPathPointIndex < 0)
                            oldPathPointIndex = 0;
                        if (sb.Length > 0)
                        {
                            TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                        }
                        if (path.PointCount > 0)
                        {
                            PointF[] list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
                            for (int k = oldPathPointIndex; k < list.Length; k++)
                            {
                                if (list[k].X > addLeft)
                                    addLeft = list[k].X;
                            }
                        }
                        if (addLeft == 0)
                            addLeft = left + 2;
                        left = addLeft;

                        if (_borderWidth > 0)
                            g.DrawPath(new Pen(_borderColor, _borderWidth), path);
                        g.FillPath(new SolidBrush(c), path);
                        path.Reset();
                        //path = new GraphicsPath();
                        sb = new StringBuilder();
                        if (colorStack.Count > 0)
                            c = colorStack.Pop();
                    }
                    i += 6;
                }
                else if (text.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase))
                {
                    italicFromStart = i == 0;
                    if (sb.Length > 0)
                    {
                        TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                    }
                    isItalic = true;
                    i += 2;
                }
                else if (text.Substring(i).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) && isItalic)
                {
                    if (lastText.EndsWith(' ') && !sb.StartsWith(' '))
                    {
                        string t = sb.ToString();
                        sb.Clear();
                        sb.Append(' ');
                        sb.Append(t);
                    }
                    TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                    isItalic = false;
                    i += 3;
                }
                else if (text.Substring(i).StartsWith(Environment.NewLine))
                {
                    TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);

                    top += lineHeight;
                    newLine = true;
                    i += Environment.NewLine.Length - 1;
                    lineNumber++;
                    if (lineNumber < lefts.Count)
                    {
                        leftMargin = lefts[lineNumber];
                        left = leftMargin;
                    }
                    if (isItalic)
                        italicFromStart = true;
                }
                else
                {
                    sb.Append(text[i]);
                }
                i++;
            }
            if (sb.Length > 0)
                TextDraw.DrawText(font, sf, path, sb, isItalic, subtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
            sf.Dispose();

            if (_borderWidth > 0)
                g.DrawPath(new Pen(_borderColor, _borderWidth), path);
            g.FillPath(new SolidBrush(c), path);
            g.Dispose();
            var nbmp = new NikseBitmap(bmp);
            nbmp.CropTransparentSidesAndBottom(2, true);
            return nbmp.GetBitmap();
        }
Example #38
0
		/// <summary>
		/// Returns an enumerator that iterates through the collection.
		/// </summary>
		/// <returns>
		/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
		/// </returns>
		/// <filterpriority>1</filterpriority>
		public IEnumerator<IPropertyBag> GetEnumerator()
		{
			// make sure this object is not disposed yet
			CheckDisposed();

			// create a buffer
			var buffer = new StringBuilder();

			// read until end of line or end of file
			var inTextQualifier = false;
			var firstLineRead = false;
			var row = new PropertyBag();
			var cellIndex = 0;
			var headerList = new List<string>();
			while (true)
			{
				// read the current character
				var currentCharacter = input.Reader.Read();

				// check for end of line
				if (currentCharacter == -1)
					yield break;

				// append the character
				buffer.Append((char) currentCharacter);

				// check for text qualifier
				if (buffer.EndsWith(format.TextQualifier))
				{
					// eat the text qualifier
					buffer.Length -= format.TextQualifier.Length;

					// toggle the flag
					inTextQualifier = !inTextQualifier;
				}
				else if (inTextQualifier)
					continue;

				// check for column delimitor
				if (buffer.EndsWith(format.ColumnDelimitor))
				{
					// eat the column delimitor
					buffer.Length -= format.ColumnDelimitor.Length;

					// get the read value
					var value = buffer.ToString();

					// if the first line is read, store the value in the row property bag
					if (firstLineRead)
						row.Set(headerList[cellIndex], value);
					else
					{
						// if the first line contains the header, the value contains a column name, otherwise store the value in the row property bag
						if (firstLineIsHeader)
							headerList.Add(value);
						else
						{
							// add a header to the list and store the value
							headerList.Add(cellIndex.ToString(CultureInfo.InvariantCulture));
							row.Set(headerList[cellIndex], value);
						}
					}

					// reset the buffer
					buffer.Length = 0;

					// increment the cell index
					cellIndex++;

					// keep reading
					continue;
				}

				// check for row delimitor
				if (buffer.EndsWith(format.RowDelimitor))
				{
					// eat the row delimitor
					buffer.Length -= format.RowDelimitor.Length;

					// get the read value
					var value = buffer.ToString();
					buffer.Length = 0;

					// set the value
					if (!firstLineRead)
					{
						firstLineRead = true;
						// if the first line contains the header, store the header value
						if (firstLineIsHeader)
						{
							headerList.Add(value);
							cellIndex = 0;
							continue;
						}

						// add header based on cell index
						headerList.Add(cellIndex.ToString(CultureInfo.InvariantCulture));
					}

					// store the value
					row.Set(headerList[cellIndex], value);

					// return the result
					yield return row;

					// reset
					row = new PropertyBag();
					cellIndex = 0;
				}
			}
		}
Example #39
0
        public void FixCasing(List<string> namesEtc, bool changeNameCases, bool makeUppercaseAfterBreak, bool checkLastLine, string lastLine)
        {
            var replaceIds = new List<string>();
            var replaceNames = new List<string>();
            var originalNames = new List<string>();
            ReplaceNames1Remove(namesEtc, replaceIds, replaceNames, originalNames);

            if (checkLastLine)
            {
                string s = HtmlUtil.RemoveHtmlTags(lastLine).TrimEnd().TrimEnd('\"').TrimEnd();

                bool startWithUppercase = string.IsNullOrEmpty(s) ||
                                          s.EndsWith('.') ||
                                          s.EndsWith('!') ||
                                          s.EndsWith('?') ||
                                          s.EndsWith(". ♪", StringComparison.Ordinal) ||
                                          s.EndsWith("! ♪", StringComparison.Ordinal) ||
                                          s.EndsWith("? ♪", StringComparison.Ordinal) ||
                                          s.EndsWith(']') ||
                                          s.EndsWith(')') ||
                                          s.EndsWith(':');

                // start with uppercase after music symbol - but only if next line does not start with music symbol
                if (!startWithUppercase && (s.EndsWith('♪') || s.EndsWith('♫')))
                {
                    if (!Pre.Contains(new[] { '♪', '♫' }))
                        startWithUppercase = true;
                }

                if (startWithUppercase && StrippedText.Length > 0 && !Pre.Contains("..."))
                {
                    StrippedText = char.ToUpper(StrippedText[0]) + StrippedText.Substring(1);
                }
            }

            if (makeUppercaseAfterBreak && StrippedText.Contains(ExpectedCharsArray))
            {
                const string breakAfterChars = @".!?:;)]}([{";
                const string expectedChars = "\"`´'()<>!?.- \r\n";
                var sb = new StringBuilder();
                bool lastWasBreak = false;
                for (int i = 0; i < StrippedText.Length; i++)
                {
                    var s = StrippedText[i];
                    if (lastWasBreak)
                    {
                        if (expectedChars.Contains(s))
                        {
                            sb.Append(s);
                        }
                        else if ((sb.EndsWith('<') || sb.ToString().EndsWith("</", StringComparison.Ordinal)) && i + 1 < StrippedText.Length && StrippedText[i + 1] == '>')
                        { // tags
                            sb.Append(s);
                        }
                        else if (sb.EndsWith('<') && s == '/' && i + 2 < StrippedText.Length && StrippedText[i + 2] == '>')
                        { // tags
                            sb.Append(s);
                        }
                        else if (sb.ToString().EndsWith("... ", StringComparison.Ordinal))
                        {
                            sb.Append(s);
                            lastWasBreak = false;
                        }
                        else
                        {
                            if (breakAfterChars.Contains(s))
                            {
                                sb.Append(s);
                            }
                            else
                            {
                                lastWasBreak = false;
                                sb.Append(char.ToUpper(s));
                            }
                        }
                    }
                    else
                    {
                        sb.Append(s);
                        if (breakAfterChars.Contains(s))
                        {
                            var idx = sb.ToString().IndexOf('[');
                            if (s == ']' && idx > 1)
                            { // I [Motor roaring] love you!
                                string temp = sb.ToString(0, idx - 1).Trim();
                                if (temp.Length > 0 && !char.IsLower(temp[temp.Length - 1]))
                                    lastWasBreak = true;
                            }
                            else
                            {
                                lastWasBreak = true;
                            }
                        }
                    }
                }
                StrippedText = sb.ToString();
            }

            ReplaceNames2Fix(replaceIds, changeNameCases ? replaceNames : originalNames);
        }
Example #40
0
        public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
        {
            subtitle.Paragraphs.Clear();
            subtitle.Header = null;
            byte[] buffer = FileUtil.ReadAllBytesShared(fileName);

            int i = 512;
            Paragraph last = null;
            while (i < buffer.Length - 25)
            {
                var p = new Paragraph();
                int length = buffer[i + 1];

                p.StartTime = DecodeTimestamp(buffer, i + 3);
                if (last != null && last.EndTime.TotalMilliseconds == 0)
                    last.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds - 1;

                if (length > 22)
                {
                    int start = i + 7;
                    var sb = new StringBuilder();
                    int skipCount = 0;
                    bool italics = false;
                    //bool font = false;
                    for (int k = start; k < length + i; k++)
                    {
                        byte b = buffer[k];
                        if (skipCount > 0)
                        {
                            skipCount--;
                        }
                        else if (b < 0x1F)
                        {
                            byte b2 = buffer[k + 1];
                            skipCount = 1;
                            if (sb.Length > 0 && !sb.ToString().EndsWith(Environment.NewLine) && !sb.EndsWith('>'))
                            {
                                //if (font)
                                //    sb.Append("</font>");
                                if (italics)
                                    sb.Append("</i>");
                                sb.AppendLine();
                                //font = false;
                                italics = false;
                            }
                            //string code = VobSub.Helper.IntToBin(buffer[k] * 256 + buffer[k+1], 16);
                            //var codeBytes = new List<char>();
                            //if (b == 0x11 && b2 == 0x28)
                            //{
                            //    sb.Append("<font color=\"red\">");
                            //    font = true;
                            //}
                            //else

                            if (b == 0x11 && b2 == 0x2e)
                            {
                                sb.Append("<i>");
                                italics = true;
                            }

                            //foreach (char ch in code)
                            //    codeBytes.Insert(0, ch);
                            //if (codeBytes[13] == '0' && codeBytes[14] == '0' && codeBytes[12] == '1' && codeBytes[6] == '1')
                            //{ // preamble address code
                            //    if (code.Substring(11, 4) == "1000")
                            //    {
                            //        sb.Append("<font color=\"green\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0010")
                            //    {
                            //        sb.Append("<font color=\"blue\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0011")
                            //    {
                            //        sb.Append("<font color=\"cyan\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0100")
                            //    {
                            //        sb.Append("<font color=\"red\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0101")
                            //    {
                            //        sb.Append("<font color=\"yellow\">");
                            //        font = true;
                            //    }
                            //    //else if (code.Substring(11, 4) == "0110")
                            //    //{
                            //    //    sb.Append("<font color=\"magenta\">");
                            //    //    font = true;
                            //    //}
                            //}
                            //else if (codeBytes[14] == '0' && codeBytes[13] == '0' && codeBytes[10] == '0' && codeBytes[9] == '0' && codeBytes[6] == '0' &&
                            //         codeBytes[12] == '1' && codeBytes[8] == '1' && codeBytes[6] == '1')
                            //{ // midrow code

                            //    if (code.Substring(11, 4) == "1000")
                            //    {
                            //        sb.Append("<font color=\"green\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0010")
                            //    {
                            //        sb.Append("<font color=\"blue\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0011")
                            //    {
                            //        sb.Append("<font color=\"cyan\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0100")
                            //    {
                            //        sb.Append("<font color=\"red\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0101")
                            //    {
                            //        sb.Append("<font color=\"yellow\">");
                            //        font = true;
                            //    }
                            //    //else if (code.Substring(11, 4) == "0110")
                            //    //{
                            //    //    sb.Append("<font color=\"magenta\">");
                            //    //    font = true;
                            //    //}
                            //}
                            //else if ((codeBytes[14] == '0' && codeBytes[13] == '0' && codeBytes[9] == '0' && codeBytes[6] == '0' && codeBytes[4] == '0' &&
                            //         codeBytes[12] == '1' && codeBytes[10] == '1' && codeBytes[5] == '1') || b == 0x11)
                            //{ // codeBytes[10]  == 0 ???
                            //    //control codes
                            //    if (code.Substring(11, 4) == "0111" && buffer[k] == 0x11)
                            //    {
                            //        sb.Append("<i>");
                            //        italics = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "1000")
                            //    {
                            //        sb.Append("<font color=\"green\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0010")
                            //    {
                            //        sb.Append("<font color=\"blue\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0011")
                            //    {
                            //        sb.Append("<font color=\"cyan\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0100")
                            //    {
                            //        sb.Append("<font color=\"red\">");
                            //        font = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0101")
                            //    {
                            //        sb.Append("<font color=\"yellow\">");
                            //        font = true;
                            //    }
                            //    //else if (code.Substring(11, 4) == "0110")
                            //    //{
                            //    //    sb.Append("<font color=\"magenta\">");
                            //    //    font = true;
                            //    //}
                            //}
                            //else
                            //{
                            //    if (code.Substring(11, 4) == "0111" && buffer[k] == 0x11)
                            //    {
                            //        sb.Append("<i>");
                            //        italics = true;
                            //    }
                            //    else if (code.Substring(11, 4) == "0101" && b == 0x11)
                            //    {
                            //        sb.Append("<font color=\"yellow\">");
                            //        font = true;
                            //    }
                            ////    if (code.Substring(11, 4) == "0111")
                            ////    {
                            ////        //System.Windows.Forms.MessageBox.Show(code);
                            ////        sb.Append("<i>");
                            ////    }
                            ////    else if (code.Substring(11, 4) == "0101")
                            ////        sb.Append("<font color=\"yellow\">");
                            //}
                        }
                        else if (b == 0x80)
                        {
                            //if (sb.Length == 0)
                            //    break;

                            //if (sb.Length > 0 && !sb.ToString().EndsWith(Environment.NewLine))
                            //{
                            //    if (font)
                            //        sb.Append("</font>");
                            //    if (italics)
                            //        sb.Append("</i>");
                            //    sb.AppendLine();
                            //    font = false;
                            //    italics = false;
                            //}
                        }
                        else
                        {
                            sb.Append(Encoding.GetEncoding(1252).GetString(buffer, k, 1));
                        }
                    }
                    p.Text = sb.ToString().Trim();
                    //if (font)
                    //    p.Text += "</font>";
                    if (italics)
                        p.Text += "</i>";
                    p.Text = p.Text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
                    p.Text = p.Text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
                    p.Text = p.Text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
                    subtitle.Paragraphs.Add(p);
                }
                else if (last != null)
                {
                    last.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds;
                }
                last = p;

                i += length + 3;
            }
            if (last != null)
            {
                if (last.EndTime.TotalMilliseconds == 0)
                    last.EndTime.TotalMilliseconds = last.StartTime.TotalMilliseconds + 2500;
                if (last.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
                    last.EndTime.TotalMilliseconds = last.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(last.Text);
            }

            subtitle.Renumber();
        }
        /// <summary>
        /// The calc width via draw.
        /// </summary>
        /// <param name="text">
        /// The text.
        /// </param>
        /// <param name="parameter">
        /// The parameter.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        private static int CalcWidthViaDraw(string text, MakeBitmapParameter parameter)
        {
            // text = HtmlUtil.RemoveHtmlTags(text, true).Trim();
            text = text.Trim();
            var path = new GraphicsPath();
            var sb = new StringBuilder();
            int i = 0;
            bool isItalic = false;
            bool isBold = parameter.SubtitleFontBold;
            const float top = 5f;
            bool newLine = false;
            float left = 1.0f;
            float leftMargin = left;
            int newLinePathPoint = -1;
            Color c = parameter.SubtitleColor;
            var colorStack = new Stack<Color>();
            var lastText = new StringBuilder();
            var sf = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Near };
            var bmp = new Bitmap(parameter.ScreenWidth, 200);
            var g = Graphics.FromImage(bmp);

            g.CompositingQuality = CompositingQuality.HighSpeed;
            g.SmoothingMode = SmoothingMode.HighSpeed;
            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

            Font font = SetFont(parameter, parameter.SubtitleFontSize);
            while (i < text.Length)
            {
                if (text.Substring(i).StartsWith("<font ", StringComparison.OrdinalIgnoreCase))
                {
                    float addLeft = 0;
                    int oldPathPointIndex = path.PointCount;
                    if (oldPathPointIndex < 0)
                    {
                        oldPathPointIndex = 0;
                    }

                    if (sb.Length > 0)
                    {
                        lastText.Append(sb);
                        TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                    }

                    if (path.PointCount > 0)
                    {
                        var list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
                        for (int k = oldPathPointIndex; k < list.Length; k++)
                        {
                            if (list[k].X > addLeft)
                            {
                                addLeft = list[k].X;
                            }
                        }
                    }

                    if (path.PointCount == 0)
                    {
                        addLeft = left;
                    }
                    else if (addLeft < 0.01)
                    {
                        addLeft = left + 2;
                    }

                    left = addLeft;

                    DrawShadowAndPath(parameter, g, path);
                    var p2 = new SolidBrush(c);
                    g.FillPath(p2, path);
                    p2.Dispose();
                    path.Reset();
                    path = new GraphicsPath();
                    sb = new StringBuilder();

                    int endIndex = text.Substring(i).IndexOf('>');
                    if (endIndex < 0)
                    {
                        i += 9999;
                    }
                    else
                    {
                        string fontContent = text.Substring(i, endIndex);
                        if (fontContent.Contains(" color="))
                        {
                            string[] 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('\'');
                                try
                                {
                                    colorStack.Push(c); // save old color
                                    if (fontColor.StartsWith("rgb("))
                                    {
                                        arr = fontColor.Remove(0, 4).TrimEnd(')').Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                        c = Color.FromArgb(int.Parse(arr[0]), int.Parse(arr[1]), int.Parse(arr[2]));
                                    }
                                    else
                                    {
                                        c = ColorTranslator.FromHtml(fontColor);
                                    }
                                }
                                catch
                                {
                                    c = parameter.SubtitleColor;
                                }
                            }
                        }

                        i += endIndex;
                    }
                }
                else if (text.Substring(i).StartsWith("</font>", StringComparison.OrdinalIgnoreCase))
                {
                    if (text.Substring(i).ToLower().Replace("</font>", string.Empty).Length > 0)
                    {
                        if (lastText.EndsWith(' ') && !sb.StartsWith(' '))
                        {
                            string t = sb.ToString();
                            sb.Clear();
                            sb.Append(' ');
                            sb.Append(t);
                        }

                        float addLeft = 0;
                        int oldPathPointIndex = path.PointCount - 1;
                        if (oldPathPointIndex < 0)
                        {
                            oldPathPointIndex = 0;
                        }

                        if (sb.Length > 0)
                        {
                            if (lastText.Length > 0 && left > 2)
                            {
                                left -= 1.5f;
                            }

                            lastText.Append(sb);

                            TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                        }

                        if (path.PointCount > 0)
                        {
                            var list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
                            for (int k = oldPathPointIndex; k < list.Length; k++)
                            {
                                if (list[k].X > addLeft)
                                {
                                    addLeft = list[k].X;
                                }
                            }
                        }

                        if (addLeft < 0.01)
                        {
                            addLeft = left + 2;
                        }

                        left = addLeft;

                        DrawShadowAndPath(parameter, g, path);
                        g.FillPath(new SolidBrush(c), path);
                        path.Reset();
                        sb = new StringBuilder();
                        if (colorStack.Count > 0)
                        {
                            c = colorStack.Pop();
                        }

                        if (left >= 3)
                        {
                            left -= 2.5f;
                        }
                    }

                    i += 6;
                }
                else if (text.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase))
                {
                    if (sb.Length > 0)
                    {
                        lastText.Append(sb);
                        TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                    }

                    isItalic = true;
                    i += 2;
                }
                else if (text.Substring(i).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) && isItalic)
                {
                    if (lastText.EndsWith(' ') && !sb.StartsWith(' '))
                    {
                        string t = sb.ToString();
                        sb.Clear();
                        sb.Append(' ');
                        sb.Append(t);
                    }

                    lastText.Append(sb);
                    TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                    isItalic = false;
                    i += 3;
                }
                else if (text.Substring(i).StartsWith("<b>", StringComparison.OrdinalIgnoreCase))
                {
                    if (sb.Length > 0)
                    {
                        lastText.Append(sb);
                        TextDraw.DrawText(font, sf, path, sb, isItalic, isBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                    }

                    isBold = true;
                    i += 2;
                }
                else if (text.Substring(i).StartsWith("</b>", StringComparison.OrdinalIgnoreCase) && isBold)
                {
                    if (lastText.EndsWith(' ') && !sb.StartsWith(' '))
                    {
                        string t = sb.ToString();
                        sb.Clear();
                        sb.Append(' ');
                        sb.Append(t);
                    }

                    lastText.Append(sb);
                    TextDraw.DrawText(font, sf, path, sb, isItalic, isBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                    isBold = false;
                    i += 3;
                }
                else
                {
                    sb.Append(text[i]);
                }

                i++;
            }

            if (sb.Length > 0)
            {
                TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
            }

            DrawShadowAndPath(parameter, g, path);
            g.FillPath(new SolidBrush(c), path);
            g.Dispose();

            var nbmp = new NikseBitmap(bmp);
            nbmp.CropTransparentSidesAndBottom(0, true);
            bmp.Dispose();
            font.Dispose();
            sf.Dispose();
            return nbmp.Width;
        }
        /// <summary>
        /// The generate image from text with style inner.
        /// </summary>
        /// <param name="parameter">
        /// The parameter.
        /// </param>
        /// <returns>
        /// The <see cref="Bitmap"/>.
        /// </returns>
        private static Bitmap GenerateImageFromTextWithStyleInner(MakeBitmapParameter parameter)
        {
            string text = parameter.P.Text;

            text = RemoveSubStationAlphaFormatting(text);

            text = text.Replace("<I>", "<i>");
            text = text.Replace("</I>", "</i>");
            text = HtmlUtil.FixInvalidItalicTags(text);

            text = text.Replace("<B>", "<b>");
            text = text.Replace("</B>", "</b>");

            // no support for underline
            text = HtmlUtil.RemoveOpenCloseTags(text, HtmlUtil.TagUnderline);

            Font font = null;
            Bitmap bmp = null;
            try
            {
                font = SetFont(parameter, parameter.SubtitleFontSize);
                var lineHeight = parameter.LineHeight; // (textSize.Height * 0.64f);

                SizeF textSize;
                using (var bmpTemp = new Bitmap(1, 1))
                using (var g = Graphics.FromImage(bmpTemp))
                {
                    textSize = g.MeasureString(HtmlUtil.RemoveHtmlTags(text), font);
                }

                int sizeX = (int)(textSize.Width * 1.8) + 150;
                int sizeY = (int)(textSize.Height * 0.9) + 50;
                if (sizeX < 1)
                {
                    sizeX = 1;
                }

                if (sizeY < 1)
                {
                    sizeY = 1;
                }

                if (parameter.BackgroundColor != Color.Transparent)
                {
                    var nbmpTemp = new NikseBitmap(sizeX, sizeY);
                    nbmpTemp.Fill(parameter.BackgroundColor);
                    bmp = nbmpTemp.GetBitmap();
                }
                else
                {
                    bmp = new Bitmap(sizeX, sizeY);
                }

                // align lines with gjpqy, a bit lower
                var lines = text.SplitToLines();
                int baseLinePadding = 13;
                if (parameter.SubtitleFontSize < 30)
                {
                    baseLinePadding = 12;
                }

                if (parameter.SubtitleFontSize < 25)
                {
                    baseLinePadding = 9;
                }

                if (lines.Length > 0)
                {
                    var lastLine = lines[lines.Length - 1];
                    if (lastLine.Contains(new[] { 'g', 'j', 'p', 'q', 'y', ',', 'ý', 'ę', 'ç', 'Ç' }))
                    {
                        var textNoBelow = lastLine.Replace('g', 'a').Replace('j', 'a').Replace('p', 'a').Replace('q', 'a').Replace('y', 'a').Replace(',', 'a').Replace('ý', 'a').Replace('ę', 'a').Replace('ç', 'a').Replace('Ç', 'a');
                        baseLinePadding -= (int)Math.Round(TextDraw.MeasureTextHeight(font, lastLine, parameter.SubtitleFontBold) - TextDraw.MeasureTextHeight(font, textNoBelow, parameter.SubtitleFontBold));
                    }
                    else
                    {
                        baseLinePadding += 1;
                    }

                    if (baseLinePadding < 0)
                    {
                        baseLinePadding = 0;
                    }
                }

                // TODO: Better baseline - test http://bobpowell.net/formattingtext.aspx
                // float baselineOffset=font.SizeInPoints/font.FontFamily.GetEmHeight(font.Style)*font.FontFamily.GetCellAscent(font.Style);
                // float baselineOffsetPixels = g.DpiY/72f*baselineOffset;
                // baseLinePadding = (int)Math.Round(baselineOffsetPixels);
                var lefts = new List<float>();
                if (text.Contains("<font", StringComparison.OrdinalIgnoreCase) || text.Contains("<i>", StringComparison.OrdinalIgnoreCase))
                {
                    foreach (string line in text.SplitToLines())
                    {
                        var lineNoHtml = HtmlUtil.RemoveOpenCloseTags(line, HtmlUtil.TagItalic, HtmlUtil.TagFont);
                        if (parameter.AlignLeft)
                        {
                            lefts.Add(5);
                        }
                        else if (parameter.AlignRight)
                        {
                            lefts.Add(bmp.Width - CalcWidthViaDraw(lineNoHtml, parameter) - 15); // calculate via drawing+crop
                        }
                        else
                        {
                            lefts.Add((float)((bmp.Width - CalcWidthViaDraw(lineNoHtml, parameter) + 5.0) / 2.0)); // calculate via drawing+crop
                        }
                    }
                }
                else
                {
                    foreach (var line in HtmlUtil.RemoveOpenCloseTags(text, HtmlUtil.TagItalic, HtmlUtil.TagFont).SplitToLines())
                    {
                        if (parameter.AlignLeft)
                        {
                            lefts.Add(5);
                        }
                        else if (parameter.AlignRight)
                        {
                            lefts.Add(bmp.Width - (TextDraw.MeasureTextWidth(font, line, parameter.SubtitleFontBold) + 15));
                        }
                        else
                        {
                            lefts.Add((float)((bmp.Width - TextDraw.MeasureTextWidth(font, line, parameter.SubtitleFontBold) + 15) / 2.0));
                        }
                    }
                }

                var sf = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Near };

                using (var g = Graphics.FromImage(bmp))
                {
                    g.CompositingQuality = CompositingQuality.HighQuality;
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

                    if (parameter.SimpleRendering)
                    {
                        if (text.StartsWith("<font ", StringComparison.Ordinal) && Utilities.CountTagInText(text, "<font") == 1)
                        {
                            parameter.SubtitleColor = Utilities.GetColorFromFontString(text, parameter.SubtitleColor);
                        }

                        text = HtmlUtil.RemoveHtmlTags(text, true); // TODO: Perhaps check single color...
                        var brush = new SolidBrush(parameter.BorderColor);
                        int x = 3;
                        const int y = 3;
                        sf.Alignment = StringAlignment.Near;
                        if (parameter.AlignLeft)
                        {
                            sf.Alignment = StringAlignment.Near;
                        }
                        else if (parameter.AlignRight)
                        {
                            sf.Alignment = StringAlignment.Far;
                            x = parameter.ScreenWidth - 5;
                        }
                        else
                        {
                            sf.Alignment = StringAlignment.Center;
                            x = parameter.ScreenWidth / 2;
                        }

                        bmp = new Bitmap(parameter.ScreenWidth, sizeY);

                        Graphics surface = Graphics.FromImage(bmp);
                        surface.CompositingQuality = CompositingQuality.HighSpeed;
                        surface.InterpolationMode = InterpolationMode.Default;
                        surface.SmoothingMode = SmoothingMode.HighSpeed;
                        surface.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
                        for (int j = 0; j < parameter.BorderWidth; j++)
                        {
                            surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 0 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y + 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 0 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y + 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 0 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y + 1 + j }, sf);

                            surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y - 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y - 0 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y + 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y - 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y - 0 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y + 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y - 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y - 0 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y + 1 + j }, sf);

                            surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y - 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y - 0 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j, Y = y + 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y - 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y - 0 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j + 1, Y = y + 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y - 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y - 0 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - j - 1, Y = y + 1 - j }, sf);

                            surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 0 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y + 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 0 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y + 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 0 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y + 1 - j }, sf);

                            surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y - 0 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j, Y = y + 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y - 0 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j + 1, Y = y + 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 1 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y - 0 + j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + j - 1, Y = y + 1 + j }, sf);

                            surface.DrawString(text, font, brush, new PointF { X = x, Y = y - 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x, Y = y - 0 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x, Y = y + 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + 1, Y = y - 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + 1, Y = y - 0 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x + 1, Y = y + 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - 1, Y = y - 1 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - 1, Y = y - 0 - j }, sf);
                            surface.DrawString(text, font, brush, new PointF { X = x - 1, Y = y + 1 - j }, sf);
                        }

                        brush.Dispose();
                        brush = new SolidBrush(parameter.SubtitleColor);
                        surface.CompositingQuality = CompositingQuality.HighQuality;
                        surface.SmoothingMode = SmoothingMode.HighQuality;
                        surface.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        surface.DrawString(text, font, brush, new PointF { X = x, Y = y }, sf);
                        surface.Dispose();
                        brush.Dispose();
                    }
                    else
                    {
                        var path = new GraphicsPath();
                        var sb = new StringBuilder();
                        bool isItalic = false;
                        bool isBold = parameter.SubtitleFontBold;
                        float left = 5;
                        if (lefts.Count > 0)
                        {
                            left = lefts[0];
                        }

                        float top = 5;
                        bool newLine = false;
                        int lineNumber = 0;
                        float leftMargin = left;
                        int newLinePathPoint = -1;
                        Color c = parameter.SubtitleColor;
                        var colorStack = new Stack<Color>();
                        var lastText = new StringBuilder();
                        int numberOfCharsOnCurrentLine = 0;
                        for (var i = 0; i < text.Length; i++)
                        {
                            if (text.Substring(i).StartsWith("<font ", StringComparison.OrdinalIgnoreCase))
                            {
                                float addLeft = 0;
                                int oldPathPointIndex = path.PointCount;
                                if (oldPathPointIndex < 0)
                                {
                                    oldPathPointIndex = 0;
                                }

                                if (sb.Length > 0)
                                {
                                    lastText.Append(sb);
                                    TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                                }

                                if (path.PointCount > 0)
                                {
                                    var list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
                                    for (int k = oldPathPointIndex; k < list.Length; k++)
                                    {
                                        if (list[k].X > addLeft)
                                        {
                                            addLeft = list[k].X;
                                        }
                                    }
                                }

                                if (path.PointCount == 0)
                                {
                                    addLeft = left;
                                }
                                else if (addLeft < 0.01)
                                {
                                    addLeft = left + 2;
                                }

                                left = addLeft;

                                DrawShadowAndPath(parameter, g, path);
                                var p2 = new SolidBrush(c);
                                g.FillPath(p2, path);
                                p2.Dispose();
                                path.Reset();
                                path = new GraphicsPath();
                                sb = new StringBuilder();

                                int endIndex = text.Substring(i).IndexOf('>');
                                if (endIndex < 0)
                                {
                                    i += 9999;
                                }
                                else
                                {
                                    string fontContent = text.Substring(i, endIndex);
                                    if (fontContent.Contains(" color="))
                                    {
                                        string[] 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('\'');
                                            try
                                            {
                                                colorStack.Push(c); // save old color
                                                if (fontColor.StartsWith("rgb(", StringComparison.Ordinal))
                                                {
                                                    arr = fontColor.Remove(0, 4).TrimEnd(')').Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                                    c = Color.FromArgb(int.Parse(arr[0]), int.Parse(arr[1]), int.Parse(arr[2]));
                                                }
                                                else
                                                {
                                                    c = ColorTranslator.FromHtml(fontColor);
                                                }
                                            }
                                            catch
                                            {
                                                c = parameter.SubtitleColor;
                                            }
                                        }
                                    }

                                    i += endIndex;
                                }
                            }
                            else if (text.Substring(i).StartsWith("</font>", StringComparison.OrdinalIgnoreCase))
                            {
                                if (text.Substring(i).ToLower().Replace("</font>", string.Empty).Length > 0)
                                {
                                    if (lastText.EndsWith(' ') && !sb.StartsWith(' '))
                                    {
                                        string t = sb.ToString();
                                        sb.Clear();
                                        sb.Append(' ');
                                        sb.Append(t);
                                    }

                                    float addLeft = 0;
                                    int oldPathPointIndex = path.PointCount - 1;
                                    if (oldPathPointIndex < 0)
                                    {
                                        oldPathPointIndex = 0;
                                    }

                                    if (sb.Length > 0)
                                    {
                                        if (lastText.Length > 0 && left > 2)
                                        {
                                            left -= 1.5f;
                                        }

                                        lastText.Append(sb);

                                        TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                                    }

                                    if (path.PointCount > 0)
                                    {
                                        var list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
                                        for (int k = oldPathPointIndex; k < list.Length; k++)
                                        {
                                            if (list[k].X > addLeft)
                                            {
                                                addLeft = list[k].X;
                                            }
                                        }
                                    }

                                    if (addLeft < 0.01)
                                    {
                                        addLeft = left + 2;
                                    }

                                    left = addLeft;

                                    DrawShadowAndPath(parameter, g, path);
                                    g.FillPath(new SolidBrush(c), path);
                                    path.Reset();
                                    sb = new StringBuilder();
                                    if (colorStack.Count > 0)
                                    {
                                        c = colorStack.Pop();
                                    }

                                    if (left >= 3)
                                    {
                                        left -= 2.5f;
                                    }
                                }

                                i += 6;
                            }
                            else if (text.Substring(i).StartsWith("<i>", StringComparison.OrdinalIgnoreCase))
                            {
                                if (sb.Length > 0)
                                {
                                    lastText.Append(sb);
                                    TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                                }

                                isItalic = true;
                                i += 2;
                            }
                            else if (text.Substring(i).StartsWith("</i>", StringComparison.OrdinalIgnoreCase) && isItalic)
                            {
                                if (lastText.EndsWith(' ') && !sb.StartsWith(' '))
                                {
                                    string t = sb.ToString();
                                    sb.Clear();
                                    sb.Append(' ');
                                    sb.Append(t);
                                }

                                lastText.Append(sb);
                                TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                                isItalic = false;
                                i += 3;
                            }
                            else if (text.Substring(i).StartsWith("<b>", StringComparison.OrdinalIgnoreCase))
                            {
                                if (sb.Length > 0)
                                {
                                    lastText.Append(sb);
                                    TextDraw.DrawText(font, sf, path, sb, isItalic, isBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                                }

                                isBold = true;
                                i += 2;
                            }
                            else if (text.Substring(i).StartsWith("</b>", StringComparison.OrdinalIgnoreCase) && isBold)
                            {
                                if (lastText.EndsWith(' ') && !sb.StartsWith(' '))
                                {
                                    string t = sb.ToString();
                                    sb.Clear();
                                    sb.Append(' ');
                                    sb.Append(t);
                                }

                                lastText.Append(sb);
                                TextDraw.DrawText(font, sf, path, sb, isItalic, isBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                                isBold = false;
                                i += 3;
                            }
                            else if (text.Substring(i).StartsWith(Environment.NewLine, StringComparison.Ordinal))
                            {
                                lastText.Append(sb);
                                TextDraw.DrawText(font, sf, path, sb, isItalic, isBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);

                                top += lineHeight;
                                newLine = true;
                                i += Environment.NewLine.Length - 1;
                                lineNumber++;
                                if (lineNumber < lefts.Count)
                                {
                                    leftMargin = lefts[lineNumber];
                                    left = leftMargin;
                                }

                                numberOfCharsOnCurrentLine = 0;
                            }
                            else
                            {
                                if (numberOfCharsOnCurrentLine != 0 || text[i] != ' ')
                                {
                                    sb.Append(text[i]);
                                    numberOfCharsOnCurrentLine++;
                                }
                            }
                        }

                        if (sb.Length > 0)
                        {
                            TextDraw.DrawText(font, sf, path, sb, isItalic, parameter.SubtitleFontBold, false, left, top, ref newLine, leftMargin, ref newLinePathPoint);
                        }

                        DrawShadowAndPath(parameter, g, path);
                        g.FillPath(new SolidBrush(c), path);
                    }
                }

                sf.Dispose();

                var nbmp = new NikseBitmap(bmp);
                if (parameter.BackgroundColor == Color.Transparent)
                {
                    nbmp.CropTransparentSidesAndBottom(baseLinePadding, true);
                    nbmp.CropTransparentSidesAndBottom(2, false);
                }
                else
                {
                    nbmp.CropSidesAndBottom(4, parameter.BackgroundColor, true);
                    nbmp.CropTop(4, parameter.BackgroundColor);
                }

                if (nbmp.Width > parameter.ScreenWidth)
                {
                    parameter.Error = "#" + parameter.P.Number.ToString(CultureInfo.InvariantCulture) + ": " + nbmp.Width.ToString(CultureInfo.InvariantCulture) + " > " + parameter.ScreenWidth.ToString(CultureInfo.InvariantCulture);
                }

                if (parameter.Type3D == 1)
                {
                    // Half-side-by-side 3D
                    Bitmap singleBmp = nbmp.GetBitmap();
                    Bitmap singleHalfBmp = ScaleToHalfWidth(singleBmp);
                    singleBmp.Dispose();
                    var sideBySideBmp = new Bitmap(parameter.ScreenWidth, singleHalfBmp.Height);
                    int singleWidth = parameter.ScreenWidth / 2;
                    int singleLeftMargin = (singleWidth - singleHalfBmp.Width) / 2;

                    using (Graphics gSideBySide = Graphics.FromImage(sideBySideBmp))
                    {
                        gSideBySide.DrawImage(singleHalfBmp, singleLeftMargin + parameter.Depth3D, 0);
                        gSideBySide.DrawImage(singleHalfBmp, singleWidth + singleLeftMargin - parameter.Depth3D, 0);
                    }

                    nbmp = new NikseBitmap(sideBySideBmp);
                    if (parameter.BackgroundColor == Color.Transparent)
                    {
                        nbmp.CropTransparentSidesAndBottom(2, true);
                    }
                    else
                    {
                        nbmp.CropSidesAndBottom(4, parameter.BackgroundColor, true);
                    }
                }
                else if (parameter.Type3D == 2)
                {
                    // Half-Top/Bottom 3D
                    nbmp = Make3DTopBottom(parameter, nbmp);
                }

                return nbmp.GetBitmap();
            }
            finally
            {
                if (font != null)
                {
                    font.Dispose();
                }

                if (bmp != null)
                {
                    bmp.Dispose();
                }
            }
        }
		public void EndsWith_ContainsNonAsciiCharacters()
		{
			StringBuilder builder = new StringBuilder();
			builder.Append("\u3041\u3042\u3043\u3044");
			string endString = "\u3043\u3044";
			bool endsWith = builder.EndsWith(endString);
			Assert.IsTrue(endsWith);
		}
		public void EndsWith_StringNotAtEnd()
		{
			StringBuilder builder = new StringBuilder();
			builder.Append("abcdefg");
			string endString = "bcd";

			bool endsWith = builder.EndsWith(endString);
			Assert.IsFalse(endsWith);

			endString = "BCD";
			endsWith = builder.EndsWith(endString, StringComparison.OrdinalIgnoreCase);
			Assert.IsFalse(endsWith);
		}
		public void EndsWith_StringEmpty()
		{
			StringBuilder builder = new StringBuilder();
			builder.Append("abcdefg");
			string endString = string.Empty;
			bool endsWith = builder.EndsWith(endString);
		}
		public void EndsWith_StringNull()
		{
			StringBuilder builder = new StringBuilder();
			builder.Append("abcdefg");
			string endString = null;
			bool endsWith = builder.EndsWith(endString);
		}
        public string FixOcrErrors(string text, int index, string lastLine, bool logSuggestions, AutoGuessLevel autoGuess)
        {
            var sb = new StringBuilder();
            var word = new StringBuilder();

            if (Configuration.Settings.Tools.OcrFixUseHardcodedRules)
            {
                text = text.Replace("fi", "fi"); // fb01
                text = text.Replace("fl", "fl"); // fb02
                text = text.Replace('ν', 'v'); // NOTE: first 'v' is a special unicode character!!!!
            }

            text = ReplaceWordsBeforeLineFixes(text);

            text = FixCommenOcrLineErrors(text, lastLine);

            string lastWord = null;
            for (int i = 0; i < text.Length; i++)
            {
                if (" ¡¿,.!?:;()[]{}+-£\"#&%\r\n".Contains(text[i])) // removed $
                {
                    if (word.Length > 0)
                    {
                        string fixedWord;
                        if (lastWord != null && lastWord.Contains("COLOR=", StringComparison.OrdinalIgnoreCase))
                        {
                            fixedWord = word.ToString();
                        }
                        else
                        {
                            bool doFixWord = true;
                            if (word.Length == 1 && sb.Length > 1 && sb.EndsWith('-'))
                                doFixWord = false;
                            if (doFixWord)
                                fixedWord = _ocrFixReplaceList.FixCommonWordErrors(word.ToString());
                            else
                                fixedWord = word.ToString();
                        }
                        sb.Append(fixedWord);
                        lastWord = fixedWord;
                        word.Clear();
                    }
                    sb.Append(text[i]);
                }
                else
                {
                    word.Append(text[i]);
                }
            }
            if (word.Length > 0) // last word
            {
                string fixedWord;
                bool doFixWord = true;
                if (word.Length == 1 && sb.Length > 1 && sb.EndsWith('-'))
                    doFixWord = false;
                if (doFixWord)
                    fixedWord = _ocrFixReplaceList.FixCommonWordErrors(word.ToString());
                else
                    fixedWord = word.ToString();

                sb.Append(fixedWord);
            }

            text = FixCommenOcrLineErrors(sb.ToString(), lastLine);
            int wordsNotFound;
            text = FixUnknownWordsViaGuessOrPrompt(out wordsNotFound, text, index, null, true, false, logSuggestions, autoGuess);
            if (Configuration.Settings.Tools.OcrFixUseHardcodedRules)
            {
                text = FixLowercaseIToUppercaseI(text, lastLine);
                if (SpellCheckDictionaryName.StartsWith("en_", StringComparison.Ordinal) || _threeLetterIsoLanguageName == "eng")
                {
                    string oldText = text;
                    text = FixCommonErrors.FixAloneLowercaseIToUppercaseLine(RegexAloneI, oldText, text, 'i');
                    text = FixCommonErrors.FixAloneLowercaseIToUppercaseLine(RegexAloneIasL, oldText, text, 'l');
                }
                else if (_threeLetterIsoLanguageName == "fra")
                {
                    text = FixFrenchLApostrophe(text, " I'", lastLine);
                    text = FixFrenchLApostrophe(text, " L'", lastLine);
                    text = FixFrenchLApostrophe(text, " l'", lastLine);
                    text = FixFrenchLApostrophe(text, " I’", lastLine);
                    text = FixFrenchLApostrophe(text, " L’", lastLine);
                    text = FixFrenchLApostrophe(text, " l’", lastLine);
                }

                text = RemoveSpaceBetweenNumbers(text);
            }
            return text;
        }
        public static string GetSccText(string s, ref int errorCount)
        {
            int y = 0;
            string[] parts = s.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
            var sb = new StringBuilder();
            bool first = true;
            bool italicOn = false;
            int k = 0;
            while (k < parts.Length)
            {
                string part = parts[k];
                if (part.Length == 4)
                {
                    if (part != "94ae" && part != "9420" && part != "94ad" && part != "9426" && part != "946e" && part != "91ce" && part != "13ce" && part != "9425" && part != "9429")
                    {
                        //  Spanish inverted question mark (extended char)
                        if (part == "91b3" && k < parts.Length - 1 && parts[k + 1] == "91b3")
                        {
                            sb.Append("¿");
                            k += 2;
                            continue;
                        }

                        //  Spanish inverted exclamation mark (extended char)
                        if (part == "a180" && k < parts.Length - 2 && parts[k + 1] == "92a7" && parts[k + 2] == "92a7")
                        {
                            sb.Append("¡");
                            k += 3;
                            continue;
                        }

                        // skewed apos "’"
                        if (part == "9229" && k < parts.Length - 1 && parts[k + 1] == "9229" && sb.EndsWith('\''))
                        {
                            sb.Remove(sb.Length - 1, 1);
                            sb.Append("’");
                            k += 2;
                            continue;
                        }

                        if (part[0] == '9' || part[0] == '8')
                        {
                            if (k + 1 < parts.Length && parts[k + 1] == part)
                                k++;
                        }

                        var cp = GetColorAndPosition(part);
                        if (cp != null)
                        {
                            if (cp.Y > 0 && y >= 0 && cp.Y > y && !sb.ToString().EndsWith(Environment.NewLine) && !string.IsNullOrWhiteSpace(sb.ToString()))
                                sb.AppendLine();
                            if (cp.Y > 0)
                                y = cp.Y;
                            if ((cp.Style & FontStyle.Italic) == FontStyle.Italic && !italicOn)
                            {
                                sb.Append("<i>");
                                italicOn = true;
                            }
                            else if (cp.Style == FontStyle.Regular && italicOn)
                            {
                                sb.Append("</i>");
                                italicOn = false;
                            }
                        }
                        else
                        {
                            switch (part)
                            {
                                case "9440":
                                case "94e0":
                                    if (!sb.ToString().EndsWith(Environment.NewLine))
                                        sb.AppendLine();
                                    break;
                                case "2c75":
                                case "2cf2":
                                case "2c6f":
                                case "2c6e":
                                case "2c6d":
                                case "2c6c":
                                case "2c6b":
                                case "2c6a":
                                case "2c69":
                                case "2c68":
                                case "2c67":
                                case "2c66":
                                case "2c65":
                                case "2c64":
                                case "2c63":
                                case "2c62":
                                case "2c61":
                                    sb.Append(GetLetter(part.Substring(2, 2)));
                                    break;
                                case "2c52":
                                case "2c94":
                                    break;
                                default:
                                    var result = GetLetter(part);
                                    if (result == null)
                                    {
                                        sb.Append(GetLetter(part.Substring(0, 2)));
                                        sb.Append(GetLetter(part.Substring(2, 2)));
                                    }
                                    else
                                    {
                                        sb.Append(result);
                                    }
                                    break;
                            }
                        }
                    }
                }
                else if (part.Length > 0)
                {
                    if (!first)
                        errorCount++;
                }
                first = false;
                k++;
            }
            string res = sb.ToString().Replace("<i></i>", string.Empty).Replace("</i><i>", string.Empty);
            //res = res.Replace("♪♪", "♪");
            res = res.Replace("  ", " ").Replace("  ", " ").Replace(Environment.NewLine + " ", Environment.NewLine).Trim();
            if (res.Contains("<i>") && !res.Contains("</i>"))
                res += "</i>";
            //res = res.Replace("aã", "ã");
            //res = res.Replace("oõ", "õ");
            return HtmlUtil.FixInvalidItalicTags(res);
        }
        static void Main(string[] args)
        {
            StringBuilder str = new StringBuilder();
            str.Append("Hello_World !!!");
            Console.WriteLine("Index is at: " + str.IndexOf("World", 1));
            Console.WriteLine("Index is at: " + str.IndexOf("H"));
            Console.WriteLine("Index is at: " + str.IndexOf("e"));
            Console.WriteLine("Index is at: " + str.IndexOf("l"));
            Console.WriteLine("Index is at: " + str.IndexOf("l", 3));
            Console.WriteLine("Index is at: " + str.IndexOf("o"));
            Console.WriteLine("Index is at: " + str.IndexOf("W"));
            Console.WriteLine("Index is at: " + str.IndexOf("o"));
            Console.WriteLine("Index is at: " + str.IndexOf("r"));
            Console.WriteLine("Index is at: " + str.IndexOf("l"));
            Console.WriteLine("Index is at: " + str.IndexOf("d"));

            Console.WriteLine("Substring 5 to end: " + str.Substring(5));

            Console.WriteLine("Substring 1, length 1: " + str.Substring(1, 1));

            StringBuilder[] strs = str.Split(new String[] { " ", "_" });

            Console.WriteLine("Does string contain Hello? " + str.Contains("Hello"));

            Console.WriteLine("Does string end with !!!? " + str.EndsWith("!!!"));

            Console.WriteLine("Last index of !: " + str.LastIndexOf("!"));

            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        }