14

只是好奇,Windows 上的字体名称是否总是有英文面孔名称,或者它们是否可以根据用户选择的 UI 语言进行本地化?

也就是说,Times New Roman在中文安装Windows上也这么叫吗?

4

1 回答 1

10

如果字体创建者选择为特定语言环境发布元数据,则字体名称会被本地化,但所有字体都有一个系统已知的名称,通常是 PostScript 名称,以确保可以以合理的可靠性引用和检索相同的字体。

对于 OpenType 和 TrueType 字体,您可以在nameOpenType 文件的记录中找到本地化名称。

命名表(OpenType 规范 1.6)@Microsoft 排版
字体名称表(TrueType 规范)@Apple

对于 PostScript Type 1 字体,您可以通过它们的 FontName 声明找到分配的名称。

Adobe Type 1 字体格式 @ Adob​​e (PDF)

更新:

我检查了 PostScript 名称是否可用于实例化字体,不幸的是它不起作用。但是,使用本地化名称(从 Mark Ransom 在他的评论中的链接中检索到)确实有效。此示例使用 C#。

using System.Drawing;

namespace FontNameCheckApplication
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Font TimesNewRomanByPSName = new Font("TimesNewRomanPSMT", 16f);
            Console.WriteLine("TimesNewRomanPSMT = {0}", TimesNewRomanByPSName.Name);

            Font TimesNewRomanByName = new Font("Times New Roman", 16f);
            Console.WriteLine("Times New Roman = {0}", TimesNewRomanByName.Name);

            Font ArialByPSName = new Font("ArialMT", 16f);
            Console.WriteLine("ArialMT = {0}", ArialByPSName.Name);

            Font ArialByName = new Font("Arial", 16f);
            Console.WriteLine("Arial = {0}", ArialByName.Name);

            Font GulimByEnglishName = new Font("Gulim", 16f);
            Console.WriteLine("Gulim = {0}", GulimByEnglishName.Name);

            Font GulimByKoreanName = new Font("굴림", 16f);
            Console.WriteLine("굴림 = {0}", GulimByKoreanName.Name);

            Console.ReadKey();
        }
    }
}

不幸的是,我们在字体替换上遇到了麻烦,因为“Microsoft Sans Serif”绝对不是 Times New Roman 或 Arial。这表明 PostScript 名称不能可靠地用于引用相同的字体。

这是输出:

TimesNewRomanPSMT = Microsoft Sans Serif
Times New Roman = Times New Roman
ArialMT = Microsoft Sans Serif
Arial = Arial
Gulim = Gulim
?? = Gulim

更新#2:

这是 Win32 的示例。

需要注意的一件事CreateFontIndirect()是可以替换。在运行这个示例时,我从来没有得到一个空句柄,即使是 PostScript 名称也是如此。要查看我们是否可以获得未替换的匹配,我们应该使用EnumFontFamiliesEx()扫描可用的系统字体列表。我们得到与 C# 相同的结果,但没有替换。对于某些字体,结果可能取决于图形模式设置(参见SetGraphicsMode()/GM_ADVANCED)。

LOGFONT 结构(Windows) @MSDN
CreateFontIndirect 函数(Windows)
@MSDN SetGraphicsMode 函数(Windows)@MSDN
EnumFontFamiliesEx 函数(Windows) @MSDN
EnumFontFamExProc 回调函数(Windows) @MSDN

#include "stdafx.h"
#include <Windows.h>

void TestCreateFont(LPCTSTR lpczFontName, BYTE bCharSet)
{
  LOGFONT lf;
  lf.lfHeight = 0;
  lf.lfWidth = 0;
  lf.lfEscapement = 0;
  lf.lfOrientation = 0;
  lf.lfWeight = FW_DONTCARE;
  lf.lfItalic = FALSE;
  lf.lfUnderline = FALSE;
  lf.lfStrikeOut = FALSE;
  lf.lfCharSet = bCharSet;
  lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
  lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  lf.lfQuality = DEFAULT_QUALITY;
  lf.lfPitchAndFamily = DEFAULT_PITCH;  
  // NOTE: LF_FACESIZE = 32, WinGdi.h
  _tcsncpy_s(lf.lfFaceName, 32, lpczFontName, _tcsnlen(lpczFontName, 32));

  HFONT hf = ::CreateFontIndirect(&lf);

  // NOTE: LF_FACESIZE = 32, WinGdi.h
  _tprintf_s(_T("TestCreateFont:\r\n%.32s = %.32s, bCharSet=%d, HFONT=0x%8.8x\r\n\r\n"), lpczFontName, lf.lfFaceName, bCharSet, hf);

  ::DeleteObject(hf);
}

int CALLBACK MyEnumFontFamExProc(const LOGFONT *lpelfe, const TEXTMETRIC *lpntme, DWORD FontType, LPARAM lParam)
{
  _tprintf_s(_T("  Found: %.32s, bCharSet=%d\r\n"), lpelfe->lfFaceName, lpelfe->lfCharSet);

  return 1;
}

void TestEnumFontFamiliesEx(LPCTSTR lpczFontName, BYTE bCharSet)
{
  LOGFONT lf;
  lf.lfHeight = 0;
  lf.lfWidth = 0;
  lf.lfEscapement = 0;
  lf.lfOrientation = 0;
  lf.lfWeight = FW_DONTCARE;
  lf.lfItalic = FALSE;
  lf.lfUnderline = FALSE;
  lf.lfStrikeOut = FALSE;
  lf.lfCharSet = bCharSet;
  lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
  lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  lf.lfQuality = DEFAULT_QUALITY;
  lf.lfPitchAndFamily = DEFAULT_PITCH; // NOTE: DEFAULT_PITCH = 0, WinGdi.h
  // NOTE: LF_FACESIZE = 32, WinGdi.h
  _tcsncpy_s(lf.lfFaceName, 32, lpczFontName, _tcsnlen(lpczFontName, 32));

  _tprintf_s(_T("TestEnumFontFamiliesEx: %.32s, bCharSet=%d\r\n"), lpczFontName, bCharSet);

  HDC hdcAll = GetDC(NULL);

  ::EnumFontFamiliesEx(hdcAll, &lf, &MyEnumFontFamExProc, 0, 0);
}

int _tmain(int argc, _TCHAR* argv[])
{
  TestCreateFont(_T("TimesNewRomanPSMT"), DEFAULT_CHARSET);
  TestCreateFont(_T("Times New Roman"), DEFAULT_CHARSET);

  TestCreateFont(_T("ArialMT"), DEFAULT_CHARSET);
  TestCreateFont(_T("Arial"), DEFAULT_CHARSET);

  TestCreateFont(_T("Gulim"), DEFAULT_CHARSET);

  TestCreateFont(_T("굴림"), DEFAULT_CHARSET);

  TestEnumFontFamiliesEx(_T("TimesNewRomanPSMT"), DEFAULT_CHARSET);
  TestEnumFontFamiliesEx(_T("Times New Roman"), DEFAULT_CHARSET);

  TestEnumFontFamiliesEx(_T("ArialMT"), DEFAULT_CHARSET);
  TestEnumFontFamiliesEx(_T("Arial"), DEFAULT_CHARSET);

  TestEnumFontFamiliesEx(_T("Gulim"), DEFAULT_CHARSET);

  TestEnumFontFamiliesEx(_T("굴림"), DEFAULT_CHARSET);

  return 0;
}

结果如下:

TestCreateFont:
TimesNewRomanPSMT = TimesNewRomanPSMT, bCharSet=1, HFONT=0xda0a117c

TestCreateFont:
Times New Roman = Times New Roman, bCharSet=1, HFONT=0xdb0a117c

TestCreateFont:
ArialMT = ArialMT, bCharSet=1, HFONT=0xdc0a117c

TestCreateFont:
Arial = Arial, bCharSet=1, HFONT=0xdd0a117c

TestCreateFont:
Gulim = Gulim, bCharSet=1, HFONT=0xde0a117c

TestCreateFont:
?? = ??, bCharSet=1, HFONT=0xdf0a117c

TestEnumFontFamiliesEx: TimesNewRomanPSMT, bCharSet=1
TestEnumFontFamiliesEx: Times New Roman, bCharSet=1
  Found: Times New Roman, bCharSet=0
  Found: Times New Roman, bCharSet=177
  Found: Times New Roman, bCharSet=178
  Found: Times New Roman, bCharSet=161
  Found: Times New Roman, bCharSet=162
  Found: Times New Roman, bCharSet=186
  Found: Times New Roman, bCharSet=238
  Found: Times New Roman, bCharSet=204
  Found: Times New Roman, bCharSet=163
  Found: Times New Roman, bCharSet=0
  Found: Times New Roman, bCharSet=177
  Found: Times New Roman, bCharSet=161
  Found: Times New Roman, bCharSet=162
  Found: Times New Roman, bCharSet=186
  Found: Times New Roman, bCharSet=238
  Found: Times New Roman, bCharSet=204
  Found: Times New Roman, bCharSet=163
  Found: Times New Roman, bCharSet=0
  Found: Times New Roman, bCharSet=177
  Found: Times New Roman, bCharSet=178
  Found: Times New Roman, bCharSet=161
  Found: Times New Roman, bCharSet=162
  Found: Times New Roman, bCharSet=186
  Found: Times New Roman, bCharSet=238
  Found: Times New Roman, bCharSet=204
  Found: Times New Roman, bCharSet=163
  Found: Times New Roman, bCharSet=0
  Found: Times New Roman, bCharSet=177
  Found: Times New Roman, bCharSet=161
  Found: Times New Roman, bCharSet=162
  Found: Times New Roman, bCharSet=186
  Found: Times New Roman, bCharSet=238
  Found: Times New Roman, bCharSet=204
  Found: Times New Roman, bCharSet=163
TestEnumFontFamiliesEx: ArialMT, bCharSet=1
TestEnumFontFamiliesEx: Arial, bCharSet=1
  Found: Arial, bCharSet=0
  Found: Arial, bCharSet=177
  Found: Arial, bCharSet=178
  Found: Arial, bCharSet=161
  Found: Arial, bCharSet=162
  Found: Arial, bCharSet=186
  Found: Arial, bCharSet=238
  Found: Arial, bCharSet=204
  Found: Arial, bCharSet=163
  Found: Arial, bCharSet=0
  Found: Arial, bCharSet=177
  Found: Arial, bCharSet=161
  Found: Arial, bCharSet=162
  Found: Arial, bCharSet=186
  Found: Arial, bCharSet=238
  Found: Arial, bCharSet=204
  Found: Arial, bCharSet=163
  Found: Arial, bCharSet=0
  Found: Arial, bCharSet=177
  Found: Arial, bCharSet=178
  Found: Arial, bCharSet=161
  Found: Arial, bCharSet=162
  Found: Arial, bCharSet=186
  Found: Arial, bCharSet=238
  Found: Arial, bCharSet=204
  Found: Arial, bCharSet=163
  Found: Arial, bCharSet=0
  Found: Arial, bCharSet=177
  Found: Arial, bCharSet=161
  Found: Arial, bCharSet=162
  Found: Arial, bCharSet=186
  Found: Arial, bCharSet=238
  Found: Arial, bCharSet=204
  Found: Arial, bCharSet=163
TestEnumFontFamiliesEx: Gulim, bCharSet=1
  Found: Gulim, bCharSet=0
  Found: Gulim, bCharSet=129
  Found: Gulim, bCharSet=161
  Found: Gulim, bCharSet=162
  Found: Gulim, bCharSet=186
  Found: Gulim, bCharSet=238
  Found: Gulim, bCharSet=204
TestEnumFontFamiliesEx: ??, bCharSet=1
  Found: Gulim, bCharSet=0
  Found: Gulim, bCharSet=129
  Found: Gulim, bCharSet=161
  Found: Gulim, bCharSet=162
  Found: Gulim, bCharSet=186
  Found: Gulim, bCharSet=238
  Found: Gulim, bCharSet=204

这是 CharSet 值的片段wingdi.h

#define ANSI_CHARSET            0
#define DEFAULT_CHARSET         1
#define SYMBOL_CHARSET          2
#define SHIFTJIS_CHARSET        128
#define HANGEUL_CHARSET         129
#define HANGUL_CHARSET          129
#define GB2312_CHARSET          134
#define CHINESEBIG5_CHARSET     136
#define OEM_CHARSET             255

#define JOHAB_CHARSET           130
#define HEBREW_CHARSET          177
#define ARABIC_CHARSET          178
#define GREEK_CHARSET           161
#define TURKISH_CHARSET         162
#define VIETNAMESE_CHARSET      163
#define THAI_CHARSET            222
#define EASTEUROPE_CHARSET      238
#define RUSSIAN_CHARSET         204

#define MAC_CHARSET             77
#define BALTIC_CHARSET          186
于 2013-02-05T22:10:56.670 回答