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); }