当我在Mono.net中调用PrivateFontCollection.AddFontFile方法时,它总是返回一个标准的font-family.这个bug已经在几个网站上报道,但据我所知,没有办法解决它.错误本身尚未在Mono-libraries中修复.它有什么解决方法吗?
编辑:作为对henchman的回答的反应,我将发布代码:
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddFontFile("myFontFamily.ttf");
myFontFamily = pfc.Families[0x00];
Font myFont = new Font(myFontFamily,14.0f);
Run Code Online (Sandbox Code Playgroud)
我知道这个代码在Microsoft.Net框架上可以正常工作,但是当在Mono上执行时,它只是给出一个标准的字体系列(我认为它是Arial),其名称为myFontFamily.ttf
我们为短期使用创建了大量字体.字体嵌入在文档中.如果不再使用,我想删除字体文件.我们应该怎么做?以下简化代码不起作用:
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddFontFile(fontFile);
FontFamily family = pfc.Families[0];
Console.WriteLine(family.GetName(0));
family.Dispose();
pfc.Dispose();
GC.Collect();
GC.WaitForPendingFinalizers();
File.Delete(fontFile);
Run Code Online (Sandbox Code Playgroud)
删除文件失败,因为文件已被锁定.我还能做些什么来解放文件锁?
PS:在我们使用AddMemoryFont之前.这适用于Windows 7.但是在第一个FontFamily处理后,使用Windows 8 .NET时使用了错误的字体文件.因为每个Document都可以包含其他字体,所以我们需要非常多的字体,并且不能保存对所有字体的引用.
我有一个.NET 3.5应用程序,使用PrivateFontCollection.AddMemoryFont将字体加载到内存中,并使用它们生成图像.我最近在Windows Server 2012 R2上安装了它,它产生间歇性错误.
这个方法说明了这个问题:
private Bitmap getImage(byte[] fontFile)
{
using (PrivateFontCollection fontCollection = new PrivateFontCollection())
{
IntPtr fontBuffer = Marshal.AllocCoTaskMem(fontFile.Length);
Marshal.Copy(fontFile, 0, fontBuffer, fontFile.Length);
fontCollection.AddMemoryFont(fontBuffer, fontFile.Length);
Bitmap image = new Bitmap(200, 50);
using (Font font = new Font(fontCollection.Families[0], 11f, FontStyle.Regular))
{
using (Graphics graphics = Graphics.FromImage(image))
{
graphics.DrawString(String.Format("{0:HH:mm:ss}", DateTime.Now), font, Brushes.White, new PointF(0f, 0f));
}
}
return image;
}
}
Run Code Online (Sandbox Code Playgroud)
在Windows 7上,这一切都是一致的.在Windows Server 2012 R2上,如果使用多种字体重复调用,则会失败.例如:
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Arial.ttf"));
Run Code Online (Sandbox Code Playgroud)
即使被调用数百次,但使用多种字体调用,它仍可正常工作:
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Wingding.ttf"));
getImage(File.ReadAllBytes("c:\\Windows\\Fonts\\Arial.ttf"));
Run Code Online (Sandbox Code Playgroud)
将适用于前几次调用(20左右),但随后将开始产生随机结果(第二次调用有时会返回带有文本的图像 - 即它正在混合字体).
我偶尔(很少)在DrawString调用中得到"GDI +中发生了一般错误".
Windows 7上不会发生这些错误.
我已经尝试了各种选项来清理而没有任何成功.
作为一种解决方法,我尝试将字体文件写入磁盘,然后使用AddFontFile加载,但是(在Windows …
.net fonts gdi+ privatefontcollection windows-server-2012-r2
我有一个返回PrivateFontCollection的函数:
Public Shared Function GetCustomFonts() As PrivateFontCollection
Dim result = New PrivateFontCollection
Dim customFontFiles = {"Garamond.TTF", "Garamond-Bold.TTF", "Garamond-Italic.TTF", "EurostileExtended-Roman-DTC.TTF"}
For Each fontFile In customFontFiles
result.AddFontFile(Hosting.HostingEnvironment.MapPath("/Includes/" & fontFile))
Next
Return result
End Function
Run Code Online (Sandbox Code Playgroud)
然后我使用如下函数:
Using customFonts = Common.GetCustomFonts()
' Do some stuff here
End Using
Run Code Online (Sandbox Code Playgroud)
我希望文件将被释放,但它们仍然被锁定:我收到以下错误:'操作无法完成,因为文件在System中打开.关闭文件,然后重试.
在IIS中关闭网站没有帮助; 我们必须回收应用程序池才能发布它.
任何人都可以建议如何使用PrivateFontCollection这样的方式使文件在使用之间释放?
这是将资源从资源加载到PrivateFontCollection导致损坏的延续
这里提供的答案对于具有该UseCompatibleTextRendering方法的控件是足够的,但是它似乎不适用于其他常见控件,其中文本是主要焦点,例如:
我已经尝试过这里的信息,这些信息基本上都是用Application.SetCompatibleTextRenderingDefault线路进行的Program.cs(没有人明确说明这个设置在哪里,所以我在这里记录它).我也玩过Telerik,DevExpress和Infragistics文本控件,除了Telerik之外没有内置兼容文本渲染的能力.Teleriks控件有这个方法,但它没有效果,包括无法将forecolor设置为存储的内容在属性(一个不同的动物,只是注意到Telerik radTextBox控件的毛刺).
似乎无论我如何切片,任何对文本实际有用的控件都不会使文本正确显示正方形字符,如上面提到的原始帖子所示.
综上所述 :
成功在标签上使用相同的字体(UseCompatibleTextRendering对它们起作用) - 在同一个表单上,在同一个项目中.
受此(新?)问题影响的控件严格来说是任何可以"键入"的控件,如TextEdit,ListView,RichText,Combo等.
当谈到切换,玩弄或玩耍时 - 这意味着我已经尝试了所提供的所有控件和/或代码的所有可能组合.例如: Application.SetCompatibleTextRenderingDefault本身只有3种可能的组合. (true) (false)或完全省略.在完成这3个组合之后,我继续进行(基本故障排除,但我发现有必要解释所有基础)添加Telerik控件,然后尝试Telerik控件中的所有组合,并结合Application.SetCompatibleTextRenderingDefault命令的所有组合.测试的数量是指数级的,即渲染可能性的可能组合的数量乘以尝试的控制的数量乘以每个控件具有的渲染控制的可能性的数量,等等.