diff --git a/src/Skia/Avalonia.Skia.Android/Avalonia.Skia.Android.csproj b/src/Skia/Avalonia.Skia.Android/Avalonia.Skia.Android.csproj index a5a1981af7..b3b9a57880 100644 --- a/src/Skia/Avalonia.Skia.Android/Avalonia.Skia.Android.csproj +++ b/src/Skia/Avalonia.Skia.Android/Avalonia.Skia.Android.csproj @@ -88,6 +88,7 @@ + diff --git a/src/Skia/Avalonia.Skia.Android/RenderTarget.cs b/src/Skia/Avalonia.Skia.Android/RenderTarget.cs new file mode 100644 index 0000000000..59ad3b9fbb --- /dev/null +++ b/src/Skia/Avalonia.Skia.Android/RenderTarget.cs @@ -0,0 +1,108 @@ +using System; +using Avalonia.Media; +using Avalonia.Platform; +using SkiaSharp; +using Android.Graphics; +using Android.Views; + +namespace Avalonia.Skia +{ + internal partial class RenderTarget : IRenderTarget + { + public SKSurface Surface { get; protected set; } + + public virtual DrawingContext CreateDrawingContext() + { + return + new DrawingContext( + new DrawingContextImpl(Surface.Canvas)); + } + + public void Dispose() + { + // Nothing to do here. + } + } + + internal class WindowRenderTarget : RenderTarget + { + private readonly IPlatformHandle _hwnd; + Bitmap _bitmap; + int Width { get; set; } + int Height { get; set; } + + public WindowRenderTarget(IPlatformHandle hwnd) + { + _hwnd = hwnd; + FixSize(); + } + + private void FixSize() + { + int width, height; + GetPlatformWindowSize(out width, out height); + if (Width == width && Height == height) + return; + + Width = width; + Height = height; + + if (Surface != null) + { + Surface.Dispose(); + } + + if (_bitmap != null) + { + _bitmap.Dispose(); + } + + _bitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888); + Surface = SKSurface.Create(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Premul, _bitmap.LockPixels(), width * 4); + } + + private void GetPlatformWindowSize(out int w, out int h) + { + var surfaceView = _hwnd as SurfaceView; + w = surfaceView.Width; + h = surfaceView.Height; + } + + public override DrawingContext CreateDrawingContext() + { + FixSize(); + + var canvas = Surface.Canvas; + canvas.RestoreToCount(0); + canvas.Save(); + canvas.Clear(SKColors.Red); + canvas.ResetMatrix(); + + return + new DrawingContext( + new WindowDrawingContextImpl(this)); + } + + public void Present() + { + var surfaceView = _hwnd as SurfaceView; + Canvas canvas = null; + try + { + canvas = surfaceView.Holder.LockCanvas(null); + _bitmap.UnlockPixels(); + canvas.DrawBitmap(_bitmap, 0, 0, null); + } + catch (Exception) + { + } + finally + { + if (canvas != null) + surfaceView.Holder.UnlockCanvasAndPost(canvas); + } + + _bitmap.UnlockPixels(); + } + } +} diff --git a/src/Skia/Avalonia.Skia.Desktop/Avalonia.Skia.Desktop.csproj b/src/Skia/Avalonia.Skia.Desktop/Avalonia.Skia.Desktop.csproj index d6298a941e..f5dd4180eb 100644 --- a/src/Skia/Avalonia.Skia.Desktop/Avalonia.Skia.Desktop.csproj +++ b/src/Skia/Avalonia.Skia.Desktop/Avalonia.Skia.Desktop.csproj @@ -76,6 +76,7 @@ UnmanagedMethods.cs + diff --git a/src/Skia/Avalonia.Skia.Desktop/RenderTarget.cs b/src/Skia/Avalonia.Skia.Desktop/RenderTarget.cs new file mode 100644 index 0000000000..5b61042655 --- /dev/null +++ b/src/Skia/Avalonia.Skia.Desktop/RenderTarget.cs @@ -0,0 +1,132 @@ +using System; +using Avalonia.Media; +using Avalonia.Platform; +using SkiaSharp; +#if WIN32 +using Avalonia.Win32.Interop; +#endif + +namespace Avalonia.Skia +{ + internal partial class RenderTarget : IRenderTarget + { + public SKSurface Surface { get; protected set; } + + public virtual DrawingContext CreateDrawingContext() + { + return + new DrawingContext( + new DrawingContextImpl(Surface.Canvas)); + } + + public void Dispose() + { + // Nothing to do here. + } + } + + internal class WindowRenderTarget : RenderTarget + { + private readonly IPlatformHandle _hwnd; + SKBitmap _bitmap; + int Width { get; set; } + int Height { get; set; } + + public WindowRenderTarget(IPlatformHandle hwnd) + { + _hwnd = hwnd; + FixSize(); + } + + private void FixSize() + { + int width, height; + GetPlatformWindowSize(out width, out height); + if (Width == width && Height == height) + return; + + Width = width; + Height = height; + + if (Surface != null) + { + Surface.Dispose(); + } + + if (_bitmap != null) + { + _bitmap.Dispose(); + } + + _bitmap = new SKBitmap(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Premul); + + IntPtr length; + var pixels = _bitmap.GetPixels(out length); + + // Wrap the bitmap in a Surface and keep it cached + Surface = SKSurface.Create(_bitmap.Info, pixels, _bitmap.RowBytes); + } + + private void GetPlatformWindowSize(out int w, out int h) + { +#if WIN32 + UnmanagedMethods.RECT rc; + UnmanagedMethods.GetClientRect(_hwnd.Handle, out rc); + w = rc.right - rc.left; + h = rc.bottom - rc.top; +#else + throw new NotImplementedException(); +#endif + } + + public override DrawingContext CreateDrawingContext() + { + FixSize(); + + var canvas = Surface.Canvas; + canvas.RestoreToCount(0); + canvas.Save(); + canvas.Clear(SKColors.Red); + canvas.ResetMatrix(); + + return + new DrawingContext( + new WindowDrawingContextImpl(this)); + } + + public void Present() + { + _bitmap.LockPixels(); + IntPtr length; + var pixels = _bitmap.GetPixels(out length); + +#if WIN32 + UnmanagedMethods.BITMAPINFO bmi = new UnmanagedMethods.BITMAPINFO(); + bmi.biSize = UnmanagedMethods.SizeOf_BITMAPINFOHEADER; + bmi.biWidth = _bitmap.Width; + bmi.biHeight = -_bitmap.Height; // top-down image + bmi.biPlanes = 1; + bmi.biBitCount = 32; + bmi.biCompression = (uint)UnmanagedMethods.BitmapCompressionMode.BI_RGB; + bmi.biSizeImage = 0; + + IntPtr hdc = UnmanagedMethods.GetDC(_hwnd.Handle); + + int ret = UnmanagedMethods.SetDIBitsToDevice(hdc, + 0, 0, + (uint)_bitmap.Width, (uint)_bitmap.Height, + 0, 0, + 0, (uint)_bitmap.Height, + pixels, + ref bmi, + (uint)UnmanagedMethods.DIBColorTable.DIB_RGB_COLORS); + + UnmanagedMethods.ReleaseDC(_hwnd.Handle, hdc); +#else + throw new NotImplementedException(); +#endif + + _bitmap.UnlockPixels(); + } + } +} \ No newline at end of file diff --git a/src/Skia/Avalonia.Skia.iOS/Avalonia.Skia.iOS.csproj b/src/Skia/Avalonia.Skia.iOS/Avalonia.Skia.iOS.csproj index 3bc050a481..21123fae29 100644 --- a/src/Skia/Avalonia.Skia.iOS/Avalonia.Skia.iOS.csproj +++ b/src/Skia/Avalonia.Skia.iOS/Avalonia.Skia.iOS.csproj @@ -37,6 +37,7 @@ true + diff --git a/src/Skia/Avalonia.Skia/RenderTarget.cs b/src/Skia/Avalonia.Skia.iOS/RenderTarget.cs similarity index 62% rename from src/Skia/Avalonia.Skia/RenderTarget.cs rename to src/Skia/Avalonia.Skia.iOS/RenderTarget.cs index f57ac2168f..083b611d5c 100644 --- a/src/Skia/Avalonia.Skia/RenderTarget.cs +++ b/src/Skia/Avalonia.Skia.iOS/RenderTarget.cs @@ -2,18 +2,8 @@ using System; using Avalonia.Media; using Avalonia.Platform; using SkiaSharp; - -// TODO: I'm not sure the best way to bring in the platform specific rendering - -#if __IOS__ using CoreGraphics; using UIKit; -#elif WIN32 -using Avalonia.Win32.Interop; -#elif __ANDROID__ -using Android.Graphics; -using Android.Views; -#endif namespace Avalonia.Skia { @@ -37,11 +27,7 @@ namespace Avalonia.Skia internal class WindowRenderTarget : RenderTarget { private readonly IPlatformHandle _hwnd; -#if __ANDROID__ - Bitmap _bitmap; -#else SKBitmap _bitmap; -#endif int Width { get; set; } int Height { get; set; } @@ -51,7 +37,6 @@ namespace Avalonia.Skia FixSize(); } -#if __IOS__ private CGRect GetApplicationFrame() { // if we are excluding Status Bar then we use ApplicationFrame @@ -68,7 +53,6 @@ namespace Avalonia.Skia return UIScreen.MainScreen.Bounds; } } -#endif private void FixSize() { @@ -90,10 +74,6 @@ namespace Avalonia.Skia _bitmap.Dispose(); } -#if __ANDROID__ - _bitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888); - Surface = SKSurface.Create(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Premul, _bitmap.LockPixels(), width * 4); -#else _bitmap = new SKBitmap(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Premul); IntPtr length; @@ -101,28 +81,13 @@ namespace Avalonia.Skia // Wrap the bitmap in a Surface and keep it cached Surface = SKSurface.Create(_bitmap.Info, pixels, _bitmap.RowBytes); -#endif } private void GetPlatformWindowSize(out int w, out int h) { -#if __IOS__ var bounds = GetApplicationFrame(); w = (int)bounds.Width; h = (int)bounds.Height; - -#elif WIN32 - UnmanagedMethods.RECT rc; - UnmanagedMethods.GetClientRect(_hwnd.Handle, out rc); - w = rc.right - rc.left; - h = rc.bottom - rc.top; -#elif __ANDROID__ - var surfaceView = _hwnd as SurfaceView; - w = surfaceView.Width; - h = surfaceView.Height; -#else - throw new NotImplementedException(); -#endif } public override DrawingContext CreateDrawingContext() @@ -133,10 +98,8 @@ namespace Avalonia.Skia canvas.RestoreToCount(0); canvas.Save(); -#if __IOS__ var screenScale = UIScreen.MainScreen.Scale; canvas.Scale((float)screenScale, (float)screenScale); -#endif canvas.Clear(SKColors.Red); canvas.ResetMatrix(); @@ -148,13 +111,10 @@ namespace Avalonia.Skia public void Present() { -#if !__ANDROID__ _bitmap.LockPixels(); IntPtr length; var pixels = _bitmap.GetPixels(out length); -#endif -#if __IOS__ const int bitmapInfo = ((int)CGBitmapFlags.ByteOrder32Big) | ((int)CGImageAlphaInfo.PremultipliedLast); var bounds = GetApplicationFrame(); var statusBarOffset = UIScreen.MainScreen.Bounds.Height - bounds.Height; @@ -170,49 +130,7 @@ namespace Avalonia.Skia context.DrawImage(bounds, image); } -#elif WIN32 - UnmanagedMethods.BITMAPINFO bmi = new UnmanagedMethods.BITMAPINFO(); - bmi.biSize = UnmanagedMethods.SizeOf_BITMAPINFOHEADER; - bmi.biWidth = _bitmap.Width; - bmi.biHeight = -_bitmap.Height; // top-down image - bmi.biPlanes = 1; - bmi.biBitCount = 32; - bmi.biCompression = (uint)UnmanagedMethods.BitmapCompressionMode.BI_RGB; - bmi.biSizeImage = 0; - - IntPtr hdc = UnmanagedMethods.GetDC(_hwnd.Handle); - - int ret = UnmanagedMethods.SetDIBitsToDevice(hdc, - 0, 0, - (uint)_bitmap.Width, (uint)_bitmap.Height, - 0, 0, - 0, (uint)_bitmap.Height, - pixels, - ref bmi, - (uint)UnmanagedMethods.DIBColorTable.DIB_RGB_COLORS); - - UnmanagedMethods.ReleaseDC(_hwnd.Handle, hdc); -#elif __ANDROID__ - var surfaceView = _hwnd as SurfaceView; - Canvas canvas = null; - try - { - canvas = surfaceView.Holder.LockCanvas(null); - _bitmap.UnlockPixels(); - canvas.DrawBitmap(_bitmap, 0, 0, null); - } - catch (Exception) - { - } - finally - { - if (canvas != null) - surfaceView.Holder.UnlockCanvasAndPost(canvas); - } -#endif - _bitmap.UnlockPixels(); } - } } diff --git a/src/Skia/Avalonia.Skia/Avalonia.Skia.projitems b/src/Skia/Avalonia.Skia/Avalonia.Skia.projitems index 08f06e2570..426be548e2 100644 --- a/src/Skia/Avalonia.Skia/Avalonia.Skia.projitems +++ b/src/Skia/Avalonia.Skia/Avalonia.Skia.projitems @@ -1,4 +1,4 @@ - + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) @@ -13,7 +13,6 @@ -