Curses - определенные эмодзи (флаги) деформируют вывод терминала - PullRequest
0 голосов
/ 04 марта 2019

Когда я выводю определенные эмодзи (в частности, флаги) в подокно в проклятиях, оно деформирует вывод, даже для вывода за пределы этого подокна.

Running:


import curses

def draw_screen(stdscr):

    event = 0
    stdscr.clear()
    stdscr.refresh()

    while (event != ord('q')):

        emojis = ["??", "?", "?"]
        # emojis = ["?", "?", "?"]

        for i, emoji in enumerate(emojis):
            box1 = stdscr.subwin(11, 11, 0, i*12)
            box1.box()
            box1.addstr(0, 4, emoji)

        event = stdscr.getch()

if __name__ == "__main__":
    curses.wrapper(draw_screen)

Производит:

enter image description here

Если вы переключаете эмодзи только для сердец, все работает нормально:

enter image description here

Я понимаю, что флаг emoji - это последовательность символов региональных индикаторов, но я бы подумал, что это должно сработать, и я не уверен, как это исправить.

Я проверял это вiTerm и Terminal в Mac OS 10.13 и 10.14.

(я также заметил, что некоторые другие многоточечные эмодзи (?‍?) печатаются нормально в сыром Python, но в проклятиях делятся на два отдельных смайлика, которые составляют их)Я не уверен, если это связано.)

1 Ответ

0 голосов
/ 05 марта 2019

ncurses использует функцию операционной системы wcwidth для определения ширины символа.Terminal.app предполагает, что U + 1F1FA и U + 1F1F8 используют два столбца, в то время как wcwidth говорит, что они представляют собой только один столбец каждый.Зеленое сердце U + 1F49A рассматривается как wcwidth, так и Terminal.app как двойная ширина.Это можно увидеть, добавив символ до и после символа эмодзи: там, где ncurses введен в заблуждение, на отображаемом дисплее отображаются перекрывающиеся символы.

illustration of overlap

До Unicode9 (2016), все эти конкретные коды "нейтральная ширина" в соответствии с файлом Unicode EastAsianWidth. Технический отчет Unicode # 11 Свойство символа Unicode «Ширина Восточной Азии» (с 1999 года) подразумевает (никогда не дает четкого определения), что фактическая ширина символа «нейтральной ширины» зависит от контекста, т. Е. Еслиони используются вместе с символами двойной ширины, их следует рассматривать как символы двойной ширины.Например, он говорит:

Узкие (и нейтральные) символы всегда отображаются на символы половинной ширины в наборе смешанной ширины

, но относятся к "смешанной ширине"исключительно с точки зрения сочетания символов "полная ширина" (два столбца) и "ширина узкой части" (один столбец).

Обычно используется функция wcwidth (возможно, MacOSне исключение) возвращает одинаковую ширину для заданной кодовой точки, игнорируя настройки локали.

В Unicode 8 это соответствующие строки (диапазон значений):

1F1E6..1F1FF;N   # So    [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
1F400..1F579;N   # So   [378] RAT..JOYSTICK

В Unicode 9 , U + 1F49A "полная ширина", но два других нейтральны:

1F1E6..1F1FF;N   # So    [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
1F442..1F4FC;W   # So   [187] EAR..VIDEOCASSETTE

Я не вижу, чтобы те изменились впоследствии, через Unicode 12 (текущий).

Учитывая все это, это выглядит как ошибка в шрифте и / или ширине канала, которая передается по инерции (мало что вы можете с этим поделать, покаApple пытается заставить wcwidth согласиться со своими шрифтами).

Кстати, вы можете найти Предложение по использованию ZERO WIDTH JOINER (ZWJ) между двумя символами региональных индикаторов , относящихся к проблеме.

...