将内存字体添加到私有字体集合无法可靠地工作 [英] Adding in memory fonts to a private font collection doesn't work reliably

查看:96
本文介绍了将内存字体添加到私有字体集合无法可靠地工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好!

我的System.Drawing.Text.PrivateFontCollection类存在问题。

I have a problem with the System.Drawing.Text.PrivateFontCollection class.

我有一个文件夹有很多字体,并希望将它们全部添加到PrivateFontCollection。当我使用AddFontFile执行此操作时,结果列表的系列符合预期,我总是得到相同的列表。当我使用AddMemoryFont(我想要
来避免)时,结果列表永远不会完成,并且使用相同数据重复执行相同代码会导致不同的列表。

I have a folder with a lot of fonts and want to add them all to a PrivateFontCollection. When i do it by using AddFontFile, the resulting list of families is as expected and I always get the same list. When I do it by using AddMemoryFont (which i would like to avoid), the resulting list is never complete and repeated executions of the same code, with the same data, lead to different lists.

我添加内存字体的代码是错误的,还是方法本身有问题?

Is my code for adding in memory fonts wrong, or is the method itself buggy?

using System;
using System.Drawing.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;

namespace WindowsFormsApplication1
{
    class FontManager
    {
        private readonly string fontDir;

        public FontManager(string fontDir)
        {
            this.fontDir = fontDir;
        }

        public int LoadInMemoryFonts()
        {
            var fontCollection = new PrivateFontCollection();
            var fontFiles = Directory.GetFiles(fontDir, "*.ttf");
            Array.ForEach(fontFiles, fontFile => {
                using (var fileStream = new FileStream(fontFile, FileMode.Open, FileAccess.Read))
                {
                    var memStream = new MemoryStream();
                    fileStream.CopyTo(memStream);
                    var fontData = memStream.ToArray();                    
                    var fontDataPtr = Marshal.AllocCoTaskMem(fontData.Length);
                    try
                    {                        
                        Marshal.Copy(fontData, 0, fontDataPtr, fontData.Length);
                        fontCollection.AddMemoryFont(fontDataPtr, fontData.Length);                        
                        Thread.Sleep(1);
                    }
                    finally
                    {
                        Marshal.FreeCoTaskMem(fontDataPtr);
                    }

                }
            });
            return fontCollection.Families.Length;
        }

        public int LoadFontsFromFile()
        {
            var fontCollection = new PrivateFontCollection();
            var fontFiles = Directory.GetFiles(fontDir, "*.ttf");
            Array.ForEach(fontFiles, fontFile => {
                fontCollection.AddFontFile(fontFile);                
            });
            return fontCollection.Families.Length;
        }

    }
}

我也试过没有释放fontDataPtr,但无济于事。

I also tried without freeing the fontDataPtr, but to no avail.

推荐答案

Hi Anfreas Kolbow,

Hi Anfreas Kolbow,

感谢您在此发帖。

根据您的描述,它将无法正常工作而不是从文件中加载字体。原因特定于内存加载字体,在
AddMemoryFont方法

According to your description, it will not work instead loaded font from file. The reason is specific to memory loaded fonts, described in remarks to AddMemoryFont method.

要使用内存字体,必须使用GDI +呈现控件上的文本。使用SetCompatibleTextRenderingDefault方法,传递true,通过将控件的UseCompatibleTextRendering
属性设置为true,在应用程序或单个控件上设置GDI +呈现。有些控件无法使用GDI +进行渲染。

To use the memory font, text on a control must be rendered with GDI+. Use the SetCompatibleTextRenderingDefault method, passing true, to set GDI+ rendering on the application, or on individual controls by setting the control's UseCompatibleTextRendering property to true. Some controls cannot be rendered with GDI+.

这是一个简单的代码示例,您可以从代码项目中下载以供参考。

Here is a simple code sample you could download from the code project for your reference.

https://www.codeproject.com/Articles/107376/Embedding-Font-To-Resources

最诚挚的问候,

Wendy


这篇关于将内存字体添加到私有字体集合无法可靠地工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆