skiasharp/source/SkiaSharp.Views/SkiaSharp.Views.WindowsForms/SKControl.cs

96 lines
2.1 KiB
C#

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
namespace SkiaSharp.Views.Desktop
{
[DefaultEvent("PaintSurface")]
[DefaultProperty("Name")]
public class SKControl : Control
{
private readonly bool designMode;
private Bitmap bitmap;
public SKControl()
{
DoubleBuffered = true;
SetStyle(ControlStyles.ResizeRedraw, true);
designMode = DesignMode || LicenseManager.UsageMode == LicenseUsageMode.Designtime;
}
public SKSize CanvasSize => bitmap == null ? SKSize.Empty : new SKSize(bitmap.Width, bitmap.Height);
[Category("Appearance")]
public event EventHandler<SKPaintSurfaceEventArgs> PaintSurface;
protected override void OnPaint(PaintEventArgs e)
{
if (designMode)
return;
base.OnPaint(e);
// get the bitmap
var info = CreateBitmap();
if (info.Width == 0 || info.Height == 0)
return;
var data = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, bitmap.PixelFormat);
// create the surface
using (var surface = SKSurface.Create(info, data.Scan0, data.Stride))
{
// start drawing
OnPaintSurface(new SKPaintSurfaceEventArgs(surface, info));
surface.Canvas.Flush();
}
// write the bitmap to the graphics
bitmap.UnlockBits(data);
e.Graphics.DrawImage(bitmap, 0, 0);
}
protected virtual void OnPaintSurface(SKPaintSurfaceEventArgs e)
{
// invoke the event
PaintSurface?.Invoke(this, e);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
FreeBitmap();
}
private SKImageInfo CreateBitmap()
{
var info = new SKImageInfo(Width, Height, SKImageInfo.PlatformColorType, SKAlphaType.Premul);
if (bitmap == null || bitmap.Width != info.Width || bitmap.Height != info.Height)
{
FreeBitmap();
if (info.Width != 0 && info.Height != 0)
bitmap = new Bitmap(info.Width, info.Height, PixelFormat.Format32bppPArgb);
}
return info;
}
private void FreeBitmap()
{
if (bitmap != null)
{
bitmap.Dispose();
bitmap = null;
}
}
}
}