7 changed files with 244 additions and 84 deletions
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue