Являются ли имена шрифтов на Windows только для Windows? - программирование
Подтвердить что ты не робот

Являются ли имена шрифтов на Windows только для Windows?

Просто любопытно, что имена шрифтов в Windows всегда имеют английские имена лиц или они могут быть локализованы в зависимости от выбранного пользователем языка пользовательского интерфейса?

Другими словами, называется Times New Roman так же, как на китайской установке Windows?

4b9b3361

Ответ 1

Имена шрифтов локализуются, если создатель шрифта выбирает публикацию метаданных для определенной локали, но все шрифты имеют имя, известное в системе, обычно это имя PostScript, которое гарантирует, что один и тот же шрифт можно ссылаться и извлекать с разумной суммой надежности.

Для шрифтов OpenType и TrueType вы можете найти локализованные имена в записи name файла OpenType.

Таблица имен (OpenType Spec 1.6) @Типография Microsoft
Таблица имен шрифтов (спецификация TrueType) @Apple

Для шрифтов PostScript Type 1 вы можете найти назначенные имена по их объявлениям FontName.

Формат шрифта Adobe Type 1 @Adobe (PDF)

Update:

Я проверил, можно ли использовать имя PostScript для создания шрифта, и, к сожалению, он не работает. Однако использование локализованного имени (как было получено из ссылки Mark Ransom в его комментарии) действительно работает. Этот образец находится в С#.

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() для сканирования списка доступных системных шрифтов. Мы получаем те же результаты, что и С#, но без подстановок. Для некоторых шрифтов результаты могут зависеть от настройки графического режима (см. 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

Здесь приведен фрагмент из wingdi.h для значений CharSet.

#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