Что означает «uniE0A1», возвращаемый FT_Get_Glyph_Name?

Этот вопрос, вероятно, является результатом моего непонимания чего-то фундаментального, но я действительно мог бы сделать с некоторой помощью, так что вот.

Пытаясь разобраться с рендерингом текста, свободным типом и т. д., Я наткнулся на эти странные глифы, которые, как я понимаю, сообщают о том, что они связаны с кодовой точкой юникода, но когда я проверяю со стороны юникода, эта кодовая точка недействительна .

Например, при использовании шрифта «Hack» глиф с индексом 1437 является примером этих загадочных глифов, см. ниже, как он выглядит.

Вот некоторый демонстрационный код, использующий оболочку freetype-py python для freetype.

Во-первых, в качестве примера того, что выглядит правдоподобно и применимо к> 99% глифов, давайте посмотрим на букву "A":

import numpy as np
import freetype as FT
import unicodedata

ff = FT.Face('/usr/share/fonts/truetype/Hack-Regular.ttf')
ff.set_char_size(12<<6)

ff.load_glyph(1425)
ff.get_glyph_name(1425)
# b'uni0041'

hex 41 — это десятичное число 65, которое представляет собой ascii/unicode для «A», и визуализированное растровое изображение также выглядит как «A».

np.array(ff.glyph.bitmap.buffer).reshape(-1,8)
# array([[  0,   0,  67, 255, 121,   0,   0,   0],
#        [  0,   0, 143, 213, 198,   0,   0,   0],
#        [  0,   0, 218,  85, 250,  21,   0,   0],
#        [  0,  38, 248,   9, 203,  95,   0,   0],
#        [  0, 115, 191,   0, 136, 171,   0,   0],
#        [  0, 191, 125,   0,  69, 242,   5,   0],
#        [ 15, 250, 252, 252, 252, 255,  68,   0],
#        [ 87, 231,   2,   0,   0, 178, 145,   0],
#        [162, 152,   0,   0,   0,  97, 221,   0]])
unicodedata.name(chr(0x0041))
# 'LATIN CAPITAL LETTER A'

теперь давайте сделаем то же самое для индекса глифа 1437:

ff.load_glyph(1437)
ff.get_glyph_name(1437)
# b'uniE0A1'
np.array(ff.glyph.bitmap.buffer).reshape(-1,5)
# array([[ 56,  70,   0,   0,   0],
#        [112, 140,   0,   0,   0],
#        [112, 140,   0,   0,   0],
#        [112, 140,   0,   0,   0],
#        [112, 140,   0,   0,   0],
#        [112, 140,   0,   0,   0],
#        [105, 232, 224, 178,   0],
#        [  0, 168, 150,  40, 216],
#        [  0, 168, 241,  46, 216],
#        [  0, 168, 223, 124, 216],
#        [  0, 168, 131, 215, 216],
#        [  0, 168,  81, 212, 216],
#        [  0, 168,  84, 108, 216]])
unicodedata.name(chr(0xE0A1))
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# ValueError: no such name

Итак, глиф называет себя «uniE0A1», но, как я уже сказал, юникод не имеет там кодовой точки (я дважды проверил, и ее нет в UnicodeData.txt (кажется, версия 12)) и я не распознаю растровое изображение.

Этот вопрос слабо связан с Почему num_glyphs не соответствует количеству глифов, перечисленных FT_Get_First_Char/FT_Get_Next_Char , еще одним примером того, что вещи не складываются.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
102
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Кодовая точка U+E0A1 находится в зоне частного использования. Шрифт может использовать его для пользовательских символов.

https://www.unicode.org/charts/PDF/UE000.pdf

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

Paul Panzer 22.06.2019 22:41

@PaulPanzer Нет! Вы НЕ можете спокойно игнорировать ребят с unicode.org.

Mr Lister 23.06.2019 13:11

Я только что установил hack-fonts-3.003 и проверил глиф, созданный из символа, созданного из кодовой точки U+E0A1:

latin capital letter L over latin capital letter N

Этот символ используется в качестве индикатора номера строки в приложения с поддержкой Powerline. Поскольку персонаж в настоящее время живет в частной зоне, его значение не связано с его внешним видом. Другими словами, вы можете вывести значение символа только в том случае, если вы уже знаете, что это такое, исходя из того, как он выглядит. Я знаю, что это такое (потому что знаком с предметом), а ты (ОП) нет.

Следовательно, для решения этой проблемы существует предложение включить символы Powerline в собственно Unicode. Как только предложение будет принято, ожидайте, что шрифты и приложения перейдут с безымянного и бессмысленного U+E0A1 ‹› на U+2FE1 ‹⿡› \N{LINE NUMBER INDICATOR}.


uniE0A1 — неудачно названный идентификатор в шрифте, автор шрифта был ленив или небрежен. Он должен называться line_number_indicator или иметь похожее значимое имя.

Другие вопросы по теме