C #: проверка на неподдерживаемые символы / глифы в шрифте - PullRequest
3 голосов
/ 17 февраля 2011

Я работаю над надстройкой программного обеспечения для перевода (C #, .NET 2.0), которая отображает переведенные тексты на дисплее эмулированного устройства. Я должен проверить, могут ли все переведенные тексты отображаться с указанными шрифтами (Windows TTF). Но я не нашел способа проверить шрифт на неподдерживаемые глифы. У кого-нибудь есть идея?

Спасибо

1 Ответ

6 голосов
/ 22 февраля 2011

Вы ограничены .NET 2.0? В .NET 3.0 или выше есть класс GlyphTypeface, который может загружать файл шрифтов и предоставляет свойство CharacterToGlyphMap, которое, я считаю, может делать то, что вы хотите.

В .NET 2.0, я думаю, вам придется полагаться на PInvoke. Попробуйте что-то вроде:

using System.Drawing;
using System.Runtime.InteropServices;

[DllImport("gdi32.dll", EntryPoint = "GetGlyphIndicesW")]
private static extern uint GetGlyphIndices([In] IntPtr hdc, [In] [MarshalAs(UnmanagedType.LPTStr)] string lpsz, int c, [Out] ushort[] pgi, uint fl);

[DllImport("gdi32.dll")]
private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);

private const uint GGI_MARK_NONEXISTING_GLYPHS = 0x01;

// Create a dummy Graphics object to establish a device context
private Graphics _graphics = Graphics.FromImage(new Bitmap(1, 1));

public bool DoesGlyphExist(char c, Font font)
{
  // Get a device context from the dummy Graphics 
  IntPtr hdc = _graphics.GetHdc();
  ushort[] glyphIndices;

  try {
    IntPtr hfont = font.ToHfont();

    // Load the font into the device context
    SelectObject(hdc, hfont);

    string testString = new string(c, 1);
    glyphIndices = new ushort[testString.Length];

    GetGlyphIndices(hdc, testString, testString.Length, glyphIndices, GGI_MARK_NONEXISTING_GLYPHS);

  } finally {

    // Clean up our mess
    _graphics.ReleaseHdc(hdc);
  }

  // 0xffff is the value returned for a missing glyph
  return (glyphIndices[0] != 0xffff);
}

private void Test()
{
  Font f = new Font("Courier New", 10);

  // Glyph for A is found -- returns true
  System.Diagnostics.Debug.WriteLine(DoesGlyphExist('A', f).ToString()); 

  // Glyph for ಠ is not found -- returns false
  System.Diagnostics.Debug.WriteLine(DoesGlyphExist((char) 0xca0, f).ToString()); 
}
...