|
@@ -1,5 +1,7 @@
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
+using System.Collections.Specialized;
|
|
|
+using System.ComponentModel;
|
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
using System.Globalization;
|
|
|
using Avalonia;
|
|
@@ -374,6 +376,14 @@ namespace TextTestApp
|
|
|
InvalidateTextRunProperties();
|
|
|
break;
|
|
|
|
|
|
+ case nameof(FontFeatures):
|
|
|
+ if (change.OldValue is FontFeatureCollection oc)
|
|
|
+ oc.CollectionChanged -= OnFeatureCollectionChanged;
|
|
|
+ if (change.NewValue is FontFeatureCollection nc)
|
|
|
+ nc.CollectionChanged += OnFeatureCollectionChanged;
|
|
|
+ OnFeatureCollectionChanged(null, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
|
|
+ break;
|
|
|
+
|
|
|
case nameof(FontStyle):
|
|
|
case nameof(FontWeight):
|
|
|
case nameof(FontStretch):
|
|
@@ -422,6 +432,11 @@ namespace TextTestApp
|
|
|
base.OnPropertyChanged(change);
|
|
|
}
|
|
|
|
|
|
+ private void OnFeatureCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
|
|
+ {
|
|
|
+ InvalidateTextRunProperties();
|
|
|
+ }
|
|
|
+
|
|
|
protected override Size MeasureOverride(Size availableSize)
|
|
|
{
|
|
|
if (TextLine == null)
|
|
@@ -433,6 +448,7 @@ namespace TextTestApp
|
|
|
private const double VerticalSpacing = 5;
|
|
|
private const double HorizontalSpacing = 5;
|
|
|
private const double ArrowSize = 5;
|
|
|
+ private const double LabelFontSize = 9;
|
|
|
|
|
|
private Dictionary<string, FormattedText> _labelsCache = new();
|
|
|
protected FormattedText GetOrCreateLabel(string label, IBrush brush, bool disableCache = false)
|
|
@@ -440,7 +456,7 @@ namespace TextTestApp
|
|
|
if (_labelsCache.TryGetValue(label, out var text))
|
|
|
return text;
|
|
|
|
|
|
- text = new FormattedText(label, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, Typeface.Default, 8, brush);
|
|
|
+ text = new FormattedText(label, CultureInfo.InvariantCulture, FlowDirection.LeftToRight, Typeface.Default, LabelFontSize, brush);
|
|
|
|
|
|
if (!disableCache)
|
|
|
_labelsCache[label] = text;
|
|
@@ -519,7 +535,7 @@ namespace TextTestApp
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- double y = inkBounds.Bottom - lineBounds.Top + VerticalSpacing * 2;
|
|
|
+ double y = Math.Max(inkBounds.Bottom, lineBounds.Bottom) + VerticalSpacing * 2;
|
|
|
|
|
|
if (NextHitStroke != null)
|
|
|
{
|
|
@@ -565,6 +581,14 @@ namespace TextTestApp
|
|
|
leftLabelX -= nextLabel.WidthIncludingTrailingWhitespace;
|
|
|
}
|
|
|
|
|
|
+ if (BackspaceHitStroke != null)
|
|
|
+ {
|
|
|
+ CharacterHit backHit = textLine.GetBackspaceCaretCharacterHit(hit);
|
|
|
+ var x1 = textLine.GetDistanceFromCharacterHit(new CharacterHit(backHit.FirstCharacterIndex, 0));
|
|
|
+ var x2 = textLine.GetDistanceFromCharacterHit(new CharacterHit(backHit.FirstCharacterIndex + backHit.TrailingLength, 0));
|
|
|
+ RenderHorizontalPoint(context, x1, x2, y, BackspaceHitPen, ArrowSize);
|
|
|
+ }
|
|
|
+
|
|
|
if (PreviousHitStroke != null)
|
|
|
{
|
|
|
prevHit = textLine.GetPreviousCaretCharacterHit(hit);
|