Надо реализовать функцию в mlang: fixme:mlang:fnIMLangFontLink_GetStrCodePages (pszSrc=L"до нашей эры", cchSrc=12, dwPriorityCodePages=0) stub Это при запуске программы из состава КМ-Школы [test@euclid Client]$ wine ArchitectureTimeline.exe
для начала требуется реализовать 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 реализация присутствует.