diff --git a/host/Generated/ObjectModel/.avalonia-projection.owned.json b/host/Generated/ObjectModel/.avalonia-projection.owned.json
index 51bb1cc..9cd0608 100644
--- a/host/Generated/ObjectModel/.avalonia-projection.owned.json
+++ b/host/Generated/ObjectModel/.avalonia-projection.owned.json
@@ -211,7 +211,7 @@
},
{
"path": "IAvnControlFactory.g.cs",
- "sha256": "0b16561747ebc843651c90574e80d5b5d4047ed1de15580b1017579f521a3d0d"
+ "sha256": "07be8008a7c14ec38af1880e95e298db3d99e04842f58fd2f46504c591fb0cc7"
},
{
"path": "IAvnControlGotFocusHandler.g.cs",
@@ -337,6 +337,10 @@
"path": "IAvnFlyoutBaseOpenedHandler.g.cs",
"sha256": "c1cf785f23a37d4a3ce5855a5df4bdff1442b7a7674713f4e52bc110537b1234"
},
+ {
+ "path": "IAvnGradientBrush.g.cs",
+ "sha256": "01ffe32aea0231c96b18f33edf4e8555e5750690df40b3495a2527a6dcdd16b7"
+ },
{
"path": "IAvnGrid.g.cs",
"sha256": "7454a3819c730c3ce65e84e0c923321d052bdc231f8aabb178df4b522e4db447"
@@ -855,7 +859,7 @@
},
{
"path": "ProjectionAotRoots.g.cs",
- "sha256": "849532b0244176520ffc5b3fd818e753cb461fd7370adc9a4a2106c4a6cb3293"
+ "sha256": "d20f7a57fa84c816ab3b8913217378172da893efa5470a710a323e05d740cfbc"
},
{
"path": "ProjectionRuntime.g.cs",
@@ -863,7 +867,7 @@
},
{
"path": "ProjectionStructs.g.cs",
- "sha256": "e3179d44738612e7815e2c6823b7a5c7c3aabc9ea609bfca05cfee5cb16d0b56"
+ "sha256": "0be6a5d527ac6b2ae728fe016e4372b88bc09ecf6f3bf30b8bb34725b05bfb85"
}
]
}
diff --git a/host/Generated/ObjectModel/IAvnControlFactory.g.cs b/host/Generated/ObjectModel/IAvnControlFactory.g.cs
index f2e7fd1..bb082a4 100644
--- a/host/Generated/ObjectModel/IAvnControlFactory.g.cs
+++ b/host/Generated/ObjectModel/IAvnControlFactory.g.cs
@@ -7,7 +7,7 @@
namespace Avalonia.Host.Com;
[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)]
-[Guid("15778134-9E9F-5BAF-98FF-5510778094BA")]
+[Guid("C8BCE8E8-62C7-5E0E-8066-690059F55DFF")]
public partial interface IAvnControlFactory
{
[PreserveSig]
@@ -319,6 +319,12 @@ public partial interface IAvnControlFactory
[PreserveSig]
int CreateSolidColorBrush(AvnColor color, double opacity, out IAvnBrush? value);
+ [PreserveSig]
+ int CreateLinearGradientBrush(double opacity, int spreadMethod, int stopCount, AvnGradientStopBuffer stops, AvnRelativePoint startPoint, AvnRelativePoint endPoint, out IAvnLinearGradientBrush? value);
+
+ [PreserveSig]
+ int CreateRadialGradientBrush(double opacity, int spreadMethod, int stopCount, AvnGradientStopBuffer stops, AvnRelativePoint center, AvnRelativePoint gradientOrigin, AvnRelativeScalar radiusX, AvnRelativeScalar radiusY, out IAvnRadialGradientBrush? value);
+
}
[GeneratedComClass]
@@ -1815,4 +1821,22 @@ public int CreateSolidColorBrush(AvnColor color, double opacity, out IAvnBrush?
return global::Avalonia.Host.HResults.S_OK;
}
+ public int CreateLinearGradientBrush(double opacity, int spreadMethod, int stopCount, AvnGradientStopBuffer stops, AvnRelativePoint startPoint, AvnRelativePoint endPoint, out IAvnLinearGradientBrush? value)
+ {
+ value = null;
+ if (stopCount < 0 || stopCount > 8)
+ return global::Avalonia.Host.HResults.E_INVALIDARG;
+ value = new AvnLinearGradientBrush(opacity, spreadMethod, stopCount, stops, startPoint, endPoint);
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int CreateRadialGradientBrush(double opacity, int spreadMethod, int stopCount, AvnGradientStopBuffer stops, AvnRelativePoint center, AvnRelativePoint gradientOrigin, AvnRelativeScalar radiusX, AvnRelativeScalar radiusY, out IAvnRadialGradientBrush? value)
+ {
+ value = null;
+ if (stopCount < 0 || stopCount > 8)
+ return global::Avalonia.Host.HResults.E_INVALIDARG;
+ value = new AvnRadialGradientBrush(opacity, spreadMethod, stopCount, stops, center, gradientOrigin, radiusX, radiusY);
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
}
diff --git a/host/Generated/ObjectModel/IAvnGradientBrush.g.cs b/host/Generated/ObjectModel/IAvnGradientBrush.g.cs
new file mode 100644
index 0000000..7dea5a1
--- /dev/null
+++ b/host/Generated/ObjectModel/IAvnGradientBrush.g.cs
@@ -0,0 +1,305 @@
+//
+#nullable enable
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.Marshalling;
+
+namespace Avalonia.Host.Com;
+
+/// Capability shared by every gradient brush kind projected across the ABI.
+///
+/// A gradient brush object also implements IAvnBrush so it satisfies every
+/// brush-typed slot, but its GetColor still fails with AVN_E_NONSOLIDBRUSH;
+/// callers must query for this interface (or a derived one) to read the gradient.
+/// Stops beyond the fixed capacity of are rejected
+/// when the brush is minted for the ABI.
+///
+[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)]
+[Guid("FDAA2353-BC44-5012-A5BE-A17C7C01F41A")]
+public partial interface IAvnGradientBrush
+{
+ [PreserveSig]
+ int GetOpacity(out double value);
+
+ /// 0 = Pad, 1 = Reflect, 2 = Repeat (mirrors Avalonia.Media.GradientSpreadMethod).
+ [PreserveSig]
+ int GetSpreadMethod(out int value);
+
+ [PreserveSig]
+ int GetStopCount(out int value);
+
+ [PreserveSig]
+ int GetStops(out AvnGradientStopBuffer value);
+}
+
+/// A brush that draws with a linear gradient.
+[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)]
+[Guid("40B3D53D-330E-5D63-A040-37F1FF717FF8")]
+public partial interface IAvnLinearGradientBrush : IAvnGradientBrush
+{
+ [PreserveSig]
+ int GetStartPoint(out AvnRelativePoint value);
+
+ [PreserveSig]
+ int GetEndPoint(out AvnRelativePoint value);
+}
+
+/// A brush that draws with a radial gradient.
+[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)]
+[Guid("AEC23FCE-9FEA-506C-ABC4-774143BE80C8")]
+public partial interface IAvnRadialGradientBrush : IAvnGradientBrush
+{
+ [PreserveSig]
+ int GetCenter(out AvnRelativePoint value);
+
+ [PreserveSig]
+ int GetGradientOrigin(out AvnRelativePoint value);
+
+ [PreserveSig]
+ int GetRadiusX(out AvnRelativeScalar value);
+
+ [PreserveSig]
+ int GetRadiusY(out AvnRelativeScalar value);
+}
+
+[GeneratedComClass]
+public sealed partial class AvnLinearGradientBrush : global::Avalonia.Host.Com.IAvnBrush, IAvnLinearGradientBrush
+{
+ private readonly double _opacity;
+ private readonly int _spreadMethod;
+ private readonly int _stopCount;
+ private readonly AvnGradientStopBuffer _stops;
+ private readonly AvnRelativePoint _startPoint;
+ private readonly AvnRelativePoint _endPoint;
+
+ internal AvnLinearGradientBrush(double opacity, int spreadMethod, int stopCount, AvnGradientStopBuffer stops, AvnRelativePoint startPoint, AvnRelativePoint endPoint)
+ {
+ _opacity = opacity;
+ _spreadMethod = spreadMethod;
+ _stopCount = stopCount;
+ _stops = stops;
+ _startPoint = startPoint;
+ _endPoint = endPoint;
+ }
+
+ public int GetColor(out AvnColor value)
+ {
+ value = default;
+ return global::Avalonia.Host.HResults.AVN_E_NONSOLIDBRUSH;
+ }
+
+ public int GetOpacity(out double value)
+ {
+ value = _opacity;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetSpreadMethod(out int value)
+ {
+ value = _spreadMethod;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetStopCount(out int value)
+ {
+ value = _stopCount;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetStops(out AvnGradientStopBuffer value)
+ {
+ value = _stops;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetStartPoint(out AvnRelativePoint value)
+ {
+ value = _startPoint;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetEndPoint(out AvnRelativePoint value)
+ {
+ value = _endPoint;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ /// Projects a managed lineargradientbrush, minting the fixed-capacity stop buffer.
+ public static IAvnLinearGradientBrush FromLinearGradientBrush(global::Avalonia.Media.ILinearGradientBrush value)
+ {
+ var stops = value.GradientStops;
+ if (stops.Count > 8)
+ {
+ throw new global::System.NotSupportedException(
+ $"Gradient brush has {stops.Count} stops, more than the 8 supported across the ABI.")
+ {
+ HResult = global::Avalonia.Host.HResults.AVN_E_NONSOLIDBRUSH,
+ };
+ }
+ var buffer = new AvnGradientStopBuffer();
+ for (var i = 0; i < stops.Count; i++)
+ buffer[i] = AvnGradientStop.FromAvalonia(stops[i]);
+ return new AvnLinearGradientBrush(value.Opacity, (int)value.SpreadMethod, stops.Count, buffer, AvnRelativePoint.FromAvalonia(value.StartPoint), AvnRelativePoint.FromAvalonia(value.EndPoint));
+ }
+
+ /// Materialises an immutable lineargradientbrush from the members carried across.
+ public static global::Avalonia.Media.IBrush? ToLinearGradientBrush(IAvnLinearGradientBrush? value)
+ {
+ if (value is null)
+ return null;
+ var hr = value.GetOpacity(out var opacity);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ hr = value.GetSpreadMethod(out var spreadMethod);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ hr = value.GetStopCount(out var stopCount);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ hr = value.GetStops(out var stops);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ var managedStops = new global::Avalonia.Media.Immutable.ImmutableGradientStop[stopCount];
+ for (var i = 0; i < stopCount; i++)
+ managedStops[i] = new global::Avalonia.Media.Immutable.ImmutableGradientStop(stops[i].Offset, stops[i].Color.ToAvalonia());
+ hr = value.GetStartPoint(out var startPoint);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ hr = value.GetEndPoint(out var endPoint);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ return new global::Avalonia.Media.Immutable.ImmutableLinearGradientBrush(managedStops, opacity, transform: null, transformOrigin: null, (global::Avalonia.Media.GradientSpreadMethod)spreadMethod, startPoint.ToAvalonia(), endPoint.ToAvalonia());
+ }
+}
+
+[GeneratedComClass]
+public sealed partial class AvnRadialGradientBrush : global::Avalonia.Host.Com.IAvnBrush, IAvnRadialGradientBrush
+{
+ private readonly double _opacity;
+ private readonly int _spreadMethod;
+ private readonly int _stopCount;
+ private readonly AvnGradientStopBuffer _stops;
+ private readonly AvnRelativePoint _center;
+ private readonly AvnRelativePoint _gradientOrigin;
+ private readonly AvnRelativeScalar _radiusX;
+ private readonly AvnRelativeScalar _radiusY;
+
+ internal AvnRadialGradientBrush(double opacity, int spreadMethod, int stopCount, AvnGradientStopBuffer stops, AvnRelativePoint center, AvnRelativePoint gradientOrigin, AvnRelativeScalar radiusX, AvnRelativeScalar radiusY)
+ {
+ _opacity = opacity;
+ _spreadMethod = spreadMethod;
+ _stopCount = stopCount;
+ _stops = stops;
+ _center = center;
+ _gradientOrigin = gradientOrigin;
+ _radiusX = radiusX;
+ _radiusY = radiusY;
+ }
+
+ public int GetColor(out AvnColor value)
+ {
+ value = default;
+ return global::Avalonia.Host.HResults.AVN_E_NONSOLIDBRUSH;
+ }
+
+ public int GetOpacity(out double value)
+ {
+ value = _opacity;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetSpreadMethod(out int value)
+ {
+ value = _spreadMethod;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetStopCount(out int value)
+ {
+ value = _stopCount;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetStops(out AvnGradientStopBuffer value)
+ {
+ value = _stops;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetCenter(out AvnRelativePoint value)
+ {
+ value = _center;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetGradientOrigin(out AvnRelativePoint value)
+ {
+ value = _gradientOrigin;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetRadiusX(out AvnRelativeScalar value)
+ {
+ value = _radiusX;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ public int GetRadiusY(out AvnRelativeScalar value)
+ {
+ value = _radiusY;
+ return global::Avalonia.Host.HResults.S_OK;
+ }
+
+ /// Projects a managed radialgradientbrush, minting the fixed-capacity stop buffer.
+ public static IAvnRadialGradientBrush FromRadialGradientBrush(global::Avalonia.Media.IRadialGradientBrush value)
+ {
+ var stops = value.GradientStops;
+ if (stops.Count > 8)
+ {
+ throw new global::System.NotSupportedException(
+ $"Gradient brush has {stops.Count} stops, more than the 8 supported across the ABI.")
+ {
+ HResult = global::Avalonia.Host.HResults.AVN_E_NONSOLIDBRUSH,
+ };
+ }
+ var buffer = new AvnGradientStopBuffer();
+ for (var i = 0; i < stops.Count; i++)
+ buffer[i] = AvnGradientStop.FromAvalonia(stops[i]);
+ return new AvnRadialGradientBrush(value.Opacity, (int)value.SpreadMethod, stops.Count, buffer, AvnRelativePoint.FromAvalonia(value.Center), AvnRelativePoint.FromAvalonia(value.GradientOrigin), AvnRelativeScalar.FromAvalonia(value.RadiusX), AvnRelativeScalar.FromAvalonia(value.RadiusY));
+ }
+
+ /// Materialises an immutable radialgradientbrush from the members carried across.
+ public static global::Avalonia.Media.IBrush? ToRadialGradientBrush(IAvnRadialGradientBrush? value)
+ {
+ if (value is null)
+ return null;
+ var hr = value.GetOpacity(out var opacity);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ hr = value.GetSpreadMethod(out var spreadMethod);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ hr = value.GetStopCount(out var stopCount);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ hr = value.GetStops(out var stops);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ var managedStops = new global::Avalonia.Media.Immutable.ImmutableGradientStop[stopCount];
+ for (var i = 0; i < stopCount; i++)
+ managedStops[i] = new global::Avalonia.Media.Immutable.ImmutableGradientStop(stops[i].Offset, stops[i].Color.ToAvalonia());
+ hr = value.GetCenter(out var center);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ hr = value.GetGradientOrigin(out var gradientOrigin);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ hr = value.GetRadiusX(out var radiusX);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ hr = value.GetRadiusY(out var radiusY);
+ if (hr < 0)
+ global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);
+ return new global::Avalonia.Media.Immutable.ImmutableRadialGradientBrush(managedStops, opacity, transform: null, transformOrigin: null, (global::Avalonia.Media.GradientSpreadMethod)spreadMethod, center.ToAvalonia(), gradientOrigin.ToAvalonia(), radiusX.ToAvalonia(), radiusY.ToAvalonia());
+ }
+}
+
diff --git a/host/Generated/ObjectModel/ProjectionAotRoots.g.cs b/host/Generated/ObjectModel/ProjectionAotRoots.g.cs
index 8df1973..f350368 100644
--- a/host/Generated/ObjectModel/ProjectionAotRoots.g.cs
+++ b/host/Generated/ObjectModel/ProjectionAotRoots.g.cs
@@ -10,6 +10,8 @@ internal static class ProjectionAotRoots
{
[global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof(AvnControlFactory))]
[global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof(AvnBrush))]
+ [global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof(AvnLinearGradientBrush))]
+ [global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof(AvnRadialGradientBrush))]
[global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof(AvnCommand))]
[global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof(AvnDataTemplate))]
[global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof(AvnItemFilter))]
diff --git a/host/Generated/ObjectModel/ProjectionStructs.g.cs b/host/Generated/ObjectModel/ProjectionStructs.g.cs
index 2767986..aac38c9 100644
--- a/host/Generated/ObjectModel/ProjectionStructs.g.cs
+++ b/host/Generated/ObjectModel/ProjectionStructs.g.cs
@@ -362,3 +362,56 @@ public void FreeUtf16()
_ => false,
};
}
+
+/// Blittable ABI mirror of Avalonia.RelativePoint.
+/// Unit mirrors Avalonia.RelativeUnit: 0 relative, 1 absolute.
+[StructLayout(LayoutKind.Sequential)]
+public struct AvnRelativePoint
+{
+ public double X;
+ public double Y;
+ public int Unit;
+
+ public static AvnRelativePoint FromAvalonia(global::Avalonia.RelativePoint value) =>
+ new AvnRelativePoint { X = value.Point.X, Y = value.Point.Y, Unit = (int)value.Unit };
+
+ public readonly global::Avalonia.RelativePoint ToAvalonia() =>
+ new global::Avalonia.RelativePoint(X, Y, (global::Avalonia.RelativeUnit)Unit);
+}
+
+/// Blittable ABI mirror of Avalonia.RelativeScalar.
+/// Unit mirrors Avalonia.RelativeUnit: 0 relative, 1 absolute.
+[StructLayout(LayoutKind.Sequential)]
+public struct AvnRelativeScalar
+{
+ public double Scalar;
+ public int Unit;
+
+ public static AvnRelativeScalar FromAvalonia(global::Avalonia.RelativeScalar value) =>
+ new AvnRelativeScalar { Scalar = value.Scalar, Unit = (int)value.Unit };
+
+ public readonly global::Avalonia.RelativeScalar ToAvalonia() =>
+ new global::Avalonia.RelativeScalar(Scalar, (global::Avalonia.RelativeUnit)Unit);
+}
+
+/// Blittable ABI mirror of a single gradient stop (offset plus packed colour).
+[StructLayout(LayoutKind.Sequential)]
+public struct AvnGradientStop
+{
+ public double Offset;
+ public AvnColor Color;
+
+ public static AvnGradientStop FromAvalonia(global::Avalonia.Media.IGradientStop value) =>
+ new AvnGradientStop { Offset = value.Offset, Color = AvnColor.FromAvalonia(value.Color) };
+}
+
+/// Fixed-capacity buffer of up to 8 entries.
+///
+/// Gradient brushes with more stops than this cannot cross the ABI; the count actually in
+/// use is carried separately by IAvnGradientBrush.GetStopCount.
+///
+[System.Runtime.CompilerServices.InlineArray(8)]
+public struct AvnGradientStopBuffer
+{
+ private AvnGradientStop _element0;
+}
diff --git a/projection/Avalonia.Projection.Generator/ComSourceEmitter.cs b/projection/Avalonia.Projection.Generator/ComSourceEmitter.cs
index ca98449..e01f998 100644
--- a/projection/Avalonia.Projection.Generator/ComSourceEmitter.cs
+++ b/projection/Avalonia.Projection.Generator/ComSourceEmitter.cs
@@ -37,6 +37,8 @@ public static IReadOnlyDictionary Emit(ProjectionIr ir)
files["ProjectionStructs.g.cs"] = EmitGeometryStructs(ir);
if (ir.BrushInterfaceName is not null)
files[SimpleName(ir.BrushInterfaceName) + ".g.cs"] = EmitBrush(ir);
+ if (ir.GradientBrushInterfaceName is not null)
+ files[SimpleName(ir.GradientBrushInterfaceName) + ".g.cs"] = EmitGradientBrush(ir);
if (ir.CommandInterfaceName is not null)
files[SimpleName(ir.CommandInterfaceName) + ".g.cs"] = EmitCommand(ir);
if (ir.TemplateInterfaceName is not null)
@@ -437,6 +439,19 @@ public static string EmitFactory(ProjectionIr ir)
$" int {BrushMarshalling.FactoryMethodName}({colorAbiName} color, double opacity, out {brushName}? value);");
sb.AppendLine();
}
+ if (ir.GradientBrushInterfaceName is not null)
+ {
+ var linearName = SimpleName(ir.LinearGradientBrushInterfaceName!);
+ var radialName = SimpleName(ir.RadialGradientBrushInterfaceName!);
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(
+ $" int {GradientBrushMarshalling.CreateLinearFactoryMethodName}(double opacity, int spreadMethod, int stopCount, AvnGradientStopBuffer stops, AvnRelativePoint startPoint, AvnRelativePoint endPoint, out {linearName}? value);");
+ sb.AppendLine();
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(
+ $" int {GradientBrushMarshalling.CreateRadialFactoryMethodName}(double opacity, int spreadMethod, int stopCount, AvnGradientStopBuffer stops, AvnRelativePoint center, AvnRelativePoint gradientOrigin, AvnRelativeScalar radiusX, AvnRelativeScalar radiusY, out {radialName}? value);");
+ sb.AppendLine();
+ }
sb.AppendLine("}");
sb.AppendLine();
sb.AppendLine("[GeneratedComClass]");
@@ -488,6 +503,31 @@ public static string EmitFactory(ProjectionIr ir)
sb.AppendLine(" }");
sb.AppendLine();
}
+ if (ir.GradientBrushInterfaceName is not null)
+ {
+ var linearName = SimpleName(ir.LinearGradientBrushInterfaceName!);
+ var radialName = SimpleName(ir.RadialGradientBrushInterfaceName!);
+ sb.AppendLine(
+ $" public int {GradientBrushMarshalling.CreateLinearFactoryMethodName}(double opacity, int spreadMethod, int stopCount, AvnGradientStopBuffer stops, AvnRelativePoint startPoint, AvnRelativePoint endPoint, out {linearName}? value)");
+ sb.AppendLine(" {");
+ sb.AppendLine(" value = null;");
+ sb.AppendLine($" if (stopCount < 0 || stopCount > {GradientBrushMarshalling.MaxStops})");
+ sb.AppendLine(" return global::Avalonia.Host.HResults.E_INVALIDARG;");
+ sb.AppendLine($" value = new {linearName[1..]}(opacity, spreadMethod, stopCount, stops, startPoint, endPoint);");
+ sb.AppendLine(" return global::Avalonia.Host.HResults.S_OK;");
+ sb.AppendLine(" }");
+ sb.AppendLine();
+ sb.AppendLine(
+ $" public int {GradientBrushMarshalling.CreateRadialFactoryMethodName}(double opacity, int spreadMethod, int stopCount, AvnGradientStopBuffer stops, AvnRelativePoint center, AvnRelativePoint gradientOrigin, AvnRelativeScalar radiusX, AvnRelativeScalar radiusY, out {radialName}? value)");
+ sb.AppendLine(" {");
+ sb.AppendLine(" value = null;");
+ sb.AppendLine($" if (stopCount < 0 || stopCount > {GradientBrushMarshalling.MaxStops})");
+ sb.AppendLine(" return global::Avalonia.Host.HResults.E_INVALIDARG;");
+ sb.AppendLine($" value = new {radialName[1..]}(opacity, spreadMethod, stopCount, stops, center, gradientOrigin, radiusX, radiusY);");
+ sb.AppendLine(" return global::Avalonia.Host.HResults.S_OK;");
+ sb.AppendLine(" }");
+ sb.AppendLine();
+ }
sb.AppendLine("}");
return sb.ToString();
}
@@ -507,6 +547,11 @@ public static string EmitAotRoots(ProjectionIr ir)
{
sb.AppendLine($" [global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof({SimpleName(brushInterfaceName)[1..]}))]");
}
+ if (ir.GradientBrushInterfaceName is not null)
+ {
+ sb.AppendLine($" [global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof({SimpleName(ir.LinearGradientBrushInterfaceName!)[1..]}))]");
+ sb.AppendLine($" [global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof({SimpleName(ir.RadialGradientBrushInterfaceName!)[1..]}))]");
+ }
if (ir.CommandInterfaceName is { } commandInterfaceName)
{
sb.AppendLine($" [global::System.Diagnostics.CodeAnalysis.DynamicDependency(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, typeof({SimpleName(commandInterfaceName)[1..]}))]");
@@ -649,6 +694,246 @@ public static string EmitBrush(ProjectionIr ir)
return sb.ToString();
}
+ public static string EmitGradientBrush(ProjectionIr ir)
+ {
+ var gradientName = SimpleName(ir.GradientBrushInterfaceName
+ ?? throw new InvalidOperationException("The IR declares no projected gradient brush interface."));
+ var linearName = SimpleName(ir.LinearGradientBrushInterfaceName!);
+ var radialName = SimpleName(ir.RadialGradientBrushInterfaceName!);
+ var linearClassName = linearName[1..];
+ var radialClassName = radialName[1..];
+ var colorAbiName = GeometryMarshalling.All
+ .Single(geometry => geometry.Kind == MarshallingKind.Color).AbiName;
+ var sb = new StringBuilder();
+ sb.AppendLine("// ");
+ sb.AppendLine("#nullable enable");
+ sb.AppendLine("using System.Runtime.InteropServices;");
+ sb.AppendLine("using System.Runtime.InteropServices.Marshalling;");
+ sb.AppendLine();
+ sb.AppendLine($"namespace {NamespaceOf(ir.GradientBrushInterfaceName)};");
+ sb.AppendLine();
+ sb.AppendLine("/// Capability shared by every gradient brush kind projected across the ABI.");
+ sb.AppendLine("/// ");
+ sb.AppendLine("/// A gradient brush object also implements IAvnBrush so it satisfies every");
+ sb.AppendLine("/// brush-typed slot, but its GetColor still fails with AVN_E_NONSOLIDBRUSH;");
+ sb.AppendLine("/// callers must query for this interface (or a derived one) to read the gradient.");
+ sb.AppendLine("/// Stops beyond the fixed capacity of are rejected");
+ sb.AppendLine("/// when the brush is minted for the ABI.");
+ sb.AppendLine("/// ");
+ sb.AppendLine("[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)]");
+ sb.AppendLine($"[Guid(\"{ir.GradientBrushInterfaceIid}\")]");
+ sb.AppendLine($"public partial interface {gradientName}");
+ sb.AppendLine("{");
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(" int GetOpacity(out double value);");
+ sb.AppendLine();
+ sb.AppendLine(" /// 0 = Pad, 1 = Reflect, 2 = Repeat (mirrors Avalonia.Media.GradientSpreadMethod).");
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(" int GetSpreadMethod(out int value);");
+ sb.AppendLine();
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(" int GetStopCount(out int value);");
+ sb.AppendLine();
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(" int GetStops(out AvnGradientStopBuffer value);");
+ sb.AppendLine("}");
+ sb.AppendLine();
+ sb.AppendLine("/// A brush that draws with a linear gradient.");
+ sb.AppendLine("[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)]");
+ sb.AppendLine($"[Guid(\"{ir.LinearGradientBrushInterfaceIid}\")]");
+ sb.AppendLine($"public partial interface {linearName} : {gradientName}");
+ sb.AppendLine("{");
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(" int GetStartPoint(out AvnRelativePoint value);");
+ sb.AppendLine();
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(" int GetEndPoint(out AvnRelativePoint value);");
+ sb.AppendLine("}");
+ sb.AppendLine();
+ sb.AppendLine("/// A brush that draws with a radial gradient.");
+ sb.AppendLine("[GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)]");
+ sb.AppendLine($"[Guid(\"{ir.RadialGradientBrushInterfaceIid}\")]");
+ sb.AppendLine($"public partial interface {radialName} : {gradientName}");
+ sb.AppendLine("{");
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(" int GetCenter(out AvnRelativePoint value);");
+ sb.AppendLine();
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(" int GetGradientOrigin(out AvnRelativePoint value);");
+ sb.AppendLine();
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(" int GetRadiusX(out AvnRelativeScalar value);");
+ sb.AppendLine();
+ sb.AppendLine(" [PreserveSig]");
+ sb.AppendLine(" int GetRadiusY(out AvnRelativeScalar value);");
+ sb.AppendLine("}");
+ sb.AppendLine();
+
+ EmitGradientBrushClass(
+ sb,
+ className: linearClassName,
+ interfaceName: linearName,
+ gradientInterfaceName: gradientName,
+ managedTypeName: GradientBrushMarshalling.LinearManagedTypeName,
+ immutableManagedTypeName: GradientBrushMarshalling.ImmutableLinearManagedTypeName,
+ colorAbiName: colorAbiName,
+ shapeFields:
+ [
+ ("AvnRelativePoint", "StartPoint", "StartPoint"),
+ ("AvnRelativePoint", "EndPoint", "EndPoint"),
+ ]);
+ EmitGradientBrushClass(
+ sb,
+ className: radialClassName,
+ interfaceName: radialName,
+ gradientInterfaceName: gradientName,
+ managedTypeName: GradientBrushMarshalling.RadialManagedTypeName,
+ immutableManagedTypeName: GradientBrushMarshalling.ImmutableRadialManagedTypeName,
+ colorAbiName: colorAbiName,
+ shapeFields:
+ [
+ ("AvnRelativePoint", "Center", "Center"),
+ ("AvnRelativePoint", "GradientOrigin", "GradientOrigin"),
+ ("AvnRelativeScalar", "RadiusX", "RadiusX"),
+ ("AvnRelativeScalar", "RadiusY", "RadiusY"),
+ ]);
+ return sb.ToString();
+ }
+
+ ///
+ /// Emits one gradient-kind CCW class (linear or radial). lists
+ /// the kind-specific geometry members as (abi struct type, ABI accessor suffix, managed
+ /// property name) tuples, in addition to the opacity/spread-method/stops shared by every
+ /// gradient brush.
+ ///
+ private static void EmitGradientBrushClass(
+ StringBuilder sb,
+ string className,
+ string interfaceName,
+ string gradientInterfaceName,
+ string managedTypeName,
+ string immutableManagedTypeName,
+ string colorAbiName,
+ (string AbiType, string Accessor, string ManagedProperty)[] shapeFields)
+ {
+ sb.AppendLine("[GeneratedComClass]");
+ sb.AppendLine($"public sealed partial class {className} : global::Avalonia.Host.Com.IAvnBrush, {interfaceName}");
+ sb.AppendLine("{");
+ sb.AppendLine(" private readonly double _opacity;");
+ sb.AppendLine(" private readonly int _spreadMethod;");
+ sb.AppendLine(" private readonly int _stopCount;");
+ sb.AppendLine(" private readonly AvnGradientStopBuffer _stops;");
+ foreach (var (abiType, accessor, _) in shapeFields)
+ sb.AppendLine($" private readonly {abiType} _{FirstLower(accessor)};");
+ sb.AppendLine();
+ var ctorParams = string.Join(", ", new[] { "double opacity", "int spreadMethod", "int stopCount", "AvnGradientStopBuffer stops" }
+ .Concat(shapeFields.Select(f => $"{f.AbiType} {FirstLower(f.Accessor)}")));
+ sb.AppendLine($" internal {className}({ctorParams})");
+ sb.AppendLine(" {");
+ sb.AppendLine(" _opacity = opacity;");
+ sb.AppendLine(" _spreadMethod = spreadMethod;");
+ sb.AppendLine(" _stopCount = stopCount;");
+ sb.AppendLine(" _stops = stops;");
+ foreach (var (_, accessor, _) in shapeFields)
+ sb.AppendLine($" _{FirstLower(accessor)} = {FirstLower(accessor)};");
+ sb.AppendLine(" }");
+ sb.AppendLine();
+ sb.AppendLine($" public int GetColor(out {colorAbiName} value)");
+ sb.AppendLine(" {");
+ sb.AppendLine(" value = default;");
+ sb.AppendLine(" return global::Avalonia.Host.HResults.AVN_E_NONSOLIDBRUSH;");
+ sb.AppendLine(" }");
+ sb.AppendLine();
+ sb.AppendLine(" public int GetOpacity(out double value)");
+ sb.AppendLine(" {");
+ sb.AppendLine(" value = _opacity;");
+ sb.AppendLine(" return global::Avalonia.Host.HResults.S_OK;");
+ sb.AppendLine(" }");
+ sb.AppendLine();
+ sb.AppendLine(" public int GetSpreadMethod(out int value)");
+ sb.AppendLine(" {");
+ sb.AppendLine(" value = _spreadMethod;");
+ sb.AppendLine(" return global::Avalonia.Host.HResults.S_OK;");
+ sb.AppendLine(" }");
+ sb.AppendLine();
+ sb.AppendLine(" public int GetStopCount(out int value)");
+ sb.AppendLine(" {");
+ sb.AppendLine(" value = _stopCount;");
+ sb.AppendLine(" return global::Avalonia.Host.HResults.S_OK;");
+ sb.AppendLine(" }");
+ sb.AppendLine();
+ sb.AppendLine(" public int GetStops(out AvnGradientStopBuffer value)");
+ sb.AppendLine(" {");
+ sb.AppendLine(" value = _stops;");
+ sb.AppendLine(" return global::Avalonia.Host.HResults.S_OK;");
+ sb.AppendLine(" }");
+ foreach (var (abiType, accessor, _) in shapeFields)
+ {
+ sb.AppendLine();
+ sb.AppendLine($" public int Get{accessor}(out {abiType} value)");
+ sb.AppendLine(" {");
+ sb.AppendLine($" value = _{FirstLower(accessor)};");
+ sb.AppendLine(" return global::Avalonia.Host.HResults.S_OK;");
+ sb.AppendLine(" }");
+ }
+ sb.AppendLine();
+ sb.AppendLine($" /// Projects a managed {className[3..].ToLowerInvariant()}, minting the fixed-capacity stop buffer.");
+ sb.AppendLine($" public static {interfaceName} From{className[3..]}(global::{managedTypeName} value)");
+ sb.AppendLine(" {");
+ sb.AppendLine($" var stops = value.GradientStops;");
+ sb.AppendLine($" if (stops.Count > {GradientBrushMarshalling.MaxStops})");
+ sb.AppendLine(" {");
+ sb.AppendLine(" throw new global::System.NotSupportedException(");
+ sb.AppendLine($" $\"Gradient brush has {{stops.Count}} stops, more than the {GradientBrushMarshalling.MaxStops} supported across the ABI.\")");
+ sb.AppendLine(" {");
+ sb.AppendLine(" HResult = global::Avalonia.Host.HResults.AVN_E_NONSOLIDBRUSH,");
+ sb.AppendLine(" };");
+ sb.AppendLine(" }");
+ sb.AppendLine(" var buffer = new AvnGradientStopBuffer();");
+ sb.AppendLine(" for (var i = 0; i < stops.Count; i++)");
+ sb.AppendLine(" buffer[i] = AvnGradientStop.FromAvalonia(stops[i]);");
+ var fromArgs = string.Join(", ", new[] { "value.Opacity", "(int)value.SpreadMethod", "stops.Count", "buffer" }
+ .Concat(shapeFields.Select(f => $"{f.AbiType}.FromAvalonia(value.{f.ManagedProperty})")));
+ sb.AppendLine($" return new {className}({fromArgs});");
+ sb.AppendLine(" }");
+ sb.AppendLine();
+ sb.AppendLine($" /// Materialises an immutable {className[3..].ToLowerInvariant()} from the members carried across.");
+ sb.AppendLine($" public static global::{BrushMarshalling.ManagedTypeName}? To{className[3..]}({interfaceName}? value)");
+ sb.AppendLine(" {");
+ sb.AppendLine(" if (value is null)");
+ sb.AppendLine(" return null;");
+ sb.AppendLine(" var hr = value.GetOpacity(out var opacity);");
+ sb.AppendLine(" if (hr < 0)");
+ sb.AppendLine(" global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);");
+ sb.AppendLine(" hr = value.GetSpreadMethod(out var spreadMethod);");
+ sb.AppendLine(" if (hr < 0)");
+ sb.AppendLine(" global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);");
+ sb.AppendLine(" hr = value.GetStopCount(out var stopCount);");
+ sb.AppendLine(" if (hr < 0)");
+ sb.AppendLine(" global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);");
+ sb.AppendLine(" hr = value.GetStops(out var stops);");
+ sb.AppendLine(" if (hr < 0)");
+ sb.AppendLine(" global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);");
+ sb.AppendLine($" var managedStops = new global::{GradientBrushMarshalling.ImmutableGradientStopManagedTypeName}[stopCount];");
+ sb.AppendLine(" for (var i = 0; i < stopCount; i++)");
+ sb.AppendLine($" managedStops[i] = new global::{GradientBrushMarshalling.ImmutableGradientStopManagedTypeName}(stops[i].Offset, stops[i].Color.ToAvalonia());");
+ foreach (var (abiType, accessor, _) in shapeFields)
+ {
+ sb.AppendLine($" hr = value.Get{accessor}(out var {FirstLower(accessor)});");
+ sb.AppendLine(" if (hr < 0)");
+ sb.AppendLine(" global::System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(hr);");
+ }
+ var toArgs = string.Join(", ", new[] { "managedStops", "opacity", "transform: null", "transformOrigin: null", "(global::Avalonia.Media.GradientSpreadMethod)spreadMethod" }
+ .Concat(shapeFields.Select(f => $"{FirstLower(f.Accessor)}.ToAvalonia()")));
+ sb.AppendLine($" return new global::{immutableManagedTypeName}({toArgs});");
+ sb.AppendLine(" }");
+ sb.AppendLine("}");
+ sb.AppendLine();
+ }
+
+ private static string FirstLower(string value) =>
+ value.Length == 0 ? value : char.ToLowerInvariant(value[0]) + value[1..];
+
public static string EmitCommand(ProjectionIr ir)
{
var interfaceName = SimpleName(ir.CommandInterfaceName
@@ -1594,9 +1879,71 @@ public static string EmitGeometryStructs(ProjectionIr ir)
sb.AppendLine(" };");
sb.AppendLine("}");
sb.AppendLine();
+ if (ir.GradientBrushInterfaceName is not null)
+ EmitGradientStructs(sb);
return sb.ToString().TrimEnd() + Environment.NewLine;
}
+ private static void EmitGradientStructs(StringBuilder sb)
+ {
+ var colorAbiName = GeometryMarshalling.All
+ .Single(geometry => geometry.Kind == MarshallingKind.Color).AbiName;
+
+ sb.AppendLine("/// Blittable ABI mirror of Avalonia.RelativePoint.");
+ sb.AppendLine("/// Unit mirrors Avalonia.RelativeUnit: 0 relative, 1 absolute.");
+ sb.AppendLine("[StructLayout(LayoutKind.Sequential)]");
+ sb.AppendLine("public struct AvnRelativePoint");
+ sb.AppendLine("{");
+ sb.AppendLine(" public double X;");
+ sb.AppendLine(" public double Y;");
+ sb.AppendLine(" public int Unit;");
+ sb.AppendLine();
+ sb.AppendLine(" public static AvnRelativePoint FromAvalonia(global::Avalonia.RelativePoint value) =>");
+ sb.AppendLine(" new AvnRelativePoint { X = value.Point.X, Y = value.Point.Y, Unit = (int)value.Unit };");
+ sb.AppendLine();
+ sb.AppendLine(" public readonly global::Avalonia.RelativePoint ToAvalonia() =>");
+ sb.AppendLine(" new global::Avalonia.RelativePoint(X, Y, (global::Avalonia.RelativeUnit)Unit);");
+ sb.AppendLine("}");
+ sb.AppendLine();
+ sb.AppendLine("/// Blittable ABI mirror of Avalonia.RelativeScalar.");
+ sb.AppendLine("/// Unit mirrors Avalonia.RelativeUnit: 0 relative, 1 absolute.");
+ sb.AppendLine("[StructLayout(LayoutKind.Sequential)]");
+ sb.AppendLine("public struct AvnRelativeScalar");
+ sb.AppendLine("{");
+ sb.AppendLine(" public double Scalar;");
+ sb.AppendLine(" public int Unit;");
+ sb.AppendLine();
+ sb.AppendLine(" public static AvnRelativeScalar FromAvalonia(global::Avalonia.RelativeScalar value) =>");
+ sb.AppendLine(" new AvnRelativeScalar { Scalar = value.Scalar, Unit = (int)value.Unit };");
+ sb.AppendLine();
+ sb.AppendLine(" public readonly global::Avalonia.RelativeScalar ToAvalonia() =>");
+ sb.AppendLine(" new global::Avalonia.RelativeScalar(Scalar, (global::Avalonia.RelativeUnit)Unit);");
+ sb.AppendLine("}");
+ sb.AppendLine();
+ sb.AppendLine("/// Blittable ABI mirror of a single gradient stop (offset plus packed colour).");
+ sb.AppendLine("[StructLayout(LayoutKind.Sequential)]");
+ sb.AppendLine("public struct AvnGradientStop");
+ sb.AppendLine("{");
+ sb.AppendLine(" public double Offset;");
+ sb.AppendLine($" public {colorAbiName} Color;");
+ sb.AppendLine();
+ sb.AppendLine($" public static AvnGradientStop FromAvalonia(global::{GradientBrushMarshalling.GradientStopManagedTypeName} value) =>");
+ sb.AppendLine($" new AvnGradientStop {{ Offset = value.Offset, Color = {colorAbiName}.FromAvalonia(value.Color) }};");
+ sb.AppendLine("}");
+ sb.AppendLine();
+ sb.AppendLine($"/// Fixed-capacity buffer of up to {GradientBrushMarshalling.MaxStops} entries.");
+ sb.AppendLine("/// ");
+ sb.AppendLine("/// Gradient brushes with more stops than this cannot cross the ABI; the count actually in");
+ sb.AppendLine("/// use is carried separately by IAvnGradientBrush.GetStopCount.");
+ sb.AppendLine("/// ");
+ sb.AppendLine($"[System.Runtime.CompilerServices.InlineArray({GradientBrushMarshalling.MaxStops})]");
+ sb.AppendLine("public struct AvnGradientStopBuffer");
+ sb.AppendLine("{");
+ sb.AppendLine(" private AvnGradientStop _element0;");
+ sb.AppendLine("}");
+ sb.AppendLine();
+ }
+
public static string EmitCollection(ProjectionIr ir, ProjectedProperty collection)
{
var root = ir.Types.Single(t => t.Kind == ProjectedTypeKind.Class && t.BaseFullName is null);
diff --git a/projection/Avalonia.Projection.Generator/NativeHeaderEmitter.cs b/projection/Avalonia.Projection.Generator/NativeHeaderEmitter.cs
index ad9da44..a68d830 100644
--- a/projection/Avalonia.Projection.Generator/NativeHeaderEmitter.cs
+++ b/projection/Avalonia.Projection.Generator/NativeHeaderEmitter.cs
@@ -38,6 +38,14 @@ public static string Emit(ProjectionIr ir)
.Concat(types.Select(type => type.Name))
.Concat(statics.Select(group => SimpleName(group.Key)))
.Concat(ir.BrushInterfaceName is null ? [] : new[] { SimpleName(ir.BrushInterfaceName) })
+ .Concat(ir.GradientBrushInterfaceName is null
+ ? []
+ : new[]
+ {
+ SimpleName(ir.GradientBrushInterfaceName),
+ SimpleName(ir.LinearGradientBrushInterfaceName!),
+ SimpleName(ir.RadialGradientBrushInterfaceName!),
+ })
.Concat(ir.CommandInterfaceName is null
? []
: new[]
@@ -107,6 +115,36 @@ public static string Emit(ProjectionIr ir)
sb.AppendLine("} AvnOptionalTimeSpan;");
sb.AppendLine();
+ if (ir.GradientBrushInterfaceName is not null)
+ {
+ var colorAbiName = GeometryMarshalling.All
+ .Single(geometry => geometry.Kind == MarshallingKind.Color).AbiName;
+ sb.AppendLine("/* Blittable ABI mirror of Avalonia.RelativePoint. unit: 0 relative, 1 absolute. */");
+ sb.AppendLine("typedef struct AvnRelativePoint {");
+ sb.AppendLine(" double x;");
+ sb.AppendLine(" double y;");
+ sb.AppendLine(" int32_t unit;");
+ sb.AppendLine("} AvnRelativePoint;");
+ sb.AppendLine();
+ sb.AppendLine("/* Blittable ABI mirror of Avalonia.RelativeScalar. unit: 0 relative, 1 absolute. */");
+ sb.AppendLine("typedef struct AvnRelativeScalar {");
+ sb.AppendLine(" double scalar;");
+ sb.AppendLine(" int32_t unit;");
+ sb.AppendLine("} AvnRelativeScalar;");
+ sb.AppendLine();
+ sb.AppendLine("/* Blittable ABI mirror of a single gradient stop (offset plus packed colour). */");
+ sb.AppendLine("typedef struct AvnGradientStop {");
+ sb.AppendLine(" double offset;");
+ sb.AppendLine($" {colorAbiName} color;");
+ sb.AppendLine("} AvnGradientStop;");
+ sb.AppendLine();
+ sb.AppendLine($"/* Fixed-capacity buffer of up to {GradientBrushMarshalling.MaxStops} AvnGradientStop entries. */");
+ sb.AppendLine("typedef struct AvnGradientStopBuffer {");
+ sb.AppendLine($" AvnGradientStop stops[{GradientBrushMarshalling.MaxStops}];");
+ sb.AppendLine("} AvnGradientStopBuffer;");
+ sb.AppendLine();
+ }
+
sb.AppendLine("/* Tagged scalar carrying object? command parameters. */");
sb.AppendLine("/* tag: 0 none, 1 utf16, 2 i32, 3 f64, 4 bool. */");
sb.AppendLine("typedef struct AvnVariant {");
@@ -168,6 +206,45 @@ public static string Emit(ProjectionIr ir)
EndInterface(sb, brushName, 5);
}
+ if (ir.GradientBrushInterfaceName is { } gradientBrushInterfaceName)
+ {
+ var gradientName = SimpleName(gradientBrushInterfaceName);
+ var linearName = SimpleName(ir.LinearGradientBrushInterfaceName!);
+ var radialName = SimpleName(ir.RadialGradientBrushInterfaceName!);
+
+ EmitIid(sb, gradientName, ir.GradientBrushInterfaceIid!, 1);
+ BeginInterface(sb, gradientName);
+ EmitSlot(sb, 3, "get_opacity", gradientName, ["double* value"]);
+ EmitSlot(sb, 4, "get_spread_method", gradientName, ["int32_t* value"]);
+ EmitSlot(sb, 5, "get_stop_count", gradientName, ["int32_t* value"]);
+ EmitSlot(sb, 6, "get_stops", gradientName, ["AvnGradientStopBuffer* value"]);
+ EndInterface(sb, gradientName, 7);
+
+ // Derived gradient interfaces flatten the base's four slots ahead of their own,
+ // mirroring the single-inheritance vtable layout produced for control interfaces.
+ EmitIid(sb, linearName, ir.LinearGradientBrushInterfaceIid!, 1);
+ BeginInterface(sb, linearName);
+ EmitSlot(sb, 3, "get_opacity", linearName, ["double* value"]);
+ EmitSlot(sb, 4, "get_spread_method", linearName, ["int32_t* value"]);
+ EmitSlot(sb, 5, "get_stop_count", linearName, ["int32_t* value"]);
+ EmitSlot(sb, 6, "get_stops", linearName, ["AvnGradientStopBuffer* value"]);
+ EmitSlot(sb, 7, "get_start_point", linearName, ["AvnRelativePoint* value"]);
+ EmitSlot(sb, 8, "get_end_point", linearName, ["AvnRelativePoint* value"]);
+ EndInterface(sb, linearName, 9);
+
+ EmitIid(sb, radialName, ir.RadialGradientBrushInterfaceIid!, 1);
+ BeginInterface(sb, radialName);
+ EmitSlot(sb, 3, "get_opacity", radialName, ["double* value"]);
+ EmitSlot(sb, 4, "get_spread_method", radialName, ["int32_t* value"]);
+ EmitSlot(sb, 5, "get_stop_count", radialName, ["int32_t* value"]);
+ EmitSlot(sb, 6, "get_stops", radialName, ["AvnGradientStopBuffer* value"]);
+ EmitSlot(sb, 7, "get_center", radialName, ["AvnRelativePoint* value"]);
+ EmitSlot(sb, 8, "get_gradient_origin", radialName, ["AvnRelativePoint* value"]);
+ EmitSlot(sb, 9, "get_radius_x", radialName, ["AvnRelativeScalar* value"]);
+ EmitSlot(sb, 10, "get_radius_y", radialName, ["AvnRelativeScalar* value"]);
+ EndInterface(sb, radialName, 11);
+ }
+
if (ir.CommandInterfaceName is { } commandInterfaceName)
{
var commandName = SimpleName(commandInterfaceName);
@@ -434,6 +511,41 @@ public static string Emit(ProjectionIr ir)
"IAvnControlFactory",
[$"{colorAbiName} color", "double opacity", $"{brushName}** value"]);
}
+ if (ir.GradientBrushInterfaceName is not null)
+ {
+ var linearName = SimpleName(ir.LinearGradientBrushInterfaceName!);
+ var radialName = SimpleName(ir.RadialGradientBrushInterfaceName!);
+ EmitSlot(
+ sb,
+ factorySlot++,
+ Snake(GradientBrushMarshalling.CreateLinearFactoryMethodName),
+ "IAvnControlFactory",
+ [
+ "double opacity",
+ "int32_t spread_method",
+ "int32_t stop_count",
+ "AvnGradientStopBuffer stops",
+ "AvnRelativePoint start_point",
+ "AvnRelativePoint end_point",
+ $"{linearName}** value",
+ ]);
+ EmitSlot(
+ sb,
+ factorySlot++,
+ Snake(GradientBrushMarshalling.CreateRadialFactoryMethodName),
+ "IAvnControlFactory",
+ [
+ "double opacity",
+ "int32_t spread_method",
+ "int32_t stop_count",
+ "AvnGradientStopBuffer stops",
+ "AvnRelativePoint center",
+ "AvnRelativePoint gradient_origin",
+ "AvnRelativeScalar radius_x",
+ "AvnRelativeScalar radius_y",
+ $"{radialName}** value",
+ ]);
+ }
EndInterface(sb, "IAvnControlFactory", factorySlot);
sb.AppendLine("#endif /* AVALONIA_RUST_ABI_H */");
diff --git a/projection/Avalonia.Projection.Ir/AvaloniaProjectionProfiles.cs b/projection/Avalonia.Projection.Ir/AvaloniaProjectionProfiles.cs
index 5613c66..ef975ed 100644
--- a/projection/Avalonia.Projection.Ir/AvaloniaProjectionProfiles.cs
+++ b/projection/Avalonia.Projection.Ir/AvaloniaProjectionProfiles.cs
@@ -137,7 +137,9 @@ public static class AvaloniaProjectionProfiles
["Avalonia.Host.Com.IAvnSector"] = 11,
["Avalonia.Host.Com.IAvnLayoutTransformControl"] = 11,
["Avalonia.Host.Com.IAvnThemeVariantScope"] = 11,
- ["Avalonia.Host.Com.IAvnControlFactory"] = 13,
+ ["Avalonia.Host.Com.IAvnControlFactory"] = 14,
+ // Gradient brush wave: the factory grows CreateLinearGradientBrush/
+ // CreateRadialGradientBrush slots, so it republishes at version 14.
// Wave P. Payload-carrying replacements for the previously payload-less
// handlers: the handler Invoke slots change shape, so each handler mints a
// new IID at version 2. The advise/unadvise slots on the control interfaces
diff --git a/projection/Avalonia.Projection.Ir/BrushMarshalling.cs b/projection/Avalonia.Projection.Ir/BrushMarshalling.cs
index 2ebb58b..8baa7cd 100644
--- a/projection/Avalonia.Projection.Ir/BrushMarshalling.cs
+++ b/projection/Avalonia.Projection.Ir/BrushMarshalling.cs
@@ -4,11 +4,14 @@ namespace Avalonia.Projection.Ir;
/// The object-model projection of Avalonia.Media.IBrush.
///
///
-/// A brush crosses nano-COM as a solid colour only: the ABI interface carries a packed
-/// AvnColor plus the brush opacity and nothing else. Gradient brushes,
-/// DrawingBrush and VisualBrush are deliberately not projected — reading one
+/// IAvnBrush itself still carries a solid colour only: a packed AvnColor
+/// plus the brush opacity and nothing else, unchanged since it first shipped. Linear and radial
+/// gradient brushes are projected as an additive sibling capability (see
+/// ) that a gradient brush object also implements;
+/// DrawingBrush, VisualBrush, ImageBrush and conic gradients remain out of
+/// scope — reading any of those, or calling IAvnBrush.GetColor on a real gradient object,
/// fails with AVN_E_NONSOLIDBRUSH rather than silently degrading to a nearest colour.
-/// The interface is read-only because the managed side hands out immutable brushes; new
+/// The interface is read-only because the managed side hands out immutable brushes; new solid
/// brushes are minted through IAvnControlFactory.CreateSolidColorBrush.
///
public static class BrushMarshalling
diff --git a/projection/Avalonia.Projection.Ir/ClrTypeExtractor.cs b/projection/Avalonia.Projection.Ir/ClrTypeExtractor.cs
index f52cca4..8993597 100644
--- a/projection/Avalonia.Projection.Ir/ClrTypeExtractor.cs
+++ b/projection/Avalonia.Projection.Ir/ClrTypeExtractor.cs
@@ -40,6 +40,9 @@ public static ProjectionIr Extract(IEnumerable sourceTypes, ProjectionPoli
var brushInterfaceName = BrushMarshalling.QualifiedInterfaceName(policy.ProjectionNamespace);
var usesBrush = types.Any(type =>
type.Properties.Any(property => property.Kind == MarshallingKind.Brush));
+ var gradientBrushInterfaceName = GradientBrushMarshalling.QualifiedGradientInterfaceName(policy.ProjectionNamespace);
+ var linearGradientBrushInterfaceName = GradientBrushMarshalling.QualifiedLinearInterfaceName(policy.ProjectionNamespace);
+ var radialGradientBrushInterfaceName = GradientBrushMarshalling.QualifiedRadialInterfaceName(policy.ProjectionNamespace);
var commandInterfaceName = CommandMarshalling.QualifiedInterfaceName(policy.ProjectionNamespace);
var commandHandlerInterfaceName = CommandMarshalling.QualifiedHandlerInterfaceName(policy.ProjectionNamespace);
var usesCommand = types.Any(type =>
@@ -91,6 +94,18 @@ public static ProjectionIr Extract(IEnumerable sourceTypes, ProjectionPoli
? CreateDeterministicIid(brushInterfaceName, policy.GetAbiVersion(brushInterfaceName))
: null,
BrushAbiVersion = policy.GetAbiVersion(brushInterfaceName),
+ GradientBrushInterfaceName = usesBrush ? gradientBrushInterfaceName : null,
+ GradientBrushInterfaceIid = usesBrush
+ ? CreateDeterministicIid(gradientBrushInterfaceName, 1)
+ : null,
+ LinearGradientBrushInterfaceName = usesBrush ? linearGradientBrushInterfaceName : null,
+ LinearGradientBrushInterfaceIid = usesBrush
+ ? CreateDeterministicIid(linearGradientBrushInterfaceName, 1)
+ : null,
+ RadialGradientBrushInterfaceName = usesBrush ? radialGradientBrushInterfaceName : null,
+ RadialGradientBrushInterfaceIid = usesBrush
+ ? CreateDeterministicIid(radialGradientBrushInterfaceName, 1)
+ : null,
CommandInterfaceName = usesCommand ? commandInterfaceName : null,
CommandInterfaceIid = usesCommand
? CreateDeterministicIid(commandInterfaceName, policy.GetAbiVersion(commandInterfaceName))
diff --git a/projection/Avalonia.Projection.Ir/GradientBrushMarshalling.cs b/projection/Avalonia.Projection.Ir/GradientBrushMarshalling.cs
new file mode 100644
index 0000000..972af2b
--- /dev/null
+++ b/projection/Avalonia.Projection.Ir/GradientBrushMarshalling.cs
@@ -0,0 +1,62 @@
+namespace Avalonia.Projection.Ir;
+
+///
+/// The object-model projection of Avalonia.Media.IGradientBrush and its two supported
+/// concrete shapes, ILinearGradientBrush and IRadialGradientBrush.
+///
+///
+/// This is an additive capability layered next to : the existing
+/// IAvnBrush (solid colour) interface, IID and vtable are unchanged. A gradient brush
+/// projects as a second COM object that implements IAvnBrush (so it still satisfies every
+/// brush-typed property slot) alongside the new IAvnGradientBrush capability, queryable
+/// with a standard nano-COM QueryInterface. Calling IAvnBrush.GetColor on a real gradient
+/// object still fails with AVN_E_NONSOLIDBRUSH — only GetOpacity and the new
+/// gradient members are meaningful — so a caller that only understands solid brushes keeps
+/// working unchanged. ConicGradientBrush, DrawingBrush, VisualBrush and
+/// ImageBrush remain out of scope and keep failing the same way.
+///
+/// Gradient stops cross as a fixed-capacity inline buffer ( entries) rather
+/// than a dynamically sized collection, keeping the ABI shape a single blittable struct; a brush
+/// with more stops than that is rejected when it is minted for the ABI.
+///
+public static class GradientBrushMarshalling
+{
+ /// The maximum number of gradient stops a projected gradient brush can carry.
+ public const int MaxStops = 8;
+
+ public const string GradientManagedTypeName = "Avalonia.Media.IGradientBrush";
+ public const string LinearManagedTypeName = "Avalonia.Media.ILinearGradientBrush";
+ public const string RadialManagedTypeName = "Avalonia.Media.IRadialGradientBrush";
+ public const string GradientStopManagedTypeName = "Avalonia.Media.IGradientStop";
+
+ public const string ImmutableLinearManagedTypeName =
+ "Avalonia.Media.Immutable.ImmutableLinearGradientBrush";
+ public const string ImmutableRadialManagedTypeName =
+ "Avalonia.Media.Immutable.ImmutableRadialGradientBrush";
+ public const string ImmutableGradientStopManagedTypeName =
+ "Avalonia.Media.Immutable.ImmutableGradientStop";
+
+ /// The unqualified base capability interface name shared by C, C#, and Rust.
+ public const string GradientInterfaceName = "IAvnGradientBrush";
+
+ /// The unqualified linear-gradient interface name shared by C, C#, and Rust.
+ public const string LinearInterfaceName = "IAvnLinearGradientBrush";
+
+ /// The unqualified radial-gradient interface name shared by C, C#, and Rust.
+ public const string RadialInterfaceName = "IAvnRadialGradientBrush";
+
+ /// The factory method that mints a linear gradient brush.
+ public const string CreateLinearFactoryMethodName = "CreateLinearGradientBrush";
+
+ /// The factory method that mints a radial gradient brush.
+ public const string CreateRadialFactoryMethodName = "CreateRadialGradientBrush";
+
+ public static string QualifiedGradientInterfaceName(string projectionNamespace) =>
+ $"{projectionNamespace}.{GradientInterfaceName}";
+
+ public static string QualifiedLinearInterfaceName(string projectionNamespace) =>
+ $"{projectionNamespace}.{LinearInterfaceName}";
+
+ public static string QualifiedRadialInterfaceName(string projectionNamespace) =>
+ $"{projectionNamespace}.{RadialInterfaceName}";
+}
diff --git a/projection/Avalonia.Projection.Ir/ProjectionIr.cs b/projection/Avalonia.Projection.Ir/ProjectionIr.cs
index 5fab4c1..bb082ee 100644
--- a/projection/Avalonia.Projection.Ir/ProjectionIr.cs
+++ b/projection/Avalonia.Projection.Ir/ProjectionIr.cs
@@ -6,7 +6,7 @@ namespace Avalonia.Projection.Ir;
public sealed partial class ProjectionIr
{
public const int MinimumVersion = 1;
- public const int CurrentVersion = 16;
+ public const int CurrentVersion = 17;
public int Version { get; init; } = CurrentVersion;
public string? SourceAssembly { get; init; }
@@ -21,6 +21,18 @@ public sealed partial class ProjectionIr
public string? BrushInterfaceIid { get; init; }
public int BrushAbiVersion { get; init; } = 1;
+ ///
+ /// The projected gradient-brush capability interfaces (version 17), present only when a
+ /// member marshals as . Additive to
+ /// : the solid-brush interface, IID and vtable are unchanged.
+ ///
+ public string? GradientBrushInterfaceName { get; init; }
+ public string? GradientBrushInterfaceIid { get; init; }
+ public string? LinearGradientBrushInterfaceName { get; init; }
+ public string? LinearGradientBrushInterfaceIid { get; init; }
+ public string? RadialGradientBrushInterfaceName { get; init; }
+ public string? RadialGradientBrushInterfaceIid { get; init; }
+
///
/// The projected command interface, present only when a member marshals as
/// .
diff --git a/rust/.avalonia-projection.owned.json b/rust/.avalonia-projection.owned.json
index 5de7d23..79468c0 100644
--- a/rust/.avalonia-projection.owned.json
+++ b/rust/.avalonia-projection.owned.json
@@ -7,7 +7,7 @@
},
{
"path": "projection.ir.json",
- "sha256": "780eb004b70506dc1a826f1d67a9f83777b270d971bb211cd49ddbb5a9d5b686"
+ "sha256": "eb22a33ab7409ee8b4c3f90f17d7d1aac3b625e649ba09ed4cd3cd36a8220e42"
}
]
}
diff --git a/rust/COMPATIBILITY.md b/rust/COMPATIBILITY.md
index 148ed70..2f3c1d2 100644
--- a/rust/COMPATIBILITY.md
+++ b/rust/COMPATIBILITY.md
@@ -58,6 +58,15 @@ bindgen can emit the handler interface and its CCW constructor without
hardcoding the identity. Both fields are additive; a reader that ignores them
sees the same vtables it always did.
+Version 17 adds six optional root-level members, present whenever any member
+marshals as `MarshallingKind.Brush`: `gradientBrushInterfaceName`/`Iid`,
+`linearGradientBrushInterfaceName`/`Iid` and
+`radialGradientBrushInterfaceName`/`Iid`. They are additive to
+`BrushInterfaceName`/`BrushInterfaceIid` — the solid-brush interface, IID and
+vtable are unchanged — and no `MarshallingKind` ordinal moves. A reader that
+ignores the six new fields sees the same IR it always did; only a generator
+that projects gradient brushes needs them.
+
Version 13 adds two optional members, both host-side only. A projected property
and an attached property may carry `stringConverterTypeName`, naming the host
type that converts the member between its CLR type and the UTF-16 string in its
@@ -74,7 +83,7 @@ with a host from another.
## Native ABI
-The overlay-chrome pass widens the leaf `IAvnWindow` ABI from 7 to 8 to expose only the safe, non-nullable window work-area and dialog members. This stays local to the window leaf: `IAvnContentControl` remains at 6 and the factory remains at 13, while blockers such as `Icon`, `Position`, nullable geometry, and cancelable `Closing` payloads stay out of scope.
+The overlay-chrome pass widens the leaf `IAvnWindow` ABI from 7 to 8 to expose only the safe, non-nullable window work-area and dialog members. This stays local to the window leaf: `IAvnContentControl` remains at 6 and the factory remained at 13 as of this wave (the later gradient-brush pass below moves it again), while blockers such as `Icon`, `Position`, nullable geometry, and cancelable `Closing` payloads stay out of scope.
The wave P event-payload pass grows `IAvnControl` with `KeyUp`, `GotFocus`
and `LostFocus`, so `IAvnControl` and every interface below it republish on
@@ -88,6 +97,15 @@ old/new value pair as fields. The advise/unadvise slots on the control
interfaces keep their signatures throughout; only the handler identities move.
Consumers compiled against the version 1 handlers fail `QueryInterface`
loudly (`E_NOINTERFACE`) rather than being called through a stale vtable.
+
+The gradient-brush pass adds three brand-new interfaces —
+`IAvnGradientBrush`, `IAvnLinearGradientBrush` and `IAvnRadialGradientBrush`,
+each publishing at version 1 — and grows `IAvnControlFactory` with
+`create_linear_gradient_brush`/`create_radial_gradient_brush`, so the factory
+republishes on a fresh IID (from 13). `IAvnBrush` itself is untouched: it
+keeps its published IID and vtable, and every gradient object also answers
+`QueryInterface` for it. No other interface moves.
+
After an intentional ABI wave, regenerate the frozen snapshot with
`pwsh ./rust/regenerate-and-build.ps1 -UpdateAbiBaseline` in the same change
so `abi-baseline.json` stays the reviewed record of what is released.
diff --git a/rust/MARSHALLING.md b/rust/MARSHALLING.md
index 8b7679e..ab46c1a 100644
--- a/rust/MARSHALLING.md
+++ b/rust/MARSHALLING.md
@@ -150,9 +150,9 @@ on. Inbound, every brush is materialised as
always a solid brush by construction and anything a source brush carried beyond
colour and opacity (transforms, gradient stops) is dropped rather than guessed.
-Gradients, `DrawingBrush` and `VisualBrush` are out of scope for this ABI. A
-future wave that needs them must add a separately named, separately versioned
-interface rather than widening `IAvnBrush`.
+`DrawingBrush` and `VisualBrush` remain out of scope for this ABI. A future wave
+that needs them must add a separately named, separately versioned interface
+rather than widening `IAvnBrush`, following the pattern gradients use below.
In safe Rust the brush is a plain value; only crossing the ABI needs the factory:
@@ -172,6 +172,75 @@ so `None` clears the property and a `Brush` needs no `Some`. `Color::rgb` is a
`const` opaque-colour constructor, so a consumer can define a palette as
constants.
+## Gradient brushes
+
+Linear and radial gradients follow the sibling-interface pattern rather than
+widening `IAvnBrush`: `IAvnGradientBrush` carries the members every gradient
+shares (`Opacity`, `SpreadMethod`, `StopCount`, `Stops`), and
+`IAvnLinearGradientBrush`/`IAvnRadialGradientBrush` each derive from it and add
+their own geometry (`StartPoint`/`EndPoint`, or `Center`/`GradientOrigin`/
+`RadiusX`/`RadiusY`). Every gradient object also answers `QueryInterface` for
+plain `IAvnBrush`, so it can be assigned anywhere a solid brush could be —
+reading `Color` back off it is what returns `AVN_E_NONSOLIDBRUSH`.
+
+Stops cross the ABI as a fixed-capacity buffer rather than a COM collection:
+
+```c
+struct AvnGradientStop { double offset; AvnColor color; };
+struct AvnGradientStopBuffer { AvnGradientStop stops[8]; };
+```
+
+Eight stops is enough for chrome gradients without a heap-allocated
+marshalled array; `StopCount` says how many of the eight slots are populated,
+so a wrapper must always read count and buffer together and never assume all
+eight are meaningful. `IAvnControlFactory` mints both shapes:
+
+```c
+AvnHResult (AVN_CALL *create_linear_gradient_brush)(
+ IAvnControlFactory* self, double opacity, int32_t spreadMethod,
+ int32_t stopCount, AvnGradientStopBuffer stops,
+ AvnRelativePoint startPoint, AvnRelativePoint endPoint,
+ IAvnLinearGradientBrush** value);
+
+AvnHResult (AVN_CALL *create_radial_gradient_brush)(
+ IAvnControlFactory* self, double opacity, int32_t spreadMethod,
+ int32_t stopCount, AvnGradientStopBuffer stops,
+ AvnRelativePoint center, AvnRelativePoint gradientOrigin,
+ AvnRelativeScalar radiusX, AvnRelativeScalar radiusY,
+ IAvnRadialGradientBrush** value);
+```
+
+`AvnRelativePoint`/`AvnRelativeScalar` carry a `RelativeUnit` ordinal
+(`Relative = 0`, `Absolute = 1`) alongside their coordinates, mirroring
+`Avalonia.RelativePoint`/`RelativeUnit`. Growing `IAvnControlFactory` to add
+these two slots required minting a new IID for it (the ABI-baseline check
+treats any slot-list change under a published IID as a break, even an
+additive one) — see [Versioning of the widened vtables](#versioning-of-the-widened-vtables)
+for the general rule.
+
+In safe Rust, `LinearGradientBrush` and `RadialGradientBrush` are plain values
+alongside `Brush`, and `Paint` is the enum that spans all three shapes a
+control property can hold:
+
+```rust
+let sunset = LinearGradientBrush::new(
+ vec![
+ GradientStop::new(0.0, Color::rgb(0xFF, 0x45, 0x00)),
+ GradientStop::new(1.0, Color::rgb(0xFF, 0xD7, 0x00)),
+ ],
+ RelativePoint::new(0.0, 0.0, RelativeUnit::Relative),
+ RelativePoint::new(1.0, 1.0, RelativeUnit::Relative),
+);
+let paint: Paint = sunset.into();
+```
+
+`Paint`, `LinearGradientBrush` and `RadialGradientBrush` are additive: no
+existing `Brush`-typed property getter or setter was rewired to accept or
+return `Paint`. Reading `Background`/`BorderBrush`/`Foreground` off a
+gradient-backed control still fails with `AVN_E_NONSOLIDBRUSH` today, matching
+"reads fail rather than degrade" above; wiring chrome properties to accept a
+`Paint` is left to a future wave.
+
## Chrome members
The chrome wave allowlists the members that make a control look like part of an
@@ -631,6 +700,12 @@ by `query_interface` only. `IAvnBrush` is brand new, so it starts at version 1.
The collection interfaces and the event handler interfaces are unchanged, because
they carry interface pointers rather than the widened layouts.
+The gradient wave grows `IAvnControlFactory` again, for
+`create_linear_gradient_brush` and `create_radial_gradient_brush`, so it
+publishes another new IID. `IAvnGradientBrush`, `IAvnLinearGradientBrush` and
+`IAvnRadialGradientBrush` are brand new, so each starts at version 1; `IAvnBrush`
+itself is untouched and keeps the IID it published with.
+
`Decorator` sits between `Control` and `Border`. The chrome wave added members to
`Border`, not to `Decorator`, and nothing was added to `Decorator`'s bases either,
so `IAvnDecorator` keeps the version 3 IID it published with the layout wave even
diff --git a/rust/README.md b/rust/README.md
index 9518ec4..d4019cb 100644
--- a/rust/README.md
+++ b/rust/README.md
@@ -35,6 +35,12 @@ only; a control-valued tip reads back as `null`. See
`RefreshContainer` are projected too.
Shapes (`Rectangle`, `Ellipse`, `Line`, `Path`, `Polygon`, `Polyline`, `Arc`,
`Sector`) are projected too. Fill/Stroke are brushes; `Path.Data` is path markup.
+`LinearGradientBrush` and `RadialGradientBrush` are projected as additive,
+directly-constructible safe types built on the `IAvnControlFactory` creators
+`create_linear_gradient_brush`/`create_radial_gradient_brush`; a `Paint` enum
+spans solid and gradient shapes. Existing `Brush`-typed properties
+(`Background`, `BorderBrush`, `Foreground`) are unchanged and stay solid-only;
+see [Gradient brushes](MARSHALLING.md#gradient-brushes).
`Carousel`, `TransitioningContentControl`, `Label`, `Separator`, `GroupBox`,
`UserControl` and `LayoutTransformControl` are projected too.
`Calendar` and `CalendarDatePicker` are projected too. Calendar days cross as
diff --git a/rust/abi-baseline.json b/rust/abi-baseline.json
index 668e414..59770e0 100644
--- a/rust/abi-baseline.json
+++ b/rust/abi-baseline.json
@@ -1,7 +1,7 @@
{
"schemaVersion": 3,
"kind": "released",
- "projectionIrVersion": 16,
+ "projectionIrVersion": 17,
"producerPin": "9654332a79f637473da96054f75b2a16deaa557e",
"abiDefinitions": {
"hresult": "int32_t",
@@ -42,6 +42,28 @@
}
]
},
+ {
+ "name": "AvnGradientStop",
+ "fields": [
+ {
+ "type": "double",
+ "name": "offset"
+ },
+ {
+ "type": "AvnColor",
+ "name": "color"
+ }
+ ]
+ },
+ {
+ "name": "AvnGradientStopBuffer",
+ "fields": [
+ {
+ "type": "AvnGradientStop",
+ "name": "stops[8]"
+ }
+ ]
+ },
{
"name": "AvnGuid",
"fields": [
@@ -227,6 +249,36 @@
}
]
},
+ {
+ "name": "AvnRelativePoint",
+ "fields": [
+ {
+ "type": "double",
+ "name": "x"
+ },
+ {
+ "type": "double",
+ "name": "y"
+ },
+ {
+ "type": "int32_t",
+ "name": "unit"
+ }
+ ]
+ },
+ {
+ "name": "AvnRelativeScalar",
+ "fields": [
+ {
+ "type": "double",
+ "name": "scalar"
+ },
+ {
+ "type": "int32_t",
+ "name": "unit"
+ }
+ ]
+ },
{
"name": "AvnSize",
"fields": [
@@ -921,6 +973,141 @@
}
]
},
+ {
+ "name": "get_spread_method",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "int32_t*",
+ "name": "value"
+ }
+ ]
+ },
+ {
+ "name": "get_stop_count",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "int32_t*",
+ "name": "value"
+ }
+ ]
+ },
+ {
+ "name": "get_stops",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "AvnGradientStopBuffer*",
+ "name": "value"
+ }
+ ]
+ },
+ {
+ "name": "get_start_point",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "AvnRelativePoint*",
+ "name": "value"
+ }
+ ]
+ },
+ {
+ "name": "get_end_point",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "AvnRelativePoint*",
+ "name": "value"
+ }
+ ]
+ },
+ {
+ "name": "get_center",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "AvnRelativePoint*",
+ "name": "value"
+ }
+ ]
+ },
+ {
+ "name": "get_gradient_origin",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "AvnRelativePoint*",
+ "name": "value"
+ }
+ ]
+ },
+ {
+ "name": "get_radius_x",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "AvnRelativeScalar*",
+ "name": "value"
+ }
+ ]
+ },
+ {
+ "name": "get_radius_y",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "AvnRelativeScalar*",
+ "name": "value"
+ }
+ ]
+ },
{
"name": "execute",
"callingConvention": "AVN_CALL",
@@ -17830,6 +18017,92 @@
"name": "value"
}
]
+ },
+ {
+ "name": "create_linear_gradient_brush",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "double",
+ "name": "opacity"
+ },
+ {
+ "type": "int32_t",
+ "name": "spread_method"
+ },
+ {
+ "type": "int32_t",
+ "name": "stop_count"
+ },
+ {
+ "type": "AvnGradientStopBuffer",
+ "name": "stops"
+ },
+ {
+ "type": "AvnRelativePoint",
+ "name": "start_point"
+ },
+ {
+ "type": "AvnRelativePoint",
+ "name": "end_point"
+ },
+ {
+ "type": "IAvnLinearGradientBrush**",
+ "name": "value"
+ }
+ ]
+ },
+ {
+ "name": "create_radial_gradient_brush",
+ "callingConvention": "AVN_CALL",
+ "returnType": "AvnHResult",
+ "parameters": [
+ {
+ "type": "$self",
+ "name": "self"
+ },
+ {
+ "type": "double",
+ "name": "opacity"
+ },
+ {
+ "type": "int32_t",
+ "name": "spread_method"
+ },
+ {
+ "type": "int32_t",
+ "name": "stop_count"
+ },
+ {
+ "type": "AvnGradientStopBuffer",
+ "name": "stops"
+ },
+ {
+ "type": "AvnRelativePoint",
+ "name": "center"
+ },
+ {
+ "type": "AvnRelativePoint",
+ "name": "gradient_origin"
+ },
+ {
+ "type": "AvnRelativeScalar",
+ "name": "radius_x"
+ },
+ {
+ "type": "AvnRelativeScalar",
+ "name": "radius_y"
+ },
+ {
+ "type": "IAvnRadialGradientBrush**",
+ "name": "value"
+ }
+ ]
}
],
"irMemberCatalog": [
@@ -18545,15 +18818,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -18570,7 +18834,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -18580,6 +18843,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -18647,7 +18911,16 @@
168,
169,
170,
- 171
+ 171,
+ 172,
+ 173,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180
],
"irBases": [
"IAvnAvaloniaObject",
@@ -18722,7 +18995,7 @@
0,
1,
2,
- 48
+ 57
]
},
{
@@ -18734,7 +19007,7 @@
0,
1,
2,
- 47
+ 56
]
},
{
@@ -18746,15 +19019,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -18771,7 +19035,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -18781,6 +19044,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -18827,15 +19091,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -18916,7 +19180,16 @@
258,
259,
260,
- 261
+ 261,
+ 262,
+ 263,
+ 264,
+ 265,
+ 266,
+ 267,
+ 268,
+ 269,
+ 270
],
"irBases": [
"IAvnAvaloniaObject",
@@ -19150,8 +19423,8 @@
0,
1,
2,
- 70,
- 71
+ 79,
+ 80
],
"irBases": [
"IAvnAvaloniaObject"
@@ -19166,15 +19439,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -19191,7 +19455,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -19201,6 +19464,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -19247,23 +19511,32 @@
147,
148,
149,
- 262,
- 263,
- 198,
- 199,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 271,
+ 272,
+ 207,
+ 208,
181,
- 264,
- 265,
- 266
+ 182,
+ 183,
+ 184,
+ 185,
+ 186,
+ 187,
+ 188,
+ 189,
+ 190,
+ 273,
+ 274,
+ 275
],
"irBases": [
"IAvnAvaloniaObject",
@@ -19349,15 +19622,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -19374,7 +19638,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -19384,6 +19647,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -19430,15 +19694,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -19458,15 +19722,15 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
276,
277,
278,
@@ -19482,7 +19746,16 @@
288,
289,
290,
- 291
+ 291,
+ 292,
+ 293,
+ 294,
+ 295,
+ 296,
+ 297,
+ 298,
+ 299,
+ 300
],
"irBases": [
"IAvnAvaloniaObject",
@@ -19586,15 +19859,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -19611,7 +19875,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -19621,6 +19884,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -19667,15 +19931,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -19695,24 +19959,33 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 292,
- 293,
- 294,
- 295,
- 296,
- 297,
- 298,
- 299,
- 300,
- 301
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 301,
+ 302,
+ 303,
+ 304,
+ 305,
+ 306,
+ 307,
+ 308,
+ 309,
+ 310
],
"irBases": [
"IAvnAvaloniaObject",
@@ -19801,15 +20074,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -19826,7 +20090,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -19836,6 +20099,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -19882,15 +20146,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -19910,15 +20174,15 @@
197,
198,
199,
- 302,
- 303,
- 304,
- 305,
- 306,
- 307,
- 308,
- 309,
- 310,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
311,
312,
313,
@@ -19941,7 +20205,16 @@
330,
331,
332,
- 333
+ 333,
+ 334,
+ 335,
+ 336,
+ 337,
+ 338,
+ 339,
+ 340,
+ 341,
+ 342
],
"irBases": [
"IAvnAvaloniaObject",
@@ -20036,15 +20309,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -20061,7 +20325,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -20071,6 +20334,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -20117,15 +20381,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -20145,50 +20409,59 @@
197,
198,
199,
- 325,
- 321,
- 322,
- 323,
- 324,
- 326,
- 327,
- 302,
- 303,
- 212,
- 213,
- 304,
- 305,
- 318,
- 319,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
334,
+ 330,
+ 331,
+ 332,
+ 333,
335,
336,
- 337,
- 218,
- 219,
- 223,
- 224,
- 338,
- 339,
- 225,
- 226,
- 271,
- 272,
- 273,
- 274,
- 308,
- 309,
- 310,
311,
- 60,
- 340,
- 341,
- 342,
+ 312,
+ 221,
+ 222,
+ 313,
+ 314,
+ 327,
+ 328,
343,
344,
345,
346,
- 347
+ 227,
+ 228,
+ 232,
+ 233,
+ 347,
+ 348,
+ 234,
+ 235,
+ 280,
+ 281,
+ 282,
+ 283,
+ 317,
+ 318,
+ 319,
+ 320,
+ 69,
+ 349,
+ 350,
+ 351,
+ 352,
+ 353,
+ 354,
+ 355,
+ 356
],
"irBases": [
"IAvnAvaloniaObject",
@@ -20403,15 +20676,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -20428,7 +20692,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -20438,6 +20701,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -20484,9 +20748,18 @@
147,
148,
149,
- 348,
- 172,
- 173
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 357,
+ 181,
+ 182
],
"irBases": [
"IAvnAvaloniaObject",
@@ -20552,14 +20825,14 @@
0,
1,
2,
- 969,
- 970,
- 971,
- 972,
- 973,
- 974,
- 975,
- 976
+ 978,
+ 979,
+ 980,
+ 981,
+ 982,
+ 983,
+ 984,
+ 985
]
},
{
@@ -20571,15 +20844,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -20596,7 +20860,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -20606,6 +20869,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -20652,15 +20916,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -20680,24 +20944,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -20705,14 +20967,25 @@
365,
366,
367,
- 261,
368,
369,
+ 225,
+ 226,
370,
371,
372,
373,
- 374
+ 374,
+ 375,
+ 376,
+ 270,
+ 377,
+ 378,
+ 379,
+ 380,
+ 381,
+ 382,
+ 383
],
"irBases": [
"IAvnAvaloniaObject",
@@ -20814,15 +21087,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -20839,7 +21103,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -20849,6 +21112,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -20895,15 +21159,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -20923,15 +21187,15 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
276,
277,
278,
@@ -20948,12 +21212,21 @@
289,
290,
291,
- 375,
- 376,
- 377,
- 378,
- 379,
- 380
+ 292,
+ 293,
+ 294,
+ 295,
+ 296,
+ 297,
+ 298,
+ 299,
+ 300,
+ 384,
+ 385,
+ 386,
+ 387,
+ 388,
+ 389
],
"irBases": [
"IAvnAvaloniaObject",
@@ -21050,15 +21323,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -21075,7 +21339,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -21085,6 +21348,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -21131,15 +21395,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -21159,24 +21423,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -21184,27 +21446,38 @@
365,
366,
367,
- 261,
- 212,
- 213,
- 381,
- 382,
- 210,
- 211,
- 383,
- 223,
- 224,
+ 368,
+ 369,
225,
226,
- 384,
- 385,
- 218,
+ 370,
+ 371,
+ 372,
+ 373,
+ 374,
+ 375,
+ 376,
+ 270,
+ 221,
+ 222,
+ 390,
+ 391,
219,
- 60,
- 386,
- 259,
- 387,
- 255
+ 220,
+ 392,
+ 232,
+ 233,
+ 234,
+ 235,
+ 393,
+ 394,
+ 227,
+ 228,
+ 69,
+ 395,
+ 268,
+ 396,
+ 264
],
"irBases": [
"IAvnAvaloniaObject",
@@ -21336,15 +21609,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -21361,7 +21625,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -21371,6 +21634,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -21417,15 +21681,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -21445,16 +21709,25 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 388,
- 389
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 397,
+ 398
],
"irBases": [
"IAvnAvaloniaObject",
@@ -21539,10 +21812,10 @@
0,
1,
2,
- 36,
- 37,
- 38,
- 39
+ 45,
+ 46,
+ 47,
+ 48
]
},
{
@@ -21554,15 +21827,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -21579,7 +21843,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -21589,6 +21852,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -21635,15 +21899,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -21663,23 +21927,23 @@
197,
198,
199,
- 390,
- 391,
- 392,
- 393,
- 394,
- 395,
- 267,
- 268,
- 396,
- 397,
- 398,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
399,
400,
401,
402,
403,
404,
+ 276,
+ 277,
405,
406,
407,
@@ -21696,7 +21960,16 @@
418,
419,
420,
- 421
+ 421,
+ 422,
+ 423,
+ 424,
+ 425,
+ 426,
+ 427,
+ 428,
+ 429,
+ 430
],
"irBases": [
"IAvnAvaloniaObject",
@@ -21793,15 +22066,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -21818,7 +22082,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -21828,6 +22091,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -21874,15 +22138,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -21902,15 +22166,15 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
276,
277,
278,
@@ -21927,18 +22191,27 @@
289,
290,
291,
- 422,
- 423,
- 424,
- 425,
- 426,
- 427,
- 428,
- 429,
- 430,
+ 292,
+ 293,
+ 294,
+ 295,
+ 296,
+ 297,
+ 298,
+ 299,
+ 300,
431,
432,
- 433
+ 433,
+ 434,
+ 435,
+ 436,
+ 437,
+ 438,
+ 439,
+ 440,
+ 441,
+ 442
],
"irBases": [
"IAvnAvaloniaObject",
@@ -22085,15 +22358,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -22110,7 +22374,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -22120,6 +22383,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -22166,15 +22430,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -22194,10 +22458,19 @@
197,
198,
199,
- 426,
- 427,
- 432,
- 433
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 435,
+ 436,
+ 441,
+ 442
],
"irBases": [
"IAvnAvaloniaObject",
@@ -22278,15 +22551,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -22303,7 +22567,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -22313,6 +22576,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -22359,15 +22623,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -22387,15 +22651,15 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
276,
277,
278,
@@ -22412,24 +22676,33 @@
289,
290,
291,
- 375,
- 376,
- 377,
- 378,
- 379,
- 380,
- 422,
- 423,
- 424,
- 425,
- 426,
- 427,
- 428,
- 429,
- 430,
+ 292,
+ 293,
+ 294,
+ 295,
+ 296,
+ 297,
+ 298,
+ 299,
+ 300,
+ 384,
+ 385,
+ 386,
+ 387,
+ 388,
+ 389,
431,
432,
- 433
+ 433,
+ 434,
+ 435,
+ 436,
+ 437,
+ 438,
+ 439,
+ 440,
+ 441,
+ 442
],
"irBases": [
"IAvnAvaloniaObject",
@@ -22544,15 +22817,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -22569,7 +22833,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -22579,6 +22842,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -22625,15 +22889,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -22653,14 +22917,23 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283
],
"irBases": [
"IAvnAvaloniaObject",
@@ -22742,15 +23015,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -22767,19 +23031,19 @@
92,
93,
94,
- 35,
95,
96,
- 434,
+ 97,
98,
99,
100,
101,
102,
103,
+ 35,
104,
105,
- 106,
+ 443,
107,
108,
109,
@@ -22823,15 +23087,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -22851,24 +23115,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -22876,23 +23138,25 @@
365,
366,
367,
- 261,
- 402,
- 435,
- 436,
- 437,
- 417,
- 438,
- 421,
- 439,
- 440,
- 441,
- 442,
- 443,
+ 368,
+ 369,
+ 225,
+ 226,
+ 370,
+ 371,
+ 372,
+ 373,
+ 374,
+ 375,
+ 376,
+ 270,
+ 411,
444,
445,
446,
+ 426,
447,
+ 430,
448,
449,
450,
@@ -22906,9 +23170,18 @@
458,
459,
460,
- 415,
461,
- 419
+ 462,
+ 463,
+ 464,
+ 465,
+ 466,
+ 467,
+ 468,
+ 469,
+ 424,
+ 470,
+ 428
],
"irBases": [
"IAvnAvaloniaObject",
@@ -23048,15 +23321,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -23073,7 +23337,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -23083,6 +23346,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -23128,7 +23392,16 @@
146,
147,
148,
- 149
+ 149,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158
],
"irBases": [
"IAvnAvaloniaObject",
@@ -23195,22 +23468,13 @@
},
{
"name": "IAvnControlFactory",
- "iid": "15778134-9E9F-5BAF-98FF-5510778094BA",
+ "iid": "C8BCE8E8-62C7-5E0E-8066-690059F55DFF",
"iidConstant": "I_AVN_CONTROL_FACTORY_IID",
- "abiVersion": 13,
+ "abiVersion": 14,
"slots": [
0,
1,
2,
- 1019,
- 1020,
- 1021,
- 1022,
- 1023,
- 1024,
- 1025,
- 1026,
- 1027,
1028,
1029,
1030,
@@ -23304,7 +23568,18 @@
1118,
1119,
1120,
- 1121
+ 1121,
+ 1122,
+ 1123,
+ 1124,
+ 1125,
+ 1126,
+ 1127,
+ 1128,
+ 1129,
+ 1130,
+ 1131,
+ 1132
]
},
{
@@ -23352,12 +23627,12 @@
0,
1,
2,
- 55,
- 56,
- 57,
- 58,
- 59,
- 60
+ 64,
+ 65,
+ 66,
+ 67,
+ 68,
+ 69
]
},
{
@@ -23465,8 +23740,8 @@
0,
1,
2,
- 40,
- 41
+ 49,
+ 50
]
},
{
@@ -23478,15 +23753,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -23503,7 +23769,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -23513,6 +23778,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -23559,15 +23825,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -23587,17 +23853,17 @@
197,
198,
199,
- 273,
- 274,
- 462,
- 463,
- 464,
- 465,
- 466,
- 467,
- 468,
- 469,
- 470,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 282,
+ 283,
471,
472,
473,
@@ -23605,11 +23871,20 @@
475,
476,
477,
- 318,
- 319,
- 60,
478,
- 347
+ 479,
+ 480,
+ 481,
+ 482,
+ 483,
+ 484,
+ 485,
+ 486,
+ 327,
+ 328,
+ 69,
+ 487,
+ 356
],
"irBases": [
"IAvnAvaloniaObject",
@@ -23711,12 +23986,12 @@
0,
1,
2,
- 55,
- 61,
- 62,
- 63,
- 59,
- 60
+ 64,
+ 70,
+ 71,
+ 72,
+ 68,
+ 69
]
},
{
@@ -23728,15 +24003,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -23753,7 +24019,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -23763,6 +24028,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -23809,10 +24075,19 @@
147,
148,
149,
- 262,
- 263,
- 198,
- 199
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 271,
+ 272,
+ 207,
+ 208
],
"irBases": [
"IAvnAvaloniaObject",
@@ -23877,15 +24152,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -23902,7 +24168,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -23912,6 +24177,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -23958,15 +24224,24 @@
147,
148,
149,
- 348,
- 172,
- 173,
- 479,
- 480,
- 481,
- 482,
- 483,
- 484
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 357,
+ 181,
+ 182,
+ 488,
+ 489,
+ 490,
+ 491,
+ 492,
+ 493
],
"irBases": [
"IAvnAvaloniaObject",
@@ -24035,8 +24310,8 @@
0,
1,
2,
- 977,
- 978
+ 986,
+ 987
]
},
{
@@ -24048,15 +24323,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -24073,7 +24339,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -24083,6 +24348,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -24129,15 +24395,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -24157,15 +24423,15 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
276,
277,
278,
@@ -24181,7 +24447,16 @@
288,
289,
290,
- 291
+ 291,
+ 292,
+ 293,
+ 294,
+ 295,
+ 296,
+ 297,
+ 298,
+ 299,
+ 300
],
"irBases": [
"IAvnAvaloniaObject",
@@ -24274,15 +24549,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -24299,7 +24565,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -24309,6 +24574,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -24372,7 +24638,16 @@
164,
165,
166,
- 167
+ 167,
+ 168,
+ 169,
+ 170,
+ 171,
+ 172,
+ 173,
+ 174,
+ 175,
+ 176
],
"irBases": [
"IAvnAvaloniaObject",
@@ -24445,15 +24720,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -24470,7 +24736,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -24480,6 +24745,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -24526,15 +24792,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -24554,30 +24820,39 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 485,
- 486,
- 487,
- 488,
- 489,
- 490,
- 491,
- 492,
- 493,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
494,
495,
496,
497,
498,
499,
- 500
+ 500,
+ 501,
+ 502,
+ 503,
+ 504,
+ 505,
+ 506,
+ 507,
+ 508,
+ 509
],
"irBases": [
"IAvnAvaloniaObject",
@@ -24717,15 +24992,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -24742,7 +25008,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -24752,6 +25017,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -24798,23 +25064,32 @@
147,
148,
149,
- 348,
- 172,
- 173,
- 501,
- 502,
- 503,
- 504,
- 505,
- 506,
- 507,
- 508,
- 509,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 357,
+ 181,
+ 182,
510,
511,
512,
513,
- 514
+ 514,
+ 515,
+ 516,
+ 517,
+ 518,
+ 519,
+ 520,
+ 521,
+ 522,
+ 523
],
"irBases": [
"IAvnAvaloniaObject",
@@ -24887,47 +25162,47 @@
0,
1,
2,
- 70,
- 71,
- 402,
- 403,
- 515,
- 516,
- 517,
- 518,
- 417,
- 519,
- 421,
- 520,
- 449,
- 450,
- 447,
- 448,
- 443,
- 444,
- 439,
- 440,
- 441,
- 442,
- 457,
- 458,
- 521,
- 522,
- 523,
+ 79,
+ 80,
+ 411,
+ 412,
524,
525,
526,
- 445,
- 446,
527,
+ 426,
528,
- 419,
+ 430,
529,
- 415,
- 267,
- 268,
- 269,
- 270
+ 458,
+ 459,
+ 456,
+ 457,
+ 452,
+ 453,
+ 448,
+ 449,
+ 450,
+ 451,
+ 466,
+ 467,
+ 530,
+ 531,
+ 532,
+ 533,
+ 534,
+ 535,
+ 454,
+ 455,
+ 536,
+ 537,
+ 428,
+ 538,
+ 424,
+ 276,
+ 277,
+ 278,
+ 279
],
"irBases": [
"IAvnAvaloniaObject",
@@ -24969,17 +25244,17 @@
0,
1,
2,
- 70,
- 71,
- 402,
- 403,
- 515,
- 516,
- 517,
- 518,
- 417,
- 519,
- 421
+ 79,
+ 80,
+ 411,
+ 412,
+ 524,
+ 525,
+ 526,
+ 527,
+ 426,
+ 528,
+ 430
],
"irBases": [
"IAvnAvaloniaObject",
@@ -25018,6 +25293,21 @@
3
]
},
+ {
+ "name": "IAvnGradientBrush",
+ "iid": "FDAA2353-BC44-5012-A5BE-A17C7C01F41A",
+ "iidConstant": "I_AVN_GRADIENT_BRUSH_IID",
+ "abiVersion": 1,
+ "slots": [
+ 0,
+ 1,
+ 2,
+ 35,
+ 36,
+ 37,
+ 38
+ ]
+ },
{
"name": "IAvnGrid",
"iid": "028C589C-2C52-5505-9CD2-36A25B4F43A6",
@@ -25027,15 +25317,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -25052,7 +25333,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -25062,6 +25342,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -25108,19 +25389,28 @@
147,
148,
149,
- 348,
- 172,
- 173,
- 530,
- 531,
- 513,
- 514,
- 511,
- 512,
- 532,
- 533,
- 534,
- 535
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 357,
+ 181,
+ 182,
+ 539,
+ 540,
+ 522,
+ 523,
+ 520,
+ 521,
+ 541,
+ 542,
+ 543,
+ 544
],
"irBases": [
"IAvnAvaloniaObject",
@@ -25191,15 +25481,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -25216,7 +25497,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -25226,6 +25506,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -25272,15 +25553,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -25300,22 +25581,31 @@
197,
198,
199,
- 536,
- 537,
- 538,
- 539,
- 540,
- 541,
- 542,
- 543,
- 544,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
545,
546,
547,
548,
549,
550,
- 551
+ 551,
+ 552,
+ 553,
+ 554,
+ 555,
+ 556,
+ 557,
+ 558,
+ 559,
+ 560
],
"irBases": [
"IAvnAvaloniaObject",
@@ -25402,16 +25692,16 @@
0,
1,
2,
- 979,
- 980,
- 981,
- 982,
- 983,
- 984,
- 985,
- 986,
- 987,
- 988
+ 988,
+ 989,
+ 990,
+ 991,
+ 992,
+ 993,
+ 994,
+ 995,
+ 996,
+ 997
]
},
{
@@ -25423,15 +25713,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -25448,7 +25729,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -25458,6 +25738,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -25504,15 +25785,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -25532,18 +25813,27 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 485,
- 486,
- 487,
- 488
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 494,
+ 495,
+ 496,
+ 497
],
"irBases": [
"IAvnAvaloniaObject",
@@ -25629,15 +25919,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -25654,7 +25935,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -25664,6 +25944,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -25710,15 +25991,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -25738,18 +26019,27 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 485,
- 486,
- 487,
- 488
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 494,
+ 495,
+ 496,
+ 497
],
"irBases": [
"IAvnAvaloniaObject",
@@ -25834,15 +26124,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -25859,7 +26140,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -25869,6 +26149,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -25915,15 +26196,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -25943,22 +26224,31 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 485,
- 486,
- 487,
- 488
+ 208,
+ 358,
+ 359,
+ 246,
+ 247,
+ 215,
+ 216,
+ 360,
+ 361,
+ 362,
+ 363,
+ 364,
+ 365,
+ 494,
+ 495,
+ 496,
+ 497
],
"irBases": [
"IAvnAvaloniaObject",
@@ -26049,15 +26339,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -26074,7 +26355,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -26084,6 +26364,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -26130,15 +26411,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -26158,24 +26439,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -26183,11 +26462,22 @@
365,
366,
367,
- 261,
- 485,
- 486,
- 487,
- 488
+ 368,
+ 369,
+ 225,
+ 226,
+ 370,
+ 371,
+ 372,
+ 373,
+ 374,
+ 375,
+ 376,
+ 270,
+ 494,
+ 495,
+ 496,
+ 497
],
"irBases": [
"IAvnAvaloniaObject",
@@ -26286,15 +26576,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -26311,7 +26592,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -26321,6 +26601,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -26367,15 +26648,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -26395,15 +26676,15 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
276,
277,
278,
@@ -26420,10 +26701,19 @@
289,
290,
291,
- 552,
- 553,
- 554,
- 555
+ 292,
+ 293,
+ 294,
+ 295,
+ 296,
+ 297,
+ 298,
+ 299,
+ 300,
+ 561,
+ 562,
+ 563,
+ 564
],
"irBases": [
"IAvnAvaloniaObject",
@@ -26518,15 +26808,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -26543,7 +26824,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -26553,6 +26833,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -26599,15 +26880,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -26626,7 +26907,16 @@
196,
197,
198,
- 199
+ 199,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208
],
"irBases": [
"IAvnAvaloniaObject",
@@ -26704,15 +26994,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -26729,7 +27010,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -26739,6 +27019,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -26785,14 +27066,23 @@
147,
148,
149,
- 556,
- 557,
- 558,
- 559,
+ 150,
+ 151,
152,
153,
- 560,
- 561
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 565,
+ 566,
+ 567,
+ 568,
+ 161,
+ 162,
+ 569,
+ 570
],
"irBases": [
"IAvnAvaloniaObject",
@@ -26859,7 +27149,7 @@
0,
1,
2,
- 42
+ 51
]
},
{
@@ -26871,12 +27161,12 @@
0,
1,
2,
- 55,
- 56,
- 57,
- 58,
- 59,
- 60
+ 64,
+ 65,
+ 66,
+ 67,
+ 68,
+ 69
]
},
{
@@ -26888,7 +27178,7 @@
0,
1,
2,
- 44
+ 53
]
},
{
@@ -26900,15 +27190,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -26925,7 +27206,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -26935,6 +27215,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -26981,15 +27262,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -27009,18 +27290,27 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356
+ 208,
+ 358,
+ 359,
+ 246,
+ 247,
+ 215,
+ 216,
+ 360,
+ 361,
+ 362,
+ 363,
+ 364,
+ 365
],
"irBases": [
"IAvnAvaloniaObject",
@@ -27108,15 +27398,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -27133,7 +27414,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -27143,6 +27423,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -27189,15 +27470,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -27217,16 +27498,25 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 515,
- 562
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 524,
+ 571
],
"irBases": [
"IAvnAvaloniaObject",
@@ -27310,15 +27600,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -27335,7 +27616,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -27345,6 +27625,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -27391,12 +27672,21 @@
147,
148,
149,
- 262,
- 263,
- 198,
- 199,
- 563,
- 564
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 271,
+ 272,
+ 207,
+ 208,
+ 572,
+ 573
],
"irBases": [
"IAvnAvaloniaObject",
@@ -27463,15 +27753,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -27488,7 +27769,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -27498,6 +27778,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -27562,10 +27843,19 @@
165,
166,
167,
- 565,
- 566,
- 567,
- 568
+ 168,
+ 169,
+ 170,
+ 171,
+ 172,
+ 173,
+ 174,
+ 175,
+ 176,
+ 574,
+ 575,
+ 576,
+ 577
],
"irBases": [
"IAvnAvaloniaObject",
@@ -27631,6 +27921,23 @@
335
]
},
+ {
+ "name": "IAvnLinearGradientBrush",
+ "iid": "40B3D53D-330E-5D63-A040-37F1FF717FF8",
+ "iidConstant": "I_AVN_LINEAR_GRADIENT_BRUSH_IID",
+ "abiVersion": 1,
+ "slots": [
+ 0,
+ 1,
+ 2,
+ 35,
+ 36,
+ 37,
+ 38,
+ 39,
+ 40
+ ]
+ },
{
"name": "IAvnListBox",
"iid": "FD704B9F-4E33-516E-B48D-B1DC9AA44DCA",
@@ -27640,15 +27947,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -27665,7 +27963,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -27675,6 +27972,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -27721,15 +28019,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -27749,24 +28047,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -27774,11 +28070,22 @@
365,
366,
367,
- 261,
- 314,
- 315,
- 569,
- 570
+ 368,
+ 369,
+ 225,
+ 226,
+ 370,
+ 371,
+ 372,
+ 373,
+ 374,
+ 375,
+ 376,
+ 270,
+ 323,
+ 324,
+ 578,
+ 579
],
"irBases": [
"IAvnAvaloniaObject",
@@ -27878,15 +28185,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -27903,7 +28201,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -27913,6 +28210,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -27959,15 +28257,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -27987,16 +28285,25 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 388,
- 389
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 397,
+ 398
],
"irBases": [
"IAvnAvaloniaObject",
@@ -28080,15 +28387,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -28105,7 +28403,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -28115,6 +28412,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -28161,15 +28459,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -28189,25 +28487,25 @@
197,
198,
199,
- 571,
- 572,
- 214,
- 215,
- 573,
- 574,
- 575,
- 576,
200,
201,
- 577,
- 578,
- 579,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
580,
581,
+ 223,
+ 224,
582,
583,
584,
585,
+ 209,
+ 210,
586,
587,
588,
@@ -28215,43 +28513,43 @@
590,
591,
592,
- 239,
- 240,
593,
594,
595,
596,
597,
598,
- 218,
- 219,
599,
600,
- 271,
- 272,
- 273,
- 274,
601,
+ 248,
+ 249,
602,
- 223,
- 224,
- 338,
- 339,
- 225,
- 226,
- 241,
- 242,
- 243,
- 244,
603,
604,
605,
606,
607,
+ 227,
+ 228,
608,
609,
+ 280,
+ 281,
+ 282,
+ 283,
610,
611,
+ 232,
+ 233,
+ 347,
+ 348,
+ 234,
+ 235,
+ 250,
+ 251,
+ 252,
+ 253,
612,
613,
614,
@@ -28263,9 +28561,7 @@
620,
621,
622,
- 60,
623,
- 569,
624,
625,
626,
@@ -28274,8 +28570,9 @@
629,
630,
631,
+ 69,
632,
- 247,
+ 578,
633,
634,
635,
@@ -28285,13 +28582,23 @@
639,
640,
641,
+ 256,
642,
643,
644,
645,
646,
647,
- 648
+ 648,
+ 649,
+ 650,
+ 651,
+ 652,
+ 653,
+ 654,
+ 655,
+ 656,
+ 657
],
"irBases": [
"IAvnAvaloniaObject",
@@ -28430,15 +28737,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -28455,7 +28753,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -28465,6 +28762,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -28511,15 +28809,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -28539,24 +28837,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -28564,14 +28860,25 @@
365,
366,
367,
- 261,
- 402,
- 435,
- 436,
- 437,
- 417,
- 438,
- 421
+ 368,
+ 369,
+ 225,
+ 226,
+ 370,
+ 371,
+ 372,
+ 373,
+ 374,
+ 375,
+ 376,
+ 270,
+ 411,
+ 444,
+ 445,
+ 446,
+ 426,
+ 447,
+ 430
],
"irBases": [
"IAvnAvaloniaObject",
@@ -28674,15 +28981,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -28699,7 +28997,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -28709,6 +29006,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -28755,15 +29053,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -28783,24 +29081,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -28808,14 +29104,25 @@
365,
366,
367,
- 261,
- 402,
- 435,
- 436,
- 437,
- 417,
- 438,
- 421
+ 368,
+ 369,
+ 225,
+ 226,
+ 370,
+ 371,
+ 372,
+ 373,
+ 374,
+ 375,
+ 376,
+ 270,
+ 411,
+ 444,
+ 445,
+ 446,
+ 426,
+ 447,
+ 430
],
"irBases": [
"IAvnAvaloniaObject",
@@ -28941,48 +29248,48 @@
0,
1,
2,
- 70,
- 71,
- 402,
- 403,
- 515,
- 516,
- 517,
- 518,
- 417,
- 519,
- 421,
- 520,
- 449,
- 450,
- 447,
- 448,
- 443,
- 444,
- 439,
- 440,
- 441,
- 442,
- 457,
- 458,
- 521,
- 522,
- 523,
+ 79,
+ 80,
+ 411,
+ 412,
524,
525,
526,
- 445,
- 446,
527,
+ 426,
528,
- 419,
+ 430,
529,
- 415,
- 349,
- 237,
- 238,
- 206,
- 207
+ 458,
+ 459,
+ 456,
+ 457,
+ 452,
+ 453,
+ 448,
+ 449,
+ 450,
+ 451,
+ 466,
+ 467,
+ 530,
+ 531,
+ 532,
+ 533,
+ 534,
+ 535,
+ 454,
+ 455,
+ 536,
+ 537,
+ 428,
+ 538,
+ 424,
+ 358,
+ 246,
+ 247,
+ 215,
+ 216
],
"irBases": [
"IAvnAvaloniaObject",
@@ -29025,15 +29332,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -29050,7 +29348,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -29060,6 +29357,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -29106,15 +29404,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -29134,24 +29432,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -29159,41 +29455,52 @@
365,
366,
367,
- 261,
- 485,
- 486,
- 487,
- 488,
- 277,
- 278,
- 279,
- 280,
- 281,
- 282,
- 649,
- 650,
- 651,
- 652,
- 388,
- 389,
- 653,
- 654,
- 655,
- 656,
- 657,
- 658,
+ 368,
+ 369,
+ 225,
+ 226,
+ 370,
+ 371,
+ 372,
+ 373,
+ 374,
375,
376,
+ 270,
+ 494,
+ 495,
+ 496,
+ 497,
+ 286,
+ 287,
+ 288,
+ 289,
+ 290,
+ 291,
+ 658,
659,
660,
661,
+ 397,
+ 398,
662,
- 436,
- 435,
663,
- 291,
664,
- 665
+ 665,
+ 666,
+ 667,
+ 384,
+ 385,
+ 668,
+ 669,
+ 670,
+ 671,
+ 445,
+ 444,
+ 672,
+ 300,
+ 673,
+ 674
],
"irBases": [
"IAvnAvaloniaObject",
@@ -29334,12 +29641,12 @@
0,
1,
2,
- 49,
- 50,
- 51,
- 52,
- 53,
- 54
+ 58,
+ 59,
+ 60,
+ 61,
+ 62,
+ 63
]
},
{
@@ -29363,15 +29670,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -29388,7 +29686,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -29398,6 +29695,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -29444,15 +29742,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -29472,22 +29770,31 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 666,
- 667,
- 668,
- 669,
- 670,
- 435,
- 671,
- 672
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 675,
+ 676,
+ 677,
+ 678,
+ 679,
+ 444,
+ 680,
+ 681
],
"irBases": [
"IAvnAvaloniaObject",
@@ -29587,15 +29894,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -29612,7 +29910,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -29622,6 +29919,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -29668,15 +29966,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -29696,46 +29994,55 @@
197,
198,
199,
- 296,
- 297,
- 300,
- 301,
- 298,
- 299,
- 673,
- 674,
- 675,
- 676,
- 677,
- 678,
- 577,
- 578,
- 679,
- 680,
- 681,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 305,
+ 306,
+ 309,
+ 310,
+ 307,
+ 308,
682,
- 218,
- 219,
683,
684,
- 223,
- 224,
- 225,
- 226,
- 271,
- 272,
- 273,
- 274,
- 601,
- 602,
- 241,
- 242,
- 243,
- 244,
685,
686,
687,
- 688
+ 586,
+ 587,
+ 688,
+ 689,
+ 690,
+ 691,
+ 227,
+ 228,
+ 692,
+ 693,
+ 232,
+ 233,
+ 234,
+ 235,
+ 280,
+ 281,
+ 282,
+ 283,
+ 610,
+ 611,
+ 250,
+ 251,
+ 252,
+ 253,
+ 694,
+ 695,
+ 696,
+ 697
],
"irBases": [
"IAvnAvaloniaObject",
@@ -29857,15 +30164,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -29882,7 +30180,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -29892,6 +30189,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -29938,9 +30236,18 @@
147,
148,
149,
- 348,
- 172,
- 173
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 357,
+ 181,
+ 182
],
"irBases": [
"IAvnAvaloniaObject",
@@ -30005,15 +30312,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -30030,7 +30328,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -30040,6 +30337,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -30104,8 +30402,17 @@
165,
166,
167,
- 689,
- 690
+ 168,
+ 169,
+ 170,
+ 171,
+ 172,
+ 173,
+ 174,
+ 175,
+ 176,
+ 698,
+ 699
],
"irBases": [
"IAvnAvaloniaObject",
@@ -30179,15 +30486,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -30204,7 +30502,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -30214,6 +30511,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -30260,15 +30558,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -30288,8 +30586,17 @@
197,
198,
199,
- 689,
- 690
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 698,
+ 699
],
"irBases": [
"IAvnAvaloniaObject",
@@ -30369,15 +30676,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -30394,7 +30692,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -30404,6 +30701,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -30450,15 +30748,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -30478,20 +30776,29 @@
197,
198,
199,
- 691,
- 692,
- 693,
- 694,
- 695,
- 696,
- 697,
- 698,
- 699,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
700,
701,
702,
703,
- 704
+ 704,
+ 705,
+ 706,
+ 707,
+ 708,
+ 709,
+ 710,
+ 711,
+ 712,
+ 713
],
"irBases": [
"IAvnAvaloniaObject",
@@ -30588,15 +30895,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -30613,7 +30911,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -30623,6 +30920,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -30687,10 +30985,19 @@
165,
166,
167,
- 705,
- 706,
- 707,
- 708
+ 168,
+ 169,
+ 170,
+ 171,
+ 172,
+ 173,
+ 174,
+ 175,
+ 176,
+ 714,
+ 715,
+ 716,
+ 717
],
"irBases": [
"IAvnAvaloniaObject",
@@ -30765,15 +31072,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -30790,7 +31088,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -30800,6 +31097,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -30864,10 +31162,19 @@
165,
166,
167,
- 705,
- 706,
- 707,
- 708
+ 168,
+ 169,
+ 170,
+ 171,
+ 172,
+ 173,
+ 174,
+ 175,
+ 176,
+ 714,
+ 715,
+ 716,
+ 717
],
"irBases": [
"IAvnAvaloniaObject",
@@ -30942,15 +31249,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -30967,7 +31265,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -30977,6 +31274,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -31023,52 +31321,61 @@
147,
148,
149,
- 451,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 460,
+ 461,
+ 271,
+ 272,
+ 718,
+ 719,
+ 720,
+ 721,
+ 411,
+ 412,
452,
- 262,
- 263,
- 709,
- 710,
- 711,
- 712,
- 402,
- 403,
- 443,
- 444,
- 445,
- 446,
- 447,
- 448,
- 449,
- 450,
453,
454,
455,
456,
457,
458,
- 523,
- 524,
- 525,
- 526,
- 439,
- 440,
- 441,
- 442,
- 713,
- 714,
- 715,
- 716,
- 717,
- 718,
- 719,
- 720,
- 436,
- 435,
- 721,
- 421,
+ 459,
+ 462,
+ 463,
+ 464,
+ 465,
+ 466,
+ 467,
+ 532,
+ 533,
+ 534,
+ 535,
+ 448,
+ 449,
+ 450,
+ 451,
722,
- 417
+ 723,
+ 724,
+ 725,
+ 726,
+ 727,
+ 728,
+ 729,
+ 445,
+ 444,
+ 730,
+ 430,
+ 731,
+ 426
],
"irBases": [
"IAvnAvaloniaObject",
@@ -31168,43 +31475,43 @@
0,
1,
2,
- 70,
- 71,
- 402,
- 403,
- 515,
- 516,
- 517,
- 518,
- 417,
- 519,
- 421,
- 520,
- 449,
- 450,
- 447,
- 448,
- 443,
- 444,
- 439,
- 440,
- 441,
- 442,
- 457,
- 458,
- 521,
- 522,
- 523,
+ 79,
+ 80,
+ 411,
+ 412,
524,
525,
526,
- 445,
- 446,
527,
+ 426,
528,
- 419,
+ 430,
529,
- 415
+ 458,
+ 459,
+ 456,
+ 457,
+ 452,
+ 453,
+ 448,
+ 449,
+ 450,
+ 451,
+ 466,
+ 467,
+ 530,
+ 531,
+ 532,
+ 533,
+ 534,
+ 535,
+ 454,
+ 455,
+ 536,
+ 537,
+ 428,
+ 538,
+ 424
],
"irBases": [
"IAvnAvaloniaObject",
@@ -31279,7 +31586,7 @@
0,
1,
2,
- 46
+ 55
]
},
{
@@ -31291,15 +31598,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -31316,7 +31614,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -31326,6 +31623,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -31372,15 +31670,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -31400,18 +31698,17 @@
197,
198,
199,
- 723,
- 724,
- 725,
- 726,
- 727,
- 728,
- 729,
- 730,
- 731,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
732,
733,
- 688,
734,
735,
736,
@@ -31419,8 +31716,18 @@
738,
739,
740,
+ 741,
+ 742,
697,
- 698
+ 743,
+ 744,
+ 745,
+ 746,
+ 747,
+ 748,
+ 749,
+ 706,
+ 707
],
"irBases": [
"IAvnAvaloniaObject",
@@ -31501,6 +31808,25 @@
492
]
},
+ {
+ "name": "IAvnRadialGradientBrush",
+ "iid": "AEC23FCE-9FEA-506C-ABC4-774143BE80C8",
+ "iidConstant": "I_AVN_RADIAL_GRADIENT_BRUSH_IID",
+ "abiVersion": 1,
+ "slots": [
+ 0,
+ 1,
+ 2,
+ 35,
+ 36,
+ 37,
+ 38,
+ 41,
+ 42,
+ 43,
+ 44
+ ]
+ },
{
"name": "IAvnRadioButton",
"iid": "FBEA357A-8E1A-5579-A0CF-4FD48895DADB",
@@ -31510,15 +31836,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -31535,7 +31852,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -31545,6 +31861,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -31591,15 +31908,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -31619,15 +31936,15 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
276,
277,
278,
@@ -31644,14 +31961,23 @@
289,
290,
291,
- 375,
- 376,
- 377,
- 378,
- 379,
- 380,
- 659,
- 660
+ 292,
+ 293,
+ 294,
+ 295,
+ 296,
+ 297,
+ 298,
+ 299,
+ 300,
+ 384,
+ 385,
+ 386,
+ 387,
+ 388,
+ 389,
+ 668,
+ 669
],
"irBases": [
"IAvnAvaloniaObject",
@@ -31749,15 +32075,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -31774,7 +32091,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -31784,6 +32100,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -31830,15 +32147,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -31858,18 +32175,27 @@
197,
198,
199,
- 723,
- 724,
- 725,
- 726,
- 727,
- 728,
- 729,
- 730,
- 731,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
732,
733,
- 688
+ 734,
+ 735,
+ 736,
+ 737,
+ 738,
+ 739,
+ 740,
+ 741,
+ 742,
+ 697
],
"irBases": [
"IAvnAvaloniaObject",
@@ -31965,15 +32291,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -31990,7 +32307,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -32000,6 +32316,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -32064,10 +32381,19 @@
165,
166,
167,
- 741,
- 742,
- 743,
- 744
+ 168,
+ 169,
+ 170,
+ 171,
+ 172,
+ 173,
+ 174,
+ 175,
+ 176,
+ 750,
+ 751,
+ 752,
+ 753
],
"irBases": [
"IAvnAvaloniaObject",
@@ -32142,15 +32468,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -32167,7 +32484,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -32177,6 +32493,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -32223,15 +32540,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -32251,21 +32568,30 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 745,
- 746,
- 747,
- 748,
- 749,
- 750,
- 751
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 754,
+ 755,
+ 756,
+ 757,
+ 758,
+ 759,
+ 760
],
"irBases": [
"IAvnAvaloniaObject",
@@ -32364,15 +32690,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -32389,7 +32706,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -32399,6 +32715,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -32445,9 +32762,18 @@
147,
148,
149,
- 348,
- 172,
- 173
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 357,
+ 181,
+ 182
],
"irBases": [
"IAvnAvaloniaObject",
@@ -32513,18 +32839,18 @@
0,
1,
2,
- 989,
- 990,
- 991,
- 992,
- 993,
- 994,
- 995,
- 996,
- 997,
998,
999,
- 1000
+ 1000,
+ 1001,
+ 1002,
+ 1003,
+ 1004,
+ 1005,
+ 1006,
+ 1007,
+ 1008,
+ 1009
]
},
{
@@ -32536,15 +32862,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -32561,7 +32878,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -32571,6 +32887,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -32617,15 +32934,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -32645,15 +32962,15 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
276,
277,
278,
@@ -32670,10 +32987,19 @@
289,
290,
291,
- 752,
- 753,
- 754,
- 755
+ 292,
+ 293,
+ 294,
+ 295,
+ 296,
+ 297,
+ 298,
+ 299,
+ 300,
+ 761,
+ 762,
+ 763,
+ 764
],
"irBases": [
"IAvnAvaloniaObject",
@@ -32768,15 +33094,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -32793,7 +33110,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -32803,6 +33119,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -32849,15 +33166,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -32877,29 +33194,28 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 756,
- 757,
- 758,
- 759,
- 760,
- 761,
- 762,
- 763,
- 764,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
765,
766,
767,
768,
769,
- 491,
770,
771,
772,
@@ -32909,6 +33225,7 @@
776,
777,
778,
+ 500,
779,
780,
781,
@@ -32929,7 +33246,16 @@
796,
797,
798,
- 799
+ 799,
+ 800,
+ 801,
+ 802,
+ 803,
+ 804,
+ 805,
+ 806,
+ 807,
+ 808
],
"irBases": [
"IAvnAvaloniaObject",
@@ -33056,15 +33382,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -33081,7 +33398,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -33091,6 +33407,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -33158,7 +33475,16 @@
168,
169,
170,
- 171
+ 171,
+ 172,
+ 173,
+ 174,
+ 175,
+ 176,
+ 177,
+ 178,
+ 179,
+ 180
],
"irBases": [
"IAvnAvaloniaObject",
@@ -33233,15 +33559,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -33258,7 +33575,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -33268,6 +33584,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -33314,57 +33631,66 @@
147,
148,
149,
- 198,
- 199,
- 172,
- 173,
- 218,
- 219,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 207,
+ 208,
+ 181,
182,
- 183,
- 186,
- 187,
- 188,
- 189,
- 190,
+ 227,
+ 228,
191,
192,
- 193,
- 194,
195,
- 597,
- 598,
- 800,
- 801,
196,
197,
- 593,
- 594,
- 605,
+ 198,
+ 199,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
606,
- 802,
- 803,
- 601,
+ 607,
+ 809,
+ 810,
+ 205,
+ 206,
602,
- 184,
- 185,
- 804,
- 805,
- 581,
- 582,
- 583,
- 584,
- 589,
+ 603,
+ 614,
+ 615,
+ 811,
+ 812,
+ 610,
+ 611,
+ 193,
+ 194,
+ 813,
+ 814,
590,
591,
592,
+ 593,
+ 598,
599,
- 610,
- 621,
- 569,
- 618,
- 806,
- 627
+ 600,
+ 601,
+ 608,
+ 619,
+ 630,
+ 578,
+ 627,
+ 815,
+ 636
],
"irBases": [
"IAvnAvaloniaObject",
@@ -33468,12 +33794,12 @@
0,
1,
2,
- 55,
64,
- 65,
- 66,
- 59,
- 60
+ 73,
+ 74,
+ 75,
+ 68,
+ 69
]
},
{
@@ -33485,15 +33811,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -33510,7 +33827,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -33520,6 +33836,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -33566,15 +33883,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -33594,24 +33911,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -33619,7 +33934,18 @@
365,
366,
367,
- 261
+ 368,
+ 369,
+ 225,
+ 226,
+ 370,
+ 371,
+ 372,
+ 373,
+ 374,
+ 375,
+ 376,
+ 270
],
"irBases": [
"IAvnAvaloniaObject",
@@ -33742,15 +34068,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -33767,7 +34084,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -33777,6 +34093,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -33823,15 +34140,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -33850,7 +34167,16 @@
196,
197,
198,
- 199
+ 199,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208
],
"irBases": [
"IAvnAvaloniaObject",
@@ -33928,15 +34254,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -33953,7 +34270,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -33963,6 +34279,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -34026,7 +34343,16 @@
164,
165,
166,
- 167
+ 167,
+ 168,
+ 169,
+ 170,
+ 171,
+ 172,
+ 173,
+ 174,
+ 175,
+ 176
],
"irBases": [
"IAvnAvaloniaObject",
@@ -34098,15 +34424,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -34123,7 +34440,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -34133,6 +34449,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -34179,15 +34496,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -34207,30 +34524,39 @@
197,
198,
199,
- 723,
- 724,
- 725,
- 726,
- 727,
- 728,
- 729,
- 730,
- 731,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
732,
733,
- 688,
- 807,
- 808,
+ 734,
+ 735,
+ 736,
+ 737,
+ 738,
+ 739,
+ 740,
+ 741,
+ 742,
697,
- 698,
- 809,
- 810,
- 811,
- 812,
- 813,
- 814,
- 815,
- 816
+ 816,
+ 817,
+ 706,
+ 707,
+ 818,
+ 819,
+ 820,
+ 821,
+ 822,
+ 823,
+ 824,
+ 825
],
"irBases": [
"IAvnAvaloniaObject",
@@ -34321,15 +34647,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -34346,7 +34663,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -34356,6 +34672,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -34402,15 +34719,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -34430,18 +34747,27 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 292,
- 293,
- 294,
- 295
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 301,
+ 302,
+ 303,
+ 304
],
"irBases": [
"IAvnAvaloniaObject",
@@ -34538,15 +34864,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -34563,7 +34880,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -34573,6 +34889,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -34619,15 +34936,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -34647,24 +34964,33 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
277,
278,
+ 279,
+ 280,
281,
282,
+ 283,
+ 286,
+ 287,
+ 290,
+ 291,
+ 297,
+ 298,
288,
289,
- 279,
- 280,
- 817,
- 291
+ 826,
+ 300
],
"irBases": [
"IAvnAvaloniaObject",
@@ -34764,15 +35090,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -34789,7 +35106,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -34799,6 +35115,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -34845,15 +35162,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -34873,27 +35190,27 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 818,
- 819,
- 312,
- 313,
- 820,
- 821,
- 822,
- 823,
- 824,
- 825,
- 826,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
827,
828,
+ 321,
+ 322,
829,
830,
831,
@@ -34906,7 +35223,16 @@
838,
839,
840,
- 841
+ 841,
+ 842,
+ 843,
+ 844,
+ 845,
+ 846,
+ 847,
+ 848,
+ 849,
+ 850
],
"irBases": [
"IAvnAvaloniaObject",
@@ -35050,15 +35376,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -35075,7 +35392,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -35085,6 +35401,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -35131,17 +35448,26 @@
147,
148,
149,
- 348,
- 172,
- 173,
- 842,
- 843,
- 697,
- 698,
- 844,
- 845,
- 846,
- 847
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 357,
+ 181,
+ 182,
+ 851,
+ 852,
+ 706,
+ 707,
+ 853,
+ 854,
+ 855,
+ 856
],
"irBases": [
"IAvnAvaloniaObject",
@@ -35211,12 +35537,12 @@
0,
1,
2,
- 55,
- 67,
+ 64,
+ 76,
+ 77,
+ 78,
68,
- 69,
- 59,
- 60
+ 69
]
},
{
@@ -35228,15 +35554,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -35250,7 +35567,16 @@
89,
90,
91,
- 92
+ 92,
+ 93,
+ 94,
+ 95,
+ 96,
+ 97,
+ 98,
+ 99,
+ 100,
+ 101
],
"irBases": [
"IAvnAvaloniaObject",
@@ -35353,15 +35679,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -35378,7 +35695,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -35388,6 +35704,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -35434,15 +35751,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -35462,24 +35779,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -35487,19 +35802,30 @@
365,
366,
367,
- 261,
- 271,
- 272,
- 273,
- 274,
- 848,
- 849,
- 269,
+ 368,
+ 369,
+ 225,
+ 226,
+ 370,
+ 371,
+ 372,
+ 373,
+ 374,
+ 375,
+ 376,
270,
- 850,
- 851,
- 852,
- 853
+ 280,
+ 281,
+ 282,
+ 283,
+ 857,
+ 858,
+ 278,
+ 279,
+ 859,
+ 860,
+ 861,
+ 862
],
"irBases": [
"IAvnAvaloniaObject",
@@ -35603,15 +35929,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -35628,7 +35945,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -35638,6 +35954,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -35684,15 +36001,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -35712,27 +36029,36 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 485,
- 486,
- 487,
- 488,
- 854,
- 388,
- 389,
- 424,
- 425,
- 855,
- 856,
- 852,
- 853
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 494,
+ 495,
+ 496,
+ 497,
+ 863,
+ 397,
+ 398,
+ 433,
+ 434,
+ 864,
+ 865,
+ 861,
+ 862
],
"irBases": [
"IAvnAvaloniaObject",
@@ -35823,15 +36149,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -35848,7 +36165,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -35858,6 +36174,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -35904,15 +36221,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -35932,24 +36249,22 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
359,
- 360,
+ 246,
+ 247,
+ 215,
216,
- 217,
+ 360,
361,
362,
363,
@@ -35957,15 +36272,26 @@
365,
366,
367,
- 261,
- 314,
- 315,
- 569,
- 570,
- 857,
- 858,
- 859,
- 860
+ 368,
+ 369,
+ 225,
+ 226,
+ 370,
+ 371,
+ 372,
+ 373,
+ 374,
+ 375,
+ 376,
+ 270,
+ 323,
+ 324,
+ 578,
+ 579,
+ 866,
+ 867,
+ 868,
+ 869
],
"irBases": [
"IAvnAvaloniaObject",
@@ -36068,15 +36394,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -36093,7 +36410,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -36103,6 +36419,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -36149,15 +36466,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -36177,14 +36494,23 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283
],
"irBases": [
"IAvnAvaloniaObject",
@@ -36267,15 +36593,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -36290,24 +36607,33 @@
90,
91,
92,
- 487,
- 488,
- 485,
- 486,
- 861,
- 862,
- 107,
- 108,
- 109,
- 110,
93,
94,
- 863,
- 864,
- 271,
- 272,
- 865,
- 866
+ 95,
+ 96,
+ 97,
+ 98,
+ 99,
+ 100,
+ 101,
+ 496,
+ 497,
+ 494,
+ 495,
+ 870,
+ 871,
+ 116,
+ 117,
+ 118,
+ 119,
+ 102,
+ 103,
+ 872,
+ 873,
+ 280,
+ 281,
+ 874,
+ 875
],
"irBases": [
"IAvnAvaloniaObject",
@@ -36349,15 +36675,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -36374,7 +36691,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -36384,6 +36700,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -36430,15 +36747,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -36458,16 +36775,25 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 388,
- 389
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 397,
+ 398
],
"irBases": [
"IAvnAvaloniaObject",
@@ -36552,15 +36878,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -36577,7 +36894,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -36587,6 +36903,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -36633,15 +36950,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -36660,7 +36977,16 @@
196,
197,
198,
- 199
+ 199,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208
],
"irBases": [
"IAvnAvaloniaObject",
@@ -36737,15 +37063,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -36762,7 +37079,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -36772,6 +37088,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -36818,42 +37135,51 @@
147,
148,
149,
- 198,
- 199,
- 172,
- 173,
- 218,
- 219,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 207,
+ 208,
+ 181,
182,
- 183,
- 186,
- 187,
- 188,
- 189,
- 190,
+ 227,
+ 228,
191,
192,
- 193,
- 194,
195,
- 597,
- 598,
- 800,
- 801,
196,
197,
- 593,
- 594,
- 605,
+ 198,
+ 199,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
606,
- 802,
- 803,
- 601,
+ 607,
+ 809,
+ 810,
+ 205,
+ 206,
602,
- 184,
- 185,
- 804,
- 805
+ 603,
+ 614,
+ 615,
+ 811,
+ 812,
+ 610,
+ 611,
+ 193,
+ 194,
+ 813,
+ 814
],
"irBases": [
"IAvnAvaloniaObject",
@@ -36934,15 +37260,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -36959,7 +37276,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -36969,6 +37285,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -37015,15 +37332,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -37043,25 +37360,25 @@
197,
198,
199,
- 571,
- 572,
- 214,
- 215,
- 573,
- 574,
- 575,
- 576,
200,
201,
- 577,
- 578,
- 579,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
580,
581,
+ 223,
+ 224,
582,
583,
584,
585,
+ 209,
+ 210,
586,
587,
588,
@@ -37069,43 +37386,43 @@
590,
591,
592,
- 239,
- 240,
593,
594,
595,
596,
597,
598,
- 218,
- 219,
599,
600,
- 271,
- 272,
- 273,
- 274,
601,
+ 248,
+ 249,
602,
- 223,
- 224,
- 338,
- 339,
- 225,
- 226,
- 241,
- 242,
- 243,
- 244,
603,
604,
605,
606,
607,
+ 227,
+ 228,
608,
609,
+ 280,
+ 281,
+ 282,
+ 283,
610,
611,
+ 232,
+ 233,
+ 347,
+ 348,
+ 234,
+ 235,
+ 250,
+ 251,
+ 252,
+ 253,
612,
613,
614,
@@ -37117,9 +37434,7 @@
620,
621,
622,
- 60,
623,
- 569,
624,
625,
626,
@@ -37128,10 +37443,21 @@
629,
630,
631,
+ 69,
632,
- 247,
+ 578,
633,
- 634
+ 634,
+ 635,
+ 636,
+ 637,
+ 638,
+ 639,
+ 640,
+ 641,
+ 256,
+ 642,
+ 643
],
"irBases": [
"IAvnAvaloniaObject",
@@ -37321,7 +37647,7 @@
0,
1,
2,
- 43
+ 52
]
},
{
@@ -37333,7 +37659,7 @@
0,
1,
2,
- 45
+ 54
]
},
{
@@ -37345,15 +37671,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -37370,7 +37687,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -37380,6 +37696,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -37426,12 +37743,21 @@
147,
148,
149,
- 262,
- 263,
- 198,
- 199,
- 867,
- 868
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 271,
+ 272,
+ 207,
+ 208,
+ 876,
+ 877
],
"irBases": [
"IAvnAvaloniaObject",
@@ -37498,15 +37824,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -37523,7 +37840,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -37533,6 +37849,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -37579,15 +37896,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -37607,12 +37924,21 @@
197,
198,
199,
- 536,
- 537,
- 538,
- 539,
- 540,
- 541
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 545,
+ 546,
+ 547,
+ 548,
+ 549,
+ 550
],
"irBases": [
"IAvnAvaloniaObject",
@@ -37729,15 +38055,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -37754,7 +38071,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -37764,6 +38080,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -37810,15 +38127,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -37838,21 +38155,30 @@
197,
198,
199,
- 273,
- 274,
- 869,
- 870,
- 871,
- 872,
- 873,
- 874,
- 875,
- 876,
- 877,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 282,
+ 283,
878,
- 60,
879,
- 880
+ 880,
+ 881,
+ 882,
+ 883,
+ 884,
+ 885,
+ 886,
+ 887,
+ 69,
+ 888,
+ 889
],
"irBases": [
"IAvnAvaloniaObject",
@@ -37950,15 +38276,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -37975,7 +38292,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -37985,6 +38301,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -38031,15 +38348,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -38059,15 +38376,15 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
276,
277,
278,
@@ -38084,12 +38401,21 @@
289,
290,
291,
- 375,
- 376,
- 377,
- 378,
- 379,
- 380
+ 292,
+ 293,
+ 294,
+ 295,
+ 296,
+ 297,
+ 298,
+ 299,
+ 300,
+ 384,
+ 385,
+ 386,
+ 387,
+ 388,
+ 389
],
"irBases": [
"IAvnAvaloniaObject",
@@ -38197,15 +38523,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -38222,7 +38539,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -38232,6 +38548,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -38278,15 +38595,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -38306,28 +38623,37 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
277,
278,
+ 279,
+ 280,
281,
282,
+ 283,
+ 286,
+ 287,
+ 290,
+ 291,
+ 297,
+ 298,
288,
289,
- 279,
- 280,
- 817,
- 291,
- 375,
- 376,
- 881,
- 380
+ 826,
+ 300,
+ 384,
+ 385,
+ 890,
+ 389
],
"irBases": [
"IAvnAvaloniaObject",
@@ -38430,15 +38756,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -38455,7 +38772,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -38465,6 +38781,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -38511,15 +38828,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -38539,15 +38856,15 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 275,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
276,
277,
278,
@@ -38564,20 +38881,29 @@
289,
290,
291,
- 375,
- 376,
- 377,
- 378,
- 379,
- 380,
- 882,
- 883,
- 884,
- 885,
- 886,
- 887,
- 888,
- 889
+ 292,
+ 293,
+ 294,
+ 295,
+ 296,
+ 297,
+ 298,
+ 299,
+ 300,
+ 384,
+ 385,
+ 386,
+ 387,
+ 388,
+ 389,
+ 891,
+ 892,
+ 893,
+ 894,
+ 895,
+ 896,
+ 897,
+ 898
],
"irBases": [
"IAvnAvaloniaObject",
@@ -38678,15 +39004,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -38703,7 +39020,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -38713,6 +39029,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -38759,15 +39076,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -38787,14 +39104,23 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283
],
"irBases": [
"IAvnAvaloniaObject",
@@ -38877,15 +39203,6 @@
0,
1,
2,
- 1001,
- 1002,
- 1003,
- 1004,
- 1005,
- 1006,
- 1007,
- 1008,
- 1009,
1010,
1011,
1012,
@@ -38894,7 +39211,16 @@
1015,
1016,
1017,
- 1018
+ 1018,
+ 1019,
+ 1020,
+ 1021,
+ 1022,
+ 1023,
+ 1024,
+ 1025,
+ 1026,
+ 1027
]
},
{
@@ -38906,15 +39232,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -38931,7 +39248,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -38941,6 +39257,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -38987,15 +39304,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -39015,18 +39332,27 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 890,
- 891,
- 892,
- 893
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
+ 899,
+ 900,
+ 901,
+ 902
],
"irBases": [
"IAvnAvaloniaObject",
@@ -39123,20 +39449,20 @@
0,
1,
2,
- 70,
- 71,
- 277,
- 278,
- 281,
- 282,
- 894,
- 895,
- 896,
- 897,
- 93,
- 94,
- 898,
- 899
+ 79,
+ 80,
+ 286,
+ 287,
+ 290,
+ 291,
+ 903,
+ 904,
+ 905,
+ 906,
+ 102,
+ 103,
+ 907,
+ 908
],
"irBases": [
"IAvnAvaloniaObject",
@@ -39172,15 +39498,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -39197,7 +39514,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -39207,6 +39523,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -39253,15 +39570,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -39281,34 +39598,43 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 357,
+ 208,
358,
- 314,
- 315,
+ 359,
+ 246,
+ 247,
+ 215,
216,
- 217,
- 900,
- 901,
- 902,
- 903,
- 569,
- 570,
- 904,
- 905,
- 906,
- 261
+ 360,
+ 361,
+ 362,
+ 363,
+ 364,
+ 365,
+ 366,
+ 367,
+ 323,
+ 324,
+ 225,
+ 226,
+ 909,
+ 910,
+ 911,
+ 912,
+ 578,
+ 579,
+ 913,
+ 914,
+ 915,
+ 270
],
"irBases": [
"IAvnAvaloniaObject",
@@ -39408,15 +39734,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -39433,7 +39750,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -39443,6 +39759,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -39489,15 +39806,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -39517,31 +39834,40 @@
197,
198,
199,
- 349,
- 350,
- 237,
- 238,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
206,
207,
- 351,
- 352,
- 353,
- 354,
- 355,
- 356,
- 485,
- 486,
- 487,
- 488,
- 491,
- 492,
- 388,
- 389,
- 907,
- 908,
- 498,
- 909,
- 494
+ 208,
+ 358,
+ 359,
+ 246,
+ 247,
+ 215,
+ 216,
+ 360,
+ 361,
+ 362,
+ 363,
+ 364,
+ 365,
+ 494,
+ 495,
+ 496,
+ 497,
+ 500,
+ 501,
+ 397,
+ 398,
+ 916,
+ 917,
+ 507,
+ 918,
+ 503
],
"irBases": [
"IAvnAvaloniaObject",
@@ -39689,15 +40015,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -39714,7 +40031,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -39724,6 +40040,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -39770,19 +40087,28 @@
147,
148,
149,
- 348,
- 172,
- 173,
- 910,
- 911,
- 912,
- 913,
- 914,
- 915,
- 513,
- 514,
- 511,
- 512
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 357,
+ 181,
+ 182,
+ 919,
+ 920,
+ 921,
+ 922,
+ 923,
+ 924,
+ 522,
+ 523,
+ 520,
+ 521
],
"irBases": [
"IAvnAvaloniaObject",
@@ -39853,15 +40179,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -39878,7 +40195,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -39888,6 +40204,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -39934,15 +40251,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -39962,14 +40279,23 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283
],
"irBases": [
"IAvnAvaloniaObject",
@@ -40052,12 +40378,12 @@
0,
1,
2,
- 55,
64,
- 65,
- 66,
- 59,
- 60
+ 73,
+ 74,
+ 75,
+ 68,
+ 69
]
},
{
@@ -40069,15 +40395,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -40094,7 +40411,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -40104,6 +40420,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -40150,12 +40467,21 @@
147,
148,
149,
+ 150,
+ 151,
152,
153,
- 560,
- 561,
- 262,
- 263
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 161,
+ 162,
+ 569,
+ 570,
+ 271,
+ 272
],
"irBases": [
"IAvnAvaloniaObject",
@@ -40221,15 +40547,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -40246,7 +40563,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -40256,6 +40572,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -40302,15 +40619,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -40330,23 +40647,23 @@
197,
198,
199,
- 267,
- 268,
- 269,
- 270,
- 271,
- 272,
- 273,
- 274,
- 916,
- 917,
- 918,
- 919,
- 920,
- 921,
- 922,
- 923,
- 924,
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 276,
+ 277,
+ 278,
+ 279,
+ 280,
+ 281,
+ 282,
+ 283,
925,
926,
927,
@@ -40365,20 +40682,29 @@
940,
941,
942,
- 894,
- 895,
943,
944,
945,
946,
947,
- 435,
948,
- 517,
949,
950,
951,
- 419
+ 903,
+ 904,
+ 952,
+ 953,
+ 954,
+ 955,
+ 956,
+ 444,
+ 957,
+ 526,
+ 958,
+ 959,
+ 960,
+ 428
],
"irBases": [
"IAvnAvaloniaObject",
@@ -40498,15 +40824,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -40523,7 +40840,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -40533,6 +40849,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -40579,15 +40896,15 @@
147,
148,
149,
- 172,
- 173,
- 174,
- 175,
- 176,
- 177,
- 178,
- 179,
- 180,
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
181,
182,
183,
@@ -40607,15 +40924,24 @@
197,
198,
199,
- 952,
- 953,
- 954,
- 955,
- 956,
- 957,
- 958,
- 959,
- 960
+ 200,
+ 201,
+ 202,
+ 203,
+ 204,
+ 205,
+ 206,
+ 207,
+ 208,
+ 961,
+ 962,
+ 963,
+ 964,
+ 965,
+ 966,
+ 967,
+ 968,
+ 969
],
"irBases": [
"IAvnAvaloniaObject",
@@ -40700,15 +41026,6 @@
0,
1,
2,
- 70,
- 71,
- 72,
- 73,
- 74,
- 75,
- 76,
- 77,
- 78,
79,
80,
81,
@@ -40725,7 +41042,6 @@
92,
93,
94,
- 35,
95,
96,
97,
@@ -40735,6 +41051,7 @@
101,
102,
103,
+ 35,
104,
105,
106,
@@ -40781,21 +41098,30 @@
147,
148,
149,
- 348,
- 172,
- 173,
- 961,
- 962,
- 800,
- 801,
- 697,
- 698,
- 963,
- 964,
- 965,
- 966,
- 967,
- 968
+ 150,
+ 151,
+ 152,
+ 153,
+ 154,
+ 155,
+ 156,
+ 157,
+ 158,
+ 357,
+ 181,
+ 182,
+ 970,
+ 971,
+ 809,
+ 810,
+ 706,
+ 707,
+ 972,
+ 973,
+ 974,
+ 975,
+ 976,
+ 977
],
"irBases": [
"IAvnAvaloniaObject",
diff --git a/rust/avalonia-bindgen/src/emit.rs b/rust/avalonia-bindgen/src/emit.rs
index 9208e71..27a2e7f 100644
--- a/rust/avalonia-bindgen/src/emit.rs
+++ b/rust/avalonia-bindgen/src/emit.rs
@@ -134,6 +134,10 @@ pub(crate) fn emit_sys_module(ir: &ProjectionIr) -> String {
out.push_str(&emit_brush(ir));
out.push('\n');
}
+ if ir.gradient_brush_interface_name.is_some() {
+ out.push_str(&emit_gradient_brush(ir));
+ out.push('\n');
+ }
if ir.command_interface_name.is_some() {
out.push_str(&emit_command(ir));
out.push('\n');
@@ -414,6 +418,211 @@ fn emit_brush(ir: &ProjectionIr) -> String {
)
}
+fn emit_gradient_brush(ir: &ProjectionIr) -> String {
+ let gradient_name = simple_name(
+ ir.gradient_brush_interface_name
+ .as_deref()
+ .expect("gradientBrushInterfaceName"),
+ );
+ let gradient_iid = ir
+ .gradient_brush_interface_iid
+ .as_deref()
+ .expect("gradientBrushInterfaceIid for a projected gradient brush");
+ let linear_name = simple_name(
+ ir.linear_gradient_brush_interface_name
+ .as_deref()
+ .expect("linearGradientBrushInterfaceName"),
+ );
+ let linear_iid = ir
+ .linear_gradient_brush_interface_iid
+ .as_deref()
+ .expect("linearGradientBrushInterfaceIid");
+ let radial_name = simple_name(
+ ir.radial_gradient_brush_interface_name
+ .as_deref()
+ .expect("radialGradientBrushInterfaceName"),
+ );
+ let radial_iid = ir
+ .radial_gradient_brush_interface_iid
+ .as_deref()
+ .expect("radialGradientBrushInterfaceIid");
+ let color = geometry::find("Color")
+ .expect("Color geometry struct")
+ .abi_name;
+
+ let mut out = String::from(
+ "/// Blittable ABI mirror of Avalonia.RelativePoint. unit: 0 relative, 1 absolute.\n\
+ #[repr(C)]\n\
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]\n\
+ pub struct AvnRelativePoint {\n\
+ \x20 pub x: f64,\n\
+ \x20 pub y: f64,\n\
+ \x20 pub unit: i32,\n\
+ }\n\n\
+ /// Blittable ABI mirror of Avalonia.RelativeScalar. unit: 0 relative, 1 absolute.\n\
+ #[repr(C)]\n\
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]\n\
+ pub struct AvnRelativeScalar {\n\
+ \x20 pub scalar: f64,\n\
+ \x20 pub unit: i32,\n\
+ }\n\n",
+ );
+ out.push_str(&format!(
+ "/// Blittable ABI mirror of a single gradient stop (offset plus packed colour).\n\
+ #[repr(C)]\n\
+ #[derive(Clone, Copy, Debug, Default, PartialEq)]\n\
+ pub struct AvnGradientStop {{\n\
+ \x20 pub offset: f64,\n\
+ \x20 pub color: {color},\n\
+ }}\n\n\
+ /// Fixed-capacity buffer of up to {max_stops} `AvnGradientStop` entries.\n\
+ #[repr(C)]\n\
+ #[derive(Clone, Copy, Debug)]\n\
+ pub struct AvnGradientStopBuffer {{\n\
+ \x20 pub stops: [AvnGradientStop; {max_stops}],\n\
+ }}\n\n\
+ impl Default for AvnGradientStopBuffer {{\n\
+ \x20 fn default() -> Self {{\n\
+ \x20 Self {{ stops: [AvnGradientStop::default(); {max_stops}] }}\n\
+ \x20 }}\n\
+ }}\n\n",
+ max_stops = GRADIENT_MAX_STOPS
+ ));
+
+ out.push_str(&format!(
+ "/// Capability shared by every gradient brush kind projected across the ABI.\n\
+ pub const {gradient_shouty}_IID: Guid = {gradient_iid_literal};\n\n\
+ #[repr(C)]\n\
+ struct {gradient_name}Vtbl {{\n\
+ \x20 query_interface: unsafe extern \"system\" fn(*mut IUnknown, *const Guid, *mut *mut c_void) -> i32,\n\
+ \x20 add_ref: unsafe extern \"system\" fn(*mut IUnknown) -> u32,\n\
+ \x20 release: unsafe extern \"system\" fn(*mut IUnknown) -> u32,\n\
+ \x20 get_opacity: unsafe extern \"system\" fn(*mut {gradient_name}, *mut f64) -> i32,\n\
+ \x20 get_spread_method: unsafe extern \"system\" fn(*mut {gradient_name}, *mut i32) -> i32,\n\
+ \x20 get_stop_count: unsafe extern \"system\" fn(*mut {gradient_name}, *mut i32) -> i32,\n\
+ \x20 get_stops: unsafe extern \"system\" fn(*mut {gradient_name}, *mut AvnGradientStopBuffer) -> i32,\n\
+ }}\n\n\
+ #[repr(C)]\n\
+ pub struct {gradient_name} {{\n\
+ \x20 vtbl: *const {gradient_name}Vtbl,\n\
+ }}\n\n\
+ unsafe impl ComInterface for {gradient_name} {{\n\
+ \x20 const IID: Guid = {gradient_shouty}_IID;\n\
+ }}\n\n\
+ impl ComPtr<{gradient_name}> {{\n\
+ {gradient_getters}\
+ }}\n\n",
+ gradient_shouty = to_shouty(gradient_name),
+ gradient_iid_literal = guid_literal(gradient_iid),
+ gradient_getters = emit_gradient_getters(gradient_name),
+ ));
+
+ out.push_str(&emit_gradient_shape(
+ linear_name,
+ linear_iid,
+ &[
+ ("get_start_point", "start_point", "AvnRelativePoint"),
+ ("get_end_point", "end_point", "AvnRelativePoint"),
+ ],
+ ));
+ out.push_str(&emit_gradient_shape(
+ radial_name,
+ radial_iid,
+ &[
+ ("get_center", "center", "AvnRelativePoint"),
+ ("get_gradient_origin", "gradient_origin", "AvnRelativePoint"),
+ ("get_radius_x", "radius_x", "AvnRelativeScalar"),
+ ("get_radius_y", "radius_y", "AvnRelativeScalar"),
+ ],
+ ));
+ out
+}
+
+/// The fixed capacity of `AvnGradientStopBuffer`; must match `GradientBrushMarshalling.MaxStops`
+/// on the C# projection side.
+const GRADIENT_MAX_STOPS: usize = 8;
+
+fn emit_gradient_getters(gradient_name: &str) -> String {
+ format!(
+ "\x20 pub fn opacity(&self) -> Result {{\n\
+ \x20 unsafe {{\n\
+ \x20 let mut value = 0.0;\n\
+ \x20 let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_opacity)(self.as_raw(), &mut value);\n\
+ \x20 hresult::check(hr).map(|_| value)\n\
+ \x20 }}\n\
+ \x20 }}\n\
+ \x20 /// 0 = Pad, 1 = Reflect, 2 = Repeat.\n\
+ \x20 pub fn spread_method(&self) -> Result {{\n\
+ \x20 unsafe {{\n\
+ \x20 let mut value = 0;\n\
+ \x20 let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_spread_method)(self.as_raw(), &mut value);\n\
+ \x20 hresult::check(hr).map(|_| value)\n\
+ \x20 }}\n\
+ \x20 }}\n\
+ \x20 pub fn stop_count(&self) -> Result {{\n\
+ \x20 unsafe {{\n\
+ \x20 let mut value = 0;\n\
+ \x20 let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_stop_count)(self.as_raw(), &mut value);\n\
+ \x20 hresult::check(hr).map(|_| value)\n\
+ \x20 }}\n\
+ \x20 }}\n\
+ \x20 pub fn stops(&self) -> Result {{\n\
+ \x20 unsafe {{\n\
+ \x20 let mut value = AvnGradientStopBuffer::default();\n\
+ \x20 let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_stops)(self.as_raw(), &mut value);\n\
+ \x20 hresult::check(hr).map(|_| value)\n\
+ \x20 }}\n\
+ \x20 }}\n",
+ )
+ .replace("{gradient_name}", gradient_name)
+}
+
+/// Emits one derived gradient-kind interface (linear or radial). The vtable flattens the
+/// four base `IAvnGradientBrush` slots ahead of the kind-specific slots, mirroring the
+/// single-inheritance layout produced for the native header and the generated C# interface.
+fn emit_gradient_shape(name: &str, iid: &str, accessors: &[(&str, &str, &str)]) -> String {
+ let mut vtbl = format!(
+ "#[repr(C)]\nstruct {name}Vtbl {{\n\
+ \x20 query_interface: unsafe extern \"system\" fn(*mut IUnknown, *const Guid, *mut *mut c_void) -> i32,\n\
+ \x20 add_ref: unsafe extern \"system\" fn(*mut IUnknown) -> u32,\n\
+ \x20 release: unsafe extern \"system\" fn(*mut IUnknown) -> u32,\n\
+ \x20 get_opacity: unsafe extern \"system\" fn(*mut {name}, *mut f64) -> i32,\n\
+ \x20 get_spread_method: unsafe extern \"system\" fn(*mut {name}, *mut i32) -> i32,\n\
+ \x20 get_stop_count: unsafe extern \"system\" fn(*mut {name}, *mut i32) -> i32,\n\
+ \x20 get_stops: unsafe extern \"system\" fn(*mut {name}, *mut AvnGradientStopBuffer) -> i32,\n"
+ );
+ for (accessor, _field_name, field_type) in accessors {
+ vtbl.push_str(&format!(
+ " {accessor}: unsafe extern \"system\" fn(*mut {name}, *mut {field_type}) -> i32,\n"
+ ));
+ }
+ vtbl.push_str("}\n\n");
+
+ let mut out = format!(
+ "{vtbl}#[repr(C)]\npub struct {name} {{\n\x20 vtbl: *const {name}Vtbl,\n}}\n\n\
+ unsafe impl ComInterface for {name} {{\n\x20 const IID: Guid = {shouty}_IID;\n}}\n\n\
+ pub const {shouty}_IID: Guid = {iid_literal};\n\n\
+ impl ComPtr<{name}> {{\n\
+ {getters}",
+ shouty = to_shouty(name),
+ iid_literal = guid_literal(iid),
+ getters = emit_gradient_getters(name),
+ );
+ for (accessor, field_name, field_type) in accessors {
+ out.push_str(&format!(
+ " pub fn {field_name}(&self) -> Result<{field_type}> {{\n\
+ \x20 unsafe {{\n\
+ \x20 let mut value = {field_type}::default();\n\
+ \x20 let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().{accessor})(self.as_raw(), &mut value);\n\
+ \x20 hresult::check(hr).map(|_| value)\n\
+ \x20 }}\n\
+ \x20 }}\n"
+ ));
+ }
+ out.push_str("}\n\n");
+ out
+}
+
fn emit_command(ir: &ProjectionIr) -> String {
let name = simple_name(
ir.command_interface_name
@@ -1472,6 +1681,18 @@ fn emit_factory(ir: &ProjectionIr) -> String {
" create_solid_color_brush: unsafe extern \"system\" fn(*mut IAvnControlFactory, {color}, f64, *mut *mut {brush}) -> i32,\n"
));
}
+ if let Some(linear) = ir.linear_gradient_brush_interface_name.as_deref() {
+ let linear = simple_name(linear);
+ let radial = simple_name(
+ ir.radial_gradient_brush_interface_name
+ .as_deref()
+ .expect("radialGradientBrushInterfaceName"),
+ );
+ out.push_str(&format!(
+ " create_linear_gradient_brush: unsafe extern \"system\" fn(*mut IAvnControlFactory, f64, i32, i32, AvnGradientStopBuffer, AvnRelativePoint, AvnRelativePoint, *mut *mut {linear}) -> i32,\n\
+ \x20 create_radial_gradient_brush: unsafe extern \"system\" fn(*mut IAvnControlFactory, f64, i32, i32, AvnGradientStopBuffer, AvnRelativePoint, AvnRelativePoint, AvnRelativeScalar, AvnRelativeScalar, *mut *mut {radial}) -> i32,\n"
+ ));
+ }
out.push_str("}\n\n#[repr(C)]\npub struct IAvnControlFactory {\n vtbl: *const IAvnControlFactoryVtbl,\n}\n\n");
out.push_str("unsafe impl ComInterface for IAvnControlFactory {\n const IID: Guid = IAVN_CONTROL_FACTORY_IID;\n}\n\n");
out.push_str("impl ComPtr {\n");
@@ -1522,6 +1743,56 @@ fn emit_factory(ir: &ProjectionIr) -> String {
\x20 }}\n"
));
}
+ if let Some(linear) = ir.linear_gradient_brush_interface_name.as_deref() {
+ let linear = simple_name(linear);
+ let radial = simple_name(
+ ir.radial_gradient_brush_interface_name
+ .as_deref()
+ .expect("radialGradientBrushInterfaceName"),
+ );
+ out.push_str(&format!(
+ " #[allow(clippy::too_many_arguments)]\n\
+ \x20 pub fn create_linear_gradient_brush(\n\
+ \x20 &self,\n\
+ \x20 opacity: f64,\n\
+ \x20 spread_method: i32,\n\
+ \x20 stop_count: i32,\n\
+ \x20 stops: AvnGradientStopBuffer,\n\
+ \x20 start_point: AvnRelativePoint,\n\
+ \x20 end_point: AvnRelativePoint,\n\
+ \x20 ) -> Result> {{\n\
+ \x20 unsafe {{\n\
+ \x20 let mut value = ptr::null_mut();\n\
+ \x20 let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().create_linear_gradient_brush)(\n\
+ \x20 self.as_raw(), opacity, spread_method, stop_count, stops, start_point, end_point, &mut value,\n\
+ \x20 );\n\
+ \x20 hresult::check(hr)?;\n\
+ \x20 ComPtr::from_raw(value).ok_or(Error(hresult::E_POINTER))\n\
+ \x20 }}\n\
+ \x20 }}\n\
+ \x20 #[allow(clippy::too_many_arguments)]\n\
+ \x20 pub fn create_radial_gradient_brush(\n\
+ \x20 &self,\n\
+ \x20 opacity: f64,\n\
+ \x20 spread_method: i32,\n\
+ \x20 stop_count: i32,\n\
+ \x20 stops: AvnGradientStopBuffer,\n\
+ \x20 center: AvnRelativePoint,\n\
+ \x20 gradient_origin: AvnRelativePoint,\n\
+ \x20 radius_x: AvnRelativeScalar,\n\
+ \x20 radius_y: AvnRelativeScalar,\n\
+ \x20 ) -> Result> {{\n\
+ \x20 unsafe {{\n\
+ \x20 let mut value = ptr::null_mut();\n\
+ \x20 let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().create_radial_gradient_brush)(\n\
+ \x20 self.as_raw(), opacity, spread_method, stop_count, stops, center, gradient_origin, radius_x, radius_y, &mut value,\n\
+ \x20 );\n\
+ \x20 hresult::check(hr)?;\n\
+ \x20 ComPtr::from_raw(value).ok_or(Error(hresult::E_POINTER))\n\
+ \x20 }}\n\
+ \x20 }}\n"
+ ));
+ }
out.push_str("}\n");
out
}
diff --git a/rust/avalonia-bindgen/src/emit_safe.rs b/rust/avalonia-bindgen/src/emit_safe.rs
index 34eca30..9bcd1b0 100644
--- a/rust/avalonia-bindgen/src/emit_safe.rs
+++ b/rust/avalonia-bindgen/src/emit_safe.rs
@@ -57,6 +57,9 @@ pub(crate) fn emit_safe_module(ir: &ProjectionIr) -> String {
if ir.brush_interface_name.is_some() {
out.push_str(&emit_brush());
}
+ if ir.gradient_brush_interface_name.is_some() {
+ out.push_str(&emit_gradient_brush());
+ }
let flags_enums: std::collections::HashSet<&str> = ir
.enums
@@ -198,6 +201,276 @@ fn emit_brush() -> String {
)
}
+fn emit_gradient_brush() -> String {
+ String::from(
+ "/// Spread behaviour for a gradient outside its `[0, 1]` stop range.\n\
+ /// Mirrors `Avalonia.Media.GradientSpreadMethod`.\n\
+ #[repr(i32)]\n\
+ #[derive(Clone, Copy, Debug, PartialEq, Eq)]\n\
+ pub enum SpreadMethod {\n\
+ \x20 Pad = 0,\n\
+ \x20 Reflect = 1,\n\
+ \x20 Repeat = 2,\n\
+ }\n\n\
+ impl TryFrom for SpreadMethod {\n\
+ \x20 type Error = crate::Error;\n\
+ \x20 fn try_from(value: i32) -> Result {\n\
+ \x20 match value {\n\
+ \x20 0 => Ok(Self::Pad),\n\
+ \x20 1 => Ok(Self::Reflect),\n\
+ \x20 2 => Ok(Self::Repeat),\n\
+ \x20 _ => Err(crate::Error::InvalidEnumValue(value)),\n\
+ \x20 }\n\
+ \x20 }\n\
+ }\n\n\
+ /// Whether a gradient coordinate is relative to the shape's bounding box or an\n\
+ /// absolute value. Mirrors `Avalonia.RelativeUnit`.\n\
+ #[repr(i32)]\n\
+ #[derive(Clone, Copy, Debug, PartialEq, Eq)]\n\
+ pub enum RelativeUnit {\n\
+ \x20 Relative = 0,\n\
+ \x20 Absolute = 1,\n\
+ }\n\n\
+ impl TryFrom for RelativeUnit {\n\
+ \x20 type Error = crate::Error;\n\
+ \x20 fn try_from(value: i32) -> Result {\n\
+ \x20 match value {\n\
+ \x20 0 => Ok(Self::Relative),\n\
+ \x20 1 => Ok(Self::Absolute),\n\
+ \x20 _ => Err(crate::Error::InvalidEnumValue(value)),\n\
+ \x20 }\n\
+ \x20 }\n\
+ }\n\n\
+ /// A point whose X/Y may each be relative to the shape's bounding box.\n\
+ #[derive(Clone, Copy, Debug, PartialEq)]\n\
+ pub struct RelativePoint {\n\
+ \x20 pub x: f64,\n\
+ \x20 pub y: f64,\n\
+ \x20 pub unit: RelativeUnit,\n\
+ }\n\n\
+ impl RelativePoint {\n\
+ \x20 pub const fn new(x: f64, y: f64, unit: RelativeUnit) -> Self {\n\
+ \x20 Self { x, y, unit }\n\
+ \x20 }\n\n\
+ \x20 pub(crate) fn to_abi(self) -> sys::AvnRelativePoint {\n\
+ \x20 sys::AvnRelativePoint { x: self.x, y: self.y, unit: self.unit as i32 }\n\
+ \x20 }\n\n\
+ \x20 pub(crate) fn from_abi(value: sys::AvnRelativePoint) -> Result {\n\
+ \x20 Ok(Self { x: value.x, y: value.y, unit: RelativeUnit::try_from(value.unit)? })\n\
+ \x20 }\n\
+ }\n\n\
+ /// A scalar (for example a radius) that may be relative to the shape's bounding box.\n\
+ #[derive(Clone, Copy, Debug, PartialEq)]\n\
+ pub struct RelativeScalar {\n\
+ \x20 pub scalar: f64,\n\
+ \x20 pub unit: RelativeUnit,\n\
+ }\n\n\
+ impl RelativeScalar {\n\
+ \x20 pub const fn new(scalar: f64, unit: RelativeUnit) -> Self {\n\
+ \x20 Self { scalar, unit }\n\
+ \x20 }\n\n\
+ \x20 pub(crate) fn to_abi(self) -> sys::AvnRelativeScalar {\n\
+ \x20 sys::AvnRelativeScalar { scalar: self.scalar, unit: self.unit as i32 }\n\
+ \x20 }\n\n\
+ \x20 pub(crate) fn from_abi(value: sys::AvnRelativeScalar) -> Result {\n\
+ \x20 Ok(Self { scalar: value.scalar, unit: RelativeUnit::try_from(value.unit)? })\n\
+ \x20 }\n\
+ }\n\n\
+ /// A single colour stop along a gradient, at `offset` in `[0, 1]`.\n\
+ #[derive(Clone, Copy, Debug, PartialEq)]\n\
+ pub struct GradientStop {\n\
+ \x20 pub offset: f64,\n\
+ \x20 pub color: Color,\n\
+ }\n\n\
+ impl GradientStop {\n\
+ \x20 pub const fn new(offset: f64, color: Color) -> Self {\n\
+ \x20 Self { offset, color }\n\
+ \x20 }\n\n\
+ \x20 fn to_abi(self) -> sys::AvnGradientStop {\n\
+ \x20 sys::AvnGradientStop { offset: self.offset, color: self.color.into() }\n\
+ \x20 }\n\n\
+ \x20 fn from_abi(value: sys::AvnGradientStop) -> Self {\n\
+ \x20 Self { offset: value.offset, color: value.color.into() }\n\
+ \x20 }\n\
+ }\n\n\
+ /// Packs up to the ABI's fixed capacity of stops into an `AvnGradientStopBuffer`.\n\
+ /// Fails if `stops` carries more entries than the buffer can hold.\n\
+ fn gradient_stops_to_abi(stops: &[GradientStop]) -> Result {\n\
+ \x20 let mut buffer = sys::AvnGradientStopBuffer::default();\n\
+ \x20 if stops.len() > buffer.stops.len() {\n\
+ \x20 return Err(crate::Error::Abi(sys::Error(sys::E_INVALIDARG)));\n\
+ \x20 }\n\
+ \x20 for (slot, stop) in buffer.stops.iter_mut().zip(stops) {\n\
+ \x20 *slot = stop.to_abi();\n\
+ \x20 }\n\
+ \x20 Ok(buffer)\n\
+ }\n\n\
+ fn gradient_stops_from_abi(buffer: sys::AvnGradientStopBuffer, count: i32) -> Vec {\n\
+ \x20 let count = usize::try_from(count).unwrap_or(0).min(buffer.stops.len());\n\
+ \x20 buffer.stops[..count].iter().copied().map(GradientStop::from_abi).collect()\n\
+ }\n\n\
+ /// A linear gradient brush: colour stops interpolated along a line from\n\
+ /// `start_point` to `end_point`.\n\
+ #[derive(Clone, Debug, PartialEq)]\n\
+ pub struct LinearGradientBrush {\n\
+ \x20 pub opacity: f64,\n\
+ \x20 pub spread_method: SpreadMethod,\n\
+ \x20 pub stops: Vec,\n\
+ \x20 pub start_point: RelativePoint,\n\
+ \x20 pub end_point: RelativePoint,\n\
+ }\n\n\
+ impl LinearGradientBrush {\n\
+ \x20 /// A fully opaque linear gradient with `SpreadMethod::Pad`.\n\
+ \x20 pub fn new(stops: Vec, start_point: RelativePoint, end_point: RelativePoint) -> Self {\n\
+ \x20 Self {\n\
+ \x20 opacity: 1.0,\n\
+ \x20 spread_method: SpreadMethod::Pad,\n\
+ \x20 stops,\n\
+ \x20 start_point,\n\
+ \x20 end_point,\n\
+ \x20 }\n\
+ \x20 }\n\n\
+ \x20 pub(crate) fn to_raw(&self) -> Result> {\n\
+ \x20 let buffer = gradient_stops_to_abi(&self.stops)?;\n\
+ \x20 let stop_count = i32::try_from(self.stops.len()).unwrap_or(i32::MAX);\n\
+ \x20 with_factory(|factory| {\n\
+ \x20 factory.create_linear_gradient_brush(\n\
+ \x20 self.opacity,\n\
+ \x20 self.spread_method as i32,\n\
+ \x20 stop_count,\n\
+ \x20 buffer,\n\
+ \x20 self.start_point.to_abi(),\n\
+ \x20 self.end_point.to_abi(),\n\
+ \x20 )\n\
+ \x20 })\n\
+ \x20 }\n\n\
+ \x20 pub(crate) fn from_raw(raw: &sys::ComPtr) -> Result {\n\
+ \x20 let count = raw.stop_count()?;\n\
+ \x20 Ok(Self {\n\
+ \x20 opacity: raw.opacity()?,\n\
+ \x20 spread_method: SpreadMethod::try_from(raw.spread_method()?)?,\n\
+ \x20 stops: gradient_stops_from_abi(raw.stops()?, count),\n\
+ \x20 start_point: RelativePoint::from_abi(raw.start_point()?)?,\n\
+ \x20 end_point: RelativePoint::from_abi(raw.end_point()?)?,\n\
+ \x20 })\n\
+ \x20 }\n\
+ }\n\n\
+ /// A radial gradient brush: colour stops interpolated outward from\n\
+ /// `gradient_origin` through an ellipse centred at `center` with radii\n\
+ /// `radius_x`/`radius_y`.\n\
+ #[derive(Clone, Debug, PartialEq)]\n\
+ pub struct RadialGradientBrush {\n\
+ \x20 pub opacity: f64,\n\
+ \x20 pub spread_method: SpreadMethod,\n\
+ \x20 pub stops: Vec,\n\
+ \x20 pub center: RelativePoint,\n\
+ \x20 pub gradient_origin: RelativePoint,\n\
+ \x20 pub radius_x: RelativeScalar,\n\
+ \x20 pub radius_y: RelativeScalar,\n\
+ }\n\n\
+ impl RadialGradientBrush {\n\
+ \x20 /// A fully opaque radial gradient with `SpreadMethod::Pad`.\n\
+ \x20 pub fn new(\n\
+ \x20 stops: Vec,\n\
+ \x20 center: RelativePoint,\n\
+ \x20 gradient_origin: RelativePoint,\n\
+ \x20 radius_x: RelativeScalar,\n\
+ \x20 radius_y: RelativeScalar,\n\
+ \x20 ) -> Self {\n\
+ \x20 Self {\n\
+ \x20 opacity: 1.0,\n\
+ \x20 spread_method: SpreadMethod::Pad,\n\
+ \x20 stops,\n\
+ \x20 center,\n\
+ \x20 gradient_origin,\n\
+ \x20 radius_x,\n\
+ \x20 radius_y,\n\
+ \x20 }\n\
+ \x20 }\n\n\
+ \x20 pub(crate) fn to_raw(&self) -> Result> {\n\
+ \x20 let buffer = gradient_stops_to_abi(&self.stops)?;\n\
+ \x20 let stop_count = i32::try_from(self.stops.len()).unwrap_or(i32::MAX);\n\
+ \x20 with_factory(|factory| {\n\
+ \x20 factory.create_radial_gradient_brush(\n\
+ \x20 self.opacity,\n\
+ \x20 self.spread_method as i32,\n\
+ \x20 stop_count,\n\
+ \x20 buffer,\n\
+ \x20 self.center.to_abi(),\n\
+ \x20 self.gradient_origin.to_abi(),\n\
+ \x20 self.radius_x.to_abi(),\n\
+ \x20 self.radius_y.to_abi(),\n\
+ \x20 )\n\
+ \x20 })\n\
+ \x20 }\n\n\
+ \x20 pub(crate) fn from_raw(raw: &sys::ComPtr) -> Result {\n\
+ \x20 let count = raw.stop_count()?;\n\
+ \x20 Ok(Self {\n\
+ \x20 opacity: raw.opacity()?,\n\
+ \x20 spread_method: SpreadMethod::try_from(raw.spread_method()?)?,\n\
+ \x20 stops: gradient_stops_from_abi(raw.stops()?, count),\n\
+ \x20 center: RelativePoint::from_abi(raw.center()?)?,\n\
+ \x20 gradient_origin: RelativePoint::from_abi(raw.gradient_origin()?)?,\n\
+ \x20 radius_x: RelativeScalar::from_abi(raw.radius_x()?)?,\n\
+ \x20 radius_y: RelativeScalar::from_abi(raw.radius_y()?)?,\n\
+ \x20 })\n\
+ \x20 }\n\
+ }\n\n\
+ /// Any brush shape that can be assigned to a `Brush`-typed control property: a\n\
+ /// solid colour, or one of the two projected gradient shapes.\n\
+ #[derive(Clone, Debug, PartialEq)]\n\
+ pub enum Paint {\n\
+ \x20 Solid(Brush),\n\
+ \x20 LinearGradient(LinearGradientBrush),\n\
+ \x20 RadialGradient(RadialGradientBrush),\n\
+ }\n\n\
+ impl Paint {\n\
+ \x20 pub(crate) fn to_raw(&self) -> Result> {\n\
+ \x20 match self {\n\
+ \x20 Self::Solid(brush) => brush.to_raw(),\n\
+ \x20 Self::LinearGradient(brush) => Ok(brush.to_raw()?.query_interface()?),\n\
+ \x20 Self::RadialGradient(brush) => Ok(brush.to_raw()?.query_interface()?),\n\
+ \x20 }\n\
+ \x20 }\n\n\
+ \x20 pub(crate) fn from_raw(raw: &sys::ComPtr) -> Result {\n\
+ \x20 match raw.color() {\n\
+ \x20 Ok(color) => Ok(Self::Solid(Brush::new(color.into(), raw.opacity()?))),\n\
+ \x20 Err(sys::Error(sys::AVN_E_NONSOLIDBRUSH)) => {\n\
+ \x20 if let Ok(linear) = raw.query_interface::() {\n\
+ \x20 return Ok(Self::LinearGradient(LinearGradientBrush::from_raw(&linear)?));\n\
+ \x20 }\n\
+ \x20 if let Ok(radial) = raw.query_interface::() {\n\
+ \x20 return Ok(Self::RadialGradient(RadialGradientBrush::from_raw(&radial)?));\n\
+ \x20 }\n\
+ \x20 Err(crate::Error::Abi(sys::Error(sys::AVN_E_NONSOLIDBRUSH)))\n\
+ \x20 }\n\
+ \x20 Err(error) => Err(error.into()),\n\
+ \x20 }\n\
+ \x20 }\n\
+ }\n\n\
+ impl From for Paint {\n\
+ \x20 fn from(brush: Brush) -> Self {\n\
+ \x20 Self::Solid(brush)\n\
+ \x20 }\n\
+ }\n\n\
+ impl From for Paint {\n\
+ \x20 fn from(color: Color) -> Self {\n\
+ \x20 Self::Solid(Brush::solid(color))\n\
+ \x20 }\n\
+ }\n\n\
+ impl From for Paint {\n\
+ \x20 fn from(brush: LinearGradientBrush) -> Self {\n\
+ \x20 Self::LinearGradient(brush)\n\
+ \x20 }\n\
+ }\n\n\
+ impl From for Paint {\n\
+ \x20 fn from(brush: RadialGradientBrush) -> Self {\n\
+ \x20 Self::RadialGradient(brush)\n\
+ \x20 }\n\
+ }\n\n",
+ )
+}
+
fn emit_collection(property: &ProjectedProperty) -> String {
let name = simple_name(property.interface_name.as_deref().expect("interfaceName"));
let safe_name = name.strip_prefix("IAvn").unwrap_or(name);
diff --git a/rust/avalonia-bindgen/src/ir.rs b/rust/avalonia-bindgen/src/ir.rs
index e055239..f3e6f2f 100644
--- a/rust/avalonia-bindgen/src/ir.rs
+++ b/rust/avalonia-bindgen/src/ir.rs
@@ -8,6 +8,18 @@ pub struct ProjectionIr {
pub factory_iid: Option,
pub brush_interface_name: Option,
pub brush_interface_iid: Option,
+ #[serde(default)]
+ pub gradient_brush_interface_name: Option,
+ #[serde(default)]
+ pub gradient_brush_interface_iid: Option,
+ #[serde(default)]
+ pub linear_gradient_brush_interface_name: Option,
+ #[serde(default)]
+ pub linear_gradient_brush_interface_iid: Option,
+ #[serde(default)]
+ pub radial_gradient_brush_interface_name: Option,
+ #[serde(default)]
+ pub radial_gradient_brush_interface_iid: Option,
pub command_interface_name: Option,
pub command_interface_iid: Option,
#[serde(default)]
diff --git a/rust/avalonia-bindgen/src/lib.rs b/rust/avalonia-bindgen/src/lib.rs
index 117679d..415359c 100644
--- a/rust/avalonia-bindgen/src/lib.rs
+++ b/rust/avalonia-bindgen/src/lib.rs
@@ -259,11 +259,11 @@ mod tests {
#[test]
fn future_schema_version_is_rejected_by_public_entrypoint() {
- let error = generate_from_json(r#"{ "version": 17, "types": [] }"#)
+ let error = generate_from_json(r#"{ "version": 18, "types": [] }"#)
.unwrap_err()
.to_string();
- assert!(error.contains("Unsupported projection IR version 17"));
- assert!(error.contains("1..=16"));
+ assert!(error.contains("Unsupported projection IR version 18"));
+ assert!(error.contains("1..=17"));
}
#[test]
@@ -436,9 +436,9 @@ mod tests {
#[test]
fn generate_from_ir_rejects_future_version() {
- let ir: ProjectionIr = serde_json::from_str(r#"{ "version": 17, "types": [] }"#).unwrap();
+ let ir: ProjectionIr = serde_json::from_str(r#"{ "version": 18, "types": [] }"#).unwrap();
let error = generate_from_ir(&ir).unwrap_err().to_string();
- assert!(error.contains("Unsupported projection IR version 17"));
+ assert!(error.contains("Unsupported projection IR version 18"));
}
#[test]
diff --git a/rust/avalonia-bindgen/src/validate.rs b/rust/avalonia-bindgen/src/validate.rs
index 1e587e2..4c561b7 100644
--- a/rust/avalonia-bindgen/src/validate.rs
+++ b/rust/avalonia-bindgen/src/validate.rs
@@ -5,7 +5,7 @@ use crate::ir::{
};
pub const MINIMUM_VERSION: i32 = 1;
-pub const CURRENT_VERSION: i32 = 16;
+pub const CURRENT_VERSION: i32 = 17;
const SUPPORTED_MARSHALLING_KINDS: &[&str] = &[
"Void",
diff --git a/rust/avalonia-sys/include/.avalonia-projection.owned.json b/rust/avalonia-sys/include/.avalonia-projection.owned.json
index 4e05010..44aff59 100644
--- a/rust/avalonia-sys/include/.avalonia-projection.owned.json
+++ b/rust/avalonia-sys/include/.avalonia-projection.owned.json
@@ -3,7 +3,7 @@
"files": [
{
"path": "avalonia-rust-abi.h",
- "sha256": "267a44997b95dde7426d3212bf5316652f7ba923a94a8c9150749f5b2ae33175"
+ "sha256": "d9046a8786e5917a3c205a4b773fe0e73252ca79f2e52020d6a9188ba5b105d2"
}
]
}
diff --git a/rust/avalonia-sys/include/avalonia-rust-abi.h b/rust/avalonia-sys/include/avalonia-rust-abi.h
index c36bf62..69cccf6 100644
--- a/rust/avalonia-sys/include/avalonia-rust-abi.h
+++ b/rust/avalonia-sys/include/avalonia-rust-abi.h
@@ -125,6 +125,30 @@ typedef struct AvnOptionalTimeSpan {
int64_t ticks;
} AvnOptionalTimeSpan;
+/* Blittable ABI mirror of Avalonia.RelativePoint. unit: 0 relative, 1 absolute. */
+typedef struct AvnRelativePoint {
+ double x;
+ double y;
+ int32_t unit;
+} AvnRelativePoint;
+
+/* Blittable ABI mirror of Avalonia.RelativeScalar. unit: 0 relative, 1 absolute. */
+typedef struct AvnRelativeScalar {
+ double scalar;
+ int32_t unit;
+} AvnRelativeScalar;
+
+/* Blittable ABI mirror of a single gradient stop (offset plus packed colour). */
+typedef struct AvnGradientStop {
+ double offset;
+ AvnColor color;
+} AvnGradientStop;
+
+/* Fixed-capacity buffer of up to 8 AvnGradientStop entries. */
+typedef struct AvnGradientStopBuffer {
+ AvnGradientStop stops[8];
+} AvnGradientStopBuffer;
+
/* Tagged scalar carrying object? command parameters. */
/* tag: 0 none, 1 utf16, 2 i32, 3 f64, 4 bool. */
typedef struct AvnVariant {
@@ -302,6 +326,8 @@ typedef struct IAvnFlyoutBaseClosedHandler IAvnFlyoutBaseClosedHandler;
typedef struct IAvnFlyoutBaseClosedHandlerVtbl IAvnFlyoutBaseClosedHandlerVtbl;
typedef struct IAvnFlyoutBaseOpenedHandler IAvnFlyoutBaseOpenedHandler;
typedef struct IAvnFlyoutBaseOpenedHandlerVtbl IAvnFlyoutBaseOpenedHandlerVtbl;
+typedef struct IAvnGradientBrush IAvnGradientBrush;
+typedef struct IAvnGradientBrushVtbl IAvnGradientBrushVtbl;
typedef struct IAvnGrid IAvnGrid;
typedef struct IAvnGridVtbl IAvnGridVtbl;
typedef struct IAvnGridSplitter IAvnGridSplitter;
@@ -332,6 +358,8 @@ typedef struct IAvnLayoutTransformControl IAvnLayoutTransformControl;
typedef struct IAvnLayoutTransformControlVtbl IAvnLayoutTransformControlVtbl;
typedef struct IAvnLine IAvnLine;
typedef struct IAvnLineVtbl IAvnLineVtbl;
+typedef struct IAvnLinearGradientBrush IAvnLinearGradientBrush;
+typedef struct IAvnLinearGradientBrushVtbl IAvnLinearGradientBrushVtbl;
typedef struct IAvnListBox IAvnListBox;
typedef struct IAvnListBoxVtbl IAvnListBoxVtbl;
typedef struct IAvnListBoxItem IAvnListBoxItem;
@@ -392,6 +420,8 @@ typedef struct IAvnPopupOpenedHandler IAvnPopupOpenedHandler;
typedef struct IAvnPopupOpenedHandlerVtbl IAvnPopupOpenedHandlerVtbl;
typedef struct IAvnProgressBar IAvnProgressBar;
typedef struct IAvnProgressBarVtbl IAvnProgressBarVtbl;
+typedef struct IAvnRadialGradientBrush IAvnRadialGradientBrush;
+typedef struct IAvnRadialGradientBrushVtbl IAvnRadialGradientBrushVtbl;
typedef struct IAvnRadioButton IAvnRadioButton;
typedef struct IAvnRadioButtonVtbl IAvnRadioButtonVtbl;
typedef struct IAvnRangeBase IAvnRangeBase;
@@ -2116,6 +2146,69 @@ struct IAvnBrushVtbl {
struct IAvnBrush { const IAvnBrushVtbl* vtbl; };
#define I_AVN_BRUSH_VTABLE_SLOTS 5
+static const AvnGuid I_AVN_GRADIENT_BRUSH_IID = {
+ 0xFDAA2353,
+ 0xBC44,
+ 0x5012,
+ { 0xA5, 0xBE, 0xA1, 0x7C, 0x7C, 0x01, 0xF4, 0x1A }
+};
+#define I_AVN_GRADIENT_BRUSH_ABI_VERSION 1
+struct IAvnGradientBrushVtbl {
+ AvnHResult (AVN_CALL *query_interface)(IAvnGradientBrush* self, const AvnGuid* iid, void** result); /* slot 0 */
+ uint32_t (AVN_CALL *add_ref)(IAvnGradientBrush* self); /* slot 1 */
+ uint32_t (AVN_CALL *release)(IAvnGradientBrush* self); /* slot 2 */
+ AvnHResult (AVN_CALL *get_opacity)(IAvnGradientBrush* self, double* value); /* slot 3 */
+ AvnHResult (AVN_CALL *get_spread_method)(IAvnGradientBrush* self, int32_t* value); /* slot 4 */
+ AvnHResult (AVN_CALL *get_stop_count)(IAvnGradientBrush* self, int32_t* value); /* slot 5 */
+ AvnHResult (AVN_CALL *get_stops)(IAvnGradientBrush* self, AvnGradientStopBuffer* value); /* slot 6 */
+};
+struct IAvnGradientBrush { const IAvnGradientBrushVtbl* vtbl; };
+#define I_AVN_GRADIENT_BRUSH_VTABLE_SLOTS 7
+
+static const AvnGuid I_AVN_LINEAR_GRADIENT_BRUSH_IID = {
+ 0x40B3D53D,
+ 0x330E,
+ 0x5D63,
+ { 0xA0, 0x40, 0x37, 0xF1, 0xFF, 0x71, 0x7F, 0xF8 }
+};
+#define I_AVN_LINEAR_GRADIENT_BRUSH_ABI_VERSION 1
+struct IAvnLinearGradientBrushVtbl {
+ AvnHResult (AVN_CALL *query_interface)(IAvnLinearGradientBrush* self, const AvnGuid* iid, void** result); /* slot 0 */
+ uint32_t (AVN_CALL *add_ref)(IAvnLinearGradientBrush* self); /* slot 1 */
+ uint32_t (AVN_CALL *release)(IAvnLinearGradientBrush* self); /* slot 2 */
+ AvnHResult (AVN_CALL *get_opacity)(IAvnLinearGradientBrush* self, double* value); /* slot 3 */
+ AvnHResult (AVN_CALL *get_spread_method)(IAvnLinearGradientBrush* self, int32_t* value); /* slot 4 */
+ AvnHResult (AVN_CALL *get_stop_count)(IAvnLinearGradientBrush* self, int32_t* value); /* slot 5 */
+ AvnHResult (AVN_CALL *get_stops)(IAvnLinearGradientBrush* self, AvnGradientStopBuffer* value); /* slot 6 */
+ AvnHResult (AVN_CALL *get_start_point)(IAvnLinearGradientBrush* self, AvnRelativePoint* value); /* slot 7 */
+ AvnHResult (AVN_CALL *get_end_point)(IAvnLinearGradientBrush* self, AvnRelativePoint* value); /* slot 8 */
+};
+struct IAvnLinearGradientBrush { const IAvnLinearGradientBrushVtbl* vtbl; };
+#define I_AVN_LINEAR_GRADIENT_BRUSH_VTABLE_SLOTS 9
+
+static const AvnGuid I_AVN_RADIAL_GRADIENT_BRUSH_IID = {
+ 0xAEC23FCE,
+ 0x9FEA,
+ 0x506C,
+ { 0xAB, 0xC4, 0x77, 0x41, 0x43, 0xBE, 0x80, 0xC8 }
+};
+#define I_AVN_RADIAL_GRADIENT_BRUSH_ABI_VERSION 1
+struct IAvnRadialGradientBrushVtbl {
+ AvnHResult (AVN_CALL *query_interface)(IAvnRadialGradientBrush* self, const AvnGuid* iid, void** result); /* slot 0 */
+ uint32_t (AVN_CALL *add_ref)(IAvnRadialGradientBrush* self); /* slot 1 */
+ uint32_t (AVN_CALL *release)(IAvnRadialGradientBrush* self); /* slot 2 */
+ AvnHResult (AVN_CALL *get_opacity)(IAvnRadialGradientBrush* self, double* value); /* slot 3 */
+ AvnHResult (AVN_CALL *get_spread_method)(IAvnRadialGradientBrush* self, int32_t* value); /* slot 4 */
+ AvnHResult (AVN_CALL *get_stop_count)(IAvnRadialGradientBrush* self, int32_t* value); /* slot 5 */
+ AvnHResult (AVN_CALL *get_stops)(IAvnRadialGradientBrush* self, AvnGradientStopBuffer* value); /* slot 6 */
+ AvnHResult (AVN_CALL *get_center)(IAvnRadialGradientBrush* self, AvnRelativePoint* value); /* slot 7 */
+ AvnHResult (AVN_CALL *get_gradient_origin)(IAvnRadialGradientBrush* self, AvnRelativePoint* value); /* slot 8 */
+ AvnHResult (AVN_CALL *get_radius_x)(IAvnRadialGradientBrush* self, AvnRelativeScalar* value); /* slot 9 */
+ AvnHResult (AVN_CALL *get_radius_y)(IAvnRadialGradientBrush* self, AvnRelativeScalar* value); /* slot 10 */
+};
+struct IAvnRadialGradientBrush { const IAvnRadialGradientBrushVtbl* vtbl; };
+#define I_AVN_RADIAL_GRADIENT_BRUSH_VTABLE_SLOTS 11
+
static const AvnGuid I_AVN_COMMAND_CAN_EXECUTE_CHANGED_HANDLER_IID = {
0x13E58040,
0xB570,
@@ -16239,12 +16332,12 @@ struct IAvnToolTipStatics { const IAvnToolTipStaticsVtbl* vtbl; };
#define I_AVN_TOOL_TIP_STATICS_VTABLE_SLOTS 21
static const AvnGuid I_AVN_CONTROL_FACTORY_IID = {
- 0x15778134,
- 0x9E9F,
- 0x5BAF,
- { 0x98, 0xFF, 0x55, 0x10, 0x77, 0x80, 0x94, 0xBA }
+ 0xC8BCE8E8,
+ 0x62C7,
+ 0x5E0E,
+ { 0x80, 0x66, 0x69, 0x00, 0x59, 0xF5, 0x5D, 0xFF }
};
-#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13
+#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14
struct IAvnControlFactoryVtbl {
AvnHResult (AVN_CALL *query_interface)(IAvnControlFactory* self, const AvnGuid* iid, void** result); /* slot 0 */
uint32_t (AVN_CALL *add_ref)(IAvnControlFactory* self); /* slot 1 */
@@ -16352,8 +16445,10 @@ struct IAvnControlFactoryVtbl {
AvnHResult (AVN_CALL *get_relative_panel_statics)(IAvnControlFactory* self, IAvnRelativePanelStatics** value); /* slot 103 */
AvnHResult (AVN_CALL *get_tool_tip_statics)(IAvnControlFactory* self, IAvnToolTipStatics** value); /* slot 104 */
AvnHResult (AVN_CALL *create_solid_color_brush)(IAvnControlFactory* self, AvnColor color, double opacity, IAvnBrush** value); /* slot 105 */
+ AvnHResult (AVN_CALL *create_linear_gradient_brush)(IAvnControlFactory* self, double opacity, int32_t spread_method, int32_t stop_count, AvnGradientStopBuffer stops, AvnRelativePoint start_point, AvnRelativePoint end_point, IAvnLinearGradientBrush** value); /* slot 106 */
+ AvnHResult (AVN_CALL *create_radial_gradient_brush)(IAvnControlFactory* self, double opacity, int32_t spread_method, int32_t stop_count, AvnGradientStopBuffer stops, AvnRelativePoint center, AvnRelativePoint gradient_origin, AvnRelativeScalar radius_x, AvnRelativeScalar radius_y, IAvnRadialGradientBrush** value); /* slot 107 */
};
struct IAvnControlFactory { const IAvnControlFactoryVtbl* vtbl; };
-#define I_AVN_CONTROL_FACTORY_VTABLE_SLOTS 106
+#define I_AVN_CONTROL_FACTORY_VTABLE_SLOTS 108
#endif /* AVALONIA_RUST_ABI_H */
diff --git a/rust/avalonia-sys/src/.avalonia-bindgen.owned.json b/rust/avalonia-sys/src/.avalonia-bindgen.owned.json
index 43f893d..656d4be 100644
--- a/rust/avalonia-sys/src/.avalonia-bindgen.owned.json
+++ b/rust/avalonia-sys/src/.avalonia-bindgen.owned.json
@@ -3,7 +3,7 @@
"files": [
{
"path": "generated.rs",
- "sha256": "268263810f8f0b26523e9b1991e9e47e9001c05007b04a0373fe2a44811a844a"
+ "sha256": "4db8abe8997bc5ac8b94e9aafbf282743c1dcee0302cc1ad62c1874c4d5e9544"
}
]
}
diff --git a/rust/avalonia-sys/src/generated.rs b/rust/avalonia-sys/src/generated.rs
index ffd2337..a7c3c25 100644
--- a/rust/avalonia-sys/src/generated.rs
+++ b/rust/avalonia-sys/src/generated.rs
@@ -305,6 +305,256 @@ impl ComPtr {
}
}
+/// Blittable ABI mirror of Avalonia.RelativePoint. unit: 0 relative, 1 absolute.
+#[repr(C)]
+#[derive(Clone, Copy, Debug, Default, PartialEq)]
+pub struct AvnRelativePoint {
+ pub x: f64,
+ pub y: f64,
+ pub unit: i32,
+}
+
+/// Blittable ABI mirror of Avalonia.RelativeScalar. unit: 0 relative, 1 absolute.
+#[repr(C)]
+#[derive(Clone, Copy, Debug, Default, PartialEq)]
+pub struct AvnRelativeScalar {
+ pub scalar: f64,
+ pub unit: i32,
+}
+
+/// Blittable ABI mirror of a single gradient stop (offset plus packed colour).
+#[repr(C)]
+#[derive(Clone, Copy, Debug, Default, PartialEq)]
+pub struct AvnGradientStop {
+ pub offset: f64,
+ pub color: AvnColor,
+}
+
+/// Fixed-capacity buffer of up to 8 `AvnGradientStop` entries.
+#[repr(C)]
+#[derive(Clone, Copy, Debug)]
+pub struct AvnGradientStopBuffer {
+ pub stops: [AvnGradientStop; 8],
+}
+
+impl Default for AvnGradientStopBuffer {
+ fn default() -> Self {
+ Self { stops: [AvnGradientStop::default(); 8] }
+ }
+}
+
+/// Capability shared by every gradient brush kind projected across the ABI.
+pub const I_AVN_GRADIENT_BRUSH_IID: Guid = Guid { data1: 0xFDAA2353, data2: 0xBC44, data3: 0x5012, data4: [0xA5, 0xBE, 0xA1, 0x7C, 0x7C, 0x01, 0xF4, 0x1A] };
+
+#[repr(C)]
+struct IAvnGradientBrushVtbl {
+ query_interface: unsafe extern "system" fn(*mut IUnknown, *const Guid, *mut *mut c_void) -> i32,
+ add_ref: unsafe extern "system" fn(*mut IUnknown) -> u32,
+ release: unsafe extern "system" fn(*mut IUnknown) -> u32,
+ get_opacity: unsafe extern "system" fn(*mut IAvnGradientBrush, *mut f64) -> i32,
+ get_spread_method: unsafe extern "system" fn(*mut IAvnGradientBrush, *mut i32) -> i32,
+ get_stop_count: unsafe extern "system" fn(*mut IAvnGradientBrush, *mut i32) -> i32,
+ get_stops: unsafe extern "system" fn(*mut IAvnGradientBrush, *mut AvnGradientStopBuffer) -> i32,
+}
+
+#[repr(C)]
+pub struct IAvnGradientBrush {
+ vtbl: *const IAvnGradientBrushVtbl,
+}
+
+unsafe impl ComInterface for IAvnGradientBrush {
+ const IID: Guid = I_AVN_GRADIENT_BRUSH_IID;
+}
+
+impl ComPtr {
+ pub fn opacity(&self) -> Result {
+ unsafe {
+ let mut value = 0.0;
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_opacity)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ /// 0 = Pad, 1 = Reflect, 2 = Repeat.
+ pub fn spread_method(&self) -> Result {
+ unsafe {
+ let mut value = 0;
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_spread_method)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn stop_count(&self) -> Result {
+ unsafe {
+ let mut value = 0;
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_stop_count)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn stops(&self) -> Result {
+ unsafe {
+ let mut value = AvnGradientStopBuffer::default();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_stops)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+}
+
+#[repr(C)]
+struct IAvnLinearGradientBrushVtbl {
+ query_interface: unsafe extern "system" fn(*mut IUnknown, *const Guid, *mut *mut c_void) -> i32,
+ add_ref: unsafe extern "system" fn(*mut IUnknown) -> u32,
+ release: unsafe extern "system" fn(*mut IUnknown) -> u32,
+ get_opacity: unsafe extern "system" fn(*mut IAvnLinearGradientBrush, *mut f64) -> i32,
+ get_spread_method: unsafe extern "system" fn(*mut IAvnLinearGradientBrush, *mut i32) -> i32,
+ get_stop_count: unsafe extern "system" fn(*mut IAvnLinearGradientBrush, *mut i32) -> i32,
+ get_stops: unsafe extern "system" fn(*mut IAvnLinearGradientBrush, *mut AvnGradientStopBuffer) -> i32,
+ get_start_point: unsafe extern "system" fn(*mut IAvnLinearGradientBrush, *mut AvnRelativePoint) -> i32,
+ get_end_point: unsafe extern "system" fn(*mut IAvnLinearGradientBrush, *mut AvnRelativePoint) -> i32,
+}
+
+#[repr(C)]
+pub struct IAvnLinearGradientBrush {
+ vtbl: *const IAvnLinearGradientBrushVtbl,
+}
+
+unsafe impl ComInterface for IAvnLinearGradientBrush {
+ const IID: Guid = I_AVN_LINEAR_GRADIENT_BRUSH_IID;
+}
+
+pub const I_AVN_LINEAR_GRADIENT_BRUSH_IID: Guid = Guid { data1: 0x40B3D53D, data2: 0x330E, data3: 0x5D63, data4: [0xA0, 0x40, 0x37, 0xF1, 0xFF, 0x71, 0x7F, 0xF8] };
+
+impl ComPtr {
+ pub fn opacity(&self) -> Result {
+ unsafe {
+ let mut value = 0.0;
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_opacity)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ /// 0 = Pad, 1 = Reflect, 2 = Repeat.
+ pub fn spread_method(&self) -> Result {
+ unsafe {
+ let mut value = 0;
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_spread_method)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn stop_count(&self) -> Result {
+ unsafe {
+ let mut value = 0;
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_stop_count)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn stops(&self) -> Result {
+ unsafe {
+ let mut value = AvnGradientStopBuffer::default();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_stops)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn start_point(&self) -> Result {
+ unsafe {
+ let mut value = AvnRelativePoint::default();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_start_point)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn end_point(&self) -> Result {
+ unsafe {
+ let mut value = AvnRelativePoint::default();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_end_point)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+}
+
+#[repr(C)]
+struct IAvnRadialGradientBrushVtbl {
+ query_interface: unsafe extern "system" fn(*mut IUnknown, *const Guid, *mut *mut c_void) -> i32,
+ add_ref: unsafe extern "system" fn(*mut IUnknown) -> u32,
+ release: unsafe extern "system" fn(*mut IUnknown) -> u32,
+ get_opacity: unsafe extern "system" fn(*mut IAvnRadialGradientBrush, *mut f64) -> i32,
+ get_spread_method: unsafe extern "system" fn(*mut IAvnRadialGradientBrush, *mut i32) -> i32,
+ get_stop_count: unsafe extern "system" fn(*mut IAvnRadialGradientBrush, *mut i32) -> i32,
+ get_stops: unsafe extern "system" fn(*mut IAvnRadialGradientBrush, *mut AvnGradientStopBuffer) -> i32,
+ get_center: unsafe extern "system" fn(*mut IAvnRadialGradientBrush, *mut AvnRelativePoint) -> i32,
+ get_gradient_origin: unsafe extern "system" fn(*mut IAvnRadialGradientBrush, *mut AvnRelativePoint) -> i32,
+ get_radius_x: unsafe extern "system" fn(*mut IAvnRadialGradientBrush, *mut AvnRelativeScalar) -> i32,
+ get_radius_y: unsafe extern "system" fn(*mut IAvnRadialGradientBrush, *mut AvnRelativeScalar) -> i32,
+}
+
+#[repr(C)]
+pub struct IAvnRadialGradientBrush {
+ vtbl: *const IAvnRadialGradientBrushVtbl,
+}
+
+unsafe impl ComInterface for IAvnRadialGradientBrush {
+ const IID: Guid = I_AVN_RADIAL_GRADIENT_BRUSH_IID;
+}
+
+pub const I_AVN_RADIAL_GRADIENT_BRUSH_IID: Guid = Guid { data1: 0xAEC23FCE, data2: 0x9FEA, data3: 0x506C, data4: [0xAB, 0xC4, 0x77, 0x41, 0x43, 0xBE, 0x80, 0xC8] };
+
+impl ComPtr {
+ pub fn opacity(&self) -> Result {
+ unsafe {
+ let mut value = 0.0;
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_opacity)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ /// 0 = Pad, 1 = Reflect, 2 = Repeat.
+ pub fn spread_method(&self) -> Result {
+ unsafe {
+ let mut value = 0;
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_spread_method)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn stop_count(&self) -> Result {
+ unsafe {
+ let mut value = 0;
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_stop_count)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn stops(&self) -> Result {
+ unsafe {
+ let mut value = AvnGradientStopBuffer::default();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_stops)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn center(&self) -> Result {
+ unsafe {
+ let mut value = AvnRelativePoint::default();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_center)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn gradient_origin(&self) -> Result {
+ unsafe {
+ let mut value = AvnRelativePoint::default();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_gradient_origin)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn radius_x(&self) -> Result {
+ unsafe {
+ let mut value = AvnRelativeScalar::default();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_radius_x)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+ pub fn radius_y(&self) -> Result {
+ unsafe {
+ let mut value = AvnRelativeScalar::default();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().get_radius_y)(self.as_raw(), &mut value);
+ hresult::check(hr).map(|_| value)
+ }
+ }
+}
+
+
pub const I_AVN_COMMAND_IID: Guid = Guid { data1: 0xE6F7AAF7, data2: 0xD5E7, data3: 0x503F, data4: [0x9B, 0xE6, 0x5A, 0xF8, 0xDB, 0x5B, 0x52, 0x73] };
#[repr(C)]
@@ -104862,7 +105112,7 @@ impl ComPtr {
}
}
-pub const IAVN_CONTROL_FACTORY_IID: Guid = Guid { data1: 0x15778134, data2: 0x9E9F, data3: 0x5BAF, data4: [0x98, 0xFF, 0x55, 0x10, 0x77, 0x80, 0x94, 0xBA] };
+pub const IAVN_CONTROL_FACTORY_IID: Guid = Guid { data1: 0xC8BCE8E8, data2: 0x62C7, data3: 0x5E0E, data4: [0x80, 0x66, 0x69, 0x00, 0x59, 0xF5, 0x5D, 0xFF] };
#[repr(C)]
struct IAvnControlFactoryVtbl {
@@ -104972,6 +105222,8 @@ struct IAvnControlFactoryVtbl {
get_relative_panel_statics: unsafe extern "system" fn(*mut IAvnControlFactory, *mut *mut IAvnRelativePanelStatics) -> i32,
get_tool_tip_statics: unsafe extern "system" fn(*mut IAvnControlFactory, *mut *mut IAvnToolTipStatics) -> i32,
create_solid_color_brush: unsafe extern "system" fn(*mut IAvnControlFactory, AvnColor, f64, *mut *mut IAvnBrush) -> i32,
+ create_linear_gradient_brush: unsafe extern "system" fn(*mut IAvnControlFactory, f64, i32, i32, AvnGradientStopBuffer, AvnRelativePoint, AvnRelativePoint, *mut *mut IAvnLinearGradientBrush) -> i32,
+ create_radial_gradient_brush: unsafe extern "system" fn(*mut IAvnControlFactory, f64, i32, i32, AvnGradientStopBuffer, AvnRelativePoint, AvnRelativePoint, AvnRelativeScalar, AvnRelativeScalar, *mut *mut IAvnRadialGradientBrush) -> i32,
}
#[repr(C)]
@@ -105808,4 +106060,44 @@ impl ComPtr {
ComPtr::from_raw(value).ok_or(Error(hresult::E_POINTER))
}
}
+ #[allow(clippy::too_many_arguments)]
+ pub fn create_linear_gradient_brush(
+ &self,
+ opacity: f64,
+ spread_method: i32,
+ stop_count: i32,
+ stops: AvnGradientStopBuffer,
+ start_point: AvnRelativePoint,
+ end_point: AvnRelativePoint,
+ ) -> Result> {
+ unsafe {
+ let mut value = ptr::null_mut();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().create_linear_gradient_brush)(
+ self.as_raw(), opacity, spread_method, stop_count, stops, start_point, end_point, &mut value,
+ );
+ hresult::check(hr)?;
+ ComPtr::from_raw(value).ok_or(Error(hresult::E_POINTER))
+ }
+ }
+ #[allow(clippy::too_many_arguments)]
+ pub fn create_radial_gradient_brush(
+ &self,
+ opacity: f64,
+ spread_method: i32,
+ stop_count: i32,
+ stops: AvnGradientStopBuffer,
+ center: AvnRelativePoint,
+ gradient_origin: AvnRelativePoint,
+ radius_x: AvnRelativeScalar,
+ radius_y: AvnRelativeScalar,
+ ) -> Result> {
+ unsafe {
+ let mut value = ptr::null_mut();
+ let hr = ((*self.as_raw()).vtbl.as_ref().unwrap().create_radial_gradient_brush)(
+ self.as_raw(), opacity, spread_method, stop_count, stops, center, gradient_origin, radius_x, radius_y, &mut value,
+ );
+ hresult::check(hr)?;
+ ComPtr::from_raw(value).ok_or(Error(hresult::E_POINTER))
+ }
+ }
}
diff --git a/rust/avalonia-sys/src/hresult.rs b/rust/avalonia-sys/src/hresult.rs
index bc7103d..cf7da18 100644
--- a/rust/avalonia-sys/src/hresult.rs
+++ b/rust/avalonia-sys/src/hresult.rs
@@ -5,6 +5,9 @@ pub const E_INVALIDARG: i32 = 0x8007_0057u32 as i32;
pub const E_NOINTERFACE: i32 = 0x8000_4002u32 as i32;
pub const E_NOTIMPL: i32 = 0x8000_4001u32 as i32;
pub const AVN_E_FIXTURE: i32 = 0xA7A7_0001u32 as i32;
+/// Returned by `IAvnBrush::GetColor` when the underlying brush is a gradient,
+/// drawing, or visual brush rather than a solid colour.
+pub const AVN_E_NONSOLIDBRUSH: i32 = 0xA7A7_0002u32 as i32;
pub fn succeeded(hr: i32) -> bool {
hr >= 0
diff --git a/rust/avalonia-sys/src/lib.rs b/rust/avalonia-sys/src/lib.rs
index 5da6788..8baba3e 100644
--- a/rust/avalonia-sys/src/lib.rs
+++ b/rust/avalonia-sys/src/lib.rs
@@ -54,7 +54,8 @@ pub use filters::{item_filter, text_filter, ItemFilter, TextFilter};
pub use generated::*;
pub use guid::Guid;
pub use hresult::{
- Error, Result, AVN_E_FIXTURE, E_FAIL, E_INVALIDARG, E_NOINTERFACE, E_NOTIMPL, E_POINTER, S_OK,
+ Error, Result, AVN_E_FIXTURE, AVN_E_NONSOLIDBRUSH, E_FAIL, E_INVALIDARG, E_NOINTERFACE,
+ E_NOTIMPL, E_POINTER, S_OK,
};
pub use notification::{notification, Notification, NotificationSpec};
pub use popup_placement::{popup_placement, PopupPlacement, PopupPlacementResult};
diff --git a/rust/avalonia-sys/tests/brush_abi.rs b/rust/avalonia-sys/tests/brush_abi.rs
index 0df4998..d5109e7 100644
--- a/rust/avalonia-sys/tests/brush_abi.rs
+++ b/rust/avalonia-sys/tests/brush_abi.rs
@@ -30,7 +30,6 @@ fn brush_publishes_a_read_only_colour_and_opacity_vtable() {
for forbidden in [
"*set_color)(IAvnBrush*",
"*set_opacity)(IAvnBrush*",
- "IAvnGradientBrush",
"IAvnDrawingBrush",
"IAvnVisualBrush",
] {
@@ -78,8 +77,10 @@ fn chrome_wave_interfaces_publish_abi_version_four() {
"#define I_AVN_TEMPLATED_CONTROL_ABI_VERSION 15",
"#define I_AVN_TEXT_BLOCK_ABI_VERSION 17",
// The factory grew create_solid_color_brush at version 2, a creator per wave A control
- // at version 3, and a creator per constructible wave B type at version 4.
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ // at version 3, a creator per constructible wave B type at version 4, and the gradient
+ // brush creators (create_linear_gradient_brush/create_radial_gradient_brush) moved it
+ // to version 14.
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
// Nothing was added to StyledElement, Control or Decorator, and none of their bases
// moved, so their flattened vtables are byte-identical to version 3.
"#define I_AVN_STYLED_ELEMENT_ABI_VERSION 6",
diff --git a/rust/avalonia-sys/tests/control_abi.rs b/rust/avalonia-sys/tests/control_abi.rs
index 550b85a..95fcb78 100644
--- a/rust/avalonia-sys/tests/control_abi.rs
+++ b/rust/avalonia-sys/tests/control_abi.rs
@@ -116,7 +116,7 @@ fn widened_interfaces_publish_abi_version_five() {
"#define I_AVN_AVALONIA_OBJECT_ABI_VERSION 2",
// The factory gained a creator per wave A control plus get_tool_tip_statics at version
// 3, and a creator per constructible wave B type at version 4.
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/definitions_abi.rs b/rust/avalonia-sys/tests/definitions_abi.rs
index ead1a44..3065d53 100644
--- a/rust/avalonia-sys/tests/definitions_abi.rs
+++ b/rust/avalonia-sys/tests/definitions_abi.rs
@@ -59,7 +59,7 @@ fn only_grid_moved_to_abi_version_five_for_the_definitions() {
// The factory mints no definition object, but wave A gave it a creator per new control
// and get_tool_tip_statics and wave B gave it seven more, so it now publishes at
// version 4.
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/gradient_brush_abi.rs b/rust/avalonia-sys/tests/gradient_brush_abi.rs
new file mode 100644
index 0000000..e99632e
--- /dev/null
+++ b/rust/avalonia-sys/tests/gradient_brush_abi.rs
@@ -0,0 +1,106 @@
+//! ABI guarantees for the gradient brush capability interfaces.
+//!
+//! Gradients follow the sibling-interface pattern rather than widening `IAvnBrush`:
+//! `IAvnGradientBrush` carries the members every gradient shares, and
+//! `IAvnLinearGradientBrush`/`IAvnRadialGradientBrush` each derive from it and add their own
+//! geometry. `IAvnBrush` itself keeps the IID and vtable it published with in the solid-brush
+//! wave (see `brush_abi.rs`); only `IAvnControlFactory` republishes, to gain the two new
+//! creator slots.
+
+use avalonia_sys::{
+ I_AVN_BRUSH_IID, I_AVN_GRADIENT_BRUSH_IID, I_AVN_LINEAR_GRADIENT_BRUSH_IID,
+ I_AVN_RADIAL_GRADIENT_BRUSH_IID,
+};
+
+const HEADER: &str = include_str!("../include/avalonia-rust-abi.h");
+
+#[test]
+fn gradient_brush_publishes_the_shared_read_only_members() {
+ for expected in [
+ "typedef struct IAvnGradientBrush IAvnGradientBrush;",
+ "*get_opacity)(IAvnGradientBrush* self, double* value)",
+ "*get_spread_method)(IAvnGradientBrush* self, int32_t* value)",
+ "*get_stop_count)(IAvnGradientBrush* self, int32_t* value)",
+ "*get_stops)(IAvnGradientBrush* self, AvnGradientStopBuffer* value)",
+ "#define I_AVN_GRADIENT_BRUSH_VTABLE_SLOTS 7",
+ "#define I_AVN_GRADIENT_BRUSH_ABI_VERSION 1",
+ ] {
+ assert!(HEADER.contains(expected), "header is missing `{expected}`");
+ }
+}
+
+#[test]
+fn linear_gradient_brush_adds_its_start_and_end_point() {
+ for expected in [
+ "typedef struct IAvnLinearGradientBrush IAvnLinearGradientBrush;",
+ "*get_start_point)(IAvnLinearGradientBrush* self, AvnRelativePoint* value)",
+ "*get_end_point)(IAvnLinearGradientBrush* self, AvnRelativePoint* value)",
+ "#define I_AVN_LINEAR_GRADIENT_BRUSH_VTABLE_SLOTS 9",
+ "#define I_AVN_LINEAR_GRADIENT_BRUSH_ABI_VERSION 1",
+ ] {
+ assert!(HEADER.contains(expected), "header is missing `{expected}`");
+ }
+}
+
+#[test]
+fn radial_gradient_brush_adds_its_ellipse_geometry() {
+ for expected in [
+ "typedef struct IAvnRadialGradientBrush IAvnRadialGradientBrush;",
+ "*get_center)(IAvnRadialGradientBrush* self, AvnRelativePoint* value)",
+ "*get_gradient_origin)(IAvnRadialGradientBrush* self, AvnRelativePoint* value)",
+ "*get_radius_x)(IAvnRadialGradientBrush* self, AvnRelativeScalar* value)",
+ "*get_radius_y)(IAvnRadialGradientBrush* self, AvnRelativeScalar* value)",
+ "#define I_AVN_RADIAL_GRADIENT_BRUSH_VTABLE_SLOTS 11",
+ "#define I_AVN_RADIAL_GRADIENT_BRUSH_ABI_VERSION 1",
+ ] {
+ assert!(HEADER.contains(expected), "header is missing `{expected}`");
+ }
+}
+
+#[test]
+fn gradients_are_minted_by_the_factory_and_carry_a_fixed_capacity_stop_buffer() {
+ assert!(HEADER.contains(
+ "*create_linear_gradient_brush)(IAvnControlFactory* self, double opacity, \
+ int32_t spread_method, int32_t stop_count, AvnGradientStopBuffer stops, \
+ AvnRelativePoint start_point, AvnRelativePoint end_point, \
+ IAvnLinearGradientBrush** value)"
+ ));
+ assert!(HEADER.contains(
+ "*create_radial_gradient_brush)(IAvnControlFactory* self, double opacity, \
+ int32_t spread_method, int32_t stop_count, AvnGradientStopBuffer stops, \
+ AvnRelativePoint center, AvnRelativePoint gradient_origin, \
+ AvnRelativeScalar radius_x, AvnRelativeScalar radius_y, \
+ IAvnRadialGradientBrush** value)"
+ ));
+ assert!(HEADER.contains("AvnGradientStop stops[8];"));
+}
+
+#[test]
+fn gradient_interfaces_are_brand_new_and_distinct_from_each_other_and_from_brush() {
+ let iids = [
+ ("IAvnBrush", I_AVN_BRUSH_IID),
+ ("IAvnGradientBrush", I_AVN_GRADIENT_BRUSH_IID),
+ ("IAvnLinearGradientBrush", I_AVN_LINEAR_GRADIENT_BRUSH_IID),
+ ("IAvnRadialGradientBrush", I_AVN_RADIAL_GRADIENT_BRUSH_IID),
+ ];
+ for (i, (name_a, iid_a)) in iids.iter().enumerate() {
+ for (name_b, iid_b) in &iids[i + 1..] {
+ assert_ne!(
+ format_iid(iid_a),
+ format_iid(iid_b),
+ "{name_a} and {name_b} must not share an IID"
+ );
+ }
+ }
+}
+
+fn format_iid(iid: &avalonia_sys::Guid) -> String {
+ let mut out = format!("{:08X}-{:04X}-{:04X}-", iid.data1, iid.data2, iid.data3);
+ for (index, byte) in iid.data4.iter().enumerate() {
+ if index == 2 {
+ out.push('-');
+ }
+ out.push_str(&format!("{byte:02X}"));
+ }
+ out
+}
diff --git a/rust/avalonia-sys/tests/wave_a_abi.rs b/rust/avalonia-sys/tests/wave_a_abi.rs
index 41c9a4f..a1bc74f 100644
--- a/rust/avalonia-sys/tests/wave_a_abi.rs
+++ b/rust/avalonia-sys/tests/wave_a_abi.rs
@@ -80,7 +80,7 @@ fn wave_a_interfaces_publish_abi_version_one_and_nothing_else_moved() {
"#define I_AVN_HEADERED_CONTENT_CONTROL_ABI_VERSION 16",
// Only the factory grew slots. Wave B moved it again, from 3 to 4, for its own
// creators; every wave A interface still publishes at version 1.
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/wave_b_abi.rs b/rust/avalonia-sys/tests/wave_b_abi.rs
index 641f569..ff42e19 100644
--- a/rust/avalonia-sys/tests/wave_b_abi.rs
+++ b/rust/avalonia-sys/tests/wave_b_abi.rs
@@ -151,7 +151,7 @@ fn the_factory_gains_a_creator_per_constructible_wave_b_type() {
"*create_date_picker)(IAvnControlFactory* self, IAvnDatePicker** value)",
"*create_time_picker)(IAvnControlFactory* self, IAvnTimePicker** value)",
"*create_headered_selecting_items_control)(IAvnControlFactory* self, IAvnHeaderedSelectingItemsControl** value)",
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/wave_c_abi.rs b/rust/avalonia-sys/tests/wave_c_abi.rs
index 4517085..4f93e71 100644
--- a/rust/avalonia-sys/tests/wave_c_abi.rs
+++ b/rust/avalonia-sys/tests/wave_c_abi.rs
@@ -73,7 +73,7 @@ fn viewbox_child_is_a_control_and_grid_splitter_sits_on_thumb() {
"*advise_drag_delta)(IAvnThumb* self, IAvnThumbDragDeltaHandler* handler, int64_t* subscription_id)",
"*create_thumb)(IAvnControlFactory* self, IAvnThumb** value)",
"*create_grid_splitter)(IAvnControlFactory* self, IAvnGridSplitter** value)",
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/wave_d_abi.rs b/rust/avalonia-sys/tests/wave_d_abi.rs
index 1a71b68..09a330e 100644
--- a/rust/avalonia-sys/tests/wave_d_abi.rs
+++ b/rust/avalonia-sys/tests/wave_d_abi.rs
@@ -36,7 +36,7 @@ fn split_button_carries_click_and_command() {
"*create_menu_flyout)(IAvnControlFactory* self, IAvnMenuFlyout** value)",
"#define I_AVN_SPLIT_BUTTON_ABI_VERSION 15",
"#define I_AVN_TOGGLE_SPLIT_BUTTON_ABI_VERSION 15",
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/wave_e_abi.rs b/rust/avalonia-sys/tests/wave_e_abi.rs
index cbba856..71eddb3 100644
--- a/rust/avalonia-sys/tests/wave_e_abi.rs
+++ b/rust/avalonia-sys/tests/wave_e_abi.rs
@@ -11,7 +11,7 @@ fn numeric_up_down_decimals_are_utf16_strings() {
"*set_increment)(IAvnNumericUpDown* self, const uint16_t* value)",
"*create_numeric_up_down)(IAvnControlFactory* self, IAvnNumericUpDown** value)",
"#define I_AVN_NUMERIC_UP_DOWN_ABI_VERSION 13",
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/wave_f_abi.rs b/rust/avalonia-sys/tests/wave_f_abi.rs
index f1b4ab7..feaa7a2 100644
--- a/rust/avalonia-sys/tests/wave_f_abi.rs
+++ b/rust/avalonia-sys/tests/wave_f_abi.rs
@@ -13,7 +13,7 @@ fn calendar_days_are_yyyy_mm_dd_strings() {
"*create_calendar_date_picker)(IAvnControlFactory* self, IAvnCalendarDatePicker** value)",
"#define I_AVN_CALENDAR_ABI_VERSION 15",
"#define I_AVN_CALENDAR_DATE_PICKER_ABI_VERSION 14",
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/wave_g_abi.rs b/rust/avalonia-sys/tests/wave_g_abi.rs
index 3b2dcc7..d932bb1 100644
--- a/rust/avalonia-sys/tests/wave_g_abi.rs
+++ b/rust/avalonia-sys/tests/wave_g_abi.rs
@@ -18,7 +18,7 @@ fn content_chrome_publishes_at_version_one() {
"*create_group_box)(IAvnControlFactory* self, IAvnGroupBox** value)",
"*create_user_control)(IAvnControlFactory* self, IAvnUserControl** value)",
"#define I_AVN_CAROUSEL_ABI_VERSION 16",
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/wave_h_abi.rs b/rust/avalonia-sys/tests/wave_h_abi.rs
index a5d1d24..b47a4fa 100644
--- a/rust/avalonia-sys/tests/wave_h_abi.rs
+++ b/rust/avalonia-sys/tests/wave_h_abi.rs
@@ -17,7 +17,7 @@ fn shapes_carry_brushes_points_and_path_data() {
"*create_line)(IAvnControlFactory* self, IAvnLine** value)",
"*create_path)(IAvnControlFactory* self, IAvnPath** value)",
"#define I_AVN_SHAPE_ABI_VERSION 11",
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/wave_i_abi.rs b/rust/avalonia-sys/tests/wave_i_abi.rs
index 870f1bc..ecf98f0 100644
--- a/rust/avalonia-sys/tests/wave_i_abi.rs
+++ b/rust/avalonia-sys/tests/wave_i_abi.rs
@@ -22,7 +22,7 @@ fn overlay_controls_publish_at_version_one() {
"*create_tray_icon)(IAvnControlFactory* self, IAvnTrayIcon** value)",
"#define I_AVN_POPUP_ABI_VERSION 11",
"#define I_AVN_TRAY_ICON_ABI_VERSION 3",
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/wave_j_abi.rs b/rust/avalonia-sys/tests/wave_j_abi.rs
index 2aadd0f..f9bc473 100644
--- a/rust/avalonia-sys/tests/wave_j_abi.rs
+++ b/rust/avalonia-sys/tests/wave_j_abi.rs
@@ -15,7 +15,7 @@ fn command_bar_family_publishes_at_version_one() {
"*create_theme_variant_scope)(IAvnControlFactory* self, IAvnThemeVariantScope** value)",
"#define I_AVN_COMMAND_BAR_ABI_VERSION 15",
"#define I_AVN_PIPS_PAGER_ABI_VERSION 13",
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia-sys/tests/wave_k_abi.rs b/rust/avalonia-sys/tests/wave_k_abi.rs
index 39d5acd..dc29ff1 100644
--- a/rust/avalonia-sys/tests/wave_k_abi.rs
+++ b/rust/avalonia-sys/tests/wave_k_abi.rs
@@ -13,7 +13,7 @@ fn icons_and_table_view_publish_at_version_one() {
"*create_table_view_column)(IAvnControlFactory* self, IAvnTableViewColumn** value)",
"#define I_AVN_PATH_ICON_ABI_VERSION 12",
"#define I_AVN_TABLE_VIEW_ABI_VERSION 16",
- "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 13",
+ "#define I_AVN_CONTROL_FACTORY_ABI_VERSION 14",
] {
assert!(HEADER.contains(expected), "header is missing `{expected}`");
}
diff --git a/rust/avalonia/src/.avalonia-bindgen.owned.json b/rust/avalonia/src/.avalonia-bindgen.owned.json
index da09294..f1c6744 100644
--- a/rust/avalonia/src/.avalonia-bindgen.owned.json
+++ b/rust/avalonia/src/.avalonia-bindgen.owned.json
@@ -3,7 +3,7 @@
"files": [
{
"path": "generated.rs",
- "sha256": "b120c2c8d67b750704a9a5724e9cfcb784875021ae17b8963e127fa54dee55c9"
+ "sha256": "541283736e93b09b2b55c38e106e8bf29b026595cda766f7409bf31f0f588cd7"
}
]
}
diff --git a/rust/avalonia/src/generated.rs b/rust/avalonia/src/generated.rs
index 8e7bb20..7a98843 100644
--- a/rust/avalonia/src/generated.rs
+++ b/rust/avalonia/src/generated.rs
@@ -533,6 +533,304 @@ impl From for Brush {
}
}
+/// Spread behaviour for a gradient outside its `[0, 1]` stop range.
+/// Mirrors `Avalonia.Media.GradientSpreadMethod`.
+#[repr(i32)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum SpreadMethod {
+ Pad = 0,
+ Reflect = 1,
+ Repeat = 2,
+}
+
+impl TryFrom for SpreadMethod {
+ type Error = crate::Error;
+ fn try_from(value: i32) -> Result {
+ match value {
+ 0 => Ok(Self::Pad),
+ 1 => Ok(Self::Reflect),
+ 2 => Ok(Self::Repeat),
+ _ => Err(crate::Error::InvalidEnumValue(value)),
+ }
+ }
+}
+
+/// Whether a gradient coordinate is relative to the shape's bounding box or an
+/// absolute value. Mirrors `Avalonia.RelativeUnit`.
+#[repr(i32)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum RelativeUnit {
+ Relative = 0,
+ Absolute = 1,
+}
+
+impl TryFrom for RelativeUnit {
+ type Error = crate::Error;
+ fn try_from(value: i32) -> Result {
+ match value {
+ 0 => Ok(Self::Relative),
+ 1 => Ok(Self::Absolute),
+ _ => Err(crate::Error::InvalidEnumValue(value)),
+ }
+ }
+}
+
+/// A point whose X/Y may each be relative to the shape's bounding box.
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct RelativePoint {
+ pub x: f64,
+ pub y: f64,
+ pub unit: RelativeUnit,
+}
+
+impl RelativePoint {
+ pub const fn new(x: f64, y: f64, unit: RelativeUnit) -> Self {
+ Self { x, y, unit }
+ }
+
+ pub(crate) fn to_abi(self) -> sys::AvnRelativePoint {
+ sys::AvnRelativePoint { x: self.x, y: self.y, unit: self.unit as i32 }
+ }
+
+ pub(crate) fn from_abi(value: sys::AvnRelativePoint) -> Result {
+ Ok(Self { x: value.x, y: value.y, unit: RelativeUnit::try_from(value.unit)? })
+ }
+}
+
+/// A scalar (for example a radius) that may be relative to the shape's bounding box.
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct RelativeScalar {
+ pub scalar: f64,
+ pub unit: RelativeUnit,
+}
+
+impl RelativeScalar {
+ pub const fn new(scalar: f64, unit: RelativeUnit) -> Self {
+ Self { scalar, unit }
+ }
+
+ pub(crate) fn to_abi(self) -> sys::AvnRelativeScalar {
+ sys::AvnRelativeScalar { scalar: self.scalar, unit: self.unit as i32 }
+ }
+
+ pub(crate) fn from_abi(value: sys::AvnRelativeScalar) -> Result {
+ Ok(Self { scalar: value.scalar, unit: RelativeUnit::try_from(value.unit)? })
+ }
+}
+
+/// A single colour stop along a gradient, at `offset` in `[0, 1]`.
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct GradientStop {
+ pub offset: f64,
+ pub color: Color,
+}
+
+impl GradientStop {
+ pub const fn new(offset: f64, color: Color) -> Self {
+ Self { offset, color }
+ }
+
+ fn to_abi(self) -> sys::AvnGradientStop {
+ sys::AvnGradientStop { offset: self.offset, color: self.color.into() }
+ }
+
+ fn from_abi(value: sys::AvnGradientStop) -> Self {
+ Self { offset: value.offset, color: value.color.into() }
+ }
+}
+
+/// Packs up to the ABI's fixed capacity of stops into an `AvnGradientStopBuffer`.
+/// Fails if `stops` carries more entries than the buffer can hold.
+fn gradient_stops_to_abi(stops: &[GradientStop]) -> Result {
+ let mut buffer = sys::AvnGradientStopBuffer::default();
+ if stops.len() > buffer.stops.len() {
+ return Err(crate::Error::Abi(sys::Error(sys::E_INVALIDARG)));
+ }
+ for (slot, stop) in buffer.stops.iter_mut().zip(stops) {
+ *slot = stop.to_abi();
+ }
+ Ok(buffer)
+}
+
+fn gradient_stops_from_abi(buffer: sys::AvnGradientStopBuffer, count: i32) -> Vec {
+ let count = usize::try_from(count).unwrap_or(0).min(buffer.stops.len());
+ buffer.stops[..count].iter().copied().map(GradientStop::from_abi).collect()
+}
+
+/// A linear gradient brush: colour stops interpolated along a line from
+/// `start_point` to `end_point`.
+#[derive(Clone, Debug, PartialEq)]
+pub struct LinearGradientBrush {
+ pub opacity: f64,
+ pub spread_method: SpreadMethod,
+ pub stops: Vec,
+ pub start_point: RelativePoint,
+ pub end_point: RelativePoint,
+}
+
+impl LinearGradientBrush {
+ /// A fully opaque linear gradient with `SpreadMethod::Pad`.
+ pub fn new(stops: Vec, start_point: RelativePoint, end_point: RelativePoint) -> Self {
+ Self {
+ opacity: 1.0,
+ spread_method: SpreadMethod::Pad,
+ stops,
+ start_point,
+ end_point,
+ }
+ }
+
+ pub(crate) fn to_raw(&self) -> Result> {
+ let buffer = gradient_stops_to_abi(&self.stops)?;
+ let stop_count = i32::try_from(self.stops.len()).unwrap_or(i32::MAX);
+ with_factory(|factory| {
+ factory.create_linear_gradient_brush(
+ self.opacity,
+ self.spread_method as i32,
+ stop_count,
+ buffer,
+ self.start_point.to_abi(),
+ self.end_point.to_abi(),
+ )
+ })
+ }
+
+ pub(crate) fn from_raw(raw: &sys::ComPtr) -> Result {
+ let count = raw.stop_count()?;
+ Ok(Self {
+ opacity: raw.opacity()?,
+ spread_method: SpreadMethod::try_from(raw.spread_method()?)?,
+ stops: gradient_stops_from_abi(raw.stops()?, count),
+ start_point: RelativePoint::from_abi(raw.start_point()?)?,
+ end_point: RelativePoint::from_abi(raw.end_point()?)?,
+ })
+ }
+}
+
+/// A radial gradient brush: colour stops interpolated outward from
+/// `gradient_origin` through an ellipse centred at `center` with radii
+/// `radius_x`/`radius_y`.
+#[derive(Clone, Debug, PartialEq)]
+pub struct RadialGradientBrush {
+ pub opacity: f64,
+ pub spread_method: SpreadMethod,
+ pub stops: Vec,
+ pub center: RelativePoint,
+ pub gradient_origin: RelativePoint,
+ pub radius_x: RelativeScalar,
+ pub radius_y: RelativeScalar,
+}
+
+impl RadialGradientBrush {
+ /// A fully opaque radial gradient with `SpreadMethod::Pad`.
+ pub fn new(
+ stops: Vec,
+ center: RelativePoint,
+ gradient_origin: RelativePoint,
+ radius_x: RelativeScalar,
+ radius_y: RelativeScalar,
+ ) -> Self {
+ Self {
+ opacity: 1.0,
+ spread_method: SpreadMethod::Pad,
+ stops,
+ center,
+ gradient_origin,
+ radius_x,
+ radius_y,
+ }
+ }
+
+ pub(crate) fn to_raw(&self) -> Result> {
+ let buffer = gradient_stops_to_abi(&self.stops)?;
+ let stop_count = i32::try_from(self.stops.len()).unwrap_or(i32::MAX);
+ with_factory(|factory| {
+ factory.create_radial_gradient_brush(
+ self.opacity,
+ self.spread_method as i32,
+ stop_count,
+ buffer,
+ self.center.to_abi(),
+ self.gradient_origin.to_abi(),
+ self.radius_x.to_abi(),
+ self.radius_y.to_abi(),
+ )
+ })
+ }
+
+ pub(crate) fn from_raw(raw: &sys::ComPtr) -> Result {
+ let count = raw.stop_count()?;
+ Ok(Self {
+ opacity: raw.opacity()?,
+ spread_method: SpreadMethod::try_from(raw.spread_method()?)?,
+ stops: gradient_stops_from_abi(raw.stops()?, count),
+ center: RelativePoint::from_abi(raw.center()?)?,
+ gradient_origin: RelativePoint::from_abi(raw.gradient_origin()?)?,
+ radius_x: RelativeScalar::from_abi(raw.radius_x()?)?,
+ radius_y: RelativeScalar::from_abi(raw.radius_y()?)?,
+ })
+ }
+}
+
+/// Any brush shape that can be assigned to a `Brush`-typed control property: a
+/// solid colour, or one of the two projected gradient shapes.
+#[derive(Clone, Debug, PartialEq)]
+pub enum Paint {
+ Solid(Brush),
+ LinearGradient(LinearGradientBrush),
+ RadialGradient(RadialGradientBrush),
+}
+
+impl Paint {
+ pub(crate) fn to_raw(&self) -> Result> {
+ match self {
+ Self::Solid(brush) => brush.to_raw(),
+ Self::LinearGradient(brush) => Ok(brush.to_raw()?.query_interface()?),
+ Self::RadialGradient(brush) => Ok(brush.to_raw()?.query_interface()?),
+ }
+ }
+
+ pub(crate) fn from_raw(raw: &sys::ComPtr) -> Result {
+ match raw.color() {
+ Ok(color) => Ok(Self::Solid(Brush::new(color.into(), raw.opacity()?))),
+ Err(sys::Error(sys::AVN_E_NONSOLIDBRUSH)) => {
+ if let Ok(linear) = raw.query_interface::() {
+ return Ok(Self::LinearGradient(LinearGradientBrush::from_raw(&linear)?));
+ }
+ if let Ok(radial) = raw.query_interface::() {
+ return Ok(Self::RadialGradient(RadialGradientBrush::from_raw(&radial)?));
+ }
+ Err(crate::Error::Abi(sys::Error(sys::AVN_E_NONSOLIDBRUSH)))
+ }
+ Err(error) => Err(error.into()),
+ }
+ }
+}
+
+impl From for Paint {
+ fn from(brush: Brush) -> Self {
+ Self::Solid(brush)
+ }
+}
+
+impl From for Paint {
+ fn from(color: Color) -> Self {
+ Self::Solid(Brush::solid(color))
+ }
+}
+
+impl From for Paint {
+ fn from(brush: LinearGradientBrush) -> Self {
+ Self::LinearGradient(brush)
+ }
+}
+
+impl From for Paint {
+ fn from(brush: RadialGradientBrush) -> Self {
+ Self::RadialGradient(brush)
+ }
+}
+
#[repr(i32)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AutoCompleteFilterMode {
diff --git a/rust/avalonia/tests/gradient_brush_round_trip.rs b/rust/avalonia/tests/gradient_brush_round_trip.rs
new file mode 100644
index 0000000..ae4d936
--- /dev/null
+++ b/rust/avalonia/tests/gradient_brush_round_trip.rs
@@ -0,0 +1,91 @@
+//! The safe gradient brush types (`LinearGradientBrush`, `RadialGradientBrush`, `Paint`) and
+//! their supporting value types (`GradientStop`, `SpreadMethod`, `RelativeUnit`,
+//! `RelativePoint`, `RelativeScalar`).
+//!
+//! Like `Brush`, these are plain values in Rust; minting one across the ABI needs a live
+//! host factory (`IAvnControlFactory::CreateLinearGradientBrush` /
+//! `CreateRadialGradientBrush`). Neither shape is wired to a `Background`/`BorderBrush`/
+//! `Foreground` control property in this wave, so there is no public route to a real ABI
+//! round trip from outside the crate; these tests cover the value semantics that the ABI
+//! marshalling (`to_abi`/`from_abi`) builds on.
+
+use avalonia::{Color, GradientStop, LinearGradientBrush, Paint, RadialGradientBrush};
+use avalonia::{RelativePoint, RelativeScalar, RelativeUnit, SpreadMethod};
+
+#[test]
+fn new_linear_gradient_is_fully_opaque_with_pad_spread() {
+ let stops = vec![
+ GradientStop::new(0.0, Color::rgb(0xFF, 0x00, 0x00)),
+ GradientStop::new(1.0, Color::rgb(0x00, 0x00, 0xFF)),
+ ];
+ let start = RelativePoint::new(0.0, 0.0, RelativeUnit::Relative);
+ let end = RelativePoint::new(1.0, 1.0, RelativeUnit::Relative);
+
+ let brush = LinearGradientBrush::new(stops.clone(), start, end);
+
+ assert_eq!(brush.opacity, 1.0);
+ assert_eq!(brush.spread_method, SpreadMethod::Pad);
+ assert_eq!(brush.stops, stops);
+ assert_eq!(brush.start_point, start);
+ assert_eq!(brush.end_point, end);
+}
+
+#[test]
+fn new_radial_gradient_is_fully_opaque_with_pad_spread() {
+ let stops = vec![GradientStop::new(0.5, Color::rgb(0x10, 0x20, 0x30))];
+ let center = RelativePoint::new(0.5, 0.5, RelativeUnit::Relative);
+ let origin = RelativePoint::new(0.5, 0.5, RelativeUnit::Relative);
+ let radius_x = RelativeScalar::new(0.5, RelativeUnit::Relative);
+ let radius_y = RelativeScalar::new(0.5, RelativeUnit::Relative);
+
+ let brush = RadialGradientBrush::new(stops.clone(), center, origin, radius_x, radius_y);
+
+ assert_eq!(brush.opacity, 1.0);
+ assert_eq!(brush.spread_method, SpreadMethod::Pad);
+ assert_eq!(brush.stops, stops);
+ assert_eq!(brush.center, center);
+ assert_eq!(brush.gradient_origin, origin);
+ assert_eq!(brush.radius_x, radius_x);
+ assert_eq!(brush.radius_y, radius_y);
+}
+
+#[test]
+fn spread_method_round_trips_through_its_abi_ordinal() {
+ assert_eq!(SpreadMethod::try_from(0).unwrap(), SpreadMethod::Pad);
+ assert_eq!(SpreadMethod::try_from(1).unwrap(), SpreadMethod::Reflect);
+ assert_eq!(SpreadMethod::try_from(2).unwrap(), SpreadMethod::Repeat);
+ assert!(SpreadMethod::try_from(3).is_err());
+}
+
+#[test]
+fn relative_unit_round_trips_through_its_abi_ordinal() {
+ assert_eq!(RelativeUnit::try_from(0).unwrap(), RelativeUnit::Relative);
+ assert_eq!(RelativeUnit::try_from(1).unwrap(), RelativeUnit::Absolute);
+ assert!(RelativeUnit::try_from(2).is_err());
+}
+
+#[test]
+fn a_colour_converts_into_a_solid_paint() {
+ let paint: Paint = Color::rgb(0x10, 0x20, 0x30).into();
+
+ assert_eq!(paint, Paint::Solid(Color::rgb(0x10, 0x20, 0x30).into()));
+}
+
+#[test]
+fn a_gradient_brush_converts_into_the_matching_paint_variant() {
+ let linear = LinearGradientBrush::new(
+ vec![GradientStop::new(0.0, Color::rgb(0xFF, 0xFF, 0xFF))],
+ RelativePoint::new(0.0, 0.0, RelativeUnit::Relative),
+ RelativePoint::new(1.0, 0.0, RelativeUnit::Relative),
+ );
+ let radial = RadialGradientBrush::new(
+ vec![GradientStop::new(0.0, Color::rgb(0x00, 0x00, 0x00))],
+ RelativePoint::new(0.5, 0.5, RelativeUnit::Relative),
+ RelativePoint::new(0.5, 0.5, RelativeUnit::Relative),
+ RelativeScalar::new(0.5, RelativeUnit::Relative),
+ RelativeScalar::new(0.5, RelativeUnit::Relative),
+ );
+
+ assert_eq!(Paint::from(linear.clone()), Paint::LinearGradient(linear));
+ assert_eq!(Paint::from(radial.clone()), Paint::RadialGradient(radial));
+}
diff --git a/rust/projection.ir.json b/rust/projection.ir.json
index b4dc214..6d6227c 100644
--- a/rust/projection.ir.json
+++ b/rust/projection.ir.json
@@ -1,11 +1,17 @@
{
- "version": 16,
+ "version": 17,
"sourceAssembly": "Avalonia.Base,Avalonia.Controls",
- "factoryIid": "15778134-9E9F-5BAF-98FF-5510778094BA",
- "factoryAbiVersion": 13,
+ "factoryIid": "C8BCE8E8-62C7-5E0E-8066-690059F55DFF",
+ "factoryAbiVersion": 14,
"brushInterfaceName": "Avalonia.Host.Com.IAvnBrush",
"brushInterfaceIid": "FC7CCBAE-ED75-5C6D-8516-DF706E137ED3",
"brushAbiVersion": 1,
+ "gradientBrushInterfaceName": "Avalonia.Host.Com.IAvnGradientBrush",
+ "gradientBrushInterfaceIid": "FDAA2353-BC44-5012-A5BE-A17C7C01F41A",
+ "linearGradientBrushInterfaceName": "Avalonia.Host.Com.IAvnLinearGradientBrush",
+ "linearGradientBrushInterfaceIid": "40B3D53D-330E-5D63-A040-37F1FF717FF8",
+ "radialGradientBrushInterfaceName": "Avalonia.Host.Com.IAvnRadialGradientBrush",
+ "radialGradientBrushInterfaceIid": "AEC23FCE-9FEA-506C-ABC4-774143BE80C8",
"commandInterfaceName": "Avalonia.Host.Com.IAvnCommand",
"commandInterfaceIid": "E6F7AAF7-D5E7-503F-9BE6-5AF8DB5B5273",
"commandAbiVersion": 2,
diff --git a/rust/release-manifest.json b/rust/release-manifest.json
index cdfe70e..e82a5f3 100644
--- a/rust/release-manifest.json
+++ b/rust/release-manifest.json
@@ -10,7 +10,7 @@
}
],
"schemas": {
- "projectionIr": 16,
+ "projectionIr": 17,
"viewModelIr": 5,
"abiBaseline": 3,
"consumerAppManifest": 1
diff --git a/tests/Avalonia.Projection.Ir.Tests/ClrTypeExtractorTests.cs b/tests/Avalonia.Projection.Ir.Tests/ClrTypeExtractorTests.cs
index dea6ce0..8b3548d 100644
--- a/tests/Avalonia.Projection.Ir.Tests/ClrTypeExtractorTests.cs
+++ b/tests/Avalonia.Projection.Ir.Tests/ClrTypeExtractorTests.cs
@@ -348,9 +348,9 @@ public void Chrome_members_keep_the_abi_version_of_the_interfaces_they_widened()
// The factory grew a creator per wave A control plus GetToolTipStatics, then one per
// constructible wave B type, then one per constructible wave C type, so it has moved
// three times off the version 2 IID it published for CreateSolidColorBrush.
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
Assert.Equal(
- ClrTypeExtractor.CreateDeterministicIid("Avalonia.Host.Com.IAvnControlFactory", 13),
+ ClrTypeExtractor.CreateDeterministicIid("Avalonia.Host.Com.IAvnControlFactory", 14),
ir.FactoryIid);
}
@@ -1275,7 +1275,7 @@ public void Wave_c_layout_panels_publish_new_interfaces_at_version_one()
property => property.Name is "Above" or "Below" or "LeftOf" or "RightOf"
or "AlignLeftWith" or "Order" or "Grow" or "Shrink" or "Basis");
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1336,7 +1336,7 @@ public void Wave_d_button_family_publishes_new_interfaces_at_version_one()
Assert.Equal(MarshallingKind.ComCollection, items.Kind);
Assert.Equal("Avalonia.Host.Com.IAvnItemList", items.InterfaceName);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1381,7 +1381,7 @@ public void Wave_e_input_controls_publish_new_interfaces_at_version_one()
Assert.True(selectedText.CanRead);
Assert.False(selectedText.CanWrite);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1420,7 +1420,7 @@ public void Wave_f_calendar_family_publishes_new_interfaces_at_version_one()
Assert.Equal("Avalonia.Host.Com.AvnDateList", selectedDates.HostImplementationTypeName);
Assert.False(selectedDates.CanWrite);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1449,7 +1449,7 @@ public void Wave_g_content_chrome_publishes_new_interfaces_at_version_one()
Type(ir, "IAvnLayoutTransformControl").Properties,
p => p.Name == "LayoutTransform");
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1491,7 +1491,7 @@ public void Wave_h_shapes_publish_new_interfaces_at_version_one()
Assert.Equal(MarshallingKind.StringUtf16, polygonPoints.Kind);
Assert.Equal("Avalonia.Host.Com.AvnPointList", polygonPoints.StringConverterTypeName);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1517,7 +1517,7 @@ public void Wave_i_overlay_publishes_new_interfaces_at_version_one()
MarshallingKind.Command,
Type(ir, "IAvnTrayIcon").Properties.Single(p => p.Name == "Command").Kind);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1541,7 +1541,7 @@ public void Wave_j_command_bar_publishes_new_interfaces_at_version_one()
var buttonIcon = Type(ir, "IAvnCommandBarButton").Properties.Single(p => p.Name == "Icon");
Assert.Equal(MarshallingKind.Variant, buttonIcon.Kind);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1572,7 +1572,7 @@ public void Wave_k_icons_and_table_view_publish_new_interfaces_at_version_one()
var width = Type(ir, "IAvnTableViewColumn").Properties.Single(p => p.Name == "Width");
Assert.Equal(MarshallingKind.StringUtf16, width.Kind);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1635,7 +1635,7 @@ public void Wave_m_fonts_bump_templated_control_and_text_block()
var trimming = textBlock.Properties.Single(p => p.Name == "TextTrimming");
Assert.Equal(MarshallingKind.StringUtf16, trimming.Kind);
Assert.Equal("Avalonia.Host.Com.AvnTextTrimming", trimming.StringConverterTypeName);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1685,7 +1685,7 @@ public void Wave_r_numeric_up_down_value_changed_carries_the_decimal_pair_as_inv
valueChanged.Parameters.Select(parameter => parameter.Name));
Assert.Contains(Type(ir, "IAvnMaskedTextBox").Properties, p => p.Name == "MaskCompleted");
Assert.Equal(15, Type(ir, "IAvnTemplatedControl").AbiVersion);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1707,7 +1707,7 @@ public void Wave_o_combo_and_scroll_use_vector_and_size()
Assert.False(scroll.Properties.Single(p => p.Name == "Extent").CanWrite);
Assert.True(scroll.Properties.Single(p => p.Name == "Offset").CanWrite);
Assert.Equal(16, Type(ir, "IAvnContentControl").AbiVersion);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1731,7 +1731,7 @@ public void Wave_p_projects_instance_flyout_and_menu_item_open()
Assert.Contains(menu.Methods, m => m.Name == "Open");
Assert.Contains(menu.Methods, m => m.Name == "Close");
Assert.Equal(16, Type(ir, "IAvnContentControl").AbiVersion);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1746,7 +1746,7 @@ public void Wave_q_sweeps_leaf_input_scalars()
Assert.Contains(Type(ir, "IAvnCalendarDatePicker").Methods, m => m.Name == "Clear");
Assert.Equal(13, Type(ir, "IAvnNumericUpDown").AbiVersion);
Assert.Contains(Type(ir, "IAvnNumericUpDown").Properties, p => p.Name == "TextAlignment");
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1765,7 +1765,7 @@ public void Items_control_leftovers_keep_items_and_selection()
Assert.Contains(selecting.Properties, p => p.Name == "AutoScrollToSelectedItem");
Assert.Equal(16, Type(ir, "IAvnContentControl").AbiVersion);
Assert.Equal(21, Type(ir, "IAvnWindow").AbiVersion);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1791,7 +1791,7 @@ public void Text_leftovers_project_line_metrics_and_scroll_to_line()
Assert.Contains(lineCount.Parameters, p => p.Name == "value" && p.Direction == ParameterDirection.Out);
Assert.Equal(MarshallingKind.CharUtf16, textBox.Properties.Single(p => p.Name == "PasswordChar").Kind);
Assert.Equal(18, Type(ir, "IAvnMaskedTextBox").AbiVersion);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1812,7 +1812,7 @@ public void Leaf_leftovers_project_marshallable_scalars_and_commands()
Assert.Equal(15, Type(ir, "IAvnStackPanel").AbiVersion);
Assert.Equal(15, Type(ir, "IAvnBorder").AbiVersion);
Assert.Contains(Type(ir, "IAvnBorder").Properties, p => p.Name == "ClipToBoundsRadius");
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1845,7 +1845,7 @@ public void Overlay_chrome_projects_popup_open_close_and_placement_target()
Assert.Equal("Avalonia.Host.Com.IAvnControl", openWithControl.Parameters.Single().InterfaceName);
Assert.True(openWithControl.Parameters.Single().IsNullable);
Assert.Contains(Type(ir, "IAvnContextMenu").Events, e => e.Name == "Opening");
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]
@@ -1866,7 +1866,7 @@ public void Control_leftovers_project_context_menu_and_loaded()
Assert.Equal(6, Type(ir, "IAvnStyledElement").AbiVersion);
Assert.Equal(19, Type(ir, "IAvnButton").AbiVersion);
Assert.Equal(4, Type(ir, "IAvnFlyout").AbiVersion);
- Assert.Equal(13, ir.FactoryAbiVersion);
+ Assert.Equal(14, ir.FactoryAbiVersion);
}
[Fact]