硬编码的字体在DOTNET
-
25-09-2019 - |
题
我已经对用户没有安装在他们的机器(宋体,Comic Sans字体MS,宋体为例)上的Windows核心字体多次遇到的问题。每当我试图建立的其中之一,它抛出一个错误,而不是回落到一个相关的,或真,的任何的其他字体。
什么是构建一个字体,如果我想它是快递的最佳方式,但我不是特别执着于它?
解决方案
可以嵌入字体作为资源,并使用关键字unsafe
(并且必须以“不安全”被编译),以获得字体...下面是一个例子代码,我用于设置一个用户控件类型的字体' OCR'
private PrivateFontCollection pfc = new PrivateFontCollection(); private Font _fntOCRFont = null; private enum FontEnum{ OCR = 0 };
这声明字体的私人珍藏......字体“OCR”嵌入与使用的命名规范,“富”是一个命名空间的资源,因此资源名称是“foo.ocraext.ttf” .. 。看着“InitOCRFont”在这里它会加载该字体,并将其添加到集合:
private void InitOCRFont(){ try{ System.IO.Stream streamFont = this.GetType().Assembly.GetManifestResourceStream("foo.ocraext.ttf"); if (streamFont != null){ byte[] fontData = new byte[streamFont.Length]; streamFont.Read(fontData, 0, (int)streamFont.Length); streamFont.Close(); unsafe{ fixed(byte *pFontData = fontData){ this.pfc.AddMemoryFont((System.IntPtr)pFontData, fontData.Length); } } }else{ throw new Exception("Error! Could not read built-in Font."); } }catch(Exception eX){ throw new Exception("InitOCRFont Method - Exception occurred!\nException was: " + eX.Message); } }
在这里,我设置用户控件中的控制设置字体到“OCR”字体通过迭代通过收集,见“InitializeCtlFont”,字体大小为10,是一次大胆“型面”:
private void InitializeCtlFont(){ this._fntOCRFont = new Font(this.pfc.Families[0], 10.0F, System.Drawing.FontStyle.Bold); if (this._fntOCRFont != null){ foreach(Control ctl in this.Controls){ if (ctl != null && ((ctl is Label) || (ctl is TextBox))){ ctl.Font = this._fntOCRFont; } } } }
当用户控制获取设置,必须以释放资源占用由字体如下所示在Dispose
方法:
try{ if (this._fntOCRFont != null) this._fntOCRFont.Dispose(); }catch{ } try{ if (this.pfc != null) this.pfc.Dispose(); }catch{ }
希望这有助于 最好的祝福, 汤姆。
其他提示
好了,你可以使用的 FontFamily.GenericMonospace
以获得一等宽字型,而不是具体快递:
Font f = new Font(FontFamily.GenericMonospace, 12, FontStyle.Regular);
您还可以使用此作为试图您的首选字体和运行到异常后的最后手段。
这是非常不寻常的。当你的程序请求的字体不可用在目标机器上的Windows字体映射器总是会提供替代字体。这替代字体通常是Microsoft无衬线在XP上更高版本的Segoe UI。这两个时间都不应该永远出现问题了。
话又说回来,如果机器是那么糟糕,它并没有核心字体可用时,它可能会提供根本没有TrueType字体。是的,这将轰炸你的计划。坦率地说,这不是你应该来处理,除非这是一个非常有价值的客户。它是平凡的,否则您的客户的支持团队来解决。