| 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 решает проблему |