首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确处理PrivateFontCollection?

如何正确处理PrivateFontCollection?
EN

Stack Overflow用户
提问于 2016-01-05 20:35:14
回答 2查看 1K关注 0票数 2

我使用PrivateFontCollection在我的web服务器上安装上传的字体。下面的代码可以工作,但是在第二次上传字体时,PrivateFontCollection引用了上传的第一个字体。所以有些东西没有得到正确的处理。有人发现我做错了什么吗?

代码语言:javascript
复制
 var fontName = string.Empty;
    using (var ms = new MemoryStream(fontBytes))
    {
        // used to store our font and make it available in our app
        using (var pfc = new PrivateFontCollection())
        {
            //create memory pointer
            IntPtr data = Marshal.AllocCoTaskMem((int)ms.Length);

            try
            {
                //copy the bytes to the unsafe memory block
                Marshal.Copy(fontBytes, 0, data, (int)ms.Length);

                // We HAVE to do this to register the font to the system (Weird .NET bug !)
                uint cFonts = 0;
                AddFontMemResourceEx(data, (uint)fontBytes.Length, IntPtr.Zero, ref cFonts);

                //pass the font to the font collection
                pfc.AddMemoryFont(data, (int)ms.Length);
                var fontWithMime = "data:application/x-font-truetype;charset=utf-8;base64," + cleanFontData;

                fontName = pfc.Families[0].Name;

                //db work here
            }
            finally
            {
                ms.Close();
                Marshal.FreeCoTaskMem(data);
            }
        }
    }
EN

回答 2

Stack Overflow用户

发布于 2016-01-05 21:16:29

PrivateFontCollection是一个非常有缺陷的类,您必须非常小心地使用它。现有代码中一个非常严重的错误是Marshal.FreeCoTaskMem()调用。在您的代码停止使用您从家庭中创建的任何Font对象之前,您应该确保不调用此函数。如果不这样做,就会导致随机的字形损坏,只有幸运时才能得到AccessViolationException。根本的问题是字体将继续使用您用AllocCoTaskMem()分配的内存,它完全不知道内存不再有效。当内存被重复使用时会发生损坏。

此外,尽管该类有一个AddMemoryFont()方法,但它没有对应的RemoveMemoryFont()方法。清理的唯一方法是调用PrivateFontCollection.Dispose()。这将删除集合中的所有字体。按照与上一段相同的规定,只有当您确信不再使用任何Font对象时,才能调用With ()。过早调用它不会导致异常。

非常尴尬的行为,只有真正安全的方式使用PFC是保持它的生命的应用程序。当然,在一个网络应用程序中很痛苦。

您可以假设添加的字体是FontFamily[]数组中的最后一个字体。这不是第一次,因为你现在已经实现了。

票数 2
EN

Stack Overflow用户

发布于 2016-01-05 20:57:16

根据AddFontMemResourceEx函数

若要删除已安装的字体,请调用RemoveFontMemResourceEx。但是,当进程结束时,即使进程没有调用RemoveFontMemResource,系统也会卸载字体。

不过,我没看到你这么做。这可能就是原因。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34620743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档