// ***********************************************************************
// Assembly : HZH_Controls
// Created : 2019-09-11
//
// ***********************************************************************
//
// Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
//
//
// Blog: https://www.cnblogs.com/bfyx
// GitHub:https://github.com/kwwwvagaa/NetWinformControl
// gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
//
// If you use this code, please keep this note.
// ***********************************************************************
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
namespace HZH_Controls
{
///
/// 字体图标图片,awesome字体默认加载,elegant字体在使用时延迟加载
/// 图标示例 http://www.fontawesome.com.cn/faicons/?tdsourcetag=s_pcqq_aiomsg
/// 图标示例 https://www.elegantthemes.com/blog/resources/elegant-icon-font
///
public static class FontImages
{
///
/// The m font collection
///
private static readonly PrivateFontCollection m_fontCollection = new PrivateFontCollection();
///
/// The m fonts awesome
///
private static readonly Dictionary m_fontsAwesome = new Dictionary();
///
/// The m fonts elegant
///
private static readonly Dictionary m_fontsElegant = new Dictionary();
///
/// The m cache maximum size
///
private static Dictionary m_cacheMaxSize = new Dictionary();
///
/// The minimum font size
///
private const int MinFontSize = 8;
///
/// The maximum font size
///
private const int MaxFontSize = 43;
///
/// 构造函数
///
/// Font file not found
static FontImages()
{
string strPath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase.ToLower().Replace("file:///", "");
string strDir = System.IO.Path.GetDirectoryName(strPath);
if (!Directory.Exists(Path.Combine(strDir, "IconFont")))
{
Directory.CreateDirectory(Path.Combine(strDir, "IconFont"));
}
string strFile = Path.Combine(strDir, "IconFont\\FontAwesome.ttf");
if (!File.Exists(strFile))
{
var fs = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("HZH_Controls.IconFont.FontAwesome.ttf");
FileStream sw = new FileStream(strFile, FileMode.Create, FileAccess.Write);
fs.CopyTo(sw);
sw.Close();
fs.Close();
}
m_fontCollection.AddFontFile(strFile);
float size = MinFontSize;
for (int i = 0; i <= (MaxFontSize - MinFontSize) * 2; i++)
{
m_fontsAwesome.Add(size.ToString("F2"), new Font(m_fontCollection.Families[0], size, FontStyle.Regular, GraphicsUnit.Point));
size += 0.5f;
}
}
///
/// Gets the font awesome.
///
/// The font awesome.
public static FontFamily FontAwesome
{
get
{
for (int i = 0; i < m_fontCollection.Families.Length; i++)
{
if (m_fontCollection.Families[i].Name == "FontAwesome")
{
return m_fontCollection.Families[i];
}
}
return m_fontCollection.Families[0];
}
}
///
/// Gets the elegant icons.
///
/// The elegant icons.
/// Font file not found
public static FontFamily ElegantIcons
{
get
{
if (m_fontsElegant.Count <= 0)
{
lock (m_fontsElegant)
{
if (m_fontsElegant.Count <= 0)
{
string strPath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase.ToLower().Replace("file:///", "");
string strDir = System.IO.Path.GetDirectoryName(strPath);
if (!Directory.Exists(Path.Combine(strDir, "IconFont")))
{
Directory.CreateDirectory(Path.Combine(strDir, "IconFont"));
}
string strFile = Path.Combine(strDir, "IconFont\\ElegantIcons.ttf");
if (!File.Exists(strFile))
{
var fs = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("HZH_Controls.IconFont.ElegantIcons.ttf");
FileStream sw = new FileStream(strFile, FileMode.Create, FileAccess.Write);
fs.CopyTo(sw);
sw.Close();
fs.Close();
}
m_fontCollection.AddFontFile(strFile);
float size = MinFontSize;
for (int i = 0; i <= (MaxFontSize - MinFontSize) * 2; i++)
{
m_fontsElegant.Add(size.ToString("F2"), new Font(m_fontCollection.Families[0], size, FontStyle.Regular, GraphicsUnit.Point));
size += 0.5f;
}
}
}
}
for (int i = 0; i < m_fontCollection.Families.Length; i++)
{
if (m_fontCollection.Families[i].Name == "ElegantIcons")
{
return m_fontCollection.Families[i];
}
}
return m_fontCollection.Families[0];
}
}
///
/// 获取图标
///
/// 图标名称
/// 图标大小
/// 前景色
/// 背景色
/// 图标
public static Icon GetIcon(FontIcons iconText, int imageSize = 32, Color? foreColor = null, Color? backColor = null)
{
Bitmap image = GetImage(iconText, imageSize, foreColor, backColor);
return image != null ? ToIcon(image, imageSize) : null;
}
///
/// 获取图标.
///
/// 图标名称.
/// 图标大小.
/// 前景色
/// 背景色.
/// Bitmap.
/// Font file not found
public static Bitmap GetImage(FontIcons iconText, int imageSize = 32, Color? foreColor = null, Color? backColor = null)
{
Dictionary _fs;
if (iconText.ToString().StartsWith("A_"))
_fs = m_fontsAwesome;
else
{
if (m_fontsElegant.Count <= 0)
{
lock (m_fontsElegant)
{
if (m_fontsElegant.Count <= 0)
{
string strPath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase.ToLower().Replace("file:///", "");
string strDir = System.IO.Path.GetDirectoryName(strPath);
if (!Directory.Exists(Path.Combine(strDir, "IconFont")))
{
Directory.CreateDirectory(Path.Combine(strDir, "IconFont"));
}
string strFile = Path.Combine(strDir, "IconFont\\ElegantIcons.ttf");
if (!File.Exists(strFile))
{
var fs = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("HZH_Controls.IconFont.ElegantIcons.ttf");
FileStream sw = new FileStream(strFile, FileMode.Create, FileAccess.Write);
fs.CopyTo(sw);
sw.Close();
fs.Close();
}
m_fontCollection.AddFontFile(strFile);
float size = MinFontSize;
for (int i = 0; i <= (MaxFontSize - MinFontSize) * 2; i++)
{
m_fontsElegant.Add(size.ToString("F2"), new Font(m_fontCollection.Families[0], size, FontStyle.Regular, GraphicsUnit.Point));
size += 0.5f;
}
}
}
}
_fs = m_fontsElegant;
}
if (!foreColor.HasValue)
foreColor = Color.Black;
Font imageFont = _fs[MinFontSize.ToString("F2")];
SizeF textSize = new SizeF(imageSize, imageSize);
using (Bitmap bitmap = new Bitmap(48, 48))
using (Graphics graphics = Graphics.FromImage(bitmap))
{
//float size = MaxFontSize;
float fltMaxSize = MaxFontSize;
if (m_cacheMaxSize.ContainsKey(imageSize))
{
fltMaxSize = Math.Max(MaxFontSize, m_cacheMaxSize[imageSize] + 5);
}
while (fltMaxSize >= MinFontSize)
{
Font font = _fs[fltMaxSize.ToString("F2")];
SizeF sf = GetIconSize(iconText, graphics, font);
if (sf.Width < imageSize && sf.Height < imageSize)
{
imageFont = font;
textSize = sf;
break;
}
fltMaxSize -= 0.5f;
}
if (!m_cacheMaxSize.ContainsKey(imageSize) || (m_cacheMaxSize.ContainsKey(imageSize) && m_cacheMaxSize[imageSize] < fltMaxSize))
{
m_cacheMaxSize[imageSize] = fltMaxSize;
}
}
Bitmap srcImage = new Bitmap(imageSize, imageSize);
using (Graphics graphics = Graphics.FromImage(srcImage))
{
if (backColor.HasValue && backColor.Value != Color.Empty && backColor.Value != Color.Transparent)
graphics.Clear(backColor.Value);
string s = char.ConvertFromUtf32((int)iconText);
graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
graphics.SetGDIHigh();
using (Brush brush2 = new SolidBrush(foreColor.Value))
{
graphics.DrawString(s, imageFont, brush2, new PointF((imageSize - textSize.Width) / 2.0f + 1, (imageSize - textSize.Height) / 2.0f + 1));
}
}
return srcImage;
}
///
/// Gets the size of the icon.
///
/// The icon text.
/// The graphics.
/// The font.
/// Size.
private static Size GetIconSize(FontIcons iconText, Graphics graphics, Font font)
{
string text = char.ConvertFromUtf32((int)iconText);
return graphics.MeasureString(text, font).ToSize();
}
///
/// Converts to icon.
///
/// The source bitmap.
/// The size.
/// Icon.
/// srcBitmap
private static Icon ToIcon(Bitmap srcBitmap, int size)
{
if (srcBitmap == null)
{
throw new ArgumentNullException("srcBitmap");
}
Icon icon;
using (MemoryStream memoryStream = new MemoryStream())
{
new Bitmap(srcBitmap, new Size(size, size)).Save(memoryStream, ImageFormat.Png);
Stream stream = new MemoryStream();
BinaryWriter binaryWriter = new BinaryWriter(stream);
if (stream.Length <= 0L)
{
return null;
}
binaryWriter.Write((byte)0);
binaryWriter.Write((byte)0);
binaryWriter.Write((short)1);
binaryWriter.Write((short)1);
binaryWriter.Write((byte)size);
binaryWriter.Write((byte)size);
binaryWriter.Write((byte)0);
binaryWriter.Write((byte)0);
binaryWriter.Write((short)0);
binaryWriter.Write((short)32);
binaryWriter.Write((int)memoryStream.Length);
binaryWriter.Write(22);
binaryWriter.Write(memoryStream.ToArray());
binaryWriter.Flush();
binaryWriter.Seek(0, SeekOrigin.Begin);
icon = new Icon(stream);
stream.Dispose();
}
return icon;
}
}
}