2016-12-05 13 views

回答

1

新建答案 - 檢查自定義字體文件

您可以檢查是否字體使用IDWriteFontFace::GetGlyphIndices method通過DirectWrite的映射字形,以特定的Unicode字符/代碼。 DirectWrite有一個C#包裝器作爲SharpDx庫的一部分,特別是SharpDX.Direct2D1 package on nuget

我以SharpDx Directwrite example on github爲例。我使用文件選擇器對話框打開文件,因爲除非用戶自己選擇文件,否則UWP應用程序不允許訪問大部分文件系統。您也可以將字體與您的應用程序。我下載了兩個免費字體來測試「副翼」和「Grundschrift」。我只是非常快速地向你展示它並不那麼難,但是我確信代碼並不遵循最佳實踐。首先,從SharpDx Directwrite自定義字體示例中添加以下三個類:ResourceFontFileStream.cs,ResourceFontLoader.csResourceFontFileEnumerator.cs。將名稱空間更改爲您的項目命名空間。在ResourceFontLoader.cs改變構造這樣:

public ResourceFontLoader(Factory factory, List<Stream> fontfiles) 
{ 
    _factory = factory; 
    var AnyFontsLoaded = false; 
    foreach (var filename in fontfiles) 
    { 
     try 
     { 
      using (filename) 
      { 
       var fontBytes = Utilities.ReadStream(filename); 
       var stream = new DataStream(fontBytes.Length, true, true); 
       stream.Write(fontBytes, 0, fontBytes.Length); 
       stream.Position = 0; 
       _fontStreams.Add(new ResourceFontFileStream(stream)); 
       AnyFontsLoaded = true; 
      } 
     } 
     catch (System.Exception) 
     { 
      // Handle all file exceptions how you see fit 
      throw; 
     } 
    } 
    if (AnyFontsLoaded) 
    { 
     // Build a Key storage that stores the index of the font 
     _keyStream = new DataStream(sizeof(int) * _fontStreams.Count, true, true); 
     for (int i = 0; i < _fontStreams.Count; i++) 
      _keyStream.Write((int)i); 
     _keyStream.Position = 0; 

     // Register the 
     _factory.RegisterFontFileLoader(this); 
     _factory.RegisterFontCollectionLoader(this); 
    } 
} 

在您的測試主頁:

public sealed partial class MainPage : Page 
{ 
    public ResourceFontLoader CurrentResourceFontLoader { get; set; } 
    public FontCollection CurrentFontCollection { get; set; } 
    public SharpDX.DirectWrite.Factory FactoryDWrite { get; private set; } 
    public List<Stream> customFontStreams { get; set; } 
    public List<string> FontFamilyNames { get; set; } 
    public MainPage() 
    { 
     customFontStreams = new List<Stream>(); 
     this.InitializeComponent(); 
    } 

    async Task LoadCustomFonts() 
    { 
     await Task.Run(() => 
     { 
      // Font Families 
      FontFamilyNames = new List<string> { "Aileron", "Grundschrift" }; 
      // Character codes to check for: 
      int[] codes = { 0x41, 0x6f, 0x7c, 0xc2aa, 0xD7A3 }; 
      FactoryDWrite = new SharpDX.DirectWrite.Factory(); 
      CurrentResourceFontLoader = new ResourceFontLoader(FactoryDWrite, customFontStreams); 
      CurrentFontCollection = new FontCollection(FactoryDWrite, CurrentResourceFontLoader, CurrentResourceFontLoader.Key); 

      foreach (var fontfamilyname in FontFamilyNames) 
      { 
       int familyIndex; 
       CurrentFontCollection.FindFamilyName(fontfamilyname, out familyIndex); 

       using (var fontFamily = CurrentFontCollection.GetFontFamily(familyIndex)) 
       { 
        var font = fontFamily.GetFont(0); 

        using (var fontface = new FontFace(font)) 
        { 
         var results = fontface.GetGlyphIndices(codes); 
         for (int i = 0; i < codes.Length - 1; i++) 
         { 
          if (results[i] > 0) 
          { 
           Debug.WriteLine("Contains the unicode character " + codes[i]); 

          } 
          else 
          { 
           Debug.WriteLine("Does not contain the unicode character " + codes[i]); 
          } 
         } 
        } 
       } 

      } 
     }); 

    } 
    private async void button_Click(object sender, RoutedEventArgs e) 
    { 
     FileOpenPicker openPicker = new FileOpenPicker(); 
     openPicker.ViewMode = PickerViewMode.List; 
     openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary; 
     openPicker.FileTypeFilter.Add(".otf"); 
     openPicker.FileTypeFilter.Add(".ttf"); 
     IReadOnlyList<StorageFile> files = await openPicker.PickMultipleFilesAsync(); 
     if (files.Count > 0) 
     { 


      // Application now has read/write access to the picked file(s) 
      foreach (StorageFile file in files) 
      { 
       customFontStreams.Add(await file.OpenStreamForReadAsync()); 
      } 
      await LoadCustomFonts(); 
     } 
    } 
} 

原來的答案 - 檢查系統字體:

使用SharpDX.Direct2D1包的示例檢查字體是否具有某些字符:

var fontName = "Segoe UI"; 

using (var factory = new Factory(FactoryType.Shared)) 
{ 
    using (var fontCollection = factory.GetSystemFontCollection(true)) 
    { 
     int familyIndex; 
     fontCollection.FindFamilyName(fontName, out familyIndex); 

     using (var fontFamily = fontCollection.GetFontFamily(familyIndex)) 
     { 
      var font = fontFamily.GetFont(0); 

      using (var fontface = new FontFace(font)) 
      { 
       int[] codes = { 0x41, 0x6f, 0x7c, 0xc2aa, 0xD7A3 }; 

       var results = fontface.GetGlyphIndices(codes); 
       for (int i = 0; i < codes.Length - 1; i++) 
       { 
        if (results[i] > 0) 
        { 
         Debug.WriteLine("Contains the unicode character " + codes[i]); 
        } 
        else 
        { 
         Debug.WriteLine("Does not contain the unicode character " + codes[i]); 
        } 
       } 
      } 
     } 

    } 
} 
+0

這看起來很有前途 - 我唯一的問題是我正在使用的字體文件不是系統字體,而是存儲在本地。任何想法,如果這適用於字體文件,如:/Fonts/AnonymousPro-regular.ttf#Anonymous Pro? – erickfiveten

+1

SharpDx github有一個使用自定義字體的例子,它在這裏複製一點點時間。 [看看](https://github.com/sharpdx/SharpDX-Samples/tree/master/Desktop/DirectWrite/CustomFont) –

+0

淘了代碼後,我仍然沒有運氣得到自定義字體的工作與SharpDx。我知道乞丐不能挑選,但希望有一個更直接的解決方案...... – erickfiveten