使用Century代替Century Gothic停止WPF

时间:2011-07-28 09:15:24

标签: wpf fonts

如果安装了Century Gothic,我们的设计会更喜欢使用Century Gothic,但如果没有,则会回到Arial或Lucidia。除非机器没有安装Century Gothic,否则确实具有Century(这似乎是很多没有Office的XP机器),这在大多数情况下都可以正常工作。 “有帮助”它代替Century,这对于Century Gothic来说是可怕的,并且完全忽略了我们的后备字体。

通过拥有Century而非Century Gothic的机器可以轻松再现,然后创建一个TextBlock,例如:

<TextBlock FontFamily="Century Gothic, Wingdings">Should be gibberish</TextBlock>

应该显示为胡言乱语的Wingdings,但它显示的是丑陋但可读的世纪。

我已尝试将Century Gothic包装在复合材料中,但这有同样的问题:

<FontFamily
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/composite-font"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib">
  <FontFamily.FamilyNames>
    <System:String x:Key="en-US">CenturyGothic</System:String>
  </FontFamily.FamilyNames>
  <FontFamily.FamilyTypefaces>
    <FamilyTypeface Weight="Normal" Stretch="Normal" Style="Normal" />
    <FamilyTypeface Weight="Bold" Stretch="Normal" Style="Normal" />
  </FontFamily.FamilyTypefaces>
  <FontFamily.FamilyMaps>
    <FontFamilyMap Target="Century Gothic" Scale="1" />
  </FontFamily.FamilyMaps>
</FontFamily>

嵌入字体不是一种选择(许可) - 是否有任何方法可以强制它忽略Century,或者我是否已将其更改为使用其他字体?

编辑:我刚刚尝试使用FontFace =“'Century Gothic',Wingdings”,但即使安装了Century Gothic也不会显示它。

4 个答案:

答案 0 :(得分:2)

您可以使用WPF样式和合并资源字典执行此操作。

创建两个资源字典,一个用于默认字体,另一个用于后备字体:

DefaultFonts.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="TextBlock">
        <Setter Property="FontFamily" Value="Century Gothic"/>
    </Style>
</ResourceDictionary>

FallbackFonts.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="TextBlock">
        <Setter Property="FontFamily" Value="Arial"/>
    </Style>
</ResourceDictionary>

将两个文件添加到项目中,并将构建操作设置为资源

将以下代码添加到您的应用启动:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {            
        base.OnStartup(e);

        string fontsResourcePath = "/DefaultFonts.xaml";
        if (!Fonts.SystemFontFamilies.Any(f => f.FamilyNames.Any(kv => kv.Value == "Century Gothic")))
        {
            fontsResourcePath = "/FallbackFonts.xaml";
        }
        this.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri(fontsResourcePath, UriKind.Relative) });
    }
}

这样做会自动在整个应用程序的所有控件上设置正确的字体(除非您在窗口,页面或控件上本地覆盖字体)。

示例:

<Grid>
    <TextBlock>This will show as Century Gothic or fall back to Arial</TextBlock>
</Grid>

快乐的编码!

答案 1 :(得分:1)

字体的完全限定路径可能会起到作用:

<TextBlock Margin="20" FontFamily="c:\windows\fonts\GOTHIC.TTF#Century Gothic, Wingdings">Should be gibberish</TextBlock>

对路径进行硬编码并不理想,但是如果用户通过非标准安装路径运行,则可以添加使用字体友好名称的回退。您还可以使用代码在注册表中查找字体目录并使用它。

另一种选择可能是使用代码迭代已安装的字体并选择你想要的那种字体。 System.Windows.Media.Fonts.SystemFontFamilies已安装字体。找到所需的字体后,可以将该字体系列对象分配给控件,而不是要求它解析字符串。

答案 2 :(得分:1)

问题似乎是WPF按家庭搜索字体,而不是Face。在您的场景中,Century和Century Gothic都是Century系列字体的一部分。因此,您需要将所有Faces映射到您想要的Faces。请确认这适用于您:

<Label Content="Hello World" FontSize="32">
    <Label.FontFamily>
        <FontFamily xmlns:sys="clr-namespace:System;assembly=mscorlib">
            <FontFamily.FamilyNames>
                <sys:String x:Key="en-US">Century, Century Gothic, Century Schoolbook</sys:String>
            </FontFamily.FamilyNames>
            <FontFamily.FamilyMaps>
                <FontFamilyMap Target="Century Gothic" />

                <!-- used when Century Gothic is not available -->
                <FontFamilyMap Target="Arial" />
            </FontFamily.FamilyMaps>
        </FontFamily>
    </Label.FontFamily>
</Label>

答案 3 :(得分:0)

好的,目前我有一个工作,如果有点笨拙的感觉,解决方案。我有一个静态助手类,如下所示:

namespace FontFallbackTest
{
    using System.Linq;
    using System.Windows.Markup;
    using System.Windows.Media;

    public static class FontHelper
    {
        private static readonly FontFamily testFont;
        public static FontFamily TestFont
        {
            get
            {
                return testFont;
            }
        }

        static FontHelper()
        {
            testFont = new FontFamily();

            testFont.FamilyNames.Add(XmlLanguage.GetLanguage("en-US"), "TestFont");

            if (Fonts.SystemFontFamilies.Any(f => f.FamilyNames.Any(kv => kv.Value == "Century Gothic")))
            {
                testFont.FamilyMaps.Add(new FontFamilyMap() { Target = "Century Gothic" });
            }

            testFont.FamilyMaps.Add(new FontFamilyMap() { Target = "Comic Sans MS", Scale = 0.5 });
        }
    }
}

然后我在我的XAML中引用如下:

<Window x:Class="FontFallbackTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:FontFallbackTest="clr-namespace:FontFallbackTest"
        Title="MainWindow" Height="550" Width="525">
    <Grid>
        <Label Margin="0,100,0,0" FontSize="48" FontFamily="{x:Static FontFallbackTest:FontHelper.TestFont}">This is some text</Label>
        <Label Margin="0,150,0,0" FontSize="48" FontFamily="{x:Static FontFallbackTest:FontHelper.TestFont}">This is more text</Label>
    </Grid>
</Window>

这似乎有效 - 显示Century Gothic,忽略Century,并允许我控制后备字体缩放。