1
0
Эх сурвалжийг харах

Merge branch 'master' into portablexaml

danwalmsley 8 жил өмнө
parent
commit
9234eb7909
52 өөрчлөгдсөн 461 нэмэгдсэн , 211 устгасан
  1. 1 2
      appveyor.yml
  2. 40 9
      build.cake
  3. 1 0
      build/SharpDX.props
  4. 0 1
      build/UnitTests.NetCore.targets
  5. 3 0
      packages.cake
  6. 0 1
      samples/BindingTest/BindingTest.csproj
  7. 0 1
      samples/ControlCatalog.Android/ControlCatalog.Android.csproj
  8. 0 1
      samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
  9. 0 1
      samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj
  10. 0 1
      samples/RenderTest/RenderTest.csproj
  11. 0 1
      samples/VirtualizationTest/VirtualizationTest.csproj
  12. 0 1
      samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
  13. 0 1
      samples/interop/GtkInteropDemo/GtkInteropDemo.csproj
  14. 1 1
      samples/interop/WindowsInteropTest/Program.cs
  15. 0 1
      samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
  16. 0 4
      src/Android/Avalonia.Android/Avalonia.Android.csproj
  17. 0 1
      src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj
  18. 7 2
      src/Avalonia.Controls/TextBox.cs
  19. 17 13
      src/Avalonia.Controls/ToolTip.cs
  20. 0 1
      src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj
  21. 0 1
      src/Gtk/Avalonia.Cairo/Avalonia.Cairo.csproj
  22. 0 1
      src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj
  23. BIN
      src/Shared/Microsoft.NuGet.Build.Tasks.Patched.dll
  24. 0 67
      src/Shared/nuget.workaround.targets
  25. 0 1
      src/Skia/Avalonia.Skia.Android/Avalonia.Skia.Android.csproj
  26. 0 1
      src/Skia/Avalonia.Skia.Desktop/Avalonia.Skia.Desktop.csproj
  27. 3 1
      src/Skia/Avalonia.Skia.iOS/Avalonia.Skia.iOS.csproj
  28. 3 9
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  29. 50 51
      src/Skia/Avalonia.Skia/FormattedTextImpl.cs
  30. 0 1
      src/Windows/Avalonia.Designer/Avalonia.Designer.csproj
  31. 0 1
      src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj
  32. 4 7
      src/Windows/Avalonia.Direct2D1/ExternalRenderTarget.cs
  33. 2 1
      src/Windows/Avalonia.Direct2D1/IExternalDirect2DRenderTargetSurface.cs
  34. 10 0
      src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj
  35. 208 0
      src/Windows/Avalonia.Win32.Interop/Wpf/Direct2DImageSurface.cs
  36. 59 0
      src/Windows/Avalonia.Win32.Interop/Wpf/IntSize.cs
  37. 19 2
      src/Windows/Avalonia.Win32.Interop/Wpf/WpfAvaloniaHost.cs
  38. 15 3
      src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs
  39. 1 9
      src/Windows/Avalonia.Win32.Interop/Wpf/WritableBitmapSurface.cs
  40. 0 1
      src/Windows/Avalonia.Win32/Avalonia.Win32.csproj
  41. 3 1
      src/iOS/Avalonia.iOS/Avalonia.iOS.csproj
  42. 0 1
      src/iOS/Avalonia.iOSTestApplication/Avalonia.iOSTestApplication.csproj
  43. 0 1
      tests/Avalonia.Benchmarks/Avalonia.Benchmarks.csproj
  44. 0 1
      tests/Avalonia.DesignerSupport.TestApp/Avalonia.DesignerSupport.TestApp.csproj
  45. 0 1
      tests/Avalonia.DesignerSupport.Tests/Avalonia.DesignerSupport.Tests.csproj
  46. 0 1
      tests/Avalonia.Direct2D1.UnitTests/Avalonia.Direct2D1.UnitTests.csproj
  47. 0 1
      tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj
  48. 11 0
      tests/Avalonia.LeakTests/toolproject/tool.csproj
  49. 0 1
      tests/Avalonia.RenderTests/Avalonia.Cairo.RenderTests.csproj
  50. 0 1
      tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.csproj
  51. 0 1
      tests/Avalonia.RenderTests/Avalonia.Skia.RenderTests.csproj
  52. 3 1
      tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj

+ 1 - 2
appveyor.yml

@@ -14,7 +14,7 @@ environment:
     secure: OtVfyN3ErqQrDTnWH2HDfJDlCiu/i4/X4wFmK3ZXXP7HmCiXYPSbTjMPwwdOxRaK
   MYGET_API_URL: https://www.myget.org/F/avalonia-ci/api/v2/package
 init:
-- ps: (New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/appveyor/ci/master/scripts/xamarin-vs2017-151-fixed.targets', "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Microsoft.Common.Targets\ImportAfter\Xamarin.Common.targets")
+- ps: if (Test-Path env:nuget_address) {[System.IO.File]::AppendAllText("C:\Windows\System32\drivers\etc\hosts", "`n$($env:nuget_address)`tapi.nuget.org")}
 install:
   - if not exist gtk-sharp-2.12.26.msi appveyor DownloadFile http://download.xamarin.com/GTKforWindows/Windows/gtk-sharp-2.12.26.msi
   - if not exist dotnet-1.0.1.exe appveyor DownloadFile https://go.microsoft.com/fwlink/?linkid=843448 -FileName "dotnet-1.0.1.exe"
@@ -26,7 +26,6 @@ before_build:
 build_script:
 - ps: .\build.ps1 -Target "AppVeyor" -Platform "$env:platform" -Configuration "$env:configuration"
 after_build:
-- tools\JetBrains.dotMemoryUnit\tools\dotMemoryUnit.exe -targetExecutable="%xunit20%\xunit.console.x86.exe" -returnTargetExitCode  --"tests\Avalonia.LeakTests\bin\Release\Avalonia.LeakTests.dll"
 - "SET PATH=C:\\Python34;C:\\Python34\\Scripts;%PATH%"
 - pip install codecov
 - codecov -f "./artifacts/coverage.xml"

+ 40 - 9
build.cake

@@ -4,8 +4,8 @@
 
 #addin "nuget:?package=Polly&version=4.2.0"
 #addin "nuget:?package=NuGet.Core&version=2.12.0"
+#tool "nuget:?package=xunit.runner.console&version=2.2.0"
 #tool "nuget:https://dotnet.myget.org/F/nuget-build/?package=NuGet.CommandLine&version=4.3.0-preview1-3980&prerelease"
-#tool "nuget:?package=JetBrains.dotMemoryUnit&version=2.3.20160517.113140"
 #tool "JetBrains.ReSharper.CommandLineTools"
 ///////////////////////////////////////////////////////////////////////////////
 // TOOLS
@@ -119,7 +119,6 @@ Task("Restore-NuGet-Packages")
             }})
         .Execute(()=> {
                 NuGetRestore(parameters.MSBuildSolution, new NuGetRestoreSettings {
-                    ToolPath = "./tools/NuGet.CommandLine/tools/NuGet.exe",
                     ToolTimeout = TimeSpan.FromMinutes(toolTimeout)
                 });
         });
@@ -194,6 +193,7 @@ Task("Run-Net-Core-Unit-Tests")
 Task("Run-Unit-Tests")
     .IsDependentOn("Run-Net-Core-Unit-Tests")
     .IsDependentOn("Build")
+    .IsDependentOn("Run-Leak-Tests")
     .WithCriteria(() => !parameters.SkipTests)
     .Does(() =>
 {
@@ -206,13 +206,6 @@ Task("Run-Unit-Tests")
         .Select(name => MakeAbsolute(File("./tests/" + name + "/bin/" + parameters.DirSuffix + "/" + name + ".dll")))
         .ToList();
 
-    if (parameters.IsRunningOnWindows)
-    {
-        var leakTests = GetFiles("./tests/Avalonia.LeakTests/bin/" + parameters.DirSuffix + "/*.LeakTests.dll");
-
-        unitTests.AddRange(leakTests);
-    }
-
     var toolPath = (parameters.IsPlatformAnyCPU || parameters.IsPlatformX86) ? 
         "./tools/xunit.runner.console/tools/xunit.console.x86.exe" :
         "./tools/xunit.runner.console/tools/xunit.console.exe";
@@ -365,6 +358,44 @@ Task("Publish-NuGet")
     Information("Publish-NuGet Task failed, but continuing with next Task...");
 });
 
+Task("Run-Leak-Tests")
+    .WithCriteria(parameters.IsRunningOnWindows)
+    .IsDependentOn("Build")
+    .Does(() =>
+    {
+        DotNetCoreRestore("tests\\Avalonia.LeakTests\\toolproject\\tool.csproj");
+        DotNetBuild("tests\\Avalonia.LeakTests\\toolproject\\tool.csproj", settings => settings.SetConfiguration("Release"));
+        var report = "tests\\Avalonia.LeakTests\\bin\\Release\\report.xml";
+        if(System.IO.File.Exists(report))
+            System.IO.File.Delete(report);
+        var proc = System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
+        {
+            FileName="tests\\Avalonia.LeakTests\\toolproject\\bin\\dotMemoryUnit.exe",
+            Arguments="-targetExecutable=\"tools\\xunit.runner.console\\tools\\xunit.console.x86.exe\" -returnTargetExitCode  -- tests\\Avalonia.LeakTests\\bin\\Release\\Avalonia.LeakTests.dll -xml tests\\Avalonia.LeakTests\\bin\\Release\\report.xml ",
+            UseShellExecute = false,
+        });
+        var st = System.Diagnostics.Stopwatch.StartNew();
+        while(!proc.HasExited && !System.IO.File.Exists(report))
+        {
+            if(st.Elapsed.TotalSeconds>60)
+            {
+                Error("Timed out, probably a bug in dotMemoryUnit");
+                proc.Kill();
+                throw new Exception("dotMemory issue");
+            }
+            proc.WaitForExit(100);
+        }
+        try{
+            proc.Kill();
+        }catch{}
+        var doc =  System.Xml.Linq.XDocument.Load(report);
+        if(doc.Root.Descendants("assembly").Any(x=>x.Attribute("failed").Value.ToString() != "0"))
+        {
+            throw new Exception("Tests failed");
+        }
+
+    });
+
 Task("Inspect")
     .WithCriteria(parameters.IsRunningOnWindows)
     .IsDependentOn("Restore-NuGet-Packages")

+ 1 - 0
build/SharpDX.props

@@ -3,6 +3,7 @@
     <PackageReference Include="SharpDX" Version="3.1.1" />
     <PackageReference Include="SharpDX.Direct2D1" Version="3.1.1" />
     <PackageReference Include="SharpDX.Direct3D11" Version="3.1.1" />
+    <PackageReference Include="SharpDX.Direct3D9" Version="3.1.1" Condition="'$(UseDirect3D9)' == 'true'" />
     <PackageReference Include="SharpDX.DXGI" Version="3.1.1" />
   </ItemGroup>
 </Project>

+ 0 - 1
build/UnitTests.NetCore.targets

@@ -25,5 +25,4 @@
   <ItemGroup>
     <PackageReference Include="System.Threading.Thread" Version="4.3.0" />
   </ItemGroup>
-  <Import Condition="'$(TargetFramework)' == 'net461'" Project="$(MSBuildThisFileDirectory)..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 3 - 0
packages.cake

@@ -81,6 +81,7 @@ public class Packages
         var SharpDXVersion = packageVersions["SharpDX"].FirstOrDefault().Item1;
         var SharpDXDirect2D1Version = packageVersions["SharpDX.Direct2D1"].FirstOrDefault().Item1;
         var SharpDXDirect3D11Version = packageVersions["SharpDX.Direct3D11"].FirstOrDefault().Item1;
+        var SharpDXDirect3D9Version = packageVersions["SharpDX.Direct3D9"].FirstOrDefault().Item1;
         var SharpDXDXGIVersion = packageVersions["SharpDX.DXGI"].FirstOrDefault().Item1;
 
         context.Information("Package: Serilog, version: {0}", SerilogVersion);
@@ -93,6 +94,7 @@ public class Packages
         context.Information("Package: SharpDX, version: {0}", SharpDXVersion);
         context.Information("Package: SharpDX.Direct2D1, version: {0}", SharpDXDirect2D1Version);
         context.Information("Package: SharpDX.Direct3D11, version: {0}", SharpDXDirect3D11Version);
+        context.Information("Package: SharpDX.Direct3D9, version: {0}", SharpDXDirect3D9Version);
         context.Information("Package: SharpDX.DXGI, version: {0}", SharpDXDXGIVersion);
 
         var nugetPackagesDir = System.Environment.GetEnvironmentVariable("NUGET_HOME")
@@ -476,6 +478,7 @@ public class Packages
                 {
                     new NuSpecDependency() { Id = "Avalonia.Win32", Version = parameters.Version },
                     new NuSpecDependency() { Id = "Avalonia.Direct2D1", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "SharpDX.Direct3D9", Version = SharpDXDirect3D9Version },
                 },
                 Files = new []
                 {

+ 0 - 1
samples/BindingTest/BindingTest.csproj

@@ -174,5 +174,4 @@
   <Import Project="..\..\build\Serilog.Sinks.Trace.props" />
   <Import Project="..\..\build\Splat.props" />
   <Import Project="..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
samples/ControlCatalog.Android/ControlCatalog.Android.csproj

@@ -158,5 +158,4 @@
   </ItemGroup>
   <Import Project="..\..\build\Rx.props" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj

@@ -144,5 +144,4 @@
   <Import Project="..\..\build\Serilog.props" />
   <Import Project="..\..\build\SkiaSharp.props" />
   <Import Project="..\..\build\Serilog.Sinks.Trace.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj

@@ -181,5 +181,4 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
samples/RenderTest/RenderTest.csproj

@@ -183,5 +183,4 @@
   <Import Project="..\..\build\Serilog.Sinks.Trace.props" />
   <Import Project="..\..\build\Splat.props" />
   <Import Project="..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
samples/VirtualizationTest/VirtualizationTest.csproj

@@ -158,5 +158,4 @@
   <Import Project="..\..\build\Serilog.Sinks.Trace.props" />
   <Import Project="..\..\build\Splat.props" />
   <Import Project="..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj

@@ -31,5 +31,4 @@
     <Import Project="..\..\..\build\Serilog.Sinks.Trace.props" />
     <Import Project="..\..\..\build\Splat.props" />
     <Import Project="..\..\..\build\Rx.props" />
-    <Import Project="$(MSBuildThisFileDirectory)..\..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
samples/interop/GtkInteropDemo/GtkInteropDemo.csproj

@@ -151,5 +151,4 @@
   </ItemGroup>
   <Import Project="..\..\..\build\Rx.props" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 1 - 1
samples/interop/WindowsInteropTest/Program.cs

@@ -15,7 +15,7 @@ namespace WindowsInteropTest
         {
             System.Windows.Forms.Application.EnableVisualStyles();
             System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
-            AppBuilder.Configure<App>().UseWin32().UseSkia().SetupWithoutStarting();
+            AppBuilder.Configure<App>().UseWin32().UseDirect2D1().SetupWithoutStarting();
             System.Windows.Forms.Application.Run(new SelectorForm());
         }
     }

+ 0 - 1
samples/interop/WindowsInteropTest/WindowsInteropTest.csproj

@@ -186,5 +186,4 @@
   <Import Project="..\..\..\build\Rx.props" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\..\build\SkiaSharp.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 4
src/Android/Avalonia.Android/Avalonia.Android.csproj

@@ -133,8 +133,4 @@
   <Import Project="..\..\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
   <Import Project="..\..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
-  <PropertyGroup Condition="'$(UseRoslynPathHack)' == ''">
-    <CscToolPath>$(MSBuildToolsPath)\Roslyn</CscToolPath>
-  </PropertyGroup>
 </Project>

+ 0 - 1
src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj

@@ -157,5 +157,4 @@
   <Import Project="..\..\..\build\Splat.props" />
   <Import Project="..\..\..\build\Sprache.props" />
   <Import Project="..\..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

+ 7 - 2
src/Avalonia.Controls/TextBox.cs

@@ -236,6 +236,11 @@ namespace Avalonia.Controls
         {
             _presenter = e.NameScope.Get<TextPresenter>("PART_TextPresenter");
             _presenter.Cursor = new Cursor(StandardCursorType.Ibeam);
+
+            if(IsFocused)
+            {
+                _presenter.ShowCaret();
+            }
         }
 
         protected override void OnGotFocus(GotFocusEventArgs e)
@@ -254,7 +259,7 @@ namespace Avalonia.Controls
             }
             else
             {
-                _presenter.ShowCaret();
+                _presenter?.ShowCaret();
             }
         }
 
@@ -263,7 +268,7 @@ namespace Avalonia.Controls
             base.OnLostFocus(e);
             SelectionStart = 0;
             SelectionEnd = 0;
-            _presenter.HideCaret();
+            _presenter?.HideCaret();
         }
 
         protected override void OnTextInput(TextInputEventArgs e)

+ 17 - 13
src/Avalonia.Controls/ToolTip.cs

@@ -106,24 +106,28 @@ namespace Avalonia.Controls
             if (control != null && control.IsVisible && control.GetVisualRoot() != null)
             {
                 var cp = (control.GetVisualRoot() as IInputRoot)?.MouseDevice?.GetPosition(control);
-                var position = control.PointToScreen(cp ?? new Point(0, 0)) + new Vector(0, 22);
 
-                if (s_popup == null)
+                if (cp.HasValue && control.IsVisible && new Rect(control.Bounds.Size).Contains(cp.Value))
                 {
-                    s_popup = new PopupRoot();
-                    s_popup.Content = new ToolTip();
-                }
-                else
-                {
-                    ((ISetLogicalParent)s_popup).SetParent(null);
-                }
+                    var position = control.PointToScreen(cp.Value) + new Vector(0, 22);
+
+                    if (s_popup == null)
+                    {
+                        s_popup = new PopupRoot();
+                        s_popup.Content = new ToolTip();
+                    }
+                    else
+                    {
+                        ((ISetLogicalParent)s_popup).SetParent(null);
+                    }
 
                 ((ISetLogicalParent)s_popup).SetParent(control);
-                ((ToolTip)s_popup.Content).Content = GetTip(control);
-                s_popup.Position = position;
-                s_popup.Show();
+                    ((ToolTip)s_popup.Content).Content = GetTip(control);
+                    s_popup.Position = position;
+                    s_popup.Show();
 
-                s_current = control;
+                    s_current = control;
+                }
             }
         }
 

+ 0 - 1
src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj

@@ -69,5 +69,4 @@
   <Import Project="..\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
src/Gtk/Avalonia.Cairo/Avalonia.Cairo.csproj

@@ -103,5 +103,4 @@
   <Import Project="..\..\Shared\RenderHelpers\RenderHelpers.projitems" Label="Shared" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj

@@ -98,5 +98,4 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="..\..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

BIN
src/Shared/Microsoft.NuGet.Build.Tasks.Patched.dll


+ 0 - 67
src/Shared/nuget.workaround.targets

@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 
-  This file is for a workaround for this NuGet issue https://github.com/NuGet/Home/issues/4532
-  It is built from the master branch of NuGet.BuildTasks with a different class name as not to conflict with the original.
-  It can most likely be removed when the next version of NuGet.BuildTasks is released: https://github.com/NuGet/NuGet.BuildTasks/pull/29
--->
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-   <UsingTask TaskName="Microsoft.NuGet.Build.Tasks.ResolveNuGetPackageAssetsPatched" AssemblyFile="Microsoft.NuGet.Build.Tasks.Patched.dll" />
-
-  <Target Name="ResolveNuGetPackageAssets"
-          DependsOnTargets="$(ResolveNuGetPackageAssetsDependsOn)"
-          Condition="'$(ResolveNuGetPackages)' == 'true' and exists('$(ProjectLockFile)')">
-
-    <ResolveNuGetPackageAssetsPatched AllowFallbackOnTargetSelection="$(DesignTimeBuild)"
-                               ContinueOnError="$(ContinueOnError)"
-                               IncludeFrameworkReferences="$(IncludeFrameworkReferencesFromNuGet)"
-                               NuGetPackagesDirectory="$(NuGetPackagesDirectory)"
-                               RuntimeIdentifier="$(NuGetRuntimeIdentifier)"
-                               ProjectLanguage="$(Language)"
-                               ProjectLockFile="$(ProjectLockFile)"
-                               ContentPreprocessorValues="@(NuGetPreprocessorValue)"
-                               ContentPreprocessorOutputDirectory="$(IntermediateOutputPath)\NuGet"
-                               TargetMonikers="$(NuGetTargetMoniker);$(_NuGetTargetFallbackMoniker)">
-
-      <Output TaskParameter="ResolvedAnalyzers" ItemName="Analyzer" />
-      <Output TaskParameter="ResolvedCopyLocalItems" ItemName="ReferenceCopyLocalPaths" />
-      <Output TaskParameter="ResolvedReferences" ItemName="_ReferencesFromNuGetPackages" />
-      <Output TaskParameter="ReferencedPackages" ItemName="ReferencedNuGetPackages" />
-      <Output TaskParameter="ContentItems" ItemName="_NuGetContentItems" />
-      <Output TaskParameter="FileWrites" ItemName="FileWrites" />
-    </ResolveNuGetPackageAssetsPatched>
-
-    <ItemGroup>
-      <!-- Remove exact references, such as if a package had a framework reference to 'System' that we already have -->
-      <Reference Remove="@(_ReferencesFromNuGetPackages)" />
-      
-      <!-- Remove simple name references that are already implicitly added -->
-      <_ReferencesFromNuGetPackages Remove="%(ReferencePath.FileName)" Condition="'%(ReferencePath.ResolvedFrom)' == 'ImplicitlyExpandTargetFramework'" />
-
-      <!-- Include NuGet references in the proper groups. Project-to-project references must go in the
-           _ResolvedProjectReferencePaths group which matches the behavior of the ResolveProjectReferences
-           target. This ensures that even if the assembly is missing on disk, it still makes it to the compiler. -->
-      <Reference Include="@(_ReferencesFromNuGetPackages)" Condition="'%(_ReferencesFromNuGetPackages.NuGetSourceType)' != 'Project'" />
-      <_ResolvedProjectReferencePaths Include="@(_ReferencesFromNuGetPackages)" Condition="'%(_ReferencesFromNuGetPackages.NuGetSourceType)' == 'Project'" />
-
-    <Reference Include="@(_ReferencesFromNuGetPackages)" />
-      <!-- Remove simple name references if we're directly providing a reference assembly to the compiler. For example,
-           consider a project with an Reference Include="System", and some NuGet package is providing System.dll -->
-      <Reference Remove="%(_ReferencesFromNuGetPackages.FileName)" Condition="'%(_ReferencesFromNuGetPackages.NuGetIsFrameworkReference)' == 'false'"/>
-    </ItemGroup>
-
-    <PropertyGroup Condition=" '$(AutoUnifyAssemblyReferences)' == 'true' ">
-      <!-- Normally Design Time Assembly Resolution (DTAR) won't consider these references.
-           Put DTAR in a mode where it will prefer the output of RAR and unify. -->
-      <DTARUseReferencesFromProject>true</DTARUseReferencesFromProject>
-    </PropertyGroup>
-
-    <!-- The items in _NuGetContentItems need to go into the appropriately-named item group, but the names depend upon the items
-         themselves. Split it apart. -->
-    <CreateItem Include="@(_NuGetContentItems)" Condition="'@(_NuGetContentItems)' != ''">
-      <Output TaskParameter="Include" ItemName="%(_NuGetContentItems.NuGetItemType)" />
-    </CreateItem>
-  </Target>
-  <PropertyGroup Condition="'$(UseRoslynPathHack)' == 'true'">
-    <CscToolPath>$(MSBuildToolsPath)\..\Roslyn</CscToolPath>
-  </PropertyGroup>
-</Project>

+ 0 - 1
src/Skia/Avalonia.Skia.Android/Avalonia.Skia.Android.csproj

@@ -86,5 +86,4 @@
   <Import Project="..\..\Shared\RenderHelpers\RenderHelpers.projitems" Label="Shared" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
   <Import Project="..\..\..\build\SkiaSharp.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
src/Skia/Avalonia.Skia.Desktop/Avalonia.Skia.Desktop.csproj

@@ -109,5 +109,4 @@
   <Import Project="..\..\Shared\RenderHelpers\RenderHelpers.projitems" Label="Shared" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\..\build\SkiaSharp.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

+ 3 - 1
src/Skia/Avalonia.Skia.iOS/Avalonia.Skia.iOS.csproj

@@ -88,5 +88,7 @@
   <Import Project="..\..\Shared\RenderHelpers\RenderHelpers.projitems" Label="Shared" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
   <Import Project="..\..\..\build\SkiaSharp.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
+  <PropertyGroup Condition="'$(UseRoslynPathHack)' == 'true'">
+    <CscToolPath>$(MSBuildToolsPath)\..\Roslyn</CscToolPath>
+  </PropertyGroup>
 </Project>

+ 3 - 9
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@@ -141,23 +141,17 @@ namespace Avalonia.Skia
             var rv = new PaintWrapper(paint);
             paint.IsStroke = false;
 
-            // TODO: SkiaSharp does not contain alpha yet!
+            
             double opacity = brush.Opacity * _currentOpacity;
-            //paint.SetAlpha(paint.GetAlpha() * opacity);
             paint.IsAntialias = true;
 
-            SKColor color = new SKColor(255, 255, 255, 255);
-
             var solid = brush as ISolidColorBrush;
-            if (solid != null)
-                color = solid.Color.ToSKColor();
-
-            paint.Color = (new SKColor(color.Red, color.Green, color.Blue, (byte)(color.Alpha * opacity)));
-
             if (solid != null)
             {
+                paint.Color = new SKColor(solid.Color.R, solid.Color.G, solid.Color.B, (byte) (solid.Color.A * opacity));
                 return rv;
             }
+            paint.Color = (new SKColor(255, 255, 255, (byte)(255 * opacity)));
 
             var gradient = brush as IGradientBrush;
             if (gradient != null)

+ 50 - 51
src/Skia/Avalonia.Skia/FormattedTextImpl.cs

@@ -42,7 +42,6 @@ namespace Avalonia.Skia
             _paint.Typeface = skiaTypeface;
             _paint.TextSize = (float)(typeface?.FontSize ?? 12);
             _paint.TextAlign = textAlignment.ToSKTextAlign();
-            _paint.BlendMode = SKBlendMode.Src;
 
             _wrapping = wrapping;
             _constraint = constraint;
@@ -200,66 +199,65 @@ namespace Avalonia.Skia
                 }
                 ctx->Canvas->restore();
             */
-            SKPaint paint = _paint;
-            IDisposable currd = null;
-            var currentWrapper = foreground;
-
-            try
+            using (var paint = _paint.Clone())
             {
-                SKPaint currFGPaint = ApplyWrapperTo(ref foreground, ref currd, paint);
-                bool hasCusomFGBrushes = _foregroundBrushes.Any();
-
-                for (int c = 0; c < _skiaLines.Count; c++)
+                IDisposable currd = null;
+                var currentWrapper = foreground;
+                SKPaint currentPaint = null;
+                try
                 {
-                    AvaloniaFormattedTextLine line = _skiaLines[c];
-
-                    float x = TransformX(origin.X, 0, paint.TextAlign);
+                    ApplyWrapperTo(ref currentPaint, foreground, ref currd, paint);
+                    bool hasCusomFGBrushes = _foregroundBrushes.Any();
 
-                    if (!hasCusomFGBrushes)
-                    {
-                        var subString = Text.Substring(line.Start, line.Length);
-                        canvas.DrawText(subString, x, origin.Y + line.Top + _lineOffset, paint);
-                    }
-                    else
+                    for (int c = 0; c < _skiaLines.Count; c++)
                     {
-                        float currX = x;
-                        string subStr;
-                        int len;
+                        AvaloniaFormattedTextLine line = _skiaLines[c];
 
-                        for (int i = line.Start; i < line.Start + line.Length;)
-                        {
-                            var fb = GetNextForegroundBrush(ref line, i, out len);
-
-                            if (fb != null)
-                            {
-                                //TODO: figure out how to get the brush size
-                                currentWrapper = context.CreatePaint(fb, new Size());
-                            }
-                            else
-                            {
-                                if (!currentWrapper.Equals(foreground)) currentWrapper.Dispose();
-                                currentWrapper = foreground;
-                            }
+                        float x = TransformX(origin.X, 0, paint.TextAlign);
 
-                            subStr = Text.Substring(i, len);
+                        if (!hasCusomFGBrushes)
+                        {
+                            var subString = Text.Substring(line.Start, line.Length);
+                            canvas.DrawText(subString, x, origin.Y + line.Top + _lineOffset, paint);
+                        }
+                        else
+                        {
+                            float currX = x;
+                            string subStr;
+                            int len;
 
-                            if (currFGPaint != currentWrapper.Paint)
+                            for (int i = line.Start; i < line.Start + line.Length;)
                             {
-                                currFGPaint = ApplyWrapperTo(ref currentWrapper, ref currd, paint);
+                                var fb = GetNextForegroundBrush(ref line, i, out len);
+
+                                if (fb != null)
+                                {
+                                    //TODO: figure out how to get the brush size
+                                    currentWrapper = context.CreatePaint(fb, new Size());
+                                }
+                                else
+                                {
+                                    if (!currentWrapper.Equals(foreground)) currentWrapper.Dispose();
+                                    currentWrapper = foreground;
+                                }
+
+                                subStr = Text.Substring(i, len);
+
+                                ApplyWrapperTo(ref currentPaint, currentWrapper, ref currd, paint);
+                                
+                                canvas.DrawText(subStr, currX, origin.Y + line.Top + _lineOffset, paint);
+
+                                i += len;
+                                currX += paint.MeasureText(subStr);
                             }
-
-                            canvas.DrawText(subStr, currX, origin.Y + line.Top + _lineOffset, paint);
-
-                            i += len;
-                            currX += paint.MeasureText(subStr);
                         }
                     }
                 }
-            }
-            finally
-            {
-                if (!currentWrapper.Equals(foreground)) currentWrapper.Dispose();
-                currd?.Dispose();
+                finally
+                {
+                    if (!currentWrapper.Equals(foreground)) currentWrapper.Dispose();
+                    currd?.Dispose();
+                }
             }
         }
 
@@ -278,12 +276,13 @@ namespace Avalonia.Skia
         private Size _size;
         private List<AvaloniaFormattedTextLine> _skiaLines;
 
-        private static SKPaint ApplyWrapperTo(ref DrawingContextImpl.PaintWrapper wrapper,
+        private static void ApplyWrapperTo(ref SKPaint current, DrawingContextImpl.PaintWrapper wrapper,
                                                 ref IDisposable curr, SKPaint paint)
         {
+            if (current == wrapper.Paint)
+                return;
             curr?.Dispose();
             curr = wrapper.ApplyTo(paint);
-            return wrapper.Paint;
         }
 
         private static bool IsBreakChar(char c)

+ 0 - 1
src/Windows/Avalonia.Designer/Avalonia.Designer.csproj

@@ -123,5 +123,4 @@
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\..\build\JetBrains.Annotations.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj

@@ -117,5 +117,4 @@
   <Import Project="..\..\Shared\RenderHelpers\RenderHelpers.projitems" Label="Shared" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\..\build\SharpDX.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

+ 4 - 7
src/Windows/Avalonia.Direct2D1/ExternalRenderTarget.cs

@@ -15,7 +15,6 @@ namespace Avalonia.Direct2D1
     {
         private readonly IExternalDirect2DRenderTargetSurface _externalRenderTargetProvider;
         private readonly DirectWriteFactory _dwFactory;
-        private SharpDX.Direct2D1.RenderTarget _target;
         public ExternalRenderTarget(IExternalDirect2DRenderTargetSurface externalRenderTargetProvider,
             DirectWriteFactory dwFactory)
         {
@@ -25,15 +24,14 @@ namespace Avalonia.Direct2D1
 
         public void Dispose()
         {
-            _target?.Dispose();
-            _target = null;
+            _externalRenderTargetProvider.DestroyRenderTarget();
         }
 
         public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
         {
-            _target = _target ?? _externalRenderTargetProvider.CreateRenderTarget();
+            var target =  _externalRenderTargetProvider.GetOrCreateRenderTarget();
             _externalRenderTargetProvider.BeforeDrawing();
-            return new DrawingContextImpl(visualBrushRenderer, _target, _dwFactory, null, () =>
+            return new DrawingContextImpl(visualBrushRenderer, target, _dwFactory, null, () =>
             {
                 try
                 {
@@ -41,8 +39,7 @@ namespace Avalonia.Direct2D1
                 }
                 catch (SharpDXException ex) when ((uint) ex.HResult == 0x8899000C) // D2DERR_RECREATE_TARGET
                 {
-                    _target?.Dispose();
-                    _target = null;
+                    _externalRenderTargetProvider.DestroyRenderTarget();
                 }
             });
         }

+ 2 - 1
src/Windows/Avalonia.Direct2D1/IExternalDirect2DRenderTargetSurface.cs

@@ -8,7 +8,8 @@ namespace Avalonia.Direct2D1
 {
     public interface IExternalDirect2DRenderTargetSurface
     {
-        SharpDX.Direct2D1.RenderTarget CreateRenderTarget();
+        SharpDX.Direct2D1.RenderTarget GetOrCreateRenderTarget();
+        void DestroyRenderTarget();
         void BeforeDrawing();
         void AfterDrawing();
     }

+ 10 - 0
src/Windows/Avalonia.Win32.Interop/Avalonia.Win32.Interop.csproj

@@ -49,6 +49,8 @@
     </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Wpf\CursorShim.cs" />
+    <Compile Include="Wpf\Direct2DImageSurface.cs" />
+    <Compile Include="Wpf\IntSize.cs" />
     <Compile Include="Wpf\WpfInteropExtensions.cs" />
     <Compile Include="Wpf\WpfAvaloniaHost.cs" />
     <Compile Include="Wpf\WpfMouseDevice.cs" />
@@ -104,10 +106,18 @@
       <Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
       <Name>Avalonia.Markup</Name>
     </ProjectReference>
+    <ProjectReference Include="..\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj">
+      <Project>{3e908f67-5543-4879-a1dc-08eace79b3cd}</Project>
+      <Name>Avalonia.Direct2D1</Name>
+    </ProjectReference>
     <ProjectReference Include="..\Avalonia.Win32\Avalonia.Win32.csproj">
       <Project>{811a76cf-1cf6-440f-963b-bbe31bd72a82}</Project>
       <Name>Avalonia.Win32</Name>
     </ProjectReference>
   </ItemGroup>
+  <PropertyGroup>
+    <UseDirect3D9>true</UseDirect3D9>
+  </PropertyGroup>
+  <Import Project="..\..\..\build\SharpDX.props" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>

+ 208 - 0
src/Windows/Avalonia.Win32.Interop/Wpf/Direct2DImageSurface.cs

@@ -0,0 +1,208 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Interop;
+using Avalonia.Direct2D1;
+using SharpDX;
+using SharpDX.Direct2D1;
+using SharpDX.Direct3D11;
+using SharpDX.Direct3D9;
+using SharpDX.DXGI;
+using AlphaMode = SharpDX.Direct2D1.AlphaMode;
+using Device = SharpDX.Direct3D11.Device;
+using Format = SharpDX.DXGI.Format;
+using MapFlags = SharpDX.Direct3D11.MapFlags;
+using PresentParameters = SharpDX.DXGI.PresentParameters;
+using Query = SharpDX.Direct3D11.Query;
+using QueryType = SharpDX.Direct3D11.QueryType;
+using RenderTarget = SharpDX.Direct2D1.RenderTarget;
+using Surface = SharpDX.DXGI.Surface;
+using SwapEffect = SharpDX.DXGI.SwapEffect;
+using Usage = SharpDX.Direct3D9.Usage;
+
+namespace Avalonia.Win32.Interop.Wpf
+{
+    class Direct2DImageSurface : IExternalDirect2DRenderTargetSurface, IDisposable
+    {
+        class SwapBuffer: IDisposable
+        {
+            private readonly Query _event;
+            private readonly SharpDX.Direct3D11.Resource _resource;
+            private readonly SharpDX.Direct3D11.Resource _sharedResource;
+            public SharpDX.Direct3D9.Surface Texture { get; }
+            public RenderTarget Target { get;}
+            public IntSize Size { get; }
+
+            public SwapBuffer(IntSize size, Vector dpi)
+            {
+                int width = (int) size.Width;
+                int height = (int) size.Height;
+                _event = new Query(s_dxDevice, new QueryDescription {Type = QueryType.Event});
+                using (var texture = new Texture2D(s_dxDevice, new Texture2DDescription
+                {
+                    Width = width,
+                    Height = height,
+                    ArraySize = 1,
+                    MipLevels = 1,
+                    Format = Format.B8G8R8A8_UNorm,
+                    Usage = ResourceUsage.Default,
+                    SampleDescription = new SampleDescription(2, 0),
+                    BindFlags = BindFlags.RenderTarget,
+                }))
+                using (var surface = texture.QueryInterface<Surface>())
+                
+                {
+                    _resource = texture.QueryInterface<SharpDX.Direct3D11.Resource>();
+                    
+                    Target = new RenderTarget(AvaloniaLocator.Current.GetService<SharpDX.Direct2D1.Factory>(), surface,
+                        new RenderTargetProperties
+                        {
+                            DpiX = (float) dpi.X,
+                            DpiY = (float) dpi.Y,
+                            MinLevel = FeatureLevel.Level_10,
+                            PixelFormat = new PixelFormat(Format.B8G8R8A8_UNorm, AlphaMode.Premultiplied),
+
+                        });
+                }
+                using (var texture = new Texture2D(s_dxDevice, new Texture2DDescription
+                {
+                    Width = width,
+                    Height = height,
+                    ArraySize = 1,
+                    MipLevels = 1,
+                    Format = Format.B8G8R8A8_UNorm,
+                    Usage = ResourceUsage.Default,
+                    SampleDescription = new SampleDescription(1, 0),
+                    BindFlags = BindFlags.RenderTarget|BindFlags.ShaderResource,
+                    OptionFlags = ResourceOptionFlags.Shared,
+                }))
+                using (var resource = texture.QueryInterface<SharpDX.DXGI.Resource>())
+                {
+                    _sharedResource = texture.QueryInterface<SharpDX.Direct3D11.Resource>();
+                    var handle = resource.SharedHandle;
+                    using (var texture9 = new Texture(s_d3DDevice, texture.Description.Width,
+                        texture.Description.Height, 1,
+                        Usage.RenderTarget, SharpDX.Direct3D9.Format.A8R8G8B8, Pool.Default, ref handle))
+                        Texture = texture9.GetSurfaceLevel(0);
+                }
+                Size = size;
+            }
+
+            public void Dispose()
+            {
+                Texture?.Dispose();
+                Target?.Dispose();
+                _resource?.Dispose();
+                _sharedResource?.Dispose();
+                _event?.Dispose();
+            }
+
+            public void Flush()
+            {
+                s_dxDevice.ImmediateContext.ResolveSubresource(_resource, 0, _sharedResource, 0, Format.B8G8R8A8_UNorm);
+                s_dxDevice.ImmediateContext.Flush();
+                s_dxDevice.ImmediateContext.End(_event);
+                s_dxDevice.ImmediateContext.GetData(_event).Dispose();
+            }
+        }
+
+        private D3DImage _image;
+        private SwapBuffer _backBuffer;
+        private readonly WpfTopLevelImpl _impl;
+        private static Device s_dxDevice;
+        private static Direct3DEx s_d3DContext;
+        private static DeviceEx s_d3DDevice;
+        private Vector _oldDpi;
+
+
+        [DllImport("user32.dll", SetLastError = false)]
+        private static extern IntPtr GetDesktopWindow();
+        void EnsureDirectX()
+        {
+            if(s_d3DDevice != null)
+                return;
+            s_d3DContext = new Direct3DEx();
+
+            SharpDX.Direct3D9.PresentParameters presentparams = new SharpDX.Direct3D9.PresentParameters
+            {
+                Windowed = true,
+                SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard,
+                DeviceWindowHandle = GetDesktopWindow(),
+                PresentationInterval = PresentInterval.Default
+            };
+            s_dxDevice = s_dxDevice ?? AvaloniaLocator.Current.GetService<SharpDX.DXGI.Device>()
+                             .QueryInterface<SharpDX.Direct3D11.Device>();
+            s_d3DDevice = new DeviceEx(s_d3DContext, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, presentparams);
+
+        }
+
+        public Direct2DImageSurface(WpfTopLevelImpl impl)
+        {
+            _impl = impl;
+        }
+
+        public RenderTarget GetOrCreateRenderTarget()
+        {
+            EnsureDirectX();
+            var scale = _impl.GetScaling();
+            var size = new IntSize(_impl.ActualWidth * scale.X, _impl.ActualHeight * scale.Y);
+            var dpi = scale * 96;
+
+            if (_backBuffer!=null && _backBuffer.Size == size)
+                return _backBuffer.Target;
+
+            if (_image == null || _oldDpi.X != dpi.X || _oldDpi.Y != dpi.Y)
+            {
+                _image = new D3DImage(dpi.X, dpi.Y);
+            }
+            _impl.ImageSource = _image;
+            
+            RemoveAndDispose(ref _backBuffer);
+            if (size == default(IntSize))
+            {
+                _image.Lock();
+                _image.SetBackBuffer(D3DResourceType.IDirect3DSurface9, IntPtr.Zero);
+                _image.Unlock();
+                return null;
+            }
+            _backBuffer = new SwapBuffer(size, dpi);
+
+            return _backBuffer.Target;
+        }
+
+        void RemoveAndDispose<T>(ref T d) where T : IDisposable
+        {
+            d?.Dispose();
+            d = default(T);
+        }
+
+        void Swap()
+        {
+            _backBuffer.Flush();
+            _image.Lock();
+            _image.SetBackBuffer(D3DResourceType.IDirect3DSurface9, _backBuffer?.Texture?.NativePointer ?? IntPtr.Zero, true);
+            _image.AddDirtyRect(new Int32Rect(0, 0, _image.PixelWidth, _image.PixelHeight));
+            _image.Unlock();
+        }
+
+        public void DestroyRenderTarget()
+        {
+            RemoveAndDispose(ref _backBuffer);
+        }
+
+        public void BeforeDrawing()
+        {
+            
+        }
+
+        public void AfterDrawing() => Swap();
+        public void Dispose()
+        {
+            RemoveAndDispose(ref _backBuffer);
+        }
+    }
+}

+ 59 - 0
src/Windows/Avalonia.Win32.Interop/Wpf/IntSize.cs

@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Avalonia.Win32.Interop.Wpf
+{
+    struct IntSize : IEquatable<IntSize>
+    {
+        public bool Equals(IntSize other)
+        {
+            return Width == other.Width && Height == other.Height;
+        }
+
+        public IntSize(int width, int height)
+        {
+            Width = width;
+            Height = height;
+        }
+
+        public IntSize(double width, double height) : this((int) width, (int) height)
+        {
+            
+        }
+
+        public static implicit  operator IntSize(System.Windows.Size size)
+        {
+            return new IntSize {Width = (int) size.Width, Height = (int) size.Height};
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) return false;
+            return obj is IntSize && Equals((IntSize) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                return (Width * 397) ^ Height;
+            }
+        }
+
+        public static bool operator ==(IntSize left, IntSize right)
+        {
+            return left.Equals(right);
+        }
+
+        public static bool operator !=(IntSize left, IntSize right)
+        {
+            return !left.Equals(right);
+        }
+
+        public int Width { get; set; }
+        public int Height { get; set; }
+    }
+}

+ 19 - 2
src/Windows/Avalonia.Win32.Interop/Wpf/WpfAvaloniaHost.cs

@@ -21,15 +21,32 @@ namespace Avalonia.Win32.Interop.Wpf
     {
         private WpfTopLevelImpl _impl;
         private readonly SynchronizationContext _sync;
+        private bool _hasChildren;
         public WpfAvaloniaHost()
         {
             _sync = SynchronizationContext.Current;
             _impl = new WpfTopLevelImpl();
             _impl.ControlRoot.Prepare();
             _impl.Visibility = Visibility.Visible;
-            AddLogicalChild(_impl);
-            AddVisualChild(_impl);
             SnapsToDevicePixels = true;
+            UseLayoutRounding = true;
+            PresentationSource.AddSourceChangedHandler(this, OnSourceChanged);
+        }
+
+        private void OnSourceChanged(object sender, SourceChangedEventArgs e)
+        {
+            if (e.NewSource != null && !_hasChildren)
+            {
+                AddLogicalChild(_impl);
+                AddVisualChild(_impl);
+                _hasChildren = true;
+            }
+            else
+            {
+                RemoveVisualChild(_impl);
+                RemoveLogicalChild(_impl);
+                _hasChildren = false;
+            }
         }
 
         public object Content

+ 15 - 3
src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs

@@ -60,7 +60,7 @@ namespace Avalonia.Win32.Interop.Wpf
             PresentationSource.AddSourceChangedHandler(this, OnSourceChanged);
             _hook = WndProc;
             _ttl = this;
-            _surfaces = new object[] {new WritableBitmapSurface(this)};
+            _surfaces = new object[] {new WritableBitmapSurface(this), new Direct2DImageSurface(this)};
             _mouse = new WpfMouseDevice(this);
             _keyboard = AvaloniaLocator.Current.GetService<IKeyboardDevice>();
 
@@ -88,7 +88,12 @@ namespace Avalonia.Win32.Interop.Wpf
             _ttl.ScalingChanged?.Invoke(_ttl.Scaling);
         }
 
-        public void Dispose() => _ttl.Closed?.Invoke();
+        public void Dispose()
+        {
+            _ttl.Closed?.Invoke();
+            foreach(var d in _surfaces.OfType<IDisposable>())
+                d.Dispose();
+        }
 
         Size ITopLevelImpl.ClientSize => _finalSize;
         IMouseDevice ITopLevelImpl.MouseDevice => _mouse;
@@ -224,6 +229,13 @@ namespace Avalonia.Win32.Interop.Wpf
         Action<double> ITopLevelImpl.ScalingChanged { get; set; }
         Action ITopLevelImpl.Closed { get; set; }
         public new event Action LostFocus;
-        
+
+        internal Vector GetScaling()
+        {
+            var src = PresentationSource.FromVisual(this)?.CompositionTarget;
+            if (src == null)
+                return new Vector(1, 1);
+            return new Vector(src.TransformToDevice.M11, src.TransformToDevice.M22);
+        }
     }
 }

+ 1 - 9
src/Windows/Avalonia.Win32.Interop/Wpf/WritableBitmapSurface.cs

@@ -24,7 +24,7 @@ namespace Avalonia.Win32.Interop.Wpf
 
         public ILockedFramebuffer Lock()
         {
-            var scale = GetScaling();
+            var scale = _impl.GetScaling();
             var size = new Size(_impl.ActualWidth * scale.X, _impl.ActualHeight * scale.Y);
             var dpi = scale * 96;
             if (_bitmap == null || _bitmap.PixelWidth != (int) size.Width || _bitmap.PixelHeight != (int) size.Height)
@@ -69,13 +69,5 @@ namespace Avalonia.Win32.Interop.Wpf
             public Vector Dpi { get; }
             public PixelFormat Format => PixelFormat.Bgra8888;
         }
-
-        Vector GetScaling()
-        {
-            var src = PresentationSource.FromVisual(_impl)?.CompositionTarget;
-            if (src == null)
-                return new Vector(1, 1);
-            return new Vector(src.TransformToDevice.M11, src.TransformToDevice.M22);
-        }
     }
 }

+ 0 - 1
src/Windows/Avalonia.Win32/Avalonia.Win32.csproj

@@ -101,5 +101,4 @@
   <Import Project="Avalonia.Win32.Shared.projitems" Label="Shared" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

+ 3 - 1
src/iOS/Avalonia.iOS/Avalonia.iOS.csproj

@@ -105,5 +105,7 @@
   <Import Project="..\..\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
   <Import Project="..\..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
+  <PropertyGroup Condition="'$(UseRoslynPathHack)' == 'true'">
+    <CscToolPath>$(MSBuildToolsPath)\..\Roslyn</CscToolPath>
+  </PropertyGroup>
 </Project>

+ 0 - 1
src/iOS/Avalonia.iOSTestApplication/Avalonia.iOSTestApplication.csproj

@@ -187,5 +187,4 @@
   </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
   <Import Project="..\..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
tests/Avalonia.Benchmarks/Avalonia.Benchmarks.csproj

@@ -103,5 +103,4 @@
   <ItemGroup>
     <PackageReference Include="BenchmarkDotNet" Version="0.10.8" />
   </ItemGroup>
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
tests/Avalonia.DesignerSupport.TestApp/Avalonia.DesignerSupport.TestApp.csproj

@@ -147,5 +147,4 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
tests/Avalonia.DesignerSupport.Tests/Avalonia.DesignerSupport.Tests.csproj

@@ -58,5 +58,4 @@
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\build\XUnit.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
tests/Avalonia.Direct2D1.UnitTests/Avalonia.Direct2D1.UnitTests.csproj

@@ -92,5 +92,4 @@
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\build\XUnit.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
tests/Avalonia.LeakTests/Avalonia.LeakTests.csproj

@@ -122,5 +122,4 @@
   <Import Project="..\..\build\Moq.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\XUnit.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 11 - 0
tests/Avalonia.LeakTests/toolproject/tool.csproj

@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
+  <PropertyGroup>
+    <OutputPath>$(MSBuildThisFileDirectory)\bin</OutputPath>
+    <OutDir>$(OutputPath)</OutDir>
+    <TargetFrameworks>net461</TargetFrameworks>
+    <OutputType>Library</OutputType>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="JetBrains.dotMemory.Unit" Version="109.0.20170720.104130-eap09" />
+  </ItemGroup>
+</Project>

+ 0 - 1
tests/Avalonia.RenderTests/Avalonia.Cairo.RenderTests.csproj

@@ -102,5 +102,4 @@
   <Import Project="..\..\build\Magick.NET-Q16-AnyCPU.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\XUnit.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.csproj

@@ -101,5 +101,4 @@
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\build\Magick.NET-Q16-AnyCPU.props" />
   <Import Project="..\..\build\XUnit.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 1
tests/Avalonia.RenderTests/Avalonia.Skia.RenderTests.csproj

@@ -102,5 +102,4 @@
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="..\..\build\Magick.NET-Q16-AnyCPU.props" />
   <Import Project="..\..\build\XUnit.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 3 - 1
tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj

@@ -52,5 +52,7 @@
   <Import Project="..\..\build\Moq.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\XUnit.props" />
-  <Import Condition="'$(TargetFramework)' == 'net461'" Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp1.1'">
+      <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+  </ItemGroup>
 </Project>