.NET PrivateFontCollection - 加载不同样式的字体

时间:2011-02-02 16:04:10

标签: .net fonts azure true-type-fonts

我正在尝试将应用程序从传统的ASP.NET移植到Azure,而且我遇到了一个字体问题。有一个组件可以使用特定的非标准字体呈现带有文本的图像(让我们将字体称为“水”)。

水存在于几个不同的TTF文件中,每个文件代表不同的风格。我总共有12种不同的TTF文件,涵盖了“Water Black Italic”,“Water Light”,“Water Regular”,“Water Ultralight”等风格。

在ASP.NET上,这是一个简单的例子,在Windows目录中安装字体,然后从代码调用中安装:

Font _fontMedium = new Font("Water Medium", iFontMedium, FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);

但是,在Azure上,您无法安装自己的字体。因此,为了能够在图像上绘制这些字体,我需要将字体文件作为内容上传到应用程序,并使用PrivateFontCollection类来单独加载它们。

我目前的代码是:

        PrivateFontCollection fontcollection = new PrivateFontCollection();
        string fontpath = string.Concat(System.Web.HttpContext.Current.Request.PhysicalApplicationPath + "assets\\");
        fontcollection.AddFontFile(string.Concat(fontpath,"water-bold-webfont.ttf"));
        fontcollection.AddFontFile(string.Concat(fontpath, "water-ultralight-webfont.ttf"));
        fontcollection.AddFontFile(string.Concat(fontpath, "water-medium-webfont.ttf"));
        FontFamily[] privatefontfamilies = fontcollection.Families;


        Font _fontMedium = new Font("Water Medium", iFontMedium, FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);
        Font _fontSmall = new Font("Water UltraLight", iFontSmall, System.Drawing.GraphicsUnit.Pixel);
        Font _fontMini = new Font("Water Bold", iFontMini, System.Drawing.GraphicsUnit.Pixel);

我遇到的问题是,在添加字体文件后中断后,fontcollection.Families集合中只有一个Family:“Water”。

类似地,在声明了字体对象之后,Family默认为Microsoft Sans-Serif。如果我改为使用:

Font _fontMedium = new Font("Water", iFontMedium, FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel);

字体加载了“Water”系列,但似乎没有让我能够正确选择样式。我唯一的字体样式选项是FontStyle枚举中定义的那些,它不包括我试图加载的所有字体样式。

简而言之,给定一个特定字体及其所有可用样式加载到单独的TTF文件中,如何将它们加载到PrivateFontCollection中并单独使用它们?

2 个答案:

答案 0 :(得分:1)

参考上面的代码,你可以试试......

Font _fontMedium = 
    new Font(privatefontfamilies[0] , iFontMedium, FontStyle.Regular, 
             System.Drawing.GraphicsUnit.Pixel);

而不是使用fontname字符串对字体进行参数化。

微软称(来源:MSDN):

  

传递给Font构造函数的第一个参数是字体系列   name(不是FontFamily对象,就像其他变体的情况一样)   Font构造函数)

我挣扎着说这绝对错了(并且不起作用)!使用fontfamily的名称,您想要创建的字体将替换为类似的字体(就像您上面所写的那样)。使用fontfamily-object作为参数可以正常工作(对我而言)。

答案 1 :(得分:0)

我有一个答案。我努力让PrivateFontCollection工作一段时间,我努力工作,GDI也不会有任何问题。

我开始深入研究像AddFontResource这样的原生Win32函数,看看他们是否可以做任何事情。我最终发现你需要做的就是将TTF字体文件打包为包的内容,将注册表项添加到“HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Fonts”中,为每种字体注册它,然后您可以使用您为注册表项指定的名称创建一个新的字体。

简而言之:

AddFont("Water (TrueType)", string.Concat(fontpath, "Water-Black.ttf"));

Font myfont = new Font("Water Black",16f);

private void AddFont(string fontname, string path) {
    Registry.SetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts", fontname, path, RegistryValueKind.String);
}

这似乎对开发工作很有用,我会在分期测试并报告回来。