C#: 检查字体中不支持的字符/字形

4
我正在开发一个翻译软件插件(C#,.NET 2.0),它可以在模拟设备显示器上显示翻译后的文本。 我需要检查所有翻译后的文本是否能够使用指定字体(Windows TTF)来显示。 但是我没有找到任何方法来检查字体中是否存在不支持的字形。 有人有想法吗?
谢谢。
1个回答

9

您是否只能使用.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()); 
}

是的,我只能使用.NET 2.0。另一个问题是,你的代码对每个单独的字符进行检查。但在某些语言(如阿拉伯语)中,字符和字形之间没有一对一的关系。有些字形取决于周围的字符,有些字符则连接成一个单独的字形。因此,我需要一个检查完整字符串的方法... - Marco
GetGlyphIndices函数确实需要一个字符串作为参数,所以如果您想要,可以传递完整的字符串。我之所以这样设置只是因为我认为您正在检查单个字符。 - Jeremy Todd
MSDN表示,GetGlyphIndices()函数“尝试为lpstr指向的字符串中的每个字符识别单个字形表示。”所以我担心这对我不起作用。有一个指向“Uniscribe”函数的链接,但我没有找到一个简单的例子... - Marco
对我有效。我添加到函数中的唯一一件事是调用DeleteObject(hfont)以防止内存不足(资源)异常。 - miasbeck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接