Summary: | 1C 7.7: в кнопку не влезает слово "Сформировать" | ||
---|---|---|---|
Product: | WINE@Etersoft | Reporter: | Vitaly Lipatov <lav> |
Component: | Графика GDI / DIB / GDIPLUS | Assignee: | Anton Rudnev <mibori> |
Status: | CLOSED FIXED | QA Contact: | |
Severity: | minor | ||
Priority: | P4 | CC: | baraka, kondratyuk, lav |
Version: | 1.0.9 | ||
Target Milestone: | --- | ||
Hardware: | PC | ||
OS: | All | ||
Whiteboard: | |||
Заявки RT: | Связано с: | ||
Дата напоминания: | |||
Bug Depends on: | |||
Bug Blocks: | 1217 | ||
Attachments: |
Кнопка в wine
Кнопка в windows |
Description
Vitaly Lipatov
2008-11-07 22:29:19 MSK
В конфигурации Зарплата и Кадры в Журнале Ввод расчётов сотрудникам документ Ввод расчёта сотруднику есть кнопка "Исправит(ь)". Я думаю, нужно взять функцию, возвращающую длину строки в точках, пробежаться по всем символам и получить ширину каждой буквы. Результат сравнить с виндой :) В процессе написания теста возникла проблема - буфер, который должен получать ширину символов, не заполняется функциями Get*Width* WINGDIAPI BOOL WINAPI GetCharWidthA(HDC,UINT,UINT,LPINT); WINGDIAPI BOOL WINAPI GetCharWidthI(HDC,UINT,UINT,LPWORD,LPINT); WINGDIAPI BOOL WINAPI GetCharWidthW(HDC,UINT,UINT,LPINT); #define GetCharWidth WINELIB_NAME_AW(GetCharWidth) Интересно, что при таком объявлении в wingdi.h в dlls/gdi32/font.c отсутствуют функции GetCharWidthA и GetCharWidthW. При этом их можно вызвать из программы. (In reply to comment #3) > В процессе написания теста возникла > проблема - буфер, который должен получать > ширину символов, не заполняется функциями > Get*Width* > > WINGDIAPI BOOL WINAPI GetCharWidthA(HDC,UINT,UINT,LPINT); > WINGDIAPI BOOL WINAPI GetCharWidthI(HDC,UINT,UINT,LPWORD,LPINT); > WINGDIAPI BOOL WINAPI GetCharWidthW(HDC,UINT,UINT,LPINT); > #define GetCharWidth WINELIB_NAME_AW(GetCharWidth) > > Интересно, что при таком объявлении в wingdi.h > в dlls/gdi32/font.c отсутствуют функции GetCharWidthA и > GetCharWidthW. При этом их можно вызвать из Использовать надо GetCharWidth32. Функции отсутствуют, потому что они опеределены через gdi32.spec: @ stdcall GetCharWidthA(long long long long) GetCharWidth32A Ширина строки одинакова с виндовым и с вайновским шрифтами. Похоже, что дело в ширине создаваемой кнопки, куда не влезает слово "сформировать". Нужно проверить разницу в ширине кнопки в Windows и в WINE (нужны скриншоты). Created attachment 931 [details]
Кнопка в wine
Created attachment 932 [details]
Кнопка в windows
Кнопки одинаковой ширины, и поля для текста в них тоже одинаковые. При выводе текста где-то неправильно считается область, в которую текст выводится. До самой функции DrawTextExW всё правильно (кажется) считается. Значит, ошибка в выводе этой функцией или в одной из вложенных. Исследуем всё в пределах DrawTextExW шаг 1. При трейсе сразу бросается в глаза такая картинка: DrawTextW L"С&формировать" ExtTextOutW L"Сформироват" ExtTextOutW L"Сформироват" ret (end) DrawTextW L"" ret (8) Функция ExtTextOutW получает длину буфера в 11 символов, хотя должна в 12 (символ & не учитывается) шаг 2. Ищем как формируется количество символов, которое попадает в ExtTextOutW (переменная len_seg, которая равна len) Находим, что это количество формируется в функции TEXT_NextLineW шаг 3. Смотрим, как формируется значение количества символов в TEXT_NextLineW. Там это значение формируется в переменной num_fit, которая инициализируется вызовом функции GetTextExtentExPointW шаг 4. Откуда в GetTextExtentExPointW берется значение 11? Оно накапливается инкрементом в переменной nFit при помощи цикла i = 0..(12 - 1) Инкремент выполняется в том случае, если правая граница символа (значение dxs[i]) не превышает некоторое значение maxExt -- очевидно, правая граница последнего символа, т. е. if (dxs[i] <= maxExt) ++nFit; на последней, 12-ой итерации, dxs[11] == 76, а maxExt == 75, поэтому инкремент ++nFit не выполнялся и к функции DrawTextExW приходило значение 11. шаг 5. проверяем, что, если заменить if (dxs[i] <= maxExt) ++nFit; на if (dxs[i] <= maxExt + 1) ++nFit; то бага решается шаг 6. Ищем, где формируется значение maxExt. Изначально оно формируется в начале функции DrawTextExW в переменной: int width = rect->right - rect->left; и расценивается как ширина, которая вычисляется не верно. т. е. вычислять надо так int width = rect->right - rect->left + 1; бага решается, если сделать такие изменения. в этом и будет состоять патч. > > в этом и будет состоять патч. > патч http://lists.etersoft.ru/pipermail/wine-patches/2009-February/000290.html решает проблему |