Re[3]: Как написать редактор текстов на C#?
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.11.22 09:07
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:
ЭФ>АДНАКА, я поискал такой код на github (чтобы там было ReadOnlySpan<Rune>) и не нашел.
ЭФ>В интернете тоже не густо...
Повторно вам поясню: надо начинать с задачи, а не с инструмента. Зачем вы всё делаете задом наперёд?
Что именно вы хотите сделать с уникодом в .Net?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Как написать редактор текстов на C#?
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.11.22 09:09
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Если рассматривать Grapheme Clusters — то это глубоко внутренняя проблема кодировки Unicode.

Похоже, проблема не в Unicode и не в кодировках.

ЭФ>Простой текстовый редактор работает с одной Grapheme Cluster как с одним знакоместом (прямоугольником),

Ну, так и замечательно. Проблема-то в чём? Что именно вы хотите сделать?
ЭФ>поэтому можно вообще посчитать, сколько каких Grapheme Cluster-ов в файле в штуках
ЭФ>и перекодировать всё во внутреннюю кодировку с одинаковой битностью, с которой потом и работать.
Зачем вы хотите перекодировать всё во внутреннюю кодировку?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Как написать редактор текстов на C#?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.11.22 12:48
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

S>> То есть использовать Encoding.UTF32. Не?


ЭФ>Оказывается, начиная с Core, есть такой класс Rune в System.Text (а в mono его вроде нет):

ЭФ>https://learn.microsoft.com/en-us/dotnet/api/system.text.rune?view=net-6.0

ЭФ>а чтобы эти руны в строки склеивать есть ReadOnlySpan<T>

Ну руны нужны для представления символа из нескольких char
По той же ссылке
int CountLetters(string s)
{
    int letterCount = 0;

    foreach (Rune rune in s.EnumerateRunes())
    {
        if (Rune.IsLetter(rune))
        { letterCount++; }
    }

    return letterCount;
}

Ниже приведен эквивалентный код, который работает со ReadOnlySpan<char>следующим кодом:



static int CountLetters(ReadOnlySpan<char> span)
{
    int letterCount = 0;

    foreach (Rune rune in span.EnumerateRunes())
    {
        if (Rune.IsLetter(rune))
        { letterCount++; }
    }

    return letterCount;
}

Приведенный выше код правильно подсчитывает буквы Osage:




CountLettersInString("𐓏𐓘𐓻𐓘𐓻𐓟 𐒻𐓟")
// Returns 8

ЭФ>АДНАКА, я поискал такой код на github (чтобы там было ReadOnlySpan<Rune>) и не нашел.
ЭФ>В интернете тоже не густо...
и солнце б утром не вставало, когда бы не было меня
Re[4]: Как написать редактор текстов на C#?
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 01.11.22 13:23
Оценка: +1
S> руны нужны для представления символа из нескольких char

Дело не в том. Мне просто нужен был тип, который точно соответствует Unicode Codepoint.
И я такой тип нашел. А в день создания топика я о таком типе слыхом не слыхивал.
Re[4]: Как написать редактор текстов на C#?
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 01.11.22 13:26
Оценка:
S> Зачем вы хотите перекодировать всё во внутреннюю кодировку?

Для того, чтобы:
1) пользоваться тупыми массивами, в которых индекс буквы совпадает с X-координатой на экране
2) использовать меньше памяти.

Так-то бы мне и Rune в массиве подошли бы (Но это неточно, так как Grapheme Cluster туда не влезет), но 4 байта это 4 байта (вроде как это расточительно).

Если текст только из цифр, русских и английских букв и некоторых знаков пунктуации,
то при использовании внутренней кодировки вполне может хватить одного байта на символ
(даже если там будет пара-тройка этих уникальных Grapheme Cluster, которые тоже скодируются в два-три конкретных значения байта).

Теоретически это может увеличить производительность кода.
Отредактировано 01.11.2022 13:30 Эйнсток Файр . Предыдущая версия . Еще …
Отредактировано 01.11.2022 13:29 Эйнсток Файр . Предыдущая версия .
Отредактировано 01.11.2022 13:28 Эйнсток Файр . Предыдущая версия .
Re[5]: Как написать редактор текстов на C#?
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.11.22 16:04
Оценка: 71 (4)
Здравствуйте, Эйнсток Файр, Вы писали:
ЭФ>Для того, чтобы:
ЭФ>1) пользоваться тупыми массивами, в которых индекс буквы совпадает с X-координатой на экране
ЭФ>2) использовать меньше памяти.
Первый пункт неосуществим в принципе, из-за комбинирующихся символов в unicode. Вот это, с точки зрения пользователя, 1 буква (попробуйте, к примеру, выделить и скопировать её фрагмент)

-----

Q̹̣̩̭̰̰̹̄ͬ̿͋̃

-----

Но её представление в Unicode состоит из 13 code points.
Как вы собираетесь разместить её в в "тупом массиве"? Сделаете ячейку массива длиной в 26 байт?
Точно так же внутри устроены современные эмоджи: берём базовый смайлик и накладываем произвольное количество комбинаторов.

Кроме того, X-координата на экране выражена в пикселах, что при использовании немоноширинного шрифта приводит к невозможности отображения X в индекс в массиве даже если ограничиться кодами из подмножества Latin1.

Поэтому можно этот пункт выкинуть из рассмотрения и сосредоточиться на втором.

ЭФ>Так-то бы мне и Rune в массиве подошли бы

Повторюсь: смотря для каких целей. Вот чтобы обработать такие строки или эмоджи, вам руны никак не помогут.

ЭФ>Если текст только из цифр, русских и английских букв и некоторых знаков пунктуации,

ЭФ>то при использовании внутренней кодировки вполне может хватить одного байта на символ.
Вы сейчас пересказываете краткое содержание сериала "интернационализация в IT", третий сезон, вторая серия "Изобретение UTF-8"

ЭФ>(даже если там будет пара-тройка этих уникальных Grapheme Cluster, которые тоже скодируются в два-три конкретных значения байта).

Что такое "внутренняя кодировка"?
ЭФ>Теоретически это может увеличить производительность кода.
Пишу вам в третий раз за последнюю неделю одну и ту же мысль: определитесь с задачей.
Вы всё время думаете об инструментах, и не успеваете задуматься о поводах их применения.
Вот например
1. когда мы двигаем курсор кнопками вправо/влево, что это означает? двигаем на весь grapheme cluster? Или на 1 code point?
1.1. Нужно ли при этом декомпозировать лигатуры, всегда композировать возможные лигатуры, или оставлять как пользователь вставил?
2. Разрешаем ли мы удалять фрагменты кластера?
— да, но только последний модификатор/часть лигатуры
— да, но не даём убрать standalone символ если справа от него есть комбинаторы
— нет, только весь кластер целиком
3. нужно ли нам поддерживать перемещение курсора по словам?
3.1. Что будет считаться границей слова?
4. Какие у нас требования по максимальной длине 1 строки?
5. Какие у нас требования по максимальному количеству строк в тексте?
6. Как быть с размерами шрифтов — важна ли нам возможность пропорционально мастштабировать текст, или пойдёт скачкообразное изменение длин строк?
7. Насколько далеко мы готовы зайти в поддержке всяких экзотических областей unicode? Каким образом будем решать проблему несуществования шрифта, который покрывает все 149+K code points?
примерно так.
Структура данных в памяти для хранения текста будет сильно зависеть от ответов на все эти вопросы.
Но заранее скажу, что массивом рун (или чего бы то ни было) вы не обойдётесь примерно ни в каком случае.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Отредактировано 01.11.2022 17:17 Sinclair . Предыдущая версия .
Re[5]: Как написать редактор текстов на C#?
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.11.22 17:18
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:
ЭФ>Дело не в том. Мне просто нужен был тип, который точно соответствует Unicode Codepoint.
Скорее всего вам нужно не это.

The number of Rune instances in a string might not match the number of user-perceivable characters shown when displaying the string.

Since Rune instances represent Unicode scalar values, components that follow the Unicode text segmentation guidelines can use Rune as a building block for counting display characters.

Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Отредактировано 01.11.2022 17:28 Sinclair . Предыдущая версия .
Re[6]: Как написать редактор текстов на C#?
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 01.11.22 19:17
Оценка:
S> Что такое "внутренняя кодировка"?

Ответы на часть Ваших вопросов есть выше
Автор: Эйнсток Файр
Дата: 01.11.22
, я процитирую:

посчитать, сколько каких Grapheme Cluster-ов в файле в штуках
и перекодировать всё во внутреннюю кодировку с одинаковой битностью, с которой потом и работать.

А для того, чтобы не писать отдельный код для 8, 16, 32 битов на символ — использовать классы-шаблоны и типизировать их типами-структурами такого размера.


Это значит, что будет массив из пар, например, строк и байтов (или дерево с хештаблицами, чтобы в строках искать быстрее, пока неважно)
Строка будет содержать в себе встреченный Grapheme Cluster, байт будет содержать порядковый номер (т.е. внутренний код).

В тот момент, когда количество символов станет превышать 256 или 65536 (что вряд ли), будет происходить перекодирование всего текста (с копированием по памяти) во внутреннюю кодировку с удвоенным числом битов, но по-прежнему одинаковым на все Grapheme Cluster-ы.
Поэтому неверно, что эта кодировка похожа на UTF-8. Моя будет оставаться фиксированной длины, а UTF-8 это кодировка переменной длины.

На те вопросы, на которые нет ответов, отвечаю:
1) я не собираюсь "разбирать" длинные Grapheme Cluster-ы (они же TextElement в .NET)
редактор не будет уметь их редактировать, только копипастить из буфера целиком (в буфер они будут попадать из браузера) или стирать насмерть.
2) про границы слов я пока не думал вообще, но такая информация скорее всего получается из CharUnicodeInfo
Если не получится, поищу на гитхабе библиотеку, которая реализует
"Unicode UAX #29 §4.1 default word boundary specification"
3) про размер памяти под текст тоже не думал и не буду, у меня на одной из машине 256GB RAM, буду хранить текстовый буфер в памяти на ней.
4) про шрифты я ещё ничего не знаю, буду читать позже. Мне достаточно повторить то, что делает Firefox (потому что я именно из него копирую).
Отредактировано 01.11.2022 19:36 Эйнсток Файр . Предыдущая версия .
Re[7]: Как написать редактор текстов на C#?
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 01.11.22 19:49
Оценка:
Для того, чтобы приделать свою кодировку (а так же енкодер и декодер) к классу Encoding,
мне понадобятся "static extension properties".

Нужно мне это для того, чтобы можно было писать не только
Encoding.UTF8, но и Encoding.MyEncoding

Из ответа на stack overflow я не понял, бывают ли такие в распоследней версии C#:
https://stackoverflow.com/questions/619033/does-c-sharp-have-extension-properties
https://github.com/dotnet/csharplang/discussions/5811

Последняя версия, я так понимаю, C# 10, и там их нет:
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history

А могли бы, наверное, и сделать, если бы вместо "this" писать ключевое слово "type", чтобы применялись эти методы и свойства не к объекту класса, а к самому классу.
Отредактировано 01.11.2022 20:16 Эйнсток Файр . Предыдущая версия . Еще …
Отредактировано 01.11.2022 20:15 Эйнсток Файр . Предыдущая версия .
Отредактировано 01.11.2022 20:01 Эйнсток Файр . Предыдущая версия .
Отредактировано 01.11.2022 19:55 Эйнсток Файр . Предыдущая версия .
Отредактировано 01.11.2022 19:54 Эйнсток Файр . Предыдущая версия .
Отредактировано 01.11.2022 19:52 Эйнсток Файр . Предыдущая версия .
Отредактировано 01.11.2022 19:50 Эйнсток Файр . Предыдущая версия .
Re[7]: Как написать редактор текстов на C#?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.11.22 05:20
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Это значит, что будет массив из пар, например, строк и байтов (или дерево с хештаблицами, чтобы в строках искать быстрее, пока неважно)

Это значит, что у вас даже для маленьких текстов будет +1 уровень косвенности. То есть вместо просто символа A вы храните у себя сам символ А, и ещё массив ссылок на строки, у которых вначале идёт длина, и уже потом — символы UCS4, из которых собственно и состоит текст. Ну либо вы оставляете null для тех символов, которые означают сами себя, тогда немножко экономите по памяти, но производительность всё равно будет так себе.
Весь выигрыш от возможности сделать line[i] вы тут же и потеряете. К тому же не сможете пользоваться векторными инструкциями для ускорения операций.
На первый взгляд кажется, что держать вместо этого дерево строк, в котором каждый лист будет в какой-то одной кодировке, будет гораздо эффективнее.
Чисто Latin1-текст будет ровно одним фрагментом однобайтовых символов.

ЭФ>В тот момент, когда количество символов станет превышать 256 или 65536 (что вряд ли), будет происходить перекодирование всего текста (с копированием по памяти) во внутреннюю кодировку с удвоенным числом битов, но по-прежнему одинаковым на все Grapheme Cluster-ы.

С точки зрения пользователя это будет выглядеть как пауза в работе, и про вас будут писать на хабре "о боже, 2023 год, а у меня ввод текста лагает".
Дерево позволяет все ситуации обработать за O(1).
ЭФ>1) я не собираюсь "разбирать" длинные Grapheme Cluster-ы (они же TextElement в .NET)

ЭФ>редактор не будет уметь их редактировать, только копипастить из буфера целиком (в буфер они будут попадать из браузера) или стирать насмерть.

Тогда придётся их разбирать. Ровно потому, что у вас одна "буква" (то, что стирается целиком при нажатии backspace или del) занимает неизвестное количество "символов", в какой кодировке бы они ни были. Опять же, в дереве вы можете держать такой кластер отдельным листом, и забесплатно иметь возможность быстро перемещаться между "буквами".

ЭФ>2) про границы слов я пока не думал вообще, но такая информация скорее всего получается из CharUnicodeInfo

ЭФ>Если не получится, поищу на гитхабе библиотеку, которая реализует
ЭФ>"Unicode UAX #29 §4.1 default word boundary specification"
Библиотека — это хорошо. Но вопрос в том, как вы будете эти границы искать в момент нажатия Ctrl-влево или Ctrl-вправо. Линейным поиском по символам внутренней кодировки? С учётом того, что для восстановления полноценного UCS4 вам нужно прыгать по двум ссылкам для каждого символа?
Опять же имеет смысл использовать для этого древовидную структуру, в которой всё это делается за O(1).

ЭФ>3) про размер памяти под текст тоже не думал и не буду, у меня на одной из машине 256GB RAM, буду хранить текстовый буфер в памяти на ней.

Если вас не беспокоит размер памяти, тогда нафига задуряться с перекодировками? Сразу храните всё в UCS4.

ЭФ>4) про шрифты я ещё ничего не знаю, буду читать позже. Мне достаточно повторить то, что делает Firefox (потому что я именно из него копирую).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Отредактировано 02.11.2022 5:21 Sinclair . Предыдущая версия .
Re[8]: Как написать редактор текстов на C#?
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 02.11.22 05:40
Оценка:
S> вы тут же и потеряете

Не тут же, а только при сохранении и рисовании.

S>С точки зрения пользователя это будет выглядеть как пауза в работе, и про вас будут писать на хабре "о боже, 2023 год, а у меня ввод текста лагает".


Можно это делать заранее, кроме того это один раз.

ЭФ>>редактор не будет уметь их редактировать, только копипастить из буфера целиком (в буфер они будут попадать из браузера) или стирать насмерть.

S> придётся их разбирать

Только при считывании.

S> прыгать по двум ссылкам


Никаких двух ссылок не будет. Внутренний код символа (байт) — это индекс в массиве.
Уровень перенаправления конечно будет один лишний, но он не ссылка, и им не обязательно пользоваться всегда.

S> Если вас не беспокоит размер памяти, тогда нафига задуряться с перекодировками? Сразу храните всё в UCS4.


Составные Grapheme Cluster не влезут в 4 байта целиком, особенно когда там 2 и более кодепоинтов.
А если будет перекодирование для обеспечения одинаковой битности всем символам,
то нет разницы, в 4, 2 или 1 байт перекодировать (в зависимости от количества разных символов в конкретном тексте).


Зато у меня убыстрятся все другие обработки, если они будут. Например парсинг не будет динамически разбираться
сколько там кодепоинтов начиная с каждой позиции. А будет работать по своим таблицам, построенным в соответствии с внутренней кодировкой.
Отредактировано 02.11.2022 5:56 Эйнсток Файр . Предыдущая версия . Еще …
Отредактировано 02.11.2022 5:54 Эйнсток Файр . Предыдущая версия .
Отредактировано 02.11.2022 5:52 Эйнсток Файр . Предыдущая версия .
Re[9]: Как написать редактор текстов на C#?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.11.22 06:41
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:
ЭФ>Не тут же, а только при сохранении и рисовании.
При всех операциях. Собственно, всё, чем занимается редактор — это рисование.
1. Рисование в ответ на изменение view (скроллинг, ресайз, перемещение курсора)
2. Рисование в ответ на изменение model
Ну, и собственно сами изменения модели.

ЭФ>Можно это делать заранее, кроме того это один раз.

"Заранее" как раз и означает, что вы всегда держите весь текст в одной кодировке. Например, в UCS4.

ЭФ>Никаких двух ссылок не будет. Внутренний код символа (байт) — это индекс в массиве.

Смотрите. Массив — это ссылка, pArrayStart.
Обращение к элементу массива — это один дереференс, *(pArrayStart + charCode).
По этому адресу лежит ссылка на ваш graphemeCluster.
То есть чтобы узнать длину этого кластера, нужно обратиться вот так:
(*(*(pArrayStart + charCode)).Length) // == (*(*(pArrayStart + charCode)+0))

А, скажем, первый символ этого кластера находится вот здесь:
(*(*(pArrayStart + charCode)).Length) // == (*(*(pArrayStart + charCode)+1))


ЭФ>Уровень перенаправления конечно будет один лишний, но он не ссылка, и им не обязательно пользоваться всегда.

Нет никаких способов перенаправления, кроме ссылок. Вы можете обозвать эту ссылку числом, но внутри CPU всё равно будет выполнять те же сдвиги, сложения, и дереференс.

ЭФ>Составные Grapheme Cluster не влезут в 4 байта целиком, особенно когда там 2 и более кодепоинтов.

Совершенно верно, не влезут.
ЭФ>А если будет перекодирование для обеспечения одинаковой битности всем символам,
ЭФ>то нет разницы, в 4, 2 или 1 байт перекодировать (в зависимости от количества разных символов в конкретном тексте).
Количество разных символов — штука динамическая. А вам ещё и придётся как-то обрабатывать ситуации, когда пользователь вводит, скажем, суррогатные пары по одному символу при помощи Alt-ввода.
Ну по факту вы всё равно придёте к дереву. Не имеет смысла представлять мегабайтный текст как один массив длиной в миллион — вставка в середину обходится слишком дорого.
Просто сейчас у вас получается плоское дерево, где узлы хранят ссылки на "кластеры", а когда вы оптимизируете это для операций редактирования, то сплошной массив превратится в похожую на rope структуру.
Плюс к этому вы обвесите эту структуру данными по расположению символов на канвасе, для пересчёта "символьной" позиции в координатную и обратно.

ЭФ>Зато у меня убыстрятся все другие обработки, если они будут. Например парсинг не будет динамически разбираться

Тут главное — заранее понять, какие именно у вас будут обработки.

ЭФ>сколько там кодепоинтов начиная с каждой позиции. А будет работать по своим таблицам, построенным в соответствии с внутренней кодировкой.

На этом вы ничего не выиграете.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[10]: Как написать редактор текстов на C#?
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 02.11.22 06:43
Оценка:
S> чтобы узнать длину этого кластера,

Мне не нужно этого делать в общем случае, только при операциях ввода-вывода.

S>Тут главное — заранее понять, какие именно у вас будут обработки.


Любые, фиксированный размер символа ускорит любые обработки.
Re[11]: Как написать редактор текстов на C#?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 02.11.22 08:34
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

S>> чтобы узнать длину этого кластера,


ЭФ>Мне не нужно этого делать в общем случае, только при операциях ввода-вывода.


S>>Тут главное — заранее понять, какие именно у вас будут обработки.


ЭФ>Любые, фиксированный размер символа ускорит любые обработки.

Ну дык и храни все в UTF-32 и не будет проблем. Я так понимаю, что Rune как раз 4 байта (Int32)
и солнце б утром не вставало, когда бы не было меня
Re[11]: Как написать редактор текстов на C#?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.11.22 08:57
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Мне не нужно этого делать в общем случае, только при операциях ввода-вывода.

Вам это будет нужно сделать при каждом выводе на экран.

ЭФ>Любые, фиксированный размер символа ускорит любые обработки.

(вздыхает) нет.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: Как написать редактор текстов на C#?
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.11.22 10:39
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Любые, фиксированный размер символа ускорит любые обработки.

Вопрос со звёздочкой: планируете ли вы использовать шрифты с лигатурами? Скажем, насколько важна для вас поддержка арабской письменности?
Чтобы она работала корректно, вам нужно передавать в рендерер шрифта их не по одному, а сразу всем блоком.
Так что для отображения слова на арабском вам придётся "собрать" его целиком перед отдачей в рендерер. У вас банальный repaint, когда поверх вашего окошка двигают какое-то другое, будет тормозить.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[12]: Как написать редактор текстов на C#?
От: Ночной Смотрящий Россия  
Дата: 02.11.22 11:52
Оценка:
Здравствуйте, Sinclair, Вы писали:

ЭФ>>Мне не нужно этого делать в общем случае, только при операциях ввода-вывода.

S>Вам это будет нужно сделать при каждом выводе на экран.

Собственно, есть такой редактор, Scintilla. И там таки реализовали эту "гениальную" идею, jagged массив с символами. Правда символ у них был поначалу 1 байт. А для юникода они потом заюзали UTF-8. В результате их API превратился в какое то фантастическое говно. С тех пор так и живут уже много лет.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Как написать редактор текстов на C#?
От: Baiker  
Дата: 02.11.22 19:19
Оценка: :)
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>how-to-make-a-custom-text-editor

ЭФ>Начнём с того, что юникод 8.0 ...

ЭФ, ну как, написал редактор?

Такое ощущение, что ты готовишься к интервью, а не к написанию редактора. В таком случае, становиться "гуру юникода" вообще нет смысла — предполагаю, что всё, что написал тебе Синклер, не знают и 1% погромиздов (включая меня). И так же на интервью мало кто из ВОПРОШАЮЩИХ будет лезть в это юникодное болото (это реально полный мрак).
Хочешь потренировать мозг — напиши тупой редактор с UTF32 под капотом, безо всяких эмодзи, code points и прочего — тупо "редактор 32-битных текстов"

По-моему, как и с HTML, юникодный стандарт свернул куда-то очень не туда. В гейропах Эпплю ПРИНУЖДАЮТ использовать USB-C вместо Lightning, но при этом никого не принуждают бросать свои извращенства (вроде письма справа-налево) и писать "как все". Вот по-моему глобализация и должна как-то сдвигать этот маразм в сторону унификации. Не говоря о том, что в общем случае большинству из 8,000,000,000 людей как-то похрен, уместятся ли шумерские письмена в юникод или нет. Надо остановиться на UTF16 (с фиксированным 2-байтовым символом), всунув туда все алфавиты по приоритету количества людей, знающих данный язык. Кто не уместился — пусть сами изобретают себе кодировки (если у них в племени вообще есть компьютеры! ). А всякие лигатуры и "комбинации" — к чёрту, без них все прекрасно жили (напомню, даже ASCII каких-то 20 лет назад всем хватало).
Чем больше мудаки из unicode усложняют и извращают стандарт (эмоджи?? серьёзно?!), тем меньше вероятность написания качественного софта. Мы слишком много прыгаем вокруг "второстепенных людей/языков", приводя адекватный мир в ступор.
Re[12]: Как написать редактор текстов на C#?
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 20.11.22 18:19
Оценка:
ЭФ>>Любые, фиксированный размер символа ускорит любые обработки.
S>Вопрос со звёздочкой: планируете ли вы использовать шрифты с лигатурами? Скажем, насколько важна для вас поддержка арабской письменности?

План такой:
1) я читаю кодепоинты из UTF-8
2) пишу склеиватель, который управляется внешним конфигом
3) склеиватель склеивает кодепоинты в TextElements (которые string)
4) делаю "перекодировщик", который управляется внешним конфигом
задача перекодировщика — преобразовывать TextElements в один или несколько символов внутренней кодировки
ffi — это пусть будет один TextElement, но три символа внутренней кодировки.
5) внутри работаю с символами внутренней кодировки фиксированной битности,
при этом отслеживаю из связь с исходными TextElements. Если обработка разбивает лигатуру,
то провожу соответствующие операции с TextElement — создаю две штуки
6) при необходимости рисовать пользуюсь TextElements,
обработки делаю во внутренней кодировке

S> Чтобы она работала корректно, вам нужно передавать в рендерер шрифта их не по одному, а сразу всем блоком.


Хорошо. Мой случай — должны обрабатываться (игнорироваться) три вида русских ударений.

S> Так что для отображения слова на арабском вам придётся "собрать" его целиком перед отдачей в рендерер.


Я не планирую поддерживать письмо справа-налево, письмо по столбцам сверху-вниз, и снизу вверх (в реальности существовали все четыре варианта).

S> У вас банальный repaint, когда поверх вашего окошка двигают какое-то другое, будет тормозить.


Это не мои проблемы, а железа. Мои проблемы — логическая корректность. В конце концов, существуют графические акселераторы, пусть мучаются.
Re[13]: Как написать редактор текстов на C#?
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.11.22 08:01
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:
ЭФ>План такой:
ЭФ>1) я читаю кодепоинты из UTF-8
ЭФ>2) пишу склеиватель, который управляется внешним конфигом
Зачем конфиг?
ЭФ>3) склеиватель склеивает кодепоинты в TextElements (которые string)
ЭФ>4) делаю "перекодировщик", который управляется внешним конфигом
ЭФ>задача перекодировщика — преобразовывать TextElements в один или несколько символов внутренней кодировки
Зачем?
ЭФ> ffi — это пусть будет один TextElement, но три символа внутренней кодировки.
То есть у вас N байт UTF-8 превращаются одновременно в 1 TextElement, которому соответствует M символов внутренней кодировки?
ЭФ>5) внутри работаю с символами внутренней кодировки фиксированной битности,
ЭФ> при этом отслеживаю из связь с исходными TextElements.
Как именно вы отслеживаете эту связь? Вот у вас лежит массив символов "внутренней кодировки". Три подряд из них соответствуют вот этому ffi, который один и тот же текстовый элемент.
Как именно устроено вот это соответствие?
ЭФ>Если обработка разбивает лигатуру,
ЭФ> то провожу соответствующие операции с TextElement — создаю две штуки
ЭФ>6) при необходимости рисовать пользуюсь TextElements,
ЭФ>обработки делаю во внутренней кодировке
По-прежнему непонятно, что за обработки вы собираетесь делать.
Понимаете, если, к примеру, у вас собственно текст — это сплошной массив "символов" вашей внутренней кодировки, и пользователь, скажем, удаляет первый из них, то что происходит?
Если я правильно понимаю вашу идею, то вам надо
1. Перевыделить массив, сделав его на 1 элемент короче. То есть если у нас там — мегабайт символов, то вы "быренько" копируете весь мегабайт за вычетом первого байта на новое место.
2. Определить, в какой TextElement показывал ваш первый символ. Допустим, это была та самая первая f из лигатуры "ffi". Кстати, в UTF-16 (System.String) это ровно 1 символ: 0xFB03
3. Выполнить переразбиение лигатуры — теперь у вас первый и второй символы должны перестать ссылаться на оригинальный элемент 0xFB03, а должны начать ссылаться на 'f' и 'i', соответственно.
4. Перерисовать весь текст — с учётом того, что у вас сменились позиции всех графем.

ЭФ>Хорошо. Мой случай — должны обрабатываться (игнорироваться) три вида русских ударений.

Ну, как бы и прекрасно. Проблема-то в чём? Чем вас не устраивает стандартный подход в виде деревьев строк/слов/символов?

S>> Так что для отображения слова на арабском вам придётся "собрать" его целиком перед отдачей в рендерер.

ЭФ>Я не планирую поддерживать письмо справа-налево, письмо по столбцам сверху-вниз, и снизу вверх (в реальности существовали все четыре варианта).
Да пёс с ним с направлением. Речь о том, что в арабском письме (и при применении различных "рукописных" шрифтов) отдельно стоящая буква пишется совсем не так, как в составе слова.

ЭФ>Это не мои проблемы, а железа. Мои проблемы — логическая корректность. В конце концов, существуют графические акселераторы, пусть мучаются.

Это очень наивный подход. Вы переваливаете проблемы не на мифические акселераторы, а на пользователей. Которые не захотят пользоваться тормозным продуктом.
Я бы ещё понял, если бы ваш подход как-то упрощал проектирование и кодирование такого редактора — так ведь нет; вы изобретаете себе искусственное усложнение кода, которое ещё и оборачивается плохой асимптотикой в быстродействии. Вы как хотите, а смысл сего от меня ускользает.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.