Page 1 of 3

Юникод

Posted: Sun Oct 09, 2011 12:40 am
by XVilka
1. Многим понятны преимущества, которые даёт юникод, расписывать не буду.
2. Уже обсуждалось - многие согласны. viewtopic.php?f=32&t=144

3. Прикрепляю библиотеку для работы с юникодом. Два файла размером 15-20Кб на Си - могут быть переведены в ассемблер.
Остальное данные.

Re: Юникод

Posted: Wed Oct 12, 2011 7:46 am
by dzavalishin
за либу спасибо :), а насчёт Колибри - я бы предложил специфицировать, как и где в системе применяется юникод.

Re: Юникод

Posted: Wed Oct 12, 2011 12:35 pm
by Phantom-84
Было бы хорошо, если бы везде применялся. Я однобайтовую кодировку использую только при прямом выводе на текстовую консоль, причем даже здесь при желании можно добиться одновременного отображения 512 различных символов.

Re: Юникод

Posted: Wed Oct 12, 2011 11:11 pm
by ilya
GNU GPL v2 License as specified on http://www.gnu.org. All Rights Reserved.

Code: Select all

utf8_1stBait_validation:
  db 1,1,1,1,1,1,1,1
  db 1,1,1,1,1,1,1,1
  db 0,0,0,0,0,0,0,0
  db 2,2,2,2,3,3,4,0

;GNU GPL v2 License as specified on http://www.gnu.org. All Rights Reserved.

; Reads utf-8 symbol into EAX at ESI.
; If function completes without error - ESI advances to next potential symbol
; Function foesn't validate unicode ranges
;---------------------------------------------------------------------------------------------------
; input: esi - pointer to memory with 4bait read access
; return:
;        eax - value
;        ecx - number of baits in utf-8 symbol, or =0 if invalid symbol 
;        CF=0 if ecx !=0,  CF=1 if ecx=0
; detroyed:
;        eflags, edx, esi+=ecx

utf8_nextChar:
  cld
  xor    eax ,eax
  lodsb
  xor    ecx, ecx
  movzx  edx, al
  shr    eax, 3
  and    edx, 1111111b
  add    cl, byte [utf8_1stBait_validation+eax]    ; cl = number of bytes in the utf8 symbol
  jz     .err2
  cmp    cl, 3
  ja     .4
  jz     .3
  jp     .2
  jmp    @f
.2:
  lodsb
  and    edx, 11111b
  btr    eax, 7                              ; clear top bit and verify if bit is set
  jnc    .err
  shl    edx, 6
  test   al, $40
  jnz    .err
  or     edx, eax

  ; add your unicode range validation here for 2byte utf8 sequence

  jmp    @f
.3:
  lodsw                                      ; load 2 bytes
  test   eax, 0100'0000'0100'0000b           ; verify that cleared bits are cleared
  jnz    .err
  not    eax
  test   eax, 1000'0000'1000'0000b           ; verify that set bits are set
  jnz    .err
  not    eax
  and    edx, 1111b                          ; only low 4bits of 1st bait are valid
  shl    eax, 2
  ror    ax, 8                               ; do
  shr    ah, 2                               ;  some
  shr    eax, 2                              ;     bit
  shl    edx, 12                             ;       swapping
  and    eax, $fff
  or     edx, eax

  ; add your unicode range validation here for 3byte utf8 sequence

  jmp    @f
.4:
  dec    esi
  lodsd
  shl    edx, 8
  test   eax, $40404000
  jnz    .err
  not    eax
  test   eax, $80808000
  jnz    .err
  not    eax

  mov    dl, ah
  bswap  eax
  shl    dl, 2
  shl    eax, 2                              ; eax:  get rid of top 2bits in AL
  shl    edx, 10                             ; edx[20:12] filled
  shr    ah, 2                               ; eax:  bring AH & AL together in one 12bit chunk
  shr    eax, 2                              ; eax[11:0] filled
  and    edx, $1ff000
  and    eax, $fff
  or     edx, eax

  ; add your unicode range validation here for 4byte utf8 sequence

@@:
  mov    eax, edx
  clc

.exit:
ret

.err2:
  sub    esi, 1
.err:
  sub    esi, ecx
  xor    ecx, ecx
  stc
  jmp    .exit
сколько всяких проверок бля, в одной простой функции

Re: Юникод

Posted: Fri Oct 14, 2011 10:58 am
by Joaquin
А можно хранить кодпойнты как последовательность не из четырёх, а трёх байт :) Ибо больше и не надо. При этом: a) данные, которые занимает текст в такой кодировке, в среднем всего на 50% длинее чем в UTF-16 (а в некоторых случаях даже до 30% процентов короче); б) данные всегда будут фиксированной длины, никаких суррогатных пар, random access к символам в строке.
Единственный минус: в отличие от UTF-32, код-юниты не будут выравнены на 4-байтную границу, поэтому обработка будет чуть медленней (но это не критично).
P.S. А назвать это можно будет "UTF-24".

Re: Юникод

Posted: Fri Oct 14, 2011 11:38 am
by XVilka
не стоит придумывать нестандартные решения - в будущем это сулит кучу проблем. Тем более выигрыш действительно невелик, возможно даже иллюзорен.

Re: Юникод

Posted: Fri Oct 14, 2011 11:46 am
by Joaquin
Я это в качестве внутреннего формата (для хранения строк, например, в ОЗУ) предложил. Преобразование UTF-24-to-UTF-x реализовать будет несложно.

Re: Юникод

Posted: Fri Oct 14, 2011 12:30 pm
by maximYCH
UCS-2?

Re: Юникод

Posted: Sat Oct 15, 2011 5:03 pm
by Phantom-84
Не стоит окончательно отказываться от суррогатных пар. Просто начинать нужно с поддержки базовой плоскости. Считать все символы из дополнительных плоскостей некорректными для служебного применения (например, в именах файлов). Их коды можно рассматривать как некорректный символ с модификатором или как два некорректных символа.
Joaquin wrote:А можно хранить кодпойнты как последовательность не из четырёх, а трёх байт :) Ибо больше и не надо.
А можно и как двух байт ;) "Ибо больше и не надо" на практике, и остаешься в рамках стандарта.

Re: Юникод

Posted: Thu Oct 27, 2011 2:45 pm
by FireWall
У меня есть такая гипотеза, что проще всего будет перейти именно на UTF-8:
- разработан в группе Plan9 (те же создатели UNIX и их ученики);
- одобрен авторитетными стандартами;
- все алгоритмы, не использующие тот факт, что длина и позиция измеряется именно в символах, будут продолжать адекватно работать.

Предполагаю главные проблемы:
- вычисление длины строки в символах (а это может быть нужно для пользователя и пользовательского интерфейса) будет работать в несколько раз медленнее;
- символ уже больше не умещается даже в int (но это происходит крайне редко), а поиск (подсчёт) вхождения символа потребуется реализовывать как поиск (подсчёт) вхождения подстроки длиной в 1 - 6 байт (в контексте UTF-8 длина строки в символах <= длине строки в байтах - число ненулевых байтов до первого нулевого).

Re: Юникод

Posted: Tue Feb 21, 2012 2:07 am
by Freeman
Требования к API Юникода есть?

Пишу сейчас реализацию, которую, как мне кажется, достаточно легко абстрагировать, ибо зависимостей минимум. TRawCodePage даже готов реализовать сам, если о формате таблиц перекодировок договоримся. Для "Колибри" вариантов два: или как-то собрать в FPC, или перенести код из дизассемблера, а потом переписать, если хочется. Есть добровольцы? Пример вывода DCU32Int прикладываю (оригинал на Паскале).

Что реализовано или будет реализовано в ближайшее время:
  • Перекодировка между представлениями Юникода (UTF-xx).
  • Перекодировка между legacy-кодировками и Юникодом.
  • Перекодировка из одной legacy-кодировки в другую через Юникод.
  • Верхний-нижний регистр -- тоже через Юникод, для всех языков сразу.
Наборы символов и кодировки:
  • UTF-8 (включая CESU-8 и модифицированный UTF-8), UTF-16 (включая суррогатные пары, BE и LE), UTF-32 (BE и LE).
  • 7-битная ASCII и ISO-8859-1 (Latin-1), не требующие таблицы перекодировки (для полноты концепций). :)
  • Однобайтовые (включая EBCDIC) и двухбайтовые кодовые страницы (Shift-JIS, Big5 и пр.)
Перекодировки UTF делаются алгоритмически. Таблицы соответствия legacy- и Юникода могут храниться во внешнем файле или ресурсах (?). Сейчас они берутся из Windows. Реализовать TRawCodePage и нагенерить для неё таблиц, -- проще простого, повторюсь.

Хранимые данные для однобайтовой кодовой страницы -- 128 × SizeOf(WideChar) = 256 байт -- для Windows- или OEM-кодировок, и вплоть до 512 байт для EBCDIC. Таблица обратной трансляции строится уже в памяти, для Windows-1251 занимает порядка 8 КБ.

Все перекодировки делаются без потерь диакритик, появления кракозяблов и вопросиков. Именно поэтому мне и потребовалось писать собственную реализацию. Если строку нельзя представить в затребованном представлении -- это ошибка. При включённом бите coForceInvalid ошибочные символы заменяются "квадратиками".

Что пока не планируется к реализации, так это композиция-декомпозиция (NFD, NFKC, NFKD), UTF-7 и прочая редко используемая байда. Не думаю, что это актуально для "Колибри". :)

Re: Юникод

Posted: Tue Feb 21, 2012 2:40 am
by Mario
Offtop: Для Колибри? На паскале? Юникод? - Дайте два! :mrgreen:

Мне так кажется это все надо в либу пихать.

Re: Юникод

Posted: Wed Feb 22, 2012 7:10 am
by Freeman
Набросал примерный API. Высказываемся.

Re: Юникод

Posted: Wed Feb 22, 2012 3:49 pm
by Mario
Я в паскале "не в зуб ногой". Лучше бы сделал текстовое описание. Как показывает практика даже хорошо прокомментированный код не всегда понятен, что уж говорить о известном только автору коде с мизером комментариев. Навык телепатии не прокачан.

Re: Юникод

Posted: Wed Feb 22, 2012 4:40 pm
by Freeman
Словесное описание -- парой сообщений выше. :)