Browse Source

Merge branch 'master' into optional-tooltip-validaiton-error

pull/5860/head
Dan Walmsley 5 years ago
committed by GitHub
parent
commit
786e340c46
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 44
      src/Avalonia.Controls/Converters/CornerRadiusFilterConverter.cs
  2. 32
      src/Avalonia.Controls/Converters/CornerRadiusFilterKind.cs
  3. 2
      src/Skia/Avalonia.Skia/TextShaperImpl.cs
  4. 43
      tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextShaperTests.cs

44
src/Avalonia.Controls/Converters/CornerRadiusFilterConverter.cs

@ -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();
}
}
}

32
src/Avalonia.Controls/Converters/CornerRadiusFilterKind.cs

@ -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
}
}

2
src/Skia/Avalonia.Skia/TextShaperImpl.cs

@ -87,7 +87,7 @@ namespace Avalonia.Skia
{
var nextCodepoint = Codepoint.ReadAt(text, i + 1, out _);
if (nextCodepoint == '\r' && codepoint == '\n' || nextCodepoint == '\n' && codepoint == '\r')
if (nextCodepoint == '\n' && codepoint == '\r')
{
count++;

43
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextShaperTests.cs

@ -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…
Cancel
Save