TODO features:
- Custom cursor showing painting size - Alt-Scroll to change painting size
This commit is contained in:
105
McBitFont/McCursor.cs
Normal file
105
McBitFont/McCursor.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace McBitFont {
|
||||
internal class McCursor {
|
||||
|
||||
public struct IconInfo {
|
||||
public bool fIcon;
|
||||
public int xHotspot;
|
||||
public int yHotspot;
|
||||
public IntPtr hbmMask;
|
||||
public IntPtr hbmColor;
|
||||
}
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr CreateIconIndirect(ref IconInfo icon);
|
||||
|
||||
/// <summary>
|
||||
/// Create a cursor from a bitmap without resizing and with the specified
|
||||
/// hot spot
|
||||
/// </summary>
|
||||
public static Cursor CreateCursorNoResize(Bitmap bmp, int xHotSpot, int yHotSpot) {
|
||||
IntPtr ptr = bmp.GetHicon();
|
||||
IconInfo tmp = new IconInfo();
|
||||
GetIconInfo(ptr, ref tmp);
|
||||
tmp.xHotspot = xHotSpot;
|
||||
tmp.yHotspot = yHotSpot;
|
||||
tmp.fIcon = false;
|
||||
ptr = CreateIconIndirect(ref tmp);
|
||||
return new Cursor(ptr);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a 32x32 cursor from a bitmap, with the hot spot in the middle
|
||||
/// </summary>
|
||||
public static Cursor CreateCursor(Bitmap bmp) {
|
||||
int xHotSpot = 16;
|
||||
int yHotSpot = 16;
|
||||
|
||||
IntPtr ptr = ((Bitmap)ResizeImage(bmp, 32, 32)).GetHicon();
|
||||
IconInfo tmp = new IconInfo();
|
||||
GetIconInfo(ptr, ref tmp);
|
||||
tmp.xHotspot = xHotSpot;
|
||||
tmp.yHotspot = yHotSpot;
|
||||
tmp.fIcon = false;
|
||||
ptr = CreateIconIndirect(ref tmp);
|
||||
return new Cursor(ptr);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Resize the image to the specified width and height.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to resize.</param>
|
||||
/// <param name="width">The width to resize to.</param>
|
||||
/// <param name="height">The height to resize to.</param>
|
||||
/// <returns>The resized image.</returns>
|
||||
public static Bitmap ResizeImage(Image image, int width, int height) {
|
||||
var destRect = new Rectangle(0, 0, width, height);
|
||||
var destImage = new Bitmap(width, height);
|
||||
|
||||
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
|
||||
|
||||
using (var graphics = Graphics.FromImage(destImage)) {
|
||||
graphics.CompositingMode = CompositingMode.SourceCopy;
|
||||
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
|
||||
using (var wrapMode = new ImageAttributes()) {
|
||||
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
|
||||
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
|
||||
}
|
||||
}
|
||||
|
||||
return destImage;
|
||||
}
|
||||
|
||||
public static Cursor GetCursor(int penSize, int cellSize, int gap) {
|
||||
int size = (cellSize + gap) * penSize;
|
||||
|
||||
Bitmap bmp = new(size, size);
|
||||
Pen pb = new(Color.Black, 1);
|
||||
SolidBrush bw = new(Color.FromArgb(160, Color.White));
|
||||
using (Graphics g = Graphics.FromImage(bmp)) {
|
||||
g.DrawRectangle(pb, 0, 0, size-1, size-1);
|
||||
g.FillRectangle(bw, 1, 1, size - 2, size - 2);
|
||||
}
|
||||
return CreateCursorNoResize(bmp, cellSize / 2, cellSize / 2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user