2011-07-28 16 views
5

Century Gothicがインストールされている場合はそのデザインを使用しますが、使用できない場合はArialまたはLucidiaに戻します。マシンにCentury Gothicがインストールされていない限り、これはほとんどの場合うまく動作しますが、にCentury(OfficeなしのXPマシンがたくさんあるようです)があります。 Century Gothicのために恐ろしくてセリフの代わりになるCenturyを「助けて」置き換え、フォールバックフォントを完全に無視します。Century Gothicの代わりにCenturyを使用してWPFを停止する

それは世紀ではなく世紀のゴシック様式を持つマシンを持っていることによって容易に再現だ、そしてなどのTextBlockを作成します。ちんぷんかんぷんWingdingsフォントとして

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

それはずショー、代わりにそれは醜いが、読みやすい世紀に示し。

私はcompositefontで世紀のゴシック様式を包む試してみたが、それは同じ問題があります:フォントを埋め込む

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

はオプション(ライセンス)ではない - にそれを強制する方法はあります世紀を無視するか、別のフォントを使用するように辞めたのですか?

編集:私はちょうどFontFace =「『世紀のゴシック』、Wingdingsフォント」を使用してみましたが、それはそれがインストールされています場合にも、世紀のゴシックを表示することはありません。ハード

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

パスをコーディングすることは理想的ではありませんが、ユーザーが実行している場合には、フォントのフレンドリ名を使用するフォールバックを追加することができます。

+0

私は理解できませんが、フォント選択モデルは、http://blogs.msdn.com/b/text/archive/2007/04/23/wpf-font-selection-modelのPDFで概要を説明しています。 aspx。それはあまり役に立たないかもしれませんが、私の目はそれを見ようとしています。 –

答えて

0

[OK]を、現在私は少しclunky感じ、解決策があります。私はこのようになります静的ヘルパークラスを持っている:

私は、このように私のXAMLで参照
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 }); 
     } 
    } 
} 

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

これが動作しているようです - 、世紀のゴシック様式を示す世紀を無視して、私を許可しますフォールバック時のフォントスケーリングを制御します。

1

フォントへの完全修飾パスは、トリックを行う可能性があります標準以外のインストールパス経由でインストールします。また、コードを使用して、レジストリ内のフォントディレクトリを検索し、それを使用することもできます。

別の方法として、インストールされたフォントを繰り返し処理し、そのようにしたいフォントを選択することもできます。 System.Windows.Media.Fonts.SystemFontFamiliesにはインストールされているフォントがあります。必要なフォントを見つけたら、文字列の解析を要求するのではなく、そのフォントファミリオブジェクトをコントロールに割り当てることができます。

+0

理想的ではありませんか?良いもの。 –

+1

これはうまくいきますが、windowsディレクトリから参照するのは事故待ちです(%windir%は機能しません)。 –

1

問題は、WPFが、顔ではなく家族によってフォントを検索しているようです。あなたのシナリオでは、CenturyとCentury Gothicはすべて世紀のフォントファミリの一部です。したがって、すべての顔を必要なものにマッピングする必要があります。あなたのためにこれが動作することを確認してください:

<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> 
+0

ああ、興味深いことに、Centuryをフォントファミリに追加することは考えられませんでした。私はフォントの選択方法についてWPFの論文を読んだのですが、同様の名前のフォントが同じファミリであると仮定することについては何も言及していません。私はチャンスがあれば、今日はそれを与えるだろう。 –

+0

Centuryがインストールされていて、Century GothicではなくCenturyで表示されていて、Arialではなく、表示されているマシンでは、これはまったく同じ問題を抱えています。 –

+0

私はそれをwin xp pro、.net 4でテストし、期待どおりに動作しました。 osやフレームワークのバージョンに影響があるのだろうか? – sellmeadog

2

これは、WPFスタイルとMerged Resource Dictionariesを使用して行うことができます。

2つのリソースディクショナリ、デフォルトのフォントのための1つの、そしてあなたのフォールバックフォントのための1つを作成します。

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> 

2つのファイルを追加します。プロジェクトに設定してビルドアクションリソース

は、アプリの起動時に次のコードを追加します

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> 

コーディングハッピー!

関連する問題