80 lines
2.9 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|