Как определяется, какой символ шрифта отображается при использовании определенной кодировки символов?

318
Foo Bar

Я пытаюсь понять всю историю появления текста на экранах. Для простоты я остаюсь с однобайтовыми кодировками (без Unicode).

На моем диске есть последовательность байтов, каждый со значением от 0 до 255. Затем я могу сообщить своим компьютерным программам, какую кодировку символов они должны использовать для отображения этих байтов. Я мог бы использовать ISO-8859-1, где, например, байт со значением 0xA4 - это круг с точками (¤). Или я мог бы переключиться на ISO-8859-15, тогда мой байт со значением 0xA4 определяется как символ евро (€).

Это все еще просто понять. Но параллельно с изменением кодировки символов я также могу изменить шрифт, чтобы определить точную форму символа. Теперь шрифт предназначен для работы со всеми кодировками символов. Итак, шрифт должен иметь оба символа: ¤ и €.

Итак, шаги, чтобы получить текст на моем экране, очевидно:

  1. Читать последовательность байтов последовательно
  2. Используйте числовое значение текущего байта для поиска в таблице кодировки символов
  3. Используйте [что-то] для поиска в файле шрифта, чтобы получить точную форму символа, найденного на шаге 2
  4. Нарисуйте символ как определено в файле шрифта

На шаге 3, что это за «что-то», которое используется для сопоставления кодировки символов со шрифтом? Файлы шрифтов зависят от кодировки символов? Итак, есть ли у шрифта какой-то встроенный механизм «двойного переключения», который работает как (псевдокод)

get_symbol(code, encoding) { switch code{ case 0xA4: switch(encoding) { case 'ISO-8859-1' : return '¤'; case 'ISO-8859-15': return '€'; } } } 

?

Каковы подробности, как получить из заданной последовательности байтов и заданной кодировки символов фактический символ из шрифта? Как это отображается, чтобы всегда давать правильный символ?

0

2 ответа на вопрос

2
Thomas Dickey

Font files are designed to show a particular encoding. The program using a given font has to assume that a value n in a given encoding is displayed by rendering the corresponding glyph number n.

Font files need not have glyphs for all possible values of a given character encoding (for Unicode it is rare for a font to cover the whole range), nor need they start with the first value from the encoding (usually the control characters are omitted). There are different file-format schemes for specifying the starting point, ending point and omitted glyphs which are used to keep font file-sizes manageable.

From the example given, the OP is likely using the X Window system. There is more than one file-format used, with corresponding different ways they are accessed. The principal ones are XLFD (older) and fontconfig (newer). With other systems (Microsoft Windows), other APIs are used (the LOGFONT structure is a good starting point). OSX is another example, with its own API (CoreText).

Those of course are for graphical interfaces. Fonts are more widely applicable than that. For instance, Linux and the BSDs allow one to specify different console fonts — which in addition to encoding, run into limitations on the number of glyphs which are usable. Here are a few useful links for those:

0
Spiff

The app drawing the text specifies a font in the text drawing APIs it's using, or if it doesn't specify, a system default font is used.

Unicode-based text drawing systems often have a font substitution algorithm to find a font that contains a certain glyph if the specified font doesn't have the glyph requested. But pre-Unicode systems generally just fail to draw a glyph or draw a "missing glyph" glyph. Even Unicode-based systems sometimes draw a "missing glyph" symbol.

Похожие вопросы