diff --git a/samples/TextTestApp/FontFeatureCollectionConverter.cs b/samples/TextTestApp/FontFeatureCollectionConverter.cs new file mode 100644 index 0000000000..26d0bdf0af --- /dev/null +++ b/samples/TextTestApp/FontFeatureCollectionConverter.cs @@ -0,0 +1,20 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using Avalonia.Media; + +namespace TextTestApp +{ + public class FontFeatureCollectionConverter : TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) + { + return sourceType == typeof(string); + } + + public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) + { + return FontFeatureCollection.Parse((string)value); + } + } +} diff --git a/samples/TextTestApp/InteractiveLineControl.cs b/samples/TextTestApp/InteractiveLineControl.cs index e7e5c5bac5..f4e26e1415 100644 --- a/samples/TextTestApp/InteractiveLineControl.cs +++ b/samples/TextTestApp/InteractiveLineControl.cs @@ -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 _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); diff --git a/samples/TextTestApp/MainWindow.axaml b/samples/TextTestApp/MainWindow.axaml index 6dd6670124..1891379912 100644 --- a/samples/TextTestApp/MainWindow.axaml +++ b/samples/TextTestApp/MainWindow.axaml @@ -23,6 +23,8 @@