Browse Source

Merge branch 'master' into opt-children-notifications

pull/5049/head
Dariusz Komosiński 6 years ago
committed by GitHub
parent
commit
0ae689df75
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      build/ApiDiff.props
  2. 2
      build/Rx.props
  3. 18
      nukebuild/Build.cs
  4. 2
      nukebuild/_build.csproj
  5. 5
      src/Avalonia.Base/Utilities/MathUtilities.cs
  6. 5
      src/Avalonia.Base/Utilities/StringTokenizer.cs
  7. 24
      src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj
  8. 4
      src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs
  9. 32
      src/Avalonia.Controls/ComboBox.cs
  10. 9
      src/Avalonia.Visuals/CornerRadius.cs
  11. 5
      src/Avalonia.Visuals/Matrix.cs
  12. 9
      src/Avalonia.Visuals/Point.cs
  13. 9
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  14. 9
      src/Avalonia.Visuals/Size.cs
  15. 9
      src/Avalonia.Visuals/Thickness.cs
  16. 9
      src/Avalonia.Visuals/Vector.cs
  17. 1
      src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj
  18. 54
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AstNodes/AvaloniaXamlIlVectorLikeConstantAstNode.cs
  19. 60
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs
  20. 31
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
  21. 2
      src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github
  22. 12
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  23. 3
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
  24. 5
      src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs
  25. 1
      tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs
  26. 29
      tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs

2
build/ApiDiff.props

@ -1,6 +1,6 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<ApiContractPackageVersion>0.10.0-preview3</ApiContractPackageVersion> <ApiContractPackageVersion>0.10.0-preview6</ApiContractPackageVersion>
<NugetPackageName Condition="'$(PackageId)' != ''">$(PackageId)</NugetPackageName> <NugetPackageName Condition="'$(PackageId)' != ''">$(PackageId)</NugetPackageName>
<NugetPackageName Condition="'$(PackageId)' == ''">Avalonia</NugetPackageName> <NugetPackageName Condition="'$(PackageId)' == ''">Avalonia</NugetPackageName>
</PropertyGroup> </PropertyGroup>

2
build/Rx.props

@ -1,5 +1,5 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Reactive" Version="4.4.1" /> <PackageReference Include="System.Reactive" Version="5.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

18
nukebuild/Build.cs

@ -107,7 +107,7 @@ partial class Build : NukeBuild
.AddProperty("JavaSdkDirectory", GetVariable<string>("JAVA_HOME_8_X64"))) .AddProperty("JavaSdkDirectory", GetVariable<string>("JAVA_HOME_8_X64")))
.AddProperty("PackageVersion", Parameters.Version) .AddProperty("PackageVersion", Parameters.Version)
.AddProperty("iOSRoslynPathHackRequired", true) .AddProperty("iOSRoslynPathHackRequired", true)
.SetToolPath(MsBuildExe.Value) .SetProcessToolPath(MsBuildExe.Value)
.SetConfiguration(Parameters.Configuration) .SetConfiguration(Parameters.Configuration)
.SetVerbosity(MSBuildVerbosity.Minimal) .SetVerbosity(MSBuildVerbosity.Minimal)
.Apply(configurator)); .Apply(configurator));
@ -132,10 +132,10 @@ partial class Build : NukeBuild
var webappDir = RootDirectory / "src" / "Avalonia.DesignerSupport" / "Remote" / "HtmlTransport" / "webapp"; var webappDir = RootDirectory / "src" / "Avalonia.DesignerSupport" / "Remote" / "HtmlTransport" / "webapp";
NpmTasks.NpmInstall(c => c NpmTasks.NpmInstall(c => c
.SetWorkingDirectory(webappDir) .SetProcessWorkingDirectory(webappDir)
.SetArgumentConfigurator(a => a.Add("--silent"))); .SetProcessArgumentConfigurator(a => a.Add("--silent")));
NpmTasks.NpmRun(c => c NpmTasks.NpmRun(c => c
.SetWorkingDirectory(webappDir) .SetProcessWorkingDirectory(webappDir)
.SetCommand("dist")); .SetCommand("dist"));
}); });
@ -157,7 +157,7 @@ partial class Build : NukeBuild
{ {
if (Parameters.IsRunningOnWindows) if (Parameters.IsRunningOnWindows)
MsBuildCommon(Parameters.MSBuildSolution, c => c MsBuildCommon(Parameters.MSBuildSolution, c => c
.SetArgumentConfigurator(a => a.Add("/r")) .SetProcessArgumentConfigurator(a => a.Add("/r"))
.AddTargets("Build") .AddTargets("Build")
); );
@ -194,7 +194,7 @@ partial class Build : NukeBuild
var eventsProject = Path.Combine(eventsDirectory, "Avalonia.ReactiveUI.Events.csproj"); var eventsProject = Path.Combine(eventsDirectory, "Avalonia.ReactiveUI.Events.csproj");
if (Parameters.IsRunningOnWindows) if (Parameters.IsRunningOnWindows)
MsBuildCommon(eventsProject, c => c MsBuildCommon(eventsProject, c => c
.SetArgumentConfigurator(a => a.Add("/r")) .SetProcessArgumentConfigurator(a => a.Add("/r"))
.AddTargets("Build") .AddTargets("Build")
); );
else else
@ -242,10 +242,10 @@ partial class Build : NukeBuild
var webappTestDir = RootDirectory / "tests" / "Avalonia.DesignerSupport.Tests" / "Remote" / "HtmlTransport" / "webapp"; var webappTestDir = RootDirectory / "tests" / "Avalonia.DesignerSupport.Tests" / "Remote" / "HtmlTransport" / "webapp";
NpmTasks.NpmInstall(c => c NpmTasks.NpmInstall(c => c
.SetWorkingDirectory(webappTestDir) .SetProcessWorkingDirectory(webappTestDir)
.SetArgumentConfigurator(a => a.Add("--silent"))); .SetProcessArgumentConfigurator(a => a.Add("--silent")));
NpmTasks.NpmRun(c => c NpmTasks.NpmRun(c => c
.SetWorkingDirectory(webappTestDir) .SetProcessWorkingDirectory(webappTestDir)
.SetCommand("test")); .SetCommand("test"));
}); });

2
nukebuild/_build.csproj

@ -10,7 +10,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Nuke.Common" Version="0.24.0" /> <PackageReference Include="Nuke.Common" Version="5.0.0" />
<PackageReference Include="xunit.runner.console" Version="2.3.1" /> <PackageReference Include="xunit.runner.console" Version="2.3.1" />
<PackageReference Include="JetBrains.dotMemoryUnit" Version="3.0.20171219.105559" /> <PackageReference Include="JetBrains.dotMemoryUnit" Version="3.0.20171219.105559" />
<PackageReference Include="vswhere" Version="2.6.7" Condition=" '$(OS)' == 'Windows_NT' " /> <PackageReference Include="vswhere" Version="2.6.7" Condition=" '$(OS)' == 'Windows_NT' " />

5
src/Avalonia.Base/Utilities/MathUtilities.cs

@ -5,7 +5,10 @@ namespace Avalonia.Utilities
/// <summary> /// <summary>
/// Provides math utilities not provided in System.Math. /// Provides math utilities not provided in System.Math.
/// </summary> /// </summary>
public static class MathUtilities #if !BUILDTASK
public
#endif
static class MathUtilities
{ {
// smallest such that 1.0+DoubleEpsilon != 1.0 // smallest such that 1.0+DoubleEpsilon != 1.0
internal static readonly double DoubleEpsilon = 2.2204460492503131e-016; internal static readonly double DoubleEpsilon = 2.2204460492503131e-016;

5
src/Avalonia.Base/Utilities/StringTokenizer.cs

@ -4,7 +4,10 @@ using static System.Char;
namespace Avalonia.Utilities namespace Avalonia.Utilities
{ {
public struct StringTokenizer : IDisposable #if !BUILDTASK
public
#endif
struct StringTokenizer : IDisposable
{ {
private const char DefaultSeparatorChar = ','; private const char DefaultSeparatorChar = ',';

24
src/Avalonia.Build.Tasks/Avalonia.Build.Tasks.csproj

@ -45,6 +45,12 @@
<Compile Include="../Avalonia.Base/Utilities/IdentifierParser.cs"> <Compile Include="../Avalonia.Base/Utilities/IdentifierParser.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link> <Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile> </Compile>
<Compile Include="../Avalonia.Base/Utilities/StringTokenizer.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
<Compile Include="../Avalonia.Base/Utilities/MathUtilities.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
<Compile Include="..\Markup\Avalonia.Markup\Markup\Parsers\ArgumentListParser.cs"> <Compile Include="..\Markup\Avalonia.Markup\Markup\Parsers\ArgumentListParser.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link> <Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile> </Compile>
@ -57,6 +63,24 @@
<Compile Include="../Avalonia.Base/Utilities/StyleClassParser.cs"> <Compile Include="../Avalonia.Base/Utilities/StyleClassParser.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link> <Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile> </Compile>
<Compile Include="../Avalonia.Visuals/Thickness.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
<Compile Include="../Avalonia.Visuals/Size.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
<Compile Include="../Avalonia.Visuals/Vector.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
<Compile Include="../Avalonia.Visuals/Point.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
<Compile Include="../Avalonia.Visuals/Matrix.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
<Compile Include="../Avalonia.Visuals/CornerRadius.cs">
<Link>Markup/%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
<Compile Remove="../Markup/Avalonia.Markup.Xaml.Loader\xamlil.github\**\obj\**\*.cs" /> <Compile Remove="../Markup/Avalonia.Markup.Xaml.Loader\xamlil.github\**\obj\**\*.cs" />
<Compile Remove="../Markup/Avalonia.Markup.Xaml.Loader\xamlil.github\src\XamlX\IL\SreTypeSystem.cs" /> <Compile Remove="../Markup/Avalonia.Markup.Xaml.Loader\xamlil.github\src\XamlX\IL\SreTypeSystem.cs" />
<PackageReference Include="Mono.Cecil" Version="0.11.2" /> <PackageReference Include="Mono.Cecil" Version="0.11.2" />

4
src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs

@ -46,7 +46,9 @@ namespace Avalonia.Build.Tasks
string output, bool verifyIl, MessageImportance logImportance, string strongNameKey, bool patchCom, string output, bool verifyIl, MessageImportance logImportance, string strongNameKey, bool patchCom,
bool skipXamlCompilation) bool skipXamlCompilation)
{ {
var typeSystem = new CecilTypeSystem(references.Concat(new[] { input }), input); var typeSystem = new CecilTypeSystem(references
.Where(r => !r.ToLowerInvariant().EndsWith("avalonia.build.tasks.dll"))
.Concat(new[] { input }), input);
var asm = typeSystem.TargetAssemblyDefinition; var asm = typeSystem.TargetAssemblyDefinition;

32
src/Avalonia.Controls/ComboBox.cs

@ -173,11 +173,10 @@ namespace Avalonia.Controls
ComboBoxItem.ContentTemplateProperty); ComboBoxItem.ContentTemplateProperty);
} }
/// <inheritdoc/> protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{ {
base.OnAttachedToLogicalTree(e); base.OnAttachedToVisualTree(e);
this.UpdateSelectionBoxItem(this.SelectedItem); this.UpdateSelectionBoxItem(SelectedItem);
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -373,19 +372,22 @@ namespace Avalonia.Controls
if (control != null) if (control != null)
{ {
control.Measure(Size.Infinity); if (VisualRoot is object)
SelectionBoxItem = new Rectangle
{ {
Width = control.DesiredSize.Width, control.Measure(Size.Infinity);
Height = control.DesiredSize.Height,
Fill = new VisualBrush SelectionBoxItem = new Rectangle
{ {
Visual = control, Width = control.DesiredSize.Width,
Stretch = Stretch.None, Height = control.DesiredSize.Height,
AlignmentX = AlignmentX.Left, Fill = new VisualBrush
} {
}; Visual = control,
Stretch = Stretch.None,
AlignmentX = AlignmentX.Left,
}
};
}
} }
else else
{ {

9
src/Avalonia.Visuals/CornerRadius.cs

@ -1,6 +1,8 @@
using System; using System;
using System.Globalization; using System.Globalization;
#if !BUILDTASK
using Avalonia.Animation.Animators; using Avalonia.Animation.Animators;
#endif
using Avalonia.Utilities; using Avalonia.Utilities;
namespace Avalonia namespace Avalonia
@ -8,11 +10,16 @@ namespace Avalonia
/// <summary> /// <summary>
/// Represents the radii of a rectangle's corners. /// Represents the radii of a rectangle's corners.
/// </summary> /// </summary>
public readonly struct CornerRadius : IEquatable<CornerRadius> #if !BUILDTASK
public
#endif
readonly struct CornerRadius : IEquatable<CornerRadius>
{ {
static CornerRadius() static CornerRadius()
{ {
#if !BUILDTASK
Animation.Animation.RegisterAnimator<CornerRadiusAnimator>(prop => typeof(CornerRadius).IsAssignableFrom(prop.PropertyType)); Animation.Animation.RegisterAnimator<CornerRadiusAnimator>(prop => typeof(CornerRadius).IsAssignableFrom(prop.PropertyType));
#endif
} }
public CornerRadius(double uniformRadius) public CornerRadius(double uniformRadius)

5
src/Avalonia.Visuals/Matrix.cs

@ -7,7 +7,10 @@ namespace Avalonia
/// <summary> /// <summary>
/// A 2x3 matrix. /// A 2x3 matrix.
/// </summary> /// </summary>
public readonly struct Matrix : IEquatable<Matrix> #if !BUILDTASK
public
#endif
readonly struct Matrix : IEquatable<Matrix>
{ {
private readonly double _m11; private readonly double _m11;
private readonly double _m12; private readonly double _m12;

9
src/Avalonia.Visuals/Point.cs

@ -1,6 +1,8 @@
using System; using System;
using System.Globalization; using System.Globalization;
#if !BUILDTASK
using Avalonia.Animation.Animators; using Avalonia.Animation.Animators;
#endif
using Avalonia.Utilities; using Avalonia.Utilities;
namespace Avalonia namespace Avalonia
@ -8,11 +10,16 @@ namespace Avalonia
/// <summary> /// <summary>
/// Defines a point. /// Defines a point.
/// </summary> /// </summary>
public readonly struct Point : IEquatable<Point> #if !BUILDTASK
public
#endif
readonly struct Point : IEquatable<Point>
{ {
static Point() static Point()
{ {
#if !BUILDTASK
Animation.Animation.RegisterAnimator<PointAnimator>(prop => typeof(Point).IsAssignableFrom(prop.PropertyType)); Animation.Animation.RegisterAnimator<PointAnimator>(prop => typeof(Point).IsAssignableFrom(prop.PropertyType));
#endif
} }
/// <summary> /// <summary>

9
src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

@ -24,7 +24,8 @@ namespace Avalonia.Rendering.SceneGraph
using (var impl = new DeferredDrawingContextImpl(this, scene.Layers)) using (var impl = new DeferredDrawingContextImpl(this, scene.Layers))
using (var context = new DrawingContext(impl)) using (var context = new DrawingContext(impl))
{ {
Update(context, scene, (VisualNode)scene.Root, scene.Root.Visual.Bounds, true); var clip = new Rect(scene.Root.Visual.Bounds.Size);
Update(context, scene, (VisualNode)scene.Root, clip, true);
} }
} }
@ -77,7 +78,7 @@ namespace Avalonia.Rendering.SceneGraph
using (var impl = new DeferredDrawingContextImpl(this, scene.Layers)) using (var impl = new DeferredDrawingContextImpl(this, scene.Layers))
using (var context = new DrawingContext(impl)) using (var context = new DrawingContext(impl))
{ {
var clip = scene.Root.Visual.Bounds; var clip = new Rect(scene.Root.Visual.Bounds.Size);
if (node.Parent != null) if (node.Parent != null)
{ {
@ -174,7 +175,9 @@ namespace Avalonia.Rendering.SceneGraph
if (visual.IsVisible) if (visual.IsVisible)
{ {
var m = Matrix.CreateTranslation(visual.Bounds.Position); var m = node != scene.Root ?
Matrix.CreateTranslation(visual.Bounds.Position) :
Matrix.Identity;
var renderTransform = Matrix.Identity; var renderTransform = Matrix.Identity;

9
src/Avalonia.Visuals/Size.cs

@ -1,6 +1,8 @@
using System; using System;
using System.Globalization; using System.Globalization;
#if !BUILDTASK
using Avalonia.Animation.Animators; using Avalonia.Animation.Animators;
#endif
using Avalonia.Utilities; using Avalonia.Utilities;
namespace Avalonia namespace Avalonia
@ -8,11 +10,16 @@ namespace Avalonia
/// <summary> /// <summary>
/// Defines a size. /// Defines a size.
/// </summary> /// </summary>
public readonly struct Size : IEquatable<Size> #if !BUILDTASK
public
#endif
readonly struct Size : IEquatable<Size>
{ {
static Size() static Size()
{ {
#if !BUILDTASK
Animation.Animation.RegisterAnimator<SizeAnimator>(prop => typeof(Size).IsAssignableFrom(prop.PropertyType)); Animation.Animation.RegisterAnimator<SizeAnimator>(prop => typeof(Size).IsAssignableFrom(prop.PropertyType));
#endif
} }
/// <summary> /// <summary>

9
src/Avalonia.Visuals/Thickness.cs

@ -1,6 +1,8 @@
using System; using System;
using System.Globalization; using System.Globalization;
#if !BUILDTASK
using Avalonia.Animation.Animators; using Avalonia.Animation.Animators;
#endif
using Avalonia.Utilities; using Avalonia.Utilities;
namespace Avalonia namespace Avalonia
@ -8,11 +10,16 @@ namespace Avalonia
/// <summary> /// <summary>
/// Describes the thickness of a frame around a rectangle. /// Describes the thickness of a frame around a rectangle.
/// </summary> /// </summary>
public readonly struct Thickness : IEquatable<Thickness> #if !BUILDTASK
public
#endif
readonly struct Thickness : IEquatable<Thickness>
{ {
static Thickness() static Thickness()
{ {
#if !BUILDTASK
Animation.Animation.RegisterAnimator<ThicknessAnimator>(prop => typeof(Thickness).IsAssignableFrom(prop.PropertyType)); Animation.Animation.RegisterAnimator<ThicknessAnimator>(prop => typeof(Thickness).IsAssignableFrom(prop.PropertyType));
#endif
} }
/// <summary> /// <summary>

9
src/Avalonia.Visuals/Vector.cs

@ -1,6 +1,8 @@
using System; using System;
using System.Globalization; using System.Globalization;
#if !BUILDTASK
using Avalonia.Animation.Animators; using Avalonia.Animation.Animators;
#endif
using Avalonia.Utilities; using Avalonia.Utilities;
#nullable enable #nullable enable
@ -10,11 +12,16 @@ namespace Avalonia
/// <summary> /// <summary>
/// Defines a vector. /// Defines a vector.
/// </summary> /// </summary>
public readonly struct Vector : IEquatable<Vector> #if !BUILDTASK
public
#endif
readonly struct Vector : IEquatable<Vector>
{ {
static Vector() static Vector()
{ {
#if !BUILDTASK
Animation.Animation.RegisterAnimator<VectorAnimator>(prop => typeof(Vector).IsAssignableFrom(prop.PropertyType)); Animation.Animation.RegisterAnimator<VectorAnimator>(prop => typeof(Vector).IsAssignableFrom(prop.PropertyType));
#endif
} }
/// <summary> /// <summary>

1
src/Markup/Avalonia.Markup.Xaml.Loader/Avalonia.Markup.Xaml.Loader.csproj

@ -4,6 +4,7 @@
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<PackageId>Avalonia.Markup.Xaml.Loader</PackageId> <PackageId>Avalonia.Markup.Xaml.Loader</PackageId>
<DefineConstants>$(DefineConstants);XAMLX_INTERNAL</DefineConstants>
</PropertyGroup> </PropertyGroup>
<Import Project="IncludeXamlIlSre.props" /> <Import Project="IncludeXamlIlSre.props" />
<ItemGroup> <ItemGroup>

54
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AstNodes/AvaloniaXamlIlVectorLikeConstantAstNode.cs

@ -0,0 +1,54 @@
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers;
using XamlX;
using XamlX.Ast;
using XamlX.Emit;
using XamlX.IL;
using XamlX.TypeSystem;
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.AstNodes
{
class AvaloniaXamlIlVectorLikeConstantAstNode : XamlAstNode, IXamlAstValueNode, IXamlAstILEmitableNode
{
private readonly IXamlConstructor _constructor;
private readonly double[] _values;
public AvaloniaXamlIlVectorLikeConstantAstNode(IXamlLineInfo lineInfo, AvaloniaXamlIlWellKnownTypes types, IXamlType type, IXamlConstructor constructor, double[] values) : base(lineInfo)
{
var parameters = constructor.Parameters;
if (parameters.Count != values.Length)
{
throw new XamlTypeSystemException($"Constructor that takes {values.Length} parameters is expected, got {parameters.Count} instead.");
}
var elementType = types.XamlIlTypes.Double;
foreach (var parameter in parameters)
{
if (parameter != elementType)
{
throw new XamlTypeSystemException($"Expected parameter of type {elementType}, got {parameter} instead.");
}
}
_constructor = constructor;
_values = values;
Type = new XamlAstClrTypeReference(lineInfo, type, false);
}
public IXamlAstTypeReference Type { get; }
public XamlILNodeEmitResult Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
{
foreach (var value in _values)
{
codeGen.Ldc_R8(value);
}
codeGen.Newobj(_constructor);
return XamlILNodeEmitResult.Type(0, Type.GetClrType());
}
}
}

60
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs

@ -205,6 +205,66 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
result = new AvaloniaXamlIlFontFamilyAstNode(types, text, node); result = new AvaloniaXamlIlFontFamilyAstNode(types, text, node);
return true; return true;
} }
if (type.Equals(types.Thickness))
{
var thickness = Thickness.Parse(text);
result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Thickness, types.ThicknessFullConstructor,
new[] { thickness.Left, thickness.Top, thickness.Right, thickness.Bottom });
return true;
}
if (type.Equals(types.Point))
{
var point = Point.Parse(text);
result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Point, types.PointFullConstructor,
new[] { point.X, point.Y });
return true;
}
if (type.Equals(types.Vector))
{
var vector = Vector.Parse(text);
result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Vector, types.VectorFullConstructor,
new[] { vector.X, vector.Y });
return true;
}
if (type.Equals(types.Size))
{
var size = Size.Parse(text);
result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Size, types.SizeFullConstructor,
new[] { size.Width, size.Height });
return true;
}
if (type.Equals(types.Matrix))
{
var matrix = Matrix.Parse(text);
result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Matrix, types.MatrixFullConstructor,
new[] { matrix.M11, matrix.M12, matrix.M21, matrix.M22, matrix.M31, matrix.M32 });
return true;
}
if (type.Equals(types.CornerRadius))
{
var cornerRadius = CornerRadius.Parse(text);
result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.CornerRadius, types.CornerRadiusFullConstructor,
new[] { cornerRadius.TopLeft, cornerRadius.TopRight, cornerRadius.BottomRight, cornerRadius.BottomLeft });
return true;
}
if (type.FullName == "Avalonia.AvaloniaProperty") if (type.FullName == "Avalonia.AvaloniaProperty")
{ {

31
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using XamlX.Emit; using XamlX.Emit;
using XamlX.IL; using XamlX.IL;
using XamlX.Transform; using XamlX.Transform;
@ -52,7 +53,18 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlType Uri { get; } public IXamlType Uri { get; }
public IXamlType FontFamily { get; } public IXamlType FontFamily { get; }
public IXamlConstructor FontFamilyConstructorUriName { get; } public IXamlConstructor FontFamilyConstructorUriName { get; }
public IXamlType Thickness { get; }
public IXamlConstructor ThicknessFullConstructor { get; }
public IXamlType Point { get; }
public IXamlConstructor PointFullConstructor { get; }
public IXamlType Vector { get; }
public IXamlConstructor VectorFullConstructor { get; }
public IXamlType Size { get; }
public IXamlConstructor SizeFullConstructor { get; }
public IXamlType Matrix { get; }
public IXamlConstructor MatrixFullConstructor { get; }
public IXamlType CornerRadius { get; }
public IXamlConstructor CornerRadiusFullConstructor { get; }
public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg)
{ {
@ -113,7 +125,22 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
Long = cfg.TypeSystem.GetType("System.Int64"); Long = cfg.TypeSystem.GetType("System.Int64");
Uri = cfg.TypeSystem.GetType("System.Uri"); Uri = cfg.TypeSystem.GetType("System.Uri");
FontFamily = cfg.TypeSystem.GetType("Avalonia.Media.FontFamily"); FontFamily = cfg.TypeSystem.GetType("Avalonia.Media.FontFamily");
FontFamilyConstructorUriName = FontFamily.FindConstructor(new List<IXamlType> { Uri, XamlIlTypes.String }); FontFamilyConstructorUriName = FontFamily.GetConstructor(new List<IXamlType> { Uri, XamlIlTypes.String });
(IXamlType, IXamlConstructor) GetNumericTypeInfo(string name, IXamlType componentType, int componentCount)
{
var type = cfg.TypeSystem.GetType(name);
var ctor = type.GetConstructor(Enumerable.Range(0, componentCount).Select(_ => componentType).ToList());
return (type, ctor);
}
(Thickness, ThicknessFullConstructor) = GetNumericTypeInfo("Avalonia.Thickness", XamlIlTypes.Double, 4);
(Point, PointFullConstructor) = GetNumericTypeInfo("Avalonia.Point", XamlIlTypes.Double, 2);
(Vector, VectorFullConstructor) = GetNumericTypeInfo("Avalonia.Vector", XamlIlTypes.Double, 2);
(Size, SizeFullConstructor) = GetNumericTypeInfo("Avalonia.Size", XamlIlTypes.Double, 2);
(Matrix, MatrixFullConstructor) = GetNumericTypeInfo("Avalonia.Matrix", XamlIlTypes.Double, 6);
(CornerRadius, CornerRadiusFullConstructor) = GetNumericTypeInfo("Avalonia.CornerRadius", XamlIlTypes.Double, 4);
} }
} }

2
src/Markup/Avalonia.Markup.Xaml.Loader/xamlil.github

@ -1 +1 @@
Subproject commit 5420df861ce6f2be5ead9efa078fe7242ce88f18 Subproject commit ea80a607c5e9d8f000160dbbb48c27ed4cfafbc9

12
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -434,7 +434,7 @@ namespace Avalonia.Skia
/// <inheritdoc /> /// <inheritdoc />
public IDrawingContextLayerImpl CreateLayer(Size size) public IDrawingContextLayerImpl CreateLayer(Size size)
{ {
return CreateRenderTarget( size); return CreateRenderTarget(size, true);
} }
/// <inheritdoc /> /// <inheritdoc />
@ -673,7 +673,7 @@ namespace Avalonia.Skia
private void ConfigureTileBrush(ref PaintWrapper paintWrapper, Size targetSize, ITileBrush tileBrush, IDrawableBitmapImpl tileBrushImage) private void ConfigureTileBrush(ref PaintWrapper paintWrapper, Size targetSize, ITileBrush tileBrush, IDrawableBitmapImpl tileBrushImage)
{ {
var calc = new TileBrushCalculator(tileBrush, tileBrushImage.PixelSize.ToSizeWithDpi(_dpi), targetSize); var calc = new TileBrushCalculator(tileBrush, tileBrushImage.PixelSize.ToSizeWithDpi(_dpi), targetSize);
var intermediate = CreateRenderTarget(calc.IntermediateSize); var intermediate = CreateRenderTarget(calc.IntermediateSize, false);
paintWrapper.AddDisposable(intermediate); paintWrapper.AddDisposable(intermediate);
@ -748,7 +748,7 @@ namespace Avalonia.Skia
if (intermediateSize.Width >= 1 && intermediateSize.Height >= 1) if (intermediateSize.Width >= 1 && intermediateSize.Height >= 1)
{ {
var intermediate = CreateRenderTarget(intermediateSize); var intermediate = CreateRenderTarget(intermediateSize, false);
using (var ctx = intermediate.CreateDrawingContext(visualBrushRenderer)) using (var ctx = intermediate.CreateDrawingContext(visualBrushRenderer))
{ {
@ -978,9 +978,10 @@ namespace Avalonia.Skia
/// Create new render target compatible with this drawing context. /// Create new render target compatible with this drawing context.
/// </summary> /// </summary>
/// <param name="size">The size of the render target in DIPs.</param> /// <param name="size">The size of the render target in DIPs.</param>
/// <param name="isLayer">Whether the render target is being created for a layer.</param>
/// <param name="format">Pixel format.</param> /// <param name="format">Pixel format.</param>
/// <returns></returns> /// <returns></returns>
private SurfaceRenderTarget CreateRenderTarget(Size size, PixelFormat? format = null) private SurfaceRenderTarget CreateRenderTarget(Size size, bool isLayer, PixelFormat? format = null)
{ {
var pixelSize = PixelSize.FromSizeWithDpi(size, _dpi); var pixelSize = PixelSize.FromSizeWithDpi(size, _dpi);
var createInfo = new SurfaceRenderTarget.CreateInfo var createInfo = new SurfaceRenderTarget.CreateInfo
@ -992,7 +993,8 @@ namespace Avalonia.Skia
DisableTextLcdRendering = !_canTextUseLcdRendering, DisableTextLcdRendering = !_canTextUseLcdRendering,
GrContext = _grContext, GrContext = _grContext,
Gpu = _gpu, Gpu = _gpu,
Session = _session Session = _session,
DisableManualFbo = !isLayer,
}; };
return new SurfaceRenderTarget(createInfo); return new SurfaceRenderTarget(createInfo);

3
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -124,7 +124,8 @@ namespace Avalonia.Skia
Width = size.Width, Width = size.Width,
Height = size.Height, Height = size.Height,
Dpi = dpi, Dpi = dpi,
DisableTextLcdRendering = false DisableTextLcdRendering = false,
DisableManualFbo = true,
}; };
return new SurfaceRenderTarget(createInfo); return new SurfaceRenderTarget(createInfo);

5
src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs

@ -51,7 +51,8 @@ namespace Avalonia.Skia
_grContext = createInfo.GrContext; _grContext = createInfo.GrContext;
_gpu = createInfo.Gpu; _gpu = createInfo.Gpu;
_surface = _gpu?.TryCreateSurface(PixelSize, createInfo.Session); if (!createInfo.DisableManualFbo)
_surface = _gpu?.TryCreateSurface(PixelSize, createInfo.Session);
if (_surface == null) if (_surface == null)
_surface = new SkiaSurfaceWrapper(CreateSurface(createInfo.GrContext, PixelSize.Width, PixelSize.Height, _surface = new SkiaSurfaceWrapper(CreateSurface(createInfo.GrContext, PixelSize.Width, PixelSize.Height,
createInfo.Format)); createInfo.Format));
@ -220,6 +221,8 @@ namespace Avalonia.Skia
public ISkiaGpu Gpu; public ISkiaGpu Gpu;
public ISkiaGpuRenderSession Session; public ISkiaGpuRenderSession Session;
public bool DisableManualFbo;
} }
} }
} }

1
tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs

@ -40,6 +40,7 @@ namespace Avalonia.Controls.UnitTests
Items = items, Items = items,
SelectedIndex = 0, SelectedIndex = 0,
}; };
var root = new TestRoot(target);
var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle; var rectangle = target.GetValue(ComboBox.SelectionBoxItemProperty) as Rectangle;
Assert.NotNull(rectangle); Assert.NotNull(rectangle);

29
tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs

@ -374,7 +374,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
</Window.DataTemplates> </Window.DataTemplates>
<ContentControl Name='target' Content='{CompiledBinding}' /> <ContentControl Name='target' Content='{CompiledBinding}' />
</Window>"; </Window>";
Assert.Throws<XamlTransformException>(() => AvaloniaRuntimeXamlLoader.Load(xaml)); ThrowsXamlTransformException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
} }
} }
@ -392,7 +392,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
<TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' /> <TextBlock Text='{CompiledBinding StringProperty}' Name='textBlock' />
</ContentControl> </ContentControl>
</Window>"; </Window>";
Assert.Throws<XamlTransformException>(() => AvaloniaRuntimeXamlLoader.Load(xaml)); ThrowsXamlTransformException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
} }
} }
@ -449,7 +449,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
</ItemsControl.DataTemplates> </ItemsControl.DataTemplates>
</ItemsControl> </ItemsControl>
</Window>"; </Window>";
Assert.Throws<XamlTransformException>(() => AvaloniaRuntimeXamlLoader.Load(xaml)); ThrowsXamlTransformException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
} }
} }
@ -599,7 +599,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
x:CompileBindings='true'> x:CompileBindings='true'>
<TextBlock Text='{Binding InvalidPath}' Name='textBlock' /> <TextBlock Text='{Binding InvalidPath}' Name='textBlock' />
</Window>"; </Window>";
Assert.Throws<XamlX.XamlParseException>(() => AvaloniaRuntimeXamlLoader.Load(xaml)); ThrowsXamlParseException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
} }
} }
@ -657,7 +657,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
x:DataType='local:TestDataContext' x:DataType='local:TestDataContext'
x:CompileBindings='notabool'> x:CompileBindings='notabool'>
</Window>"; </Window>";
Assert.Throws<XamlX.XamlParseException>(() => AvaloniaRuntimeXamlLoader.Load(xaml)); ThrowsXamlParseException(() => AvaloniaRuntimeXamlLoader.Load(xaml));
} }
} }
@ -818,8 +818,25 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
Assert.Equal(null, contentControl.Content); Assert.Equal(null, contentControl.Content);
} }
} }
}
void Throws(string type, Action cb)
{
try
{
cb();
}
catch (Exception e) when (e.GetType().Name == type)
{
return;
}
throw new Exception("Expected " + type);
}
void ThrowsXamlParseException(Action cb) => Throws("XamlParseException", cb);
void ThrowsXamlTransformException(Action cb) => Throws("XamlTransformException", cb);
}
public interface INonIntegerIndexer public interface INonIntegerIndexer
{ {
string this[string key] { get; set; } string this[string key] { get; set; }

Loading…
Cancel
Save