Вы вводите cudafont
с текстом в кодировке UTF-8. Глядя на источник , кажется, что ничего не обрабатывает UTF-8 - или даже, если я вижу это правильно, ничего, что перекодирует что-нибудь от естественного порядка глифов в шрифте до обычной кодировки:
char c = str[n];
if( c < FirstGlyph || c > LastGlyph )
continue;
c -= FirstGlyph;
... now c will hold glyph data for a character
(из функции int4 cudaFont::TextExtents
)
Это означает, что эта библиотека серьезно повреждена в его обработке символов.
A глиф в следующем контексте означает только «определенное изображение, которое может быть связано с существующими символами или комбинацией символов (то есть лигатурой»). "- это один глиф, представляющий два символа" f "и" i "). Шрифт также должен определять кодировку (встроенную в соответствии с определенным соглашением, например шрифтами PostScript Type 1, или, в случае шрифтов TrueType / OpenType, определенных в их таблице cmap
, для связывания кодов символов с их правильными глифами.
Шрифты по умолчанию CUDA DejaVu Sans и DejaVu Sans Mono являются шрифтами TrueType и содержат cmap
таблицы, поэтому их глифы могут быть физически в произвольном порядке - это на усмотрение дизайнера шрифтов. Шрифт может сначала перечислить все свои глифы A, затем все свои глифы B и т. Д. Или быть в буквальном порядке. Если шрифт содержит таблицу кодировки для Latin-1, таблица будет преобразовываться между символьным кодом для A
и позицией шрифта для соответствующего глифа. Если этот же шрифт также содержит совершенно другую кодировку, такую как EBCDI C, его собственный код для A
(который не основан на ASCII и, следовательно, не "обычный" 0x41, но 0xC1), все равно будет указывать на то же самое A
глиф в шрифте.
То, что делает cudafont
, является чем-то совершенно другим. предполагает , что глифы для как минимум basi c ASCII появляются именно в таком порядке, начиная с самого первого глифа в шрифте. Это означает, что вы не можете использовать любой другой порядок глифов, кроме того, который был установлен разработчиком шрифта. Кроме того, поскольку cudafont
ограничивает коды символов только 8 битами, вы не можете получить доступ к любому из 6,107 (DejaVu Sans Mono) и 3,309 (DejaVu Sans Mono) символов, кроме тех, которые находятся в диапазоне до кода ASCII 256.
Я кратко оглянулся на набор глифов, и мне кажется, что они в порядке Unicode . Теперь, если повезет (для программистов cudafont
s), это действительно означает, что первые 95 символов расположены в порядке ASCII.
К сожалению для you , мой читатель из Западной Европы (обычно не заинтересован в чем-либо, выходящем за границы Latin-1) - следующий по-прежнему следует общему ISO / IEC 8859-1 order , но , согласно соглашению, в диапазоне от 0x7F до 0x9F отсутствует. В Unicode Latin-1 Supplement, которая основана на оригинальной Latin-1, эти коды представляют контрольных кодов и не имеют представления глифа.
Это все еще означает, что вы не можете кормить Python по умолчанию в него кодируются строки в кодировке UTF-8, но кроме простого ASCII вы также не можете указать Python для кодирования вашего текста в Latin-1. Python может хорошо его кодировать:
text = 'fængsel'
print (text)
print (text.encode('latin-1'))
fængsel
b'f\xe6ngsel'
, но из-за этого пропущенного диапазона отображается символ, который появляется в списке только на 33 символа: ć
.
Решение: между ними пропущено 33 символа, поэтому вы можете настроить (теперь) двоичное строковое содержимое, чтобы оно снова соответствовало физическому порядку символов:
btext = bytes([c if c <= 0x7f else c-33 for c in text.encode('latin-1')])
print (btext)
b'f\xc5ngsel'
и что строка должна (теоретически) окончательно отобразить ваш fængsel
.
Любому гипотетическому пользователю, который хочет получить доступ к глифам вне диапазона этого исправления, не повезло, пока cudafont
не будет обновлено до (а) правильно использовать кодировку шрифта и (б) поддерживать полный диапазон Юникода вместо char
с. По крайней мере, он получает краткое упоминание в stb_truetype.h
:
// Todo:
// не-MS cmaps