using System; using System.Collections.Generic; using System.Globalization; using System.Text; using System.Windows.Documents; using System.Windows.Media; namespace ChatController.Core { public static class FlowDocumentExtensions { private static IEnumerable GetRunsAndParagraphs(FlowDocument doc) { for (var position = doc.ContentStart; !(position is null) && position.CompareTo(doc.ContentEnd) <= 0; position = position.GetNextContextPosition(LogicalDirection.Forward)) { if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd) { switch (position.Parent) { case Run run: yield return run; break; case Paragraph paragraph: yield return paragraph; break; } } } } public static FormattedText GetFormattedText(this FlowDocument flowDocument) { if (flowDocument is null) { throw new ArgumentNullException(nameof(flowDocument)); } var output = new FormattedText(GetText(flowDocument), CultureInfo.CurrentCulture, flowDocument.FlowDirection, new Typeface(flowDocument.FontFamily, flowDocument.FontStyle, flowDocument.FontWeight, flowDocument.FontStretch), flowDocument.FontSize, flowDocument.Foreground); var offset = 0; foreach (var textElement in GetRunsAndParagraphs(flowDocument)) { if (textElement is Run run) { var count = run.Text.Length; output.SetFontFamily(run.FontFamily, offset, count); output.SetFontStyle(run.FontStyle, offset, count); output.SetFontWeight(run.FontWeight, offset, count); output.SetFontSize(run.FontSize, offset, count); output.SetForegroundBrush(run.Foreground, offset, count); output.SetFontStretch(run.FontStretch, offset, count); output.SetTextDecorations(run.TextDecorations, offset, count); offset += count; } else { offset += Environment.NewLine.Length; } } return output; } private static string GetText(FlowDocument flowDocument) { var stringBuilder = new StringBuilder(); foreach (var textElement in GetRunsAndParagraphs(flowDocument)) { stringBuilder.Append(!(textElement is Run run) ? Environment.NewLine : run.Text); } return stringBuilder.ToString(); } } }