Как я могу распознать строки RTL в C ++ - PullRequest
3 голосов
/ 24 марта 2011

Мне нужно знать направление моего текста перед печатью.

Я использую символы Юникода.

Как я могу это сделать в C ++?

Ответы [ 4 ]

6 голосов
/ 12 апреля 2011

Если вы не хотите использовать ICU, вы всегда можете вручную проанализировать базу данных Unicode (.eg, со скриптом Python).Это текстовый файл, разделенный точкой с запятой, где каждая строка представляет символьную кодовую точку.Ищите пятую запись в каждой строке - это класс персонажа.Если это R или AL, у вас есть символ RTL, а 'L' - символ LTR.Другие классы - это слабые или нейтральные типы (например, цифры), которые, я думаю, вы бы хотели игнорировать.Используя эту информацию, вы можете создать таблицу поиска всех символов RTL, а затем использовать ее в своем коде C ++.Если вы действительно заботитесь о размере кода, вы можете минимизировать размер таблицы поиска в вашем коде, используя диапазоны (вместо записи для каждого символа), поскольку большинство символов входят в блоки своего класса BiDi.

Теперь определите функцию с именем GetCharDirection(wchar_t ch), которая возвращает значение перечисления (скажем: Dir_LTR, Dir_RTL или Dir_Neutral), проверяя таблицу поиска.

Теперь вы можете определить функцию GetStringDirection(const wchar_t*)который проходит через все символы в строке, пока не встретит символ, который не является Dir_Neutral.Этот первый ненейтральный символ в строке должен задать базовое направление для этой строки.Или, по крайней мере, так работает ICU.

5 голосов
/ 24 марта 2011

Вы можете использовать библиотеку ICU , в которой есть соответствующие функции ( ubidi_getDirection ubidi_getBaseDirection ).

Размер ICU можетможно уменьшить, перекомпилировав библиотеку данных (которая обычно составляет около 15 МБ), чтобы включить только те преобразователи / локальные данные, которые необходимы для проекта.

Раздел Сокращение размера данных ICU: преобразованиеТаблицы сайта http://userguide.icu -project.org / icudata , содержат информацию о том, как можно уменьшить размер библиотеки данных.

Если требуется только поддержка наиболее распространенныхкодировки (US-ASCII, ISO-8859-1, UTF-7/8/16/32, SCSU, BOCU-1, CESU-8), библиотека данных в любом случае не понадобится.

2 голосов
/ 05 марта 2012

Как сказал ранее Боаз Янив, может быть, что-то вроде этого будет проще и быстрее, чем анализ всего файла:

int aft_isrtl(int c){
  if (
    (c==0x05BE)||(c==0x05C0)||(c==0x05C3)||(c==0x05C6)||
    ((c>=0x05D0)&&(c<=0x05F4))||
    (c==0x0608)||(c==0x060B)||(c==0x060D)||
    ((c>=0x061B)&&(c<=0x064A))||
    ((c>=0x066D)&&(c<=0x066F))||
    ((c>=0x0671)&&(c<=0x06D5))||
    ((c>=0x06E5)&&(c<=0x06E6))||
    ((c>=0x06EE)&&(c<=0x06EF))||
    ((c>=0x06FA)&&(c<=0x0710))||
    ((c>=0x0712)&&(c<=0x072F))||
    ((c>=0x074D)&&(c<=0x07A5))||
    ((c>=0x07B1)&&(c<=0x07EA))||
    ((c>=0x07F4)&&(c<=0x07F5))||
    ((c>=0x07FA)&&(c<=0x0815))||
    (c==0x081A)||(c==0x0824)||(c==0x0828)||
    ((c>=0x0830)&&(c<=0x0858))||
    ((c>=0x085E)&&(c<=0x08AC))||
    (c==0x200F)||(c==0xFB1D)||
    ((c>=0xFB1F)&&(c<=0xFB28))||
    ((c>=0xFB2A)&&(c<=0xFD3D))||
    ((c>=0xFD50)&&(c<=0xFDFC))||
    ((c>=0xFE70)&&(c<=0xFEFC))||
    ((c>=0x10800)&&(c<=0x1091B))||
    ((c>=0x10920)&&(c<=0x10A00))||
    ((c>=0x10A10)&&(c<=0x10A33))||
    ((c>=0x10A40)&&(c<=0x10B35))||
    ((c>=0x10B40)&&(c<=0x10C48))||
    ((c>=0x1EE00)&&(c<=0x1EEBB))
  ) return 1;
  return 0;
}
0 голосов
/ 13 ноября 2011

Если вы используете Windows GDI, может показаться, что GetFontLanguageInfo (HDC) возвращает DWORD;если установлено GCP_REORDER, язык требует переупорядочения для отображения, например, иврит или арабский.

...