• Добро пожаловать на WYLEK.ru. Пожалуйста, войдите или зарегистрируйтесь.
 
38 гостей, 0 пользователей

  • Логический шрифт 5 0 5 1

Логический шрифт

Автор Leserg, 12 мая 2015, 11:24:00

« предыдущая - следующая »

LesergАвтор темы

Тема создана 12 мая 2015, 11:24:00 Последнее редактирование: 26 апреля 2018, 16:02:09 от WYLEK
Логический шрифт
Исправляем некорректное отображение кириллицы

Итак, вы сделали перевод любимой программы на русский язык, создали локализованный файл, запустили приложение и, вдруг, вместо знакомых символов видите какую-то несуразицу, типа ""Id`e^aa`o, `i^u ^ed`a^e^ic"y`a"e`e^e`e!". Блин, что делать?Самое простое решение -- выполнить замену кодовых страниц в операционной системе и добавить в реестр параметры подмены шрифтов. К сожалению, такое решение является грубым и будет работать только на вашей системе. Другие пользователи, воспользовавшись вашей работой, вместо текста на русском увидят эту несуразицу и им также придется вносить изменения в свою систему. Это в свою очередь может быть чревато негативными последствиями для других приложений. Впрочем я не буду останавливаться на этом подробно, а предлагаю вам решить проблему отображения символов кириллицы более изящно -- в самом файле приложения. Конечно для этого нужны умение работы с отладчиком, знание API-функций и понимание ассемблерных инструкций. Решение не из простых и потребует от вас определенных навыков. Надеюсь, что это небольшое руководство поможет вам самостоятельно справиться с этой проблемой.

Надеюсь, что это небольшое руководство поможет вам самостоятельно справиться с этой проблемой.

В данном руководстве рассматриваются API-функции CreateFont и CreateFontIndirect, которые используются для создания логического шрифта. Этот шрифт впоследствии также может использоваться приложением для вывода текстовой и другой информации.



Читаем здесь
Кто ищет, тот всегда найдет!

LesergАвтор темы

Ответ #1 : 28 мая 2015, 22:28:00 #1 Последнее редактирование: 29 июля 2018, 18:18:09 от WYLEK
Цитата: Nexusвот как раз по CreateFontIndirect есть интересный экземпляр... Попробуй, получится ли у тебя догадаться в чем загвоздка...


Кто ищет, тот всегда найдет!

Nexus

Ответ #2 : 29 мая 2015, 00:10:00 #2
Leserg, значит все таки обратил внимание какую подлянку делает команда REP STOS DWORD PTR [EDI]

LesergАвтор темы

Ответ #3 : 30 мая 2015, 00:26:00 #3
Цитата: Nexusвсе таки обратил внимание какую подлянку делает команда REP STOS DWORD PTR [EDI]
Почему подлянку?! Как раз наоборот, подготавливает область памяти под массив с характеристиками шрифта. Все логично. Многие свойства шрифта по умолчанию имеют значения 0 (ноль), поэтому нет смысла их задавать по отдельности. Правда в своей практике я с таким случаем сталкиваюсь впервые. Однозначно в копилку знаний.
Кто ищет, тот всегда найдет!

Nexus

Ответ #4 : 30 мая 2015, 23:08:00 #4
Цитата: LesergПочему подлянку?! Как раз наоборот, подготавливает область памяти под массив с характеристиками шрифта. Все логично.
Потому что из-за этой команды приходится переносить фрагмент кода в конец файла, некуда здесь втиснуть команду MOV DWORD PTR [ESP+93], 1. Это хорошо что здесь в конце секции кода имеется резерв куда можно примостить свой кусочек кода, в этом файле нужно подправить аж пять таких проблемных мест. А не редко мне попадались файлы, где такой резерв в конце попросту отсутствовал. Приходилось или удлинять секцию кода, или же впихивать свои наработки в промежутки между функциямипроцедурами, там где встречается последовательность байт CCCCCCCC... или 9090909090...
И вообще, я лично вместо MOV DWORD PTR [ESP+93], 1 вбил MOV DWORD PTR [ESP+90],CC000000, вдруг у конечного пользователя будет не русская локаль, и тогда будут крякозябли. А так надежнее, все для пользователя, его родимого

LesergАвтор темы

Ответ #5 : 31 мая 2015, 11:26:00 #5 Последнее редактирование: 29 июля 2018, 18:19:02 от WYLEK
Nexus, подожди, не кипятись. Обрати внимание, я вместо инструкции MOV DWORD PTR [ESP+93],1, использую инструкцию MOV BYTE PTR [ESP+93],1. Она на три байта короче предыдущей за счет указания другого типа данных. Тип DWORD нуждается в 4-х байтах, а BYTE - всего лишь в одном байте. С таким же успехом можно задать набор символов RUSSIAN_CHARSET, записав вместо 1h значение CCh: MOV BYTE PTR [ESP+93],0СС. Нет нужды использовать тип данных "двойное слово", если нужно изменить всего лишь один байт. Экономия в три байта это вполне существенно, особенно при не хватке или отсутствии достаточно свободного места. Мне тоже попадались программы, где свободного места в конце секции кода не было вообще, и, конечно, приходилось выкручиваться описанными тобой способами.

В данном конкретном случае можно обойтись без переноса кода. Нужно всего лишь немного подумать. Смотрим код:



По адресу 00404026 находится инструкция MOV DWORD PTR [ESP+7С],0Е. Её можно изменить на MOV BYTE PTR [ESP+7С],0Е, т.к. ранее область памяти под характеристики шрифта была очищена (заполнена нулями). Таким образом получим выигрыш в три байта. Далее, по адресам 00404010 - 00404020 идет побайтовая запись строки с названием шрифта. Это все можно заменить двумя инструкциями. В итоге код программы примет следующий вид:



Как видишь, по адресу 00404038 у нас еще один байт лишний остался. Но полученный код делает все тоже самое, что и оригинальный, но кроме него добавлена еще одна инструкция по установке набора символов (по адресу 00404030). Если нужна кириллица, то замени в ней значение 1h на CCh. Еще раз посмотри: мы ничего и никуда не переносили, только переделали участок кода.
Кто ищет, тот всегда найдет!

Nexus

Ответ #6 : 01 июня 2015, 00:07:00 #6
Leserg, ты допустил ошибку что похерил цикл побайтовой записи строки с названием шрифта Arial. Теперь программа не воспринимает название шрифта и выдает на экран тот, который стоит по умолчанию в системе пользователя. Попробуй после своей модификации поменять название шрифта Arial на Arial Black. В результате ничего не поменяется. А в оригинальном файле текст в окне About будет написан жирным шрифтом. В чем же причина? Причина в том, что на стек нужно запсывать собственно название шрифта, а после твоей правки на стек записывается адрес, где лежит название шрифта. В результате API функция CreateFont считывает какую-то белиберду вместо названия шрифта, ищет его в системе, естественно не находит и выставляет систеный шрифт по умолчанию, смотря у кого какой установлен.
Единственное место где можно подоптимизировать - это поменять MOV DWORD PTR [ESP+8C], 320 на MOV WORD PTR [ESP+8C], 320. Выигрыш будет еще в один байт. Дело в том, что DWORD - это 4 байта, а число 320 - это два байта, поэтому поставим WORD,т.е. двухбайтовое выражение. Только толку от такой оптимизации все равно никакой...
Цитата: gazon01Leserg, Nexus,  это уже высшая математика, нам простым смертным да такого очень далеко
Фигней страдаем

LesergАвтор темы

Ответ #7 : 02 июня 2015, 00:43:00 #7 Последнее редактирование: 29 июля 2018, 18:20:20 от WYLEK
Цитата: Nexus;16429Фигней страдаем

Ага, и не говори. Он даже gazon01"у стало интересно, чем это мы тут занимаемся. Там гляди народ потянется и больше не будет проблемы под названием "кракозябры". Надо почаще такие диспуты устраивать.  

Цитата: dinis124А программой Topo v1.2 можно решать такие проблемы?
Я не знаю, никогда такой программой не пользовался. Вообще весь мой опыт по удлинению секций сводился к дописыванию нулевых байтиков в конце файла при помощи НЕХ-редактора.
Кто ищет, тот всегда найдет!

Горыныч

Ответ #8 : 18 января 2016, 19:30:00 #8
Цитата: KopejkinПозвольте с вами не согласиться! Читают! Другое дело -  откликов нет/мало. Причина, как мне кажется, в серьезности материала, требующего осмысления, попыток практического применения, изучения дополнительных материалов и т.п.
Например, для меня  - это пока не очень понятно и довольно-таки сложно. И не потому, что плохо написано. Как раз, наоборот - это мне не хватает знаний!
Ваш материал уникален и он будет востребован. Поэтому, не поддавайтесь сомнениям и продолжайте.
Спасибо!
Присоединяюсь полностью, долго не мог разобраться с кодировкой..., по инструкции - на раз..
Ребята... ваша работа реально нужна    СПАСИБО !!

 аталог@MAIL.RU - каталог ресурсов интернет Яндекс.Метрика