Страница 1 из 2
Два вопроса по шрифтам
Добавлено: 13 Май 2010, 20:41
muskin
Clarion 6(ABC)
Заранее благодарен за ответ.
У меня два вопроса по шрифтам.
1. На основе Arial cоздал свой шрифт под собственные нужды (заменил неиспользованные символы на всякие спецсимволы).
Все хорошо работает, если по науке добавляю свой шрифт в Винду через панель управления.
Но если из своей программы копирую файл шрифта в папку %RootSystem%/Fonts и добавляю сведения о нем в реестр ([HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts]
"MPC Обычный (TrueType)"="MRC_.ttf") - никакого эффекта. Что Винде еще нужно добавить?, где она еще прописывает или регистрирует фонты?
2.Использую свой шрифт в отчетах без предварительного просмотра. А как бы узнать реальную ширину на бумаге выводимой True Type-ской строки? - я сделал так: снял метрику (Studio 5 от FontLab) со своего фонта размера 10 (каждый символ с 32 до 254 имеет свою условную ширину), создал массив условных ширин символов и с поправкой на размер шрифта и с учетом реальной ширины при печати (100 символов подчеркивания + линейка/100) сформировал массив реальных ширин символов. Этот массив реальных ширин использую в форме при наборе строки.
Процент попадания - примерно 95%.
Вопрос - я делаю через задницу или можно как-то красивее?
Re: Два вопроса по шрифтам
Добавлено: 14 Май 2010, 2:19
StillZero
по части вопроса №2...
я измеряю текст, юзая WinAPI, примерно так, код правлен, см. суть
Код: Выделить всё
loc:hDC ULONG
mem:hDC ULONG
loc:cstrTmp &CSTRING
loc:hFont ULONG
loc:hPrevFont ULONG
loc:strRect LIKE(CFC_RECT)
loc:strSize GROUP(CFC_SIZESTRUCT).
CODE
! CurrItem.Text - исходный текст
loc:cstrTmp &= NEW CSTRING(LEN(CLIP(CurrItem.Text)) + 1)
loc:cstrTmp = CLIP(CurrItem.Text)
! hWnd - окно куда может быть выведен текст
loc:hDC = CFC_GetDC(hWnd)
mem:hDC = CFC_CreateCompatibleDC(loc:hDC)
IF mem:hDC
loc:hFont = CurrItem.Menu.Comctrl.RetrieveSystemMenuFont() ! получения хэндла шрифта, который надо измерять
loc:hPrevFont = CFC_SelectObject(mem:hDC,loc:hFont)
CFC_SetTextCharacterExtra(mem:hDC,0)
IF CFC_DrawText(mem:hDC,ADDRESS(loc:cstrTmp),LEN(loc:cstrTmp),ADDRESS(loc:strRect),CFC_DT_SINGLELINE + CFC_DT_VCENTER + CFC_DT_EXPANDTABS + CFC_DT_CALCRECT)
loc:strSize.cx = ABS(loc:strRect.right - loc:strRect.left)
loc:strSize.cy = ABS(loc:strRect.bottom - loc:strRect.top)
ELSE
CFC_GetTextExtentPoint32(mem:hDC,ADDRESS(loc:cstrTmp),LEN(CLIP(loc:cstrTmp)),ADDRESS(loc:strSize))
END
Err# = CFC_SelectObject(mem:hDC,loc:hPrevFont)
Err# = CFC_DeleteObject(loc:hFont)
Err# = CFC_DeleteDC(mem:hDC)
END
CFC_ReleaseDC(hWnd,loc:hDC)
DISPOSE(loc:cstrTmp)
Re: Два вопроса по шрифтам
Добавлено: 14 Май 2010, 10:35
Admin
muskin писал(а):
Но если из своей программы копирую файл шрифта в папку %RootSystem%/Fonts и добавляю сведения о нем в реестр ([HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts]
"MPC Обычный (TrueType)"="MRC_.ttf") - никакого эффекта. Что Винде еще нужно добавить?, где она еще прописывает или регистрирует фонты?
Зачем все эти телодвижения если есть Windows API функция
AddFontResource - грузит файл со шрифтом с любого места.
Re: Два вопроса по шрифтам
Добавлено: 14 Май 2010, 11:17
seawolf
По первому вопросу помимо API можно просто ставить шрифт во время setup (все инсталлеры имеют такие функции).
По второму вопросу - видимо можно посоветовать использовать равноширинный шрифт (он один кажись Куриер) в остальных вариантах ширина выводимых строка будет разной (это зависит от набора символов в строке).
Может еще кто чего добавит.
Re: Два вопроса по шрифтам
Добавлено: 14 Май 2010, 22:44
morkovin
Но если из своей программы копирую файл шрифта в папку %RootSystem%/Fonts и добавляю сведения о нем в реестр ([HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts]
"MPC Обычный (TrueType)"="MRC_.ttf") - никакого эффекта. Что Винде еще нужно добавить?, где она еще прописывает или регистрирует фонты?
Загрузка шрифтов была подробно описана в ClaMag (сейчас нет под рукой и не вспомнить) . Вот вырезка из TXA
EMBED %ProcedureSetup
[DEFINITION]
[SOURCE]
PROPERTY:BEGIN
PRIORITY 4000
PROPERTY:END
FONT_N = 'Vampire_TTF' !LOAD FIRST FONT
if instring('WINDOWS XP',upper(clip(SYSTEM{PROP:WindowsVersion})),1) ! WINDOWS XP?
DO LOAD_FNT !
END
PROPERTY:END
!!! и сама процедура
LOAD_FNT ROUTINE
RES_HANDLE = FINDRESOURCE(SYSTEM{PROP:APPINSTANCE},ADDRESS(FONT_N),ADDRESS(RES_TYPE))
HGLOBALMEM = LOADRESOURCE(SYSTEM{PROP:APPINSTANCE},RES_HANDLE)
FONT_SIZE = SIZEOFRESOURCE(SYSTEM{PROP:APPINSTANCE},RES_HANDLE)
FONT_HANDLE = AddFontMemResourceExHGLOBALMEM,FONT_SIZE,0,ADDRESSFONT_COUNT))
FONT_COUNT += 1
Вобщем все сделано по ClaMag
Re: Два вопроса по шрифтам
Добавлено: 14 Май 2010, 23:19
muskin
Спасибо еще раз.
Анализирую подскаЗки.
AddFontResource(*LPCSTR),SIGNED,PASCAL,RAW,NAME('AddFontResourceA')
А LPCSTR в Clarion-e это CSTRING?
Вызов функции - и тут же ругательства на неправильное использование параметра функции.
А какой ей нужно подсунуть указатель и на что? (подсовывал адрес строковой переменной, содержащей путь фонта - никакого эфекта).
Re: Два вопроса по шрифтам
Добавлено: 15 Май 2010, 14:50
WadimZapara
Из описания в MSDN следует:
1) твоё объявление верное: AddFontResource(*CString FontFileName),SIGNED,PASCAL,RAW,NAME('AddFontResourceA')
2) возвращает 0 при неудаче или зарегистрированный номер шрифта
3) в параметре FontFileName должно содержаться правильное имя файла (с путём) фонта с одим из следующих расширений: .fon, .fnt, .ttf, .ttc, .fot, .otf, .mmm, или (.pfm и .pfb)
4) для последней варианта - пары файлов - строка должна быть типа 'abcxxxxx.pfm|abcxxxxx.pfb'
5) функция AddFontResource регистрирует шрифт только для текущей сессии до перезагрузки (для полной установки - требуется шрифт перечислить в реестре)
6) когда ваш шрифт вам более не нужен - необходимо его выгрузить вызовом RemoveFontResource(FontFileName)
7) ваше приложение после успешного вызова обеих этих функций должно вызывать SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0), чтобы сообщить другим окнам системы о том, что произошли изменения со шрифтами.
прототип: SendMessage(UnSigned hWnd, ULong Msg, Signed wParam, Signed lParam), Long, Pascal, Name('SendMessageA')
HWND_BROADCAST EQUATE(0FFFFh)
WM_FONTCHANGE EQUATE(01Dh)
Примечание: подозреваю, что "правильное имя файла" - означает: либо без пробелов, либо окружённое кавычками.
Re: Два вопроса по шрифтам
Добавлено: 17 Май 2010, 1:58
muskin
Это в начале:
map
module('win32.lib')
GetEnvironmentVar(*CSTRING,*CSTRING,ULONG),ULONG,PASCAL,RAW,NAME('GetEnvironmentVariableA')
AddFontResource(*LPCSTR),SIGNED,PASCAL,RAW,NAME('AddFontResourceA')
. .
Потом объявляю переменную font_path как CSTRING, а при компиляции Clarion указывает ошибку на используемый параметр.
Подскажите, что я не так делаю? - код представлен ниже
font_path='C:\Sertif\Font\MRC_.ttf'
ret#=AddFontResource(*font_path)
P.S. Был вопрос по поводу получения системной переменной из GetEnvironmentVar. Я в своей программе не указываю адресов, а просто подсовываю переменные, а не адреса - GetEnvironmentVar(имя системной переменной, имя переменной-приемника, 1024 на длину) - и все работает.
В мое случае может тоже что-то не так?
Re: Два вопроса по шрифтам
Добавлено: 17 Май 2010, 10:46
Admin
Код: Выделить всё
AddFontResource(*CSTRING FontName),RAW,LONG,PASCAL,NAME('AddFontResourceA')
...
FontFileName CSTRING(200)
...
FontFileName = '.\TTF\MONOCD.TTF'
...
IF NOT AddFontResource(FontFileName)
MESSAGE('Не смогли установить шрифт: MonoCondencedDI','Внимание',ICON:Asterisk)
END
Re: Два вопроса по шрифтам
Добавлено: 17 Май 2010, 21:05
muskin
Но не работает AddFontResource с параметром *CSTRING!!!
Указывает на параметр - неправильное использование параметра, скобок и т.д....
Реально, а не теоретически, кто-нибудь использовал эту функцию?
Re: Два вопроса по шрифтам
Добавлено: 17 Май 2010, 22:04
Дед Пахом
Ну посмотрите на декларацию типа LPCSTR, он же LONG, что же Вы суёте туда CSTRING?
Re: Два вопроса по шрифтам
Добавлено: 18 Май 2010, 0:20
Admin
muskin писал(а):Но не работает AddFontResource с параметром *CSTRING!!!
Указывает на параметр - неправильное использование параметра, скобок и т.д....
Реально, а не теоретически, кто-нибудь использовал эту функцию?
Да что вы говорите... У меня наверное Windows другой

Ниже в треде я привел пример реального кода.
В данный пост вставил пример. Все работает.
Re: Два вопроса по шрифтам
Добавлено: 18 Май 2010, 0:27
Admin
Дед Пахом писал(а):Ну посмотрите на декларацию типа LPCSTR, он же LONG, что же Вы суёте туда CSTRING?
Заблуждение... Все зависит от декларации функции.
Код: Выделить всё
AddFontResource(*CSTRING FontName),RAW,LONG,PASCAL,NAME('AddFontResourceA')
...
FontFileName CSTRING(200)
...
AddFontResource(FontFileName)
и
Код: Выделить всё
AddFontResource(LONG FontName),RAW,LONG,PASCAL,NAME('AddFontResourceA')
...
FontFileName CSTRING(200)
...
AddFontResource(ADDRESS(FontFileName))
одинаковые варианты!!!
Re: Два вопроса по шрифтам
Добавлено: 18 Май 2010, 7:38
Admin
Дед Пахом писал(а):Ну посмотрите на декларацию типа LPCSTR, он же LONG, что же Вы суёте туда CSTRING?
Предыдущий ответ больше относится к юзеру
muskin а не к тебе

Re: Два вопроса по шрифтам
Добавлено: 18 Май 2010, 22:16
muskin
Спасибо Админу за вразумление.
При описании прототипа AddFontResource(*LPSTRING),SIGNED,PASCAL,RAW,NAME('AddFontResourceA')(откуда я взял это описание - не знаю) заменил *LPString на *CString - все заработало, шрифт загружается только на время загрузки программы. Это меня полностью устраивает.
Спасибо всем.