committed by
GitHub
4 changed files with 120 additions and 1 deletions
@ -0,0 +1,44 @@ |
|||
#nullable enable |
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
using Avalonia.Data.Converters; |
|||
|
|||
namespace Avalonia.Controls.Converters |
|||
{ |
|||
/// <summary>
|
|||
/// Converts an existing CornerRadius struct to a new CornerRadius struct,
|
|||
/// with filters applied to extract only the specified fields, leaving the others set to 0.
|
|||
/// </summary>
|
|||
public class CornerRadiusFilterConverter : IValueConverter |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the type of the filter applied to the <see cref="CornerRadiusFilterConverter"/>.
|
|||
/// </summary>
|
|||
public CornerRadiusFilterKinds Filter { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the scale multiplier applied to the <see cref="CornerRadiusFilterConverter"/>.
|
|||
/// </summary>
|
|||
public double Scale { get; set; } = 1; |
|||
|
|||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) |
|||
{ |
|||
if (!(value is CornerRadius radius)) |
|||
{ |
|||
return value; |
|||
} |
|||
|
|||
return new CornerRadius( |
|||
Filter.HasAllFlags(CornerRadiusFilterKinds.TopLeft) ? radius.TopLeft * Scale : 0, |
|||
Filter.HasAllFlags(CornerRadiusFilterKinds.TopRight) ? radius.TopRight * Scale : 0, |
|||
Filter.HasAllFlags(CornerRadiusFilterKinds.BottomRight) ? radius.BottomRight * Scale : 0, |
|||
Filter.HasAllFlags(CornerRadiusFilterKinds.BottomLeft) ? radius.BottomLeft * Scale : 0); |
|||
} |
|||
|
|||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using System; |
|||
|
|||
namespace Avalonia.Controls.Converters |
|||
{ |
|||
/// <summary>
|
|||
/// Defines constants that specify the filter type for a <see cref="CornerRadiusFilterConverter"/> instance.
|
|||
/// </summary>
|
|||
[Flags] |
|||
public enum CornerRadiusFilterKinds |
|||
{ |
|||
/// <summary>
|
|||
/// No filter applied.
|
|||
/// </summary>
|
|||
None, |
|||
/// <summary>
|
|||
/// Filters TopLeft value.
|
|||
/// </summary>
|
|||
TopLeft = 1, |
|||
/// <summary>
|
|||
/// Filters TopRight value.
|
|||
/// </summary>
|
|||
TopRight = 2, |
|||
/// <summary>
|
|||
/// Filters BottomLeft value.
|
|||
/// </summary>
|
|||
BottomLeft = 4, |
|||
/// <summary>
|
|||
/// Filters BottomRight value.
|
|||
/// </summary>
|
|||
BottomRight = 8 |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
using System; |
|||
using System.Globalization; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.TextFormatting; |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|||
{ |
|||
public class TextShaperTests |
|||
{ |
|||
[Fact] |
|||
public void Should_Form_Clusters_For_BreakPairs() |
|||
{ |
|||
using (Start()) |
|||
{ |
|||
var text = "\n\r\n".AsMemory(); |
|||
|
|||
var glyphRun = TextShaper.Current.ShapeText( |
|||
text, |
|||
Typeface.Default, |
|||
12, |
|||
CultureInfo.CurrentCulture); |
|||
|
|||
Assert.Equal(glyphRun.Characters.Length, text.Length); |
|||
Assert.Equal(glyphRun.GlyphClusters.Length, text.Length); |
|||
Assert.Equal(0, glyphRun.GlyphClusters[0]); |
|||
Assert.Equal(1, glyphRun.GlyphClusters[1]); |
|||
Assert.Equal(1, glyphRun.GlyphClusters[2]); |
|||
} |
|||
} |
|||
|
|||
private static IDisposable Start() |
|||
{ |
|||
var disposable = UnitTestApplication.Start(TestServices.MockPlatformRenderInterface |
|||
.With(renderInterface: new PlatformRenderInterface(null), |
|||
textShaperImpl: new TextShaperImpl(), |
|||
fontManagerImpl: new CustomFontManagerImpl())); |
|||
|
|||
return disposable; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue