Summary: | Не реализована функция в mlang | ||
---|---|---|---|
Product: | WINE@Etersoft | Reporter: | Vitaly Lipatov <lav> |
Component: | Обработка текста и локали; Буфер | Assignee: | Виталий Перов <vitperov> |
Status: | CLOSED FIXED | QA Contact: | |
Severity: | minor | ||
Priority: | P4 | CC: | kondratyuk, vostok |
Version: | 1.0.10 | ||
Target Milestone: | --- | ||
Hardware: | PC | ||
OS: | All | ||
Whiteboard: | |||
Заявки RT: | Связано с: | ||
Дата напоминания: | |||
Bug Depends on: | |||
Bug Blocks: | 42 |
Description
Vitaly Lipatov
2008-06-27 22:19:18 MSD
для начала требуется реализовать fnIMLangFontLink_GetCharCodePages для полученя codePages, к которым относится данный символ. Думаю, надо проверять принадлежность символа к различным диапазонам, в соответствии с http://msdn.microsoft.com/en-us/library/ms776439(VS.85).aspx Думаю, подойдёт структура типа: typedef struct { DWORD From; DWORD To; DWORD CodePage; } CHARSET_BYTERANGES; #define MAXCHBRNDEX 2 static const CHARSET_BYTERANGES CH_BR[MAXCHBRNDEX] = { {0x0000, 0x007F, 0}, /* Basic Latin */ {0x0080, 0x00FF, 1} /* Latin-1 Supplement */ }; Для начала надо заполнить только для основных используемых кодовых страниц (русский + английский язык) не всё так просто, как казалось изначально. надо возвращать codePage из таблицы http://msdn.microsoft.com/en-us/library/ms776441(VS.85).aspx Такого понятия, как диапазона символов, как я понял, там в принципе не существует. Ведь есть такие символы, как пробел, содержащиеся почти во всех кодировках. ерунда какая-то: Передаём функции IMLangFontLink_GetCharCodePages посимвольно строку: static const WCHAR str[] = {'D','.',' ','Р','д',0}; При искользовании виндовой mlang.dll получаем: [0] returned 2032127 (1f01ff) [1] returned 2032127 (1f01ff) [2] returned 2032127 (1f01ff) [3] returned 0 (0) [4] returned 0 (0) При тестировании на win2k3 тест выдаёт тоже самое! Странно, почему для русских символов возвращается ноль (In reply to comment #4) > ерунда какая-то: > Передаём функции IMLangFontLink_GetCharCodePages > посимвольно строку: > static const WCHAR str[] = {'D','.',' ','Р','д',0}; > > При искользовании виндовой mlang.dll получаем: > [0] returned 2032127 (1f01ff) > [1] returned 2032127 (1f01ff) > [2] returned 2032127 (1f01ff) > [3] returned 0 (0) > [4] returned 0 (0) > > При тестировании на win2k3 тест выдаёт тоже > самое! > > Странно, почему для русских символов > возвращается ноль > Это может зависить от установленного LocaleID >
> Это может зависить от установленного LocaleID
>
Я с этим сталкиваюсь первый раз. И как его изменить?
В качестве параметра LCID не передаётся.
Пробовал WINEDLLOVERRIDES="mlang=n" LANG=ru_RU.UTF-8 ww mlang_test.exe.so - ничего не изменилось.
Искал в коде wine: есть только GetLocaleID. Set нет.
Для двухбайтных юникодных символов, таких как U+9D5D, функция fnIMLangFontLink_GetCharCodePages выдаёт не нулевое значение. А для однобайтных символов всегда выдаёт 0. Если временно не обращать внимания на проблему с возвращаемым нулём, то можно реализовать GetCharCodePages следующим образом: на странице http://www.microsoft.com/globaldev/reference/WinCP.mspx есть список кодировок, и символов, принадлежащей к кадой. Для каздой кодовой страницы создаём функцию (например IMLangFontLink_Is1251), которая пробегается по своей таблице, и ищет требуемый символ. функция fnIMLangFontLink_GetCharCodePages должна вызывать каждую такую функцию, и в случае, если символ найден, выставлять в dwCodePages соответствующий бит. >
> А для однобайтных символов всегда выдаёт 0.
>
Всегда, кроме случая, когда символ латинского алфавита
Ты просто неправильно задаёшь строку WCHAR. Для WCHAR не бывает никаких однобайтных символов. Поэтому если ты хочешь задать русскую букву в WCHAR, не надо писать 'р', пиши её код в юникоде. Наконец-то разобрался. В Си юникодные символы указываются как 0x0427. А так неправильно: '\0427','\u0427','U'+0x0427 При этом возвращается: [5] returned 917508 (e0004) b'00000000000011100000000000000100' (In reply to comment #6) > > > > Это может зависить от установленного LocaleID > > > > Я с этим сталкиваюсь первый раз. И как его > изменить? > В качестве параметра LCID не передаётся. > > Пробовал WINEDLLOVERRIDES="mlang=n" LANG=ru_RU.UTF-8 ww > mlang_test.exe.so - ничего не изменилось. > > Искал в коде wine: есть только GetLocaleID. Set нет. > Если это ещё актуально, то : BOOL WINAPI SetLocaleInfoW( LCID lcid, LCTYPE lctype, LPCWSTR data ) (In reply to comment #12) > Если это ещё актуально, то : > BOOL WINAPI SetLocaleInfoW( LCID lcid, LCTYPE lctype, LPCWSTR data ) > Или, допустим : BOOL WINAPI SetThreadLocale(LCID); (In reply to comment #12) > > Если это ещё актуально, то : > BOOL WINAPI SetLocaleInfoW( LCID lcid, LCTYPE lctype, LPCWSTR data ) > Спасибо. В будущем пригодится IMLangFontLink_GetStrCodePages реализована! Проверил ArchitectureTimeline.exe - почти ничего не изменилось Думаю надо ещё рано коммитить в school. Сначала необходимо написать несколько тестов, и убедится, что всё правильно работает Полностью переписал IMLangFontLink_GetCharCodePages. Сделал для неё тесты - проходят Сделал тесты для IMLangFontLink_GetStrCodePages - некоторые не проходят. Необходимо ещё немного подправить, и всё будет почти идеально работать. В текущей сборке патч приложен. Переписал патч и тест. Отправил в wine Патч пока не принимают. Нельзя напрямую использовать внутренние структуры даных. Требуется переписать с использованием функций EnumSystemCodePages/GetCPInfo/MultiByteToWideChar Переписал с использованием MultiByteToWideChar (используется для определения того принадлежит ли данный символ выбранной кодовой странице) По-правильному для перечисления кодовых страниц нужно использовать EnumSystemCodePages, но данная функция подразумевает наличие callback функции, которую она каждый раз вызывает чтобы вернуть НАЗВАНИЕ (строка) очередной кодовой страницы. Но как в функции GetCharCodePages получить данные, которые были переданы в callback - функцию? Единственный способ - глобальные переменные. Но это не совсем хорошо. Ничего не остаётся, как всё-таки использовать в этом месте внутреннюю функцию wine_cp_enum_table. Переписал. Протестировал. Получается: 1111110000000111111111 Должно быть: 0111110000000111111111 Ставится 1 лишний бит, относящийся к кодировке 1361 Korean (Johab) Надо ещё проверить на чистом wine, я помню, у нас были какие-то изменения в кодировок. Можно просто игнорировать данную кодировку, но на каком основании это можно сделать - я не знаю. Если всё же её игнорировать, то все тесты успешно проходятся Хотелось бы увидеть исправление в виде принятого в wine патча. Поэтому открываю повторно. Проверил на чистом wine - бит ставится. Очевидно, что кодировка 1361 не должна проверятся, но как это объяснить? Сделал патч с указанными исправлениями. Отправил. Переписал патч с учётом: 1) использование локальной структуры mlang_data вместо вызова внутренней функции wine_cp_enum_table. 2) использование макроса вместо вызова "iface->lpVtbl->...." В итоге реализация функции получилась намного правильнее, исчез пропуск кодировки 1361. Патч на MLangFontLink_GetCharCodePages приняли. Требуется переделать патч и тест на MLangFontLink_GetStrCodePages Переписал тесты. Добавил тесты на неправильные аргументы. При текущей реализации проваливаются 3 теста. Исправил реализацию. Все тесты проходят. В текущей версии eterhack реализация присутствует. |