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

发布于 2024-10-15 17:05:00 字数 1861 浏览 2 评论 0原文

我正在尝试将应用程序从传统 ASP.NET 移植到 Azure,但遇到了字体问题。有一个组件可以渲染图像,并在其上以特定的非标准字体绘制文本(我们将字体称为“Water”)。

Water 以多个不同的 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”。

同样,在声明字体对象后,该系列默认为 Microsoft Sans-Serif。如果我改为使用:

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

字体会加载“Water”系列,但似乎无法让我正确选择样式。我唯一的字体样式选项是 FontStyle 枚举中定义的选项,它不涵盖我尝试加载的所有字体样式。

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

I'm trying to port an application from traditional ASP.NET to Azure and I'm running into a font issue. There's a component that renders images with text drawn on it in a particular non-standard font (Lets call the font "Water").

Water exists as several different TTF files which each represent a different style. I have 12 different TTF files in total, covering styles such as "Water Black Italic", "Water Light", "Water Regular", "Water Ultralight" etc.

On ASP.NET, it was a simple case of installing the fonts in the Windows dir and then from the code calling:

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

However, on Azure, you can't install your own fonts. Therefore, in order to be able to draw these fonts on an image, I need to upload the font files as content with the application, and use the PrivateFontCollection class to load them individually.

My current code is this:

        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);

The problem I have is that after breaking after the font files have been added, there is only one Family in the fontcollection.Families collection: "Water".

Similarly, after the font objects have been declared, the Family defaults to a Microsoft Sans-Serif. If I instead use:

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

The font loads with the "Water" family, but doesn't seem to give me the ability to select the style properly. My only options for the font style are those defined in the FontStyle enum, which don't cover all the font styles that I'm trying to load.

In short, given a particular font and all of its available styles loaded in separate TTF files, how would you load them into a PrivateFontCollection and use them individually?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

油饼 2024-10-22 17:05:00

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

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

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

微软表示(来源:MSDN) :

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

我挣扎着发现这绝对是错误的(并且不起作用)!使用字体系列的名称,您要创建的字体将被替换为类似的字体(就像您上面所写的那样)。使用 fontfamily-object 作为参数效果很好(对我来说)。

referring to your code above, you could try...

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

instead of parametizing the font with the fontname string.

Microsoft says (Source: MSDN):

The first argument passed to the Font constructor is the font family
name (not a FontFamily object as is the case for other variations of
the Font constructor)

I struggled out that this is definitly wrong (and does not work)! Using the name of the fontfamily the font you want to create is replaced by a similar one (like you've written above). Using the fontfamily-object as parameter works fine (for me).

遥远的她 2024-10-22 17:05:00

我对此有一个答案。我花了一段时间试图让 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);
}

这似乎对开发人员来说效果很好,我将在登台上进行测试并返回报告。

I have an answer to this. I struggled for a while trying to get PrivateFontCollection to work, and GDI wouldn't have any of it.

I started to dig into native Win32 functions like AddFontResource to see if they could do anything. I eventually figured out that all you need to do is to package the TTF font files as content with the package, add registry entries to "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" for each font to register it, and then you can create a new Font just fine with the name that you gave to the registry key.

In short:

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);
}

This seems to work great on dev, I'll go test on staging and report back.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文