Files
Chat/ChatController/Core/FlowDocumentExtensions.cs
2022-05-27 11:50:37 +02:00

80 lines
2.9 KiB
C#

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