Saturday, June 20, 2015

Чем плох Юникод и как его можно улучшить.

Предлагается замена Юникоду - новый формат кодирования текста со следующими свойствами:
  • Кодирует все теоретически возможные виды символов.
  • Не требует централизованного стандартизирующего органа.
  • Позволяет увидеть текст на любом языке даже при отсутствии подходящих шрифтов.
  • Раздельно сохраняет визуальную и лингвистическую информацию о символах, позволяя приложениям игнорировать те части, которые им не нужны.
  • Позволяет включать в текст индивидуальные авторские символы и рисунки.
  • Обратно совместим с ASCII.
  • Поддерживается всеми приложениями, которые работают с однобайтными строками с 0-терминированием.
  • Может быть конвертирован из Юникода без ограничений и конвертирован в Юникод в той части, которая поддерживается Юникодом.
  • Обеспечивает быстрое декодирование во внутренний формат приложений и быстрое кодирование.
  • Компактен.

Под катом - детали и пример реализации.


Юникод - краткая история

В стародавние времена PDP-11, CP/M и MS-DOS основным устройством для работы программ был текстовый терминал. Аппаратно поддерживалось не более 256 разных символов на одном экране.

В некоторые терминалы намертво зашивалась кодировка ASCII. В другие можно было загружать свои кодировки. Большинство кодировок поддерживало одновременную работу с латинским алфавитом и еще каким-нибудь одним дополнительным.

О том, чтобы одновременно работать с несколькими (всеми возможными на свете) языками, речь не шла в принципе. Ибо все алфавиты мира не затолкаешь в аппаратное ограничение в 256 символов знакогенератора.

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

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

Юникод позволил иметь в одном приложении, в одном документе тексты на разных языках одновременно.
Информация о языке была отвязана от шрифта и у каждого символа появился жестко закрепленный стандартный код.
Это был большой шаг вперед. Но Юникод создал множество чисто технических проблем:

Что в Юникоде не так

Раньше наши символы занимали переменное число байт (как минимум в китайском, японском, корейском кодировании).
Теперь они занимают переменное число байт, 16-битных слов или 32-битное слово.

Раньше мы имели проблемы с кодировками.
Теперь у нас есть UTF-8, UTF-16-BE, UTF-16-LE, UTF-32-BE, UTF-32-LE, USC-2, UCS-4 и мы обязаны поддерживать их все.

Раньше мы должны были иметь шрифт из 128 символов ASCII и несколько шрифтов для других языков. И приложения должны были поддерживать переключение шрифтов.
Теперь нужно иметь шрифт из миллиона символов (расслабьтесь, нет таких шрифтов).

Раньше мы не могли увидеть некоторые алфавиты, если у нас нет подходящего шрифта.
Теперь мы тоже не можем их увидеть.

Раньше мы могли добавить недостающие символы уйгурского алфавита, придумав им кодировку и нарисовав шрифт.
Теперь, если символов нет в Юникоде, вам придется выделить им зарезервированные private-use code points и молиться, чтобы не приключилось коллизии (и вы удивитесь, сколько живых и интенсивно использующихся языков не представлены в Юникоде, зато там есть клингонский алфавит).

Раньше для поддержки новых символов мы были должны устанавливать дополнительные шрифты.
Теперь каждый год выходит новая ревизия Юникода, приносящая сотни новых символов.
Для поддержки новой ревизии приходится патчить существующие программы и операционные системы. На многих устаревших (прошлогодних) системах новый текст не отобразится.

Но не все проблемы имеют техническую природу. Часть проблем, если хотите, философские. Юникод не учитывает три базовых свойств текста:

  1. Текст - это последовательность знаков, которые способна нарисовать человеческая рука. И таких символов - бесконечное количество.

    Юникод дает символам коды из фиксированного и заведомо ограниченного набора.
    Пополнять этот набор могут только специально назначенные чиновники.
    А имена символов связаны не с изображением, а с ролью символа в случайно выбранной культуре.
    Например, как вы себе представляете изображение символа U+2642 "Male Sign"? (гусары, молчать :-), а это всего лишь кружок с направленной вправо-вверх стрелкой.
  2. В некоторых случаях (когда мы классифицируем, ищем или определяем степень подобия текстовых фрагментов) важны только изображения знаков. И компьютер должен учитывать только их внешний вид.

    Юникод преуспел в создании хаоса в этом вопросе, например символ "E" может кодироваться как U+0045, U+0415, U+1D31, U+0395. И это самый простой случай. Для символов с диакритическими знаками варианты будут измеряться десятками.
  3. В большинстве случаев читатель вкладывает в увиденные символы смысл в соответствии со своей культурой и языком.
    Поэтому текст должен иметь возможность подсказывать компьютеру, в какой культуре написаны те или иные символы. Т. к. от культуры зависит, какие дизайнерские шрифты могут быть применены, правила переноса, озвучения, правила смены регистра и проверки орфографии.

    Юникод не позволяет различить португальскую букву ai (аи, U+0045) и польскую букву e (U+0045) там, где это будет нужно.

Природа символа

Символ сочетает в себе две несвязанные категории из разных миров - графическое изображение (глиф) и языковое наполнение (буква).
Например, символ "M"

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

Какая из этих частей информации важнее? Обе важнее.

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

Критикуя, предлагай.

Давайте сочиним альтернативный формат кодирования текста.
Вначале определимся с требованиями:

  1. Наш формат НЕ описывает представление текста внутри приложений. Буквы в приложениях давно хранятся в виде объектов со стилевыми атрибутами (flyweight pattern).
  2. Мы формализуем кодирование текста в файлах и транспортных каналах. Поэтому мы можем хранить текст в виде байт-ориентированного стрима.
  3. Для удобства существующих приложений байт с кодом 0 будет терминатором текста.
  4. Мы можем позволить символам занимать переменное количество байт.
  5. Мы должны поддержать все возможные символы на свете, все, что способна написать человеческая рука и распознать человеческий глаз.
  6. Кодирование текста должно быть полностью децентрализованным. Никаких комитетов.
  7. Информация о внешнем виде символа и о языке должна быть разделена.
  8. Даже не имея подходящего шрифта человек должен иметь возможность увидеть текст и даже внести в него правки.


Наше кодирование должно прозрачно работать со всеми приложениями, работающими с байт-ориентированным текстом: ascii и utf-8, mbcs. Поэтому 0x00 будет терминатором текста.

Мы не можем построить одну всемирную таблицу символов, т. к. это будет фактически возвратом к Юникоду и повторению всех его проблем.
Вместо этого мы должны предусмотреть какое-то небольшое количество предопределенных символов (хотя бы для совместимости с ASCII) и синтаксис для определения новых символов.
Новый символ будет задаваться многобайтным именем и будет динамически получать числовой индекс.

В Юникоде символы тоже имеют имена, и эти имена - попытка передать смысл символа на английском языке.
Только представьте, североуральский мокшанец должен знать английский язык, чтобы прочитать название своей родной буквы, сильно искореженное английской транскрипцией :-)

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

Простой символ

Определение нового символа начитается с байта, имеющего значение 0x01, за которым следуют несколько байт - имя нового символа.
Все эти байты имеют одинаковый простой формат:
0b_CLXX_XYYY
где:
С - признак конца имени, он установлен в 1 у всех байтов имени, кроме последнего.
L - тип команды
0 - поставить точку в позиции XY
1 - провести линию из предыдущей позиции в позицию XY
XXX - три бита, задающие X-координату
YYY - три бита, задающие Y-координату

Символ рисуется в координатной сетке 8x8, что позволяет иметь в символе до восьми штрихов по горизонтали и восьми по вертикали.
Ось X направлена слева направо. Ось Y - снизу вверх. Точка 0,0 соответствует левому нижнему углу.
Начальной точкой является (1,1).
Определение символа не может заканчиваться на точку в позиции 0,0 т. к. байт со значением 0x00 - в тексте недопустим.
Если определение символа заканчивается на точку, это диакритический знак связанный со следующим символом. Если на линию, это обычный символ.

Пример:
Символ "LATIN CAPITAL LETTER A" в кодируется как D7 E1 4A
0xD7   0b_1_1_010_111   LineTo 2 7
0xE1   0b_1_1_100_001    LineTo 4 1
0x4A   0b_0_1_001_010    LineTo 1 2
Легко заметить, что визуальное кодирование имени символа, не только позволяет увидеть его при отсутствии шрифта, но и существенно выигрывает в размерах по сравнению с английским описательным именем, принятым в Юникоде.

Сложный символ

Иногда символы невозможно нарисовать точками и палочками.
Могут существовать языки с повышенными требованиями к ширине штрихов, плавности линий, могут существовать требования многоцветности или полупрозрачности,
некоторым языкам может не хватить восьми штрихов по вертикали и горизонтали.
Или автор текста может захотеть вставить в текст графический элемент, который никогда не будет частью какого-либо шрифта, но должен прилично отображаться всегда и везде.
Для этих целей в формат текста включен альтернативный способ описния внешнего вида символа.
Он начинается с байта 0x02, за которым следует длина имени символа в байтах, закодированная в 7-битном коде radix128 (о нем ниже).
За длиной следуют командные байты, которые имеют следующий формат:
ССXXXYYY
где
  СС - селектор
1 - расширение разрядов для последующих команд
2 - определение управляющей точки для кривой Безье
3 - определение точки контура.
Вместе с предыдущими управляющими точками
и предыдущей точкой контура задает линию,
квадратичный или кубический сплайн
0 - закрытие контура,
последний сегмент определяется предыдущей точкой контура,
предыдущими управляющими точками и первой точкой контура.
координаты x и y из команды 0 задают первую точку нового контура.
  XXX - 3 бита x-координаты
  YYY - 3 бита y-координаты

Символ рисуется в координатной сетке 0..1, масштабированной на высоту строки текста. ось X направлена слева направо. ось Y - снизу вверх.
Начальная точка первого контура 0 1/8.

В каждом байте присутствуют 3 бита координаты X и Y.
Координаты x и y всегда задают дробную часть числа.
В командах 2,3,0 кодируются старшие 3 бита дробной части, в предшествующих командах 1 - младшие.
Например, последовательность
01 001 000 ; расширение разрядов
11 100 111 ; точка контура задает точку в координатах:
x= 0b_1_000_000 / 0b_100_001 = 0.515625
y= 0b_1_000_000 / 0b_111_000 = 0.84375
При необходимости точка контура может иметь несколько байт расширения разрядов.

Контур длиной в 0 точек кодирует цвет и масштаб последующих контуров:
управляющая точка 0 задает множитель размера координатной сетки символа,
точка 1 - RG компоненты цвета,
точка 2 - B и Alpha-компоненты.

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

Полный пример кодирования сложного символа
02 ; сложный символ
03 ; количество байт в описании символа (radix128)
D7 ; 11_010_111 контур состоит из линии (11) из точки 0,1/8 в точку 2/8(010), 7/8(111)...
E0 ; 11_100_001 ...и линии из точки 2/8,7/8 в точку 4/8, 1/8
92 ; 10_010_010 ...и квадратичного сплайна из точки 4/8, 1/8
через управляющую точку 2/8, 2/8 в начальную точку контура 0,0
Код 2 позволяет включать в текст векторную графику произвольной сложности, многоцветную, полупрозрачную, имеющую произвольные размеры.

Языки, алфавиты и культуры

Как уже говорилось выше, для текста важен не только внешний вид буквы, но и языковая информация.
Поэтому в текст включаются маркеры языка (например, английская, русская, китайская, татарская, иврит и т.д.) или более общие маркеры алфавита (латиница, кириллица и т.д.).
Маркер начинается с байта 0x03, за которым следует длина названия языка в символах (в radix128) и символы названия языка.

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

Кодирование текста:

0 - признак конца текста,
1 - определение простого символа,
2 - определение сложного символа
3 - определение языка
4..FF - символы текущей кодовой таблицы.

Парсер текста имеет 252-элементную кодовую таблицу (от 0x04 до 0xff), каждый элемент которой хранит именованный символ, векторный символ или имя языка.
Первоначально таблица заполнена символами ASCII, (верхняя половина 80..ff заполнена уникальными символами случайно выбранных земных алфавитов, если кому-то не хватило места - без обид).
Всякий определяемый символ (с помощью последовательности 1... или 2...)
и всякий определяемый язык (с помощью последовательности 3...) замещает один из кодов 4...255 в однобайтной кодовой таблице.
Применение кода с 4 по 255 является обращением к ранее определенному символу.

Все коды соединены в LRU-list. Каждое обращение к коду переставляет его в начало списка. Каждое определение кода замещает последний элемент списка на вновь определенный символ или язык.
Таким образом, кодировщик текста пользуется предопределенными символами, определяет новые символы и создает для текста уникальную кодовую таблицу,
в которой 252 самых распространенных символа кодируются одним байтом. Это обеспечивает небольшую компрессию, но компрессия не является целью данного механизма (в конце концов zip справился бы лучше)
главная цель введения однобайтных ссылок на имена - ускорение и упрощение декодирования текста. Лук-ап имени символа в языке и лук-ап языка в системной таблице производится только один раз - при
помещении в таблицу.

Пример

Это canvas.
На страничке запущен JS, который умеет рисовать текст, закодированный в PolyCode.

Исходное кодирование:
text = [
   /*english*/ 0x4f, 0x62, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x0a,
   /*rus*/     0x06, 0x4f, 0x92, 0x45, 0x42, 0x90, 0x81, 0x48, 0x4f, 0x0a,
   /*pol*/     0x03, 0x02, 0x70, 0x6c, 0x4f, 0x63, 0x7a, 0x79, 0x77, 0x69, 0x1f, 0x73, 0x63, 0x69, 0x65, 0x0a,
   /*arab/*    0xb6, 0x20, 0xc1, 0x1c, 0xba, 0xc1, 0x0e, 0xb7, 0x0a,
   /*chineese*/ 1, 205,213,210,202,140,212,145,218,222,246,240,232,156,244,154,114,
  1, 241,153,219,161,227,138,195,204,206,246,244,251,242,140,244,141,117, 0x0a,
   // batman sign
       0x02, 0x1c, 0x05, 0xd5, 0x60, 0x94, 0xdc, 0x50, 0xdd, 0x60, 0x9c, 0x70, 0xdd, 0xe4, 0x60,
       0xa4, 0xed, 0xfd, 0x60, 0xac, 0x44, 0xf2, 0xa3, 0x60, 0xd9, 0x9b, 0x44, 0xca, 0x60, 0x8c,
];

Первая строка нарисована так, как будто в системе нет ни одного шрифта ни для какого языка.
При рисовании второй строки был добавлен латинский алфавит.

Пример демонстрирует, что:

  • Polycode прекрасно справляется с одновременным отображением множества алфавитов
  • Одновременно, использованы языки: английский, русский, польский, арабский, китайский.
  • Сохраняется информация об языке, присутствует маркер польского текста (Юникод этого не умеет) 
  • В отличие от Юникода, одинаково выглядящие символы - английская О, русская О, польская O - имеют одинаковое внутреннее представление.
  • Сохраняется информация об алфавите, поэтому мы можем оформить английскую O и польскую O разными национальными шрифтами.
  • Даже при отсутствии какого-либо шрифта, тексты продолжают читаться (а наличие шрифтов просто улучшает их вид). Это еще одно преимущество перед Юникодом.
  • Неизвестные символы - не проблема, мы легко добавляем в текст произвольные символы и иероглифы (в примере были добавлены китайские).
  • Мы можем добавлять в текст новые полиграфически безупречные символы. Например, знак бэтмена. В Юникоде нет знака бэтмена (как минимум, такого).
  • Текст занимает объем, сравнимый с utf-8, мы ничем не жертвуем за эти плюшки.

Исходный код

Желающие приглашаются поиграть с кодировками, шрифтами и исходным кодом https://jsfiddle.net/jh9gcrdj/

16 comments:

  1. Сходу: имена можно гораздо лучше ужать

    ReplyDelete
    Replies
    1. Предложи свой вариант

      Delete
    2. Например, в первом варианте использовать эскейп-маркер вместо флага конца описания. Маркер начала линии подобным же образом можно сделать, потому что многие линии будут ломаными, а не отрезками "от" и "до"

      Это я так, ремарка для реализаторов библиотеки если таковая случится.

      Delete
    3. Исправленный пример: Командное слово 6 бит {int x:3, y:3}, комбинация координат 7x0 запрещена и обозначает конец ломаной. Комбинация 7x1 запрещена и означает конец символа. При сериализации в бит-стрим нужно следить за появлением нулевого байта и искейпить его. Т.к. мы все еще хотим совместимости с существующими приложениями.
      Возьмем символ E, как имеющий больше одного штриха и ломаную (типичный символ).
      В текущей версии поликода его имя занимает 6 байт (set 2x0, line 0x0, line 0x6, line 2x6, set 2x3, endline 0x3).
      В предлагаемом варианте - 8 шестибитных команд (2x0, 0x0, 0x6, 2x6, endline, 2x3, 0x3, end) казалось бы паритет, но последовательность четырех нулей даст 12 нулеых бит битового потока и приведет к искейпингу +1 байт.
      Итого: существенно более сложный формат, который не дает выигрыша.

      Delete
  2. > Текст занимает объем, сравнимый с utf-8, мы ничем не жертвуем за эти плюшки.

    Сможете это доказать? Навскидку получается, что предложенный вариант длиннее. ASCII в UTF-8 не меняется, национальные строчки тоже не сильно прибавляют.

    Нужны примеры для коротких строк.

    (А вообще, мне нравится - готов покодить это)

    ReplyDelete
    Replies
    1. ASCII и в поликоде не меняется. Начальное заполнение lru-таблицы покрывает ascii и множество современных алфавитов.
      Новый символ, впервые встретившийся в тексте, занимает в среднем 5 байт. Такой сложный символ, как иероглиф - до 17 байт. Повторное использование символа - 1 байт.
      Даже в сложном китайском случае большинство ироглифов (синшэнцзы) распадаются на части, которые вполне можно переиспользовать в одном тексте и сократить до одного байта.

      Delete
    2. Фокус в том что считать текстом. Если у нас короткие реплики в каком-то чате, то нам придётся в каждой из этих реплик полностью прописать описание каждого символа (ну, кроме ASCII)

      Delete
    3. ... кроме 252 предопределенных однобайтных символов самых распространенных на земле форм букв. В этот набор входит и ASCII.

      А вообще странно смотрится сегодня экономия десятка байт на коротком сообщении, когда альтернативой ему становится постинг в виде мегабайтной анимированной gif-ки.

      Delete
    4. Русский алфавит попадает в предопределенный набор 252, поэтому твоя реплика будет в два раза компактнее в сравнении с utf8.
      Если записать ее на тамильском, 174 символа, ~20 уникальных глифов, ~10 байт имя глифа. ~350 - 450 байт на cooбщение. Оно же в utf8 - занимает 522 байта.

      Delete
    5. Но смайлики-то уже в юникод входят, а анимированные гифки обычно не шлются а локально заранее сохранены

      Delete
    6. > Русский алфавит попадает в предопределенный набор 252, поэтому твоя реплика будет в два раза компактнее в сравнении с utf8.

      Это не аргумент. Пусть будет не русский, а суахили

      Delete
    7. (упс, последнюю реплику считать недействительной)

      Delete
  3. В целом идея мне нравится, но у меня возник ряд вопросов.

    1. Насколько далеко простираются полномочия "рендерера неопознанных знаков"? Например, в демонстрации рендерер рисует диакритический знак. Значит ли это, что рендерер будет рисовать и лигатуры типа fi (U+FB01), и широкие диакритики типа a͡b (U+035D)? А контекстные формы арабской вязи?

    2. При отрисовке диакритика в примере он был поставлен сверху. Как быть с диакритиками, которые рисуются в других местах? Например, в тайском, кхмерском и лаосском письме есть диакритики, которые рисуются слева от буквы, к которой они привязаны. Причем это и не диакритики-то, по сути — это их гласные буквы. Как быть с корейским письмом, где в одно знакоместо могут быть упакованы от 2 до 5 букв?

    3. Как формат "простого символа" (код 1) в принципе декларирует позицию будущего диакритика? Как отличаются диакритики, которые выглядят одинаково, но имеют разный смысл в зависимости от положения относительно предыдущего знака? Или отличаются размером?

    4. Если рендерер неопознанных знаков собирается покрывать все эти случаи, не приблизится ли он по сложности к виртуальной машине OpenType? Может, тогда его сразу и использовать? Если упрощать, то насколько?

    5. Почему выбрано представление, где диакритик идет до буквы, к которой он применяется? Ведь даже по логике письма сначала рисуется основной знак, затем к нему дописывается дополнение, а не наоборот.

    6. Некоторые люди вынуждены воспринимать текст на слух. Так как одна из заявленных целей polycode — дедупликация символов, которые выглядят одинаково, то каким образом экранный читатель сможет отличить символы, одинаковые визуально, но разные семантически? Например, "буква о" и "цифра ноль"? Можно, конечно, например, перечеркивать ноль на манер ZX Spectrum, то как быть со знаками, которые выглядят примерно одинаково, но имеют кардинально разный смысл, вроде E𝖤𝗘𝙴𝔼𝐄𝐸𝑬𝘌𝙀𝔈𝕰ℰ𝓔?

    7. Лигатура fi (U+FB01) — это один знак polycode или два? А чешские диграфы ch и dž?

    8. Как объявить пробелы разной ширины, включая нулевую?

    9. В юникоде есть понятия классов символов. Что-то аналогичное в polycode?

    10. Юникод — это еще и правила (де-)нормализации и (де-)композиции знаков. Что-то аналогичное в polycode?

    11. В юникоде есть управляющие символы, многие из которых невидимы — сменить направление письма, например. Что-то аналогичное в polycode?

    12. Почему так неудачно выбрано название? Polycode уже используется существующим игровым движком на lua, который, к тому же, занял домен polycode.org.

    13. Заявленный механизм отрисовки "сложных знаков" не учитывает хинтинг. Может, все-таки OpenType?

    14. Заявленный механизм отрисовки "сложных знаков" не учитывает потребности людей с ограничениями зрения и роботов. Допустим, эмблема бэтмена — ее невозможно никак описать или прочитать так, чтобы человек это понял, т.е. polycode нужно расширить еще и описаниями букв. Автор polycode выказывал претензию, мол, с чего бы это вдруг всем подряд знать английский — значит, это тоже нужно как-то решать, потому что я могу не знать суахили, на котором описан какой-то знак, но я хочу понимать, что он значит — на моем родном языке, или же на английском.

    15. Всяческие emoji, которые на части платформ отрисовываются растром — как их включать в polycode, если "сложные символы" не поддерживают всяческие градиенты? В случае с emoji можно надеяться на шрифт — а если речь идет о, например, логотипе или флаге?

    ReplyDelete
    Replies
    1. 1. Рендерер неопознанных знаков - не шрифт и не языковая система. Он работает тогда, когда в юникоде вообще рисуются "пустые белые квадратики". Бессмысленно предъявлять к нему претензии, что он недостаточно красив.
      Если ты работаешь с лаосскими текстами, у тебя в компьютере будет установлена лаосская языковая система, которая и диакритики и овучание и сортировку правильную сделает. А если твой текст попадется, например, мне, у которого на компьютере ничего лаосского нету, я увижу лаосские каракули и маркер лаосского текста. Носитель языка эти каракули прочитать сможет (хоть и ругаться будет на их внешний вид).
      2. Диакритики накладываются поверх друг друга.
      4, 13. Поликод не шрифт, а система именования символов. Он не стремится покрывать все случаи.
      5. Диакритик — модификатор символа, если расположить его перед, мы получаем префиксный код, который удобнее парсить.
      6. Для этого служат языковые культуры. Цифра ноль создает проблемы и сейчас, думаю ее лучше зачеркнуть. Далее вот эта строчка E𝖤𝗘𝙴𝔼𝐄𝐸𝑬𝘌𝙀𝔈𝕰ℰ𝓔 не имеет никакого смысла для человека на нее смотрящего. Все эти символы имеют смыслы в своих языковых культурах и своих контекстах. Глупо было придумывать разные коды для одного и того же символа вместо явного указания языковой культуры.
      8, 11. В дефолтной языковой культуре символы ‗ ¶ будут управляющими. Можно добавить literal культуру, в которой эти символы будут отображаемыми.
      9, 10 Да. Языковые культуры.
      12. Любое слово уже кем-то занято.
      13. Open type не учитывает анимацию, полутоновые градиенты и смену инструментов при гравировании на камне. А хинтинг устарел с появлением сабпиксельного рендеринга.
      14. Алфавит — набор знаков, которые можно увидеть или пощупать. Например, я придумал новый знак и добавил его в свой текст. Естественно в этом тексте будет объяснение этого знака, иначе знак не имеет смысла. Далее этот знак начинает жить своей жизнью, его начинают цитировать, копировать из текста в текст. Если теперь кто-то встретит этот знак и захочет узнать, что он означает, он просто сделает поисковый запрос и на какой-нибудь википедии увидит обсуждение филосовского понятия, связанного с этим знаком. Если бы мы попытались отразить определение смысла знака в его названии, мы получили бы набор слов, навроде: «Cyrillic Capital Letter Big Yus» которые значат то же самое, что и оригинальный символ. Все равно придется гуглить. Лучше я сам этот символ погуглю. "я могу не знать суахили, на котором описан какой-то знак... но я хочу понимать, что он значит — на моем родном языке, или же на английском" - на твоем родном языке этот знак - число пять, на суахили - этот знак - символ солнца, на английском этот знак - что-то оскорбительное и неприличное. Удачи тебе в текстовом описании этого знака. А поликод этот знак просто изобразит как он выглядит. И вдобавок стабдит пометкой, что этот знак автор написал в культуре суахили. Удачи юникоду в кодировании этой информации.
      15. "Всяческие emoji, которые на части платформ отрисовываются растром" - это и есть присутствующая на конкретной платформе языковая система эмоджи.
      "речь идет о, например, логотипе или флаге" - о развивающемся трехмерном флаге?

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

      Delete
  4. А как же сортировка по алфавиту?
    И case insensitive сравнение строк?

    ReplyDelete
    Replies
    1. Этим занимаются уставновленные в комптютере "языковые культуры"
      "Как уже говорилось выше, для текста важен не только внешний вид буквы, но и языковая информация.
      Поэтому в текст включаются маркеры языка (например, английская, русская, китайская, татарская, иврит и т.д.) или более общие маркеры алфавита (латиница, кириллица и т.д.).....
      На компьютере установлено некоторое количество языков, выстроенных пользователем в очередь по порядку приоритетов....
      Всякий символ текста передается языкам по порядку приоритетов. Первый язык, опознавший символ переводит его в свое внутреннее представление и отображает с использованием шрифта своего языка."

      А также выполняет сортировку по алфавиту, смену регистра и т.д.

      Delete