csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.6 KiB
118 lines
3.6 KiB
using System;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Markup.Xaml;
|
|
using Avalonia.Media;
|
|
using Avalonia.Media.TextFormatting;
|
|
|
|
namespace RenderDemo.Pages
|
|
{
|
|
public class TextFormatterPage : UserControl
|
|
{
|
|
private TextLine _textLine;
|
|
|
|
public TextFormatterPage()
|
|
{
|
|
this.InitializeComponent();
|
|
}
|
|
|
|
private void InitializeComponent()
|
|
{
|
|
AvaloniaXamlLoader.Load(this);
|
|
}
|
|
|
|
public override void Render(DrawingContext context)
|
|
{
|
|
_textLine?.Draw(context, new Point());
|
|
}
|
|
|
|
protected override Size MeasureOverride(Size availableSize)
|
|
{
|
|
var defaultRunProperties = new GenericTextRunProperties(Typeface.Default, foregroundBrush: Brushes.Black,
|
|
baselineAlignment: BaselineAlignment.Center);
|
|
var paragraphProperties = new GenericTextParagraphProperties(defaultRunProperties);
|
|
|
|
var control = new Button { Content = new TextBlock { Text = "ClickMe" } };
|
|
|
|
Content = control;
|
|
|
|
var textSource = new CustomTextSource(control, defaultRunProperties);
|
|
|
|
control.Measure(Size.Infinity);
|
|
|
|
_textLine =
|
|
TextFormatter.Current.FormatLine(textSource, 0, double.PositiveInfinity, paragraphProperties);
|
|
|
|
return base.MeasureOverride(availableSize);
|
|
}
|
|
|
|
protected override Size ArrangeOverride(Size finalSize)
|
|
{
|
|
var currentX = 0d;
|
|
|
|
foreach (var textRun in _textLine.TextRuns)
|
|
{
|
|
if (textRun is ControlRun controlRun)
|
|
{
|
|
controlRun.Control.Arrange(new Rect(new Point(currentX, 0), controlRun.Size));
|
|
}
|
|
|
|
if (textRun is DrawableTextRun drawableTextRun)
|
|
{
|
|
currentX += drawableTextRun.Size.Width;
|
|
}
|
|
}
|
|
|
|
return finalSize;
|
|
}
|
|
|
|
private class CustomTextSource : ITextSource
|
|
{
|
|
private readonly Control _control;
|
|
private readonly TextRunProperties _defaultProperties;
|
|
private readonly string _text = "<-Hello World->";
|
|
|
|
public CustomTextSource(Control control, TextRunProperties defaultProperties)
|
|
{
|
|
_control = control;
|
|
_defaultProperties = defaultProperties;
|
|
}
|
|
|
|
public TextRun GetTextRun(int textSourceIndex)
|
|
{
|
|
if (textSourceIndex >= _text.Length * 2 + TextRun.DefaultTextSourceLength)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (textSourceIndex == _text.Length)
|
|
{
|
|
return new ControlRun(_control, _defaultProperties);
|
|
}
|
|
|
|
return new TextCharacters(_text.AsMemory(), _defaultProperties);
|
|
}
|
|
}
|
|
|
|
private class ControlRun : DrawableTextRun
|
|
{
|
|
private readonly Control _control;
|
|
|
|
public ControlRun(Control control, TextRunProperties properties)
|
|
{
|
|
_control = control;
|
|
Properties = properties;
|
|
}
|
|
|
|
public Control Control => _control;
|
|
public override Size Size => _control.DesiredSize;
|
|
public override double Baseline => 0;
|
|
public override TextRunProperties Properties { get; }
|
|
|
|
public override void Draw(DrawingContext drawingContext, Point origin)
|
|
{
|
|
// noop
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|