public void RenderText(IFormattedTextSegment segment)
        {
            if (Dispatcher.CheckAccess())
            {
                if (!segment.Complete)
                {
                    _incompleteSegments.Add(segment);
                }
                else
                {
                    int start = tblkMainContent.Inlines.Count - _incompleteSegments.Count;
                    start = start < 0 ? 0 : start;

                    for (int i = start; i < tblkMainContent.Inlines.Count; ++i)
                    {
                        Run prev = tblkMainContent.Inlines[i] as Run;
                        if (prev == null)
                        {
                            continue;
                        }
                        prev.Foreground = new SolidColorBrush(segment.TextColor);
                    }

                    _incompleteSegments.Clear();
                }

                Run r = new Run();
                r.Text       = segment.Text;
                r.Foreground = new SolidColorBrush(segment.TextColor);

                tblkMainContent.Inlines.Add(r);

                svMainContent.UpdateLayout();
                svMainContent.ScrollToVerticalOffset(double.MaxValue);
            }
            else
            {
                Dispatcher.BeginInvoke(() => { RenderText(segment); });
            }
        }
        public IFormattedTextSegment[] ProcessText(string text)
        {
            IFormattedTextSegment[] formattedText = new IFormattedTextSegment[] { };

            lock (_overflow)
            {
                // append any previous overflow
                string input = _overflow + text;

                // clear the overflow for the next pass
                _overflow = string.Empty;

                // find any escape sequence
                int nextEsc = input.IndexOf(cESC);

                // process the sequence if found
                if (nextEsc >= 0)
                {
                    string[] tokens = text.Split(cESC);

                    foreach (string token in tokens)
                    {
                        string parsedText = string.Empty;

                        if (rxANSICmd.IsMatch(token)) // process the command
                        {
                            if (token.Contains(";"))  // check for multiple parameters
                            {
                                int m     = token.IndexOf('m');
                                int first = int.MaxValue;
                                foreach (char c in "ABCDEFGHJKSTfmnsul")
                                {
                                    int idx = token.IndexOf(c);
                                    if (idx < 0)
                                    {
                                        continue;
                                    }
                                    first = Math.Min(idx, first);
                                }
                                if (first < m) // not SGR so just remove
                                {
                                    parsedText = token.Substring(first + 1);
                                }
                                else
                                {
                                    string[] values  = token.Split(';');
                                    int      cformat = int.Parse(values[0].Substring(1));

                                    for (int i = 1; i < values.Length; ++i)
                                    {
                                        int fm  = values[i].IndexOf('m');
                                        int val = fm < 0 ? int.Parse(values[i]) : int.Parse(values[i].Substring(0, fm));
                                        if (val >= 30 && val <= 37)
                                        {
                                            _currentColor = cformat == 0 ? colorsNormal[val] : colorsBright[val];
                                            break;
                                        }
                                    }

                                    parsedText = values[values.Length - 1].Substring(values[values.Length - 1].IndexOf('m') + 1);
                                }
                            }
                            else if (rxShorthandNormal.IsMatch(token)) // check for SGR
                            {
                                int val = int.Parse(token.Substring(1, token.IndexOf('m') - 1));
                                if (val >= 30 && val <= 37)
                                {
                                    _currentColor = colorsNormal[val];
                                }
                                parsedText = token.Substring(token.IndexOf('m') + 1);
                            }
                            else
                            {
                                // remove the ansi junk and just process the normal text
                                int first = int.MaxValue;
                                foreach (char c in "ABCDEFGHJKSTfmnsul")
                                {
                                    int idx = token.IndexOf(c);
                                    if (idx < 0)
                                    {
                                        continue;
                                    }
                                    first = Math.Min(idx, first);
                                }
                                parsedText = token.Substring(first + 1);
                            }
                        }
                        else
                        {
                            parsedText = token;
                        }

                        Array.Resize <IFormattedTextSegment>(ref formattedText, formattedText.Length + 1);
                        formattedText[formattedText.Length - 1] = new DisplayText()
                        {
                            Text = parsedText, TextColor = DefaultColor
                        };
                    }
                }
                else // use the last known color
                {
                    Array.Resize <IFormattedTextSegment>(ref formattedText, 1);
                    formattedText[0] = new DisplayText()
                    {
                        Text = input, TextColor = DefaultColor
                    };
                }
            }

            return(formattedText);
        }