LINUX.ORG.RU

Unicode library

 , ,


0

2

Привет. Господа, что можно такого заюзать для:

  1. {char|utf-8|utf-16|utf-32} <-> wchar_t конверсий
  2. Итерация по wchar_t строке
  3. Желательно кросплотформенно

По всем пунктам подходит boost::locale, но у меня впечатление, что его icu бэкэнд жутко тормозит. У меня на руках что-то вроде текстового редактора, вставка текста из буфера обмена заметно лагает. На самом деле я там могу написать оптимальней - сейчас логика «размечает» буфер текста после вставки каждого символа, надо делать разметку после вставки всех символов. Тем не менее - icu слишком жирна, я бы хотел от неё избавиться (ну а кому нужен 30ти метровый довесок?).

char<->wchar_t я могу конвертить стандартными средствами. По-моему я ищу некую либу, которая внутренне работает на wchar_t, и умеет конверсии между разными utf-N, и не дергает ничего на стороне.

Черт с ним - пусть это даже будет не wchar_t внутренне, но обязана уметь utf конверсии, вряд ли может быть что-то медленнее icu.

★★
Ответ на: комментарий от X512

Знаю, но это ничего не меняет, мне даже пофиг какой конкретно utf-N, всё это заботы искомой unicode либы.

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

Алгоритмически юникод не обходится же. Так что любая либа будет таскать за собой таблицы -> нет пути для обезжиривания.

Anoxemian ★★★★★
()
Ответ на: комментарий от X512

Можно самому написать.

Честно говоря - звучит страшно. Т.е. должно быть логичным - взяв любую code point я могу однозначно сказать - модификатор она или нет, утверждение верно? Где смотреть эти диапазоны модификаторов для составления своего алгоритма (желательно ткнуть пальцем на исчерпывающую краткую доку)? Юникодная макулатура огромна, я там потеряюсь, если никто за ручку не отведёт.

kvpfs ★★
() автор топика
Последнее исправление: kvpfs (всего исправлений: 1)

wchar_t ненужно, определись с нормальным типом для char - для редактора это вероятно uint32_t или какой-нибудь char32

mittorn ★★★★★
()
Ответ на: комментарий от mittorn

Для редактора обычный utf-8 и тип char прекрасно подходят. Всё равно даже uint32_t для кодирования одного символа не хватит, есть всякие модификаторы, комбинированные символы и т.д..

X512 ★★★★★
()
Ответ на: комментарий от X512

Ну это же логично, юникод ведь. Например, на входе ‘Й’ записана декомпозицией «U+0418 U+0306», надо понять, что это один символ.

PS: на всякие нормализации - класть.

kvpfs ★★
() автор топика
Последнее исправление: kvpfs (всего исправлений: 1)
Ответ на: комментарий от X512

Так ты же привел несложный код выше. Нет. Это чушь. Юникод однозначное зло, саахрикту тому свидетель.

Anoxemian ★★★★★
()
Ответ на: комментарий от mittorn

Зависимость юзает wchar_t, поэтому конверсии будут, это как минимум, желательно внутренне тоже быть широким.

kvpfs ★★
() автор топика
Ответ на: комментарий от fluorite

Спасибо, пока ещё поосматриваюсь. Данная либа внутренее не wchar_t (допустимо на крайняк), но и не заботится о в/из wchar_t конверсиях, тоже решаемо, но доп гемор.

kvpfs ★★
() автор топика
Ответ на: комментарий от Legioner

повторюсь:

Честно говоря - звучит страшно. Т.е. должно быть логичным - взяв любую code point я могу однозначно сказать - модификатор она или нет, утверждение верно? Где смотреть эти диапазоны модификаторов для составления своего алгоритма (желательно ткнуть пальцем на исчерпывающую краткую доку)? Юникодная макулатура огромна, я там потеряюсь, если никто за ручку не отведёт.

Покажите, пожалуйста, доку, где исчерпывающий список диапазонов код_поинтов-модификаторов.

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

Если тебе нужна вся эта муть с модификаторами, то руками не выйдет. Нужно использовать ICU. Я про перевод из utf8 в utf32 имел в виду.

Все исчерпывающие списки и таблицы есть где-то на сайте Юникода. Но там всё очень сложно будет.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от Legioner

Все исчерпывающие списки и таблицы есть где-то на сайте Юникода. Но там всё очень сложно будет.

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

В boost::locale всё из коробки работает, если бы не этот мерзкий ICU только.

kvpfs ★★
() автор топика

Сама постановка задачи не корректна:

{char|utf-8|utf-16|utf-32} <-> wchar_t конверсий

Более грамотно будет «однобайтовые кодировки»|utf-8|utf-16|utf-32 <-> в голый юникод.

neon1ks ★★
()
Ответ на: комментарий от kvpfs

Когда в Qt 6 отказались от поддержки старых кодировок, многие программы стали использовать libiconv и подобные библиотеки.

neon1ks ★★
()
Ответ на: комментарий от kvpfs

надо понять, что это один символ

Для начала определитесь что вы понимаете под символом. Есть много разных несовместимых определений.

X512 ★★★★★
()
Ответ на: комментарий от X512

Сейчас прочитал, что есть:

Full Unicode, in terms of uint16_t or uint32_t (with machine dependent endianness and alignment)

   UCS-2-INTERNAL, UCS-4-INTERNAL

Я как понимаю, что uint32_t у UCS-4-INTERNAL это ближе всего, что автор темы хочет.

neon1ks ★★
()
Ответ на: комментарий от X512

Можно итерироваться по code point’ам - это просто, пишется на коленках. Можно по символам - вот это нужно, например имеем «открытые темнокожие ладони» и следующая за ними буква ‘Й’ записанная декомпозицией - U+1F450U+1F3FF U+0418U+0306, 4 код поинта, но два символа, при проходе по символам получаем две итерации.

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

Так, до меня дошло, что все диапазоны уже собраны в реализации wcwidth, ведь она должна возвращать 0 для non-spacing символов. Наверное сделаю тестовую реализацию прохода по строке на wcwidth и сравню скорость с ICU, если разница будет в разы хотя бы, то заюзаю. Под конверсию возьму какую-нибудь либу готовую (тут уже не проблема, ту же utfcpp можно взять).

kvpfs ★★
() автор топика
Ответ на: комментарий от X512

Для символа нет, но позволит быстрее получить codepoint, что может быть оправдано с точки зрения производительности если работаешь с большими объёмами текста

mittorn ★★★★★
()
Ответ на: комментарий от kvpfs

желательно выкинуть такую зависимость. ну, конвертация в utf-8 и из него в то что надо как вариант

mittorn ★★★★★
()
Ответ на: комментарий от neon1ks

многие программы стали использовать libiconv

Я поступил так же.

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

Так, до меня дошло, что все диапазоны уже собраны в реализации wcwidth, ведь она должна возвращать 0 для non-spacing символов.

Если кто захочет повторять данный трюк, рассказываю - не работает, точнее работает, но не для всего, ненадёжно. Так wcwidth(L’\U0001F3FF’) возвращает 2 (ожидалось 0). Хотя он является модификатором в паре, которая образует один глиф L"\U0001F450\U0001F3FF". В описании к код поинту пишут:

This character is a Modifier Symbol ...
--- НО ---
The glyph is not a composition. It has a Neutral East Asian Width ...

Как же это всё больно … .

kvpfs ★★
() автор топика

Весело, UTFCPP не умеет итерацию по символам, умеет лишь по код поинтам;

utf8proc - аналогично как я понял. Правда есть у неё один плюс - умеет возвращать категории код поинтов, анализируя которые можно сделать ризбивку строки (во всяком случае мне так кажется). Но что-то пахнет это крупным геморром который сулит наличие 30 около 100 различных категорий и всевозможные их комбинации.

В сухом остатке - кроме boost::locale+ICU (ибо голое ICU трогать не хочется) вариантов и не осталось.

kvpfs ★★
() автор топика
Последнее исправление: kvpfs (всего исправлений: 1)

Спасибо за помощь и советы.

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

так артем там описывает почему именно icu и что будет без него. boost.locale (ну или booster.locale если boost не хочется тащить) можно собрать и без icu, но будет плохо работать.

zerhud
()

icu бэкэнд жутко тормозит

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

когда появляются строки, то нужно готовится к тормозам, тут ничего не сделаешь. и хорошо что есть такой icu где учитывается вся эта дичь.

zerhud
()
Ответ на: комментарий от zerhud

и хорошо что есть такой icu где учитывается вся эта дичь

Юникод - утопия, на практике не работает. Почти уверен, что любой эмулятор терминала не будет правильно работать у арабов, например, им нужна спец версия. Нет никакого кросслокального софта. Нельзя скрестить в целое алфавиты, иероглифы, разное направление, … .

Правильный подход - несколько версий юникода со своими таблицами символов. Если некоторая система письма удовлетворяет некоторым критериям для включения в таблицу алфавитных систем с письмом слева направо и без всяких декомпозиций, то добавляем её юникод_v1, если нет, то в соответствующую версию для подобных систем. Пользователи иероглифических систем (или любых других) могут провести реформу и принять алфавит с попаданием в v1. А пока из-за наличия в общем наборе всяких атавизмов вроде иероглифов (и необходимость декомпозиций как следствие) - должны страдать все юзеры значительно более простых и продвинутых алфавитных систем письма.

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

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

Юникод даёт теоретическую возможность написания софта, который может отобразить нужный язык. То, что его так просто не найти говорит скорее о программистах, чем о принципиальной возможности. Хотя сейчас мы можем писать текст на паре языков , например английски и русский и вставлять, скажем, иврит, и это будет работать .

Я считаю, что переучивать толпу людей потому что программисты не могут написать нормально, как то не очень.

zerhud
()
Ответ на: комментарий от kvpfs

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

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

Вот в каком-нибудь «чатике» такое может «не проканать», но это, как сказал zerhud, проблемы кодеров, а не юникода…

yyk ★★★★★
()
Последнее исправление: yyk (всего исправлений: 1)
Ответ на: комментарий от yyk

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

Кстати про китайцев, ведь они и сами прекрасно догадываются об ущербности иероглифов, и по сути используют алфавит для ввода в компьютер - пиньинь. Вместо создания простого/удобного набора символов, родилось какое-то Г, которое пошло на поводу у застрявших во временах наскальной живописи, давно пора переходить на алфавит.

Если кому-то очень надо какое-нибудь древнее письмо, почему нельзя сделать в тексте спец метки для смены набора символов и шрифта? При желании редактор будет правильно эти метки обрабатывать. Вместо этого втянули всё в одну таблицу, теперь как итог - теперь никто не может этим нормально пользоваться без боли, лагов и жирных либ.

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

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

Ты написал чушь. RTL-письмо отображается на экране справа налево. А данные идут точно так же, как и у LTR - первая буква первой, вторая - второй и т.д. И отобразить буковки - задача приложения, которое их рисует (браузера, текстового процессора или эмулятора терминала), т.е. это вопрос отрисовки глифов на экране.

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

Не нужно тут никаких «костылей», всё работает совершенно штатно и прозрачно, цепочка байт с символами RTL не требует никакой отличной от цепочки байт с LTR символами обработки.

P.S.

Да, и баты в файлах тоже не перевернутые с конца в начало.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Не нужно тут никаких «костылей», всё работает совершенно штатно и прозрачно, цепочка байт с символами RTL не требует никакой отличной от цепочки байт с LTR символами обработки.

Как они могут не требовать? Есть у тебя внутренниий буфер, ты можешь писать туда ввод от юзера (он тебе даёт его по одной букве), значит тебе надо запросить направление вводимого текста, расставлять соответствующие метки. А теперь представь как будет вести себя терминал и куда должен сдвигаться курсор? Вначале имеем три правых символа, потом вводим три левых, правых, … .

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

Короче всё это костыли лютые, нужна унификация систем письма, а не такой юникод. Нужно уметь признавать очевидное - латиницу в IT/технике, LTR письмо, ущербность иероглифов. Староверы могут героически пользоваться отдельной от общей таблицей символов и формошлёпить в 1С. Это не дискриминация, параллельно может существовать несколько стандартов, желающие могут сражаться с ветряными мельницами.

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

Как они могут не требовать? Есть у тебя внутренниий буфер, ты можешь писать туда ввод от юзера (он тебе даёт его по одной букве), значит тебе надо запросить направление вводимого текста,

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

А теперь представь как будет вести себя терминал и куда должен сдвигаться курсор?

Почему ты дебил? Это всё уже сделано свыше четверти века назад. Возьми любое юникодное приложение и посмотри. Это гораздо легче, чем строчить на форуме бредовые посты. Тебе даже инсталлировать его не надо, спасибо ютубу.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

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

Ты как зашоренная домохозяйка, которая считает, что отдаёт всё это в некий черный ящик, который всё сам сделает, спуститься на уровень ниже и представить усложнение архитектуры - ты не в состоянии. С дивана легко вкручивается и поддержка вертикального письма. Нажал там какую-нибудь кнопочку и готово.

Юникод в текущем виде - это боль для разработчика (на нижнем уровне), который порождает жирные/медленные решения, говнофреемворки, юзая которые конечный хомяк эту боль не видит, но тем не менее - фундамент у всего этого - дерьмовый. Я со скрипом принял модификаторы (мне это не нравится, много софта не умеет даже это, я проверял) и уж точно не собираюсь заморачиваться о RTL письме.

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

Ты как зашоренная домохозяйка, которая считает, что отдаёт всё это в некий черный ящик,

Из нас двоих это у тебя проблемы с пониманием того, как байты расположены в памяти.

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

Да ты можешь вообще нихера не делать, я тебя-то ни о чём не уговариваю. Я лишь багфиксю твоё 4.2 на этом ITT-форуме, чтоб залётный мимокрок не принял за чистую монету тот бред, что ты тут постишь.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Из нас двоих это у тебя проблемы с пониманием того, как байты расположены в памяти.

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

Все эти метки направления - просто доп мишура, интерпретировать я могу её как угодно, хранить код поинту во внутреннем буфере своего «рендерящего текст приложения» в любом порядке могу переворачивать текст, если хочу. В общем случае мне для двунаправленного письма придётся параллельно держать «массив» со сдвигами, также от направления текста зависит место отрисовки пунктуационных знаков, значит опять куча доп телодвижений на банальщине - лаги, переусложнённая архитектура.

Мне проще сделать вид, что никакого RTL письма не существует, многие делают вид, что не существует даже модификаторов, один код поинт - один символ. В реальности так, остальное - твои влажные фантазии.

kvpfs ★★
() автор топика
Ответ на: комментарий от kvpfs

utf8proc - аналогично как я понял.

Понял я неправильно, разбивать на символы она умеет (или как это называют - Grapheme Cluster Boundaries), utf8proc_grapheme_break_stateful. Я это понял, когда чуть было не начал костылить собственную разбивкку на символы. Кстати, правила были здесь и вязв этот список можно выделять символы самостоятельно.

kvpfs ★★
() автор топика

Ещё оставлю ссылку на годную либу https://github.com/yhirose/cpp-unicodelib . Она мне показалсь самой правильной и продуманной, utf8cpp utf8proc нормально работает лишь с utf8, а нафиг внутри приложухи нужен utf8? Придётся постоянно конвертить.

Правда у cpp-unicodelib есть одна особенность - автор пошёл необычным путём и вместо задания код поинтов в таблицах через диапазоны, он захардкодил всё в массивах «раскрыв» все диапазоны, бинарь пухнет малость. Да, наверное быстрее, но не думаю, что сильно. Тем не менее - штука достойная (если не всплывут никакие баги).

kvpfs ★★
() автор топика
Последнее исправление: kvpfs (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.