Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unicode issues left — metabug #2157

Open
unxed opened this issue Apr 14, 2024 · 9 comments
Open

Unicode issues left — metabug #2157

unxed opened this issue Apr 14, 2024 · 9 comments

Comments

@unxed
Copy link
Contributor

unxed commented Apr 14, 2024

#1380
#1199 (comment)
#1941
#2045
#2136
#2138

#2141

#2378

@unxed
Copy link
Contributor Author

unxed commented Aug 28, 2024

The issue of Unicode support in console applications has proven to be quite serious and goes beyond the scope of the far2l project. Specifically, the problem is that in different terminals, the width of the same string of characters can vary.

I have gathered some materials on this topic.

  1. The developer of the kitty terminal suggests using the following approach to measure the width of a Unicode string in screen cells: output the string and then measure the number of cells by which the cursor has moved.
    proposed enhancement: ESC sequence to get actual string length kovidgoyal/kitty#7789

  2. In the Microsoft Terminal bug tracker, there is a discussion about creating an API to address this issue.
    Give API to measure the space that a string occupies microsoft/terminal#218

  3. One of the developers has also prepared a library for calculating the screen width of a string in console cells, specifically for Microsoft Terminal, but I’m not sure if his solution would work in other cases. Unfortunately, its demo application doesn’t work on my Linux system. However, it might still serve as a useful reference.
    https://github.com/german-one/wtswidth---Windows-Terminal-string-width

  4. The Unicode Consortium seems to have recognized the issue and has released their recommendations.
    https://www.unicode.org/L2/L2023/23107-terminal-suppt.pdf

@unxed
Copy link
Contributor Author

unxed commented Aug 29, 2024

Перевёл на русский предложенный стандарт поддержки Юникода в текстовых терминалах с unicode.org.

https://github.com/unxed/UnicodeTerminals

@unxed
Copy link
Contributor Author

unxed commented Sep 9, 2024

Silver bullet?

#2378

@unxed
Copy link
Contributor Author

unxed commented Sep 13, 2024

Silver bullet?

Or not.

I'm afraid that solution is only feasible on Windows. In order to do that in a Unix terminal:

  • Turbo Vision uses the alternate screen buffer, which results in scrollback being disabled in most terminal emulators. You would have to print the characters you want to measure in the same screen area where your application is being drawn. For example: if you tried to print an emoji, then measure the cursor movement, then move the cursor back to its initial position, and then overwrite the emoji with the characters that used to be in that part of the screen, it is very likely that the terminal emulator would display the emoji on screen for some time.
  • Even if the characters being measured didn't appear on screen, or if that wasn't an issue, the performance of the whole process would be very poor.
  • Even if the above weren't an issue, the input stream used for reading the terminal state is the same that's used for reading user input. Therefore, you would have to either ignore user input while measuring text width, or write code that is able to keep the input events that are received while measuring text width. And then you would also have to consider the risk of waiting forever for an answer from the terminal...

So, in my opinion, you would end up with a poor experience for both the user and the programmer.

magiblot/tvision#51 (comment)

@unxed
Copy link
Contributor Author

unxed commented Sep 30, 2024

Вот тут имеется предложение по тому, как решать проблему с неоднозначностями в ширине символов Юникода, которое имеет как минимум одну реализацию, и которое в первом приближении одобрили в багтрекере Windows Terminal:

https://github.com/directvt/vtm/blob/master/doc/character_geometry.md

Суть, кратко: предлагается использовать модификаторы Unicode (кодовые точки 0xD0000-0xD02A2) для управления отображением символов в терминале. Каждый символ рассматривается как матрица ячеек обычной (т.е. half-width в текущих терминах) ширины (например, 3x1, 2x2). Модификатор указывает размер матрицы и какой ее фрагмент отображать в ячейке терминала.

Фрагменты матрицы размером до 8x4 ячеек требуют как минимум четыре связанных целочисленных значения, которые могут быть упакованы в пространство кодовых точек Unicode путем перечисления значений "wh_xy":

w: Ширина матрицы символов.
h: Высота матрицы символов.
x: Селектор горизонтального фрагмента внутри матрицы.
y: Селектор вертикального фрагмента внутри матрицы.

image

Например, этот код выведет символ размером 3x1:

printf "👩‍👩‍👧‍👧\UD0033\n"

Для матриц символов размером более 8x4 предлагается использовать пиксельную графику.

@o-sdn-o
Copy link

o-sdn-o commented Sep 30, 2024

На самом деле, это пока не реализовано полностью. В частности, терминал vtm поддерживает вывод только фрагментами, т.е. нельзя вывести сразу кластер размером 3х3, т.е. выше одной строки, пока что возможно выводить фрагменты только одинарной высоты - т.е. для случая 3х3 придется выводить три фрагмента размером 3x1. Но это чисто техническая недоделка, мне нужно просто сесть и это дописать. Хотелось сначала посмотреть, как это пойдет и поиграться с этим, и если ок, то доделать до конца. По большому счету этот подход за неколько лет ни с чем особо не законфликтовал. Года четыре я его гонял в режиме 1х1 - 2х1, и с недавнего времени я его расширил до 8х4. И да, этот подход позволяет выводить в терминале глифы сложных письменностей, таких как деванагари, для которых невозможно создать приемлемый моноширный шрифт.

@unxed
Copy link
Contributor Author

unxed commented Sep 30, 2024

Изящно! Спасибо за идею, ребята из команды Windows Terminal правы, она выглядит самой разумной на сегодняшний день.

Жалко мне в Wine не попробовать, не стартует.

@o-sdn-o
Copy link

o-sdn-o commented Sep 30, 2024

в Wine не попробовать, не стартует(

Видимо это следствие того, что там у меня не совсем стандартно эксплуатируется Win32 GDI API или там просто баг (что вероятнее).

В скором времени будет реализация для X11, и можно будет нативно на любом юниксе погонять.

@unxed
Copy link
Contributor Author

unxed commented Nov 25, 2024

Обсуждение решения проблемы синхронизации представлений о ширине символа терминала и приложения идёт здесь:
magiblot/tvision#51

В iTerm2 сделали ESC последовательность для указания точной версии Юникода, которую должен использовать терминал. Я предлагал такое в качестве одного из решений.

И там ещё один вариант предложен, тоже жизнеспособный, как по мне:
magiblot/tvision#51 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants