Извеждане на текст и шрифтове
В тази глава ще разгледаме основите на работата с шрифтове. Windows има почти неограничени възможности за контролиране на извеждането на текст. Някои от функциите вече са загубили предишното си значение (или това, което е било замислено, се е оказало почти невъзможно за изпълнение), докато други са много широко използвани. Разбира се, тук няма да можем да разгледаме повечето от функциите. Но вместо това ще разгледаме използването на специфични шрифтове за показване на текст в контекст на устройство, предвид текущата практика за използване на шрифтове в Windows днес.
Малко въведение
Всеки шрифт, с който работим в Windows, се характеризира с няколко параметъра. Шрифт (шрифт) е колекция от няколко стила на шрифта, обединени от стил и други характеристики. Примерни шрифтове: Arial, Times New Roman, MS Sans Serif. Размерът на шрифта е височината на правоъгълника, в който са разположени всички знаци на шрифта, изразена в специални единици - точки. Една точка е 1/72 от инча. Тази единица идва от печатарската индустрия. Теглото е специфичната характеристика на шрифта. В Windows са налични четири стила: нормален (нормален), курсив (курсив), получер (удебелен) и удебелен курсив (удебелен курсив). В допълнение, шрифтовете могат да бъдат с едно пространство (с фиксирана стъпка), пример е Courier New, и пропорционални (с променлива стъпка), пример е Times New Roman.
Сега Windows използва основно две групи шрифтове: растерни (примери - MS Sans Serif, Fixedsys) и контурни TrueType (примери - Arial, Courier New). Първите са строго дефинирани растерни изображения за всеки знак и са предназначени да показват не много голям текст на екрана. Последните са много сложни обекти. Те съдържат характерни очертания, коитоса боядисани по определени правила. Всеки TrueType шрифт е програма на специален език, която се изпълнява от интерпретатор, наречен растеризатор. Програмата за шрифтове напълно дефинира как конкретни растерни изображения на знаци се изчисляват въз основа на очертания. При използване на малки символи (до около 30 точки височина) моделът на контура става неправилен и символите са силно изкривени. За да се борят с това, висококачествените шрифтове използват маркиране (подсказки). Маркирането на шрифтове е изключително сложен и отнемащ време процес, така че на пазара има малко добре маркирани шрифтове. Поради това е нежелателно да се използват шрифтове TrueType за показване на текст на екрана, с изключение на стандартните шрифтове на Windows (Times New Roman, Arial и Courier New), които са маркирани много добре.
Координати при показване на текст
Функцията CDC::TextOut() отговаря за извеждането на текст към прозорец в MFC. Тя трябва да посочи координатите за изхода на низа. Тези координати са логически координати, което означава, че се измерват в логически единици. Това важи и за други функции за извеждане на прозорец. В процеса на показване на информация логическите координати се преобразуват в пиксели. По подразбиране логическите координати са пиксели, което е много удобно за нас.
Задайте цветове на текст и фон
Когато текстът се извежда с помощта на функцията TextOut(), текстът по подразбиране е черен на текущия (обикновено бял) фон. Можете обаче да промените тези настройки, като използвате следните функции:
Функциите връщат стойността на предишния цвят. Типът COLORREF е 32-битово цяло число без знак, представляващо цвят като червени, зелени и сини компоненти, всеки с размер 8 бита. Има RGB() макрос за генериране на тази стойност.
Настройка на режима на фонов дисплей
С помощта на функцията SetBkMode() можете да зададете режима на фонов дисплей. Прототипът на функцията е:
Функцията определя какво се случва с текущия цвят на фона (както и с някои други елементи), когато се показва текст. Режимът може да приеме една от двете стойности: OPAQUE и TRANSPARENT. В първия случай, когато се показва текстът, ще се показва и текущият фон. Във втория случай фонът няма да се показва (ще бъде "прозрачен"). Режимът по подразбиране е OPAQUE.
Получаване на текстови показатели
Повечето текстови шрифтове са пропорционални, което означава, че имат различна ширина на знаците. Освен това разстоянието между редовете зависи както от шрифта, така и от неговия размер. Цялото извеждане на текст в Windows се извършва програмно, така че всички тези опции трябва да бъдат взети под внимание.
Например, когато се показват един текстов ред след друг, се приема, че височината на шрифта и броят на пикселите между редовете са известни. Можете да получите тази информация, като използвате функцията:
Параметърът е указател към структура TEXTMETRIC, в която ще бъдат записани текущите настройки на шрифта на контекста на устройството. Структурата има много полета. Най-важните полета са следните:
За да получите броя на вертикалните логически единици между редовете, добавете стойностите tmHeight и tmExternalLeading. Не е същото като височината на героя.
Смяна на шрифтове
Да предположим, че имаме готов инициализиран екземпляр на класа CFont, съдържащ някакъв шрифт (ще разгледаме как да направим това малко по-късно). За промяна на шрифта в контекста на устройството се използва член-функцията SelectObject(), която в нашия случай приема един параметър - указател към шрифтовия обект. След изпълнение на тази функция текстът ще се покаже като новшрифт. Въпреки че функцията връща указател към стария шрифтов обект, не е необходимо да го запазвате.
Инициализация на шрифтов обект: избор на шрифт
След като бъде създаден обектът от класа CFont, е необходимо той да се инициализира с определен шрифт от инсталираните в системата, с посочените параметри. Може да бъде растерен или контурен шрифт.
Вероятно с право очаквате функция, която ви позволява да зададете само вида, стила и размера на шрифта, след което шрифтът ще бъде инициализиран. За съжаление нито MFC, нито Windows имат такава функция. Единствената функция, подходяща за тази задача, има прототип като този:
Функцията е изключително неудобна и значението на много от нейните параметри не е от значение днес. Функцията беше създадена отдавна и тогава идеята за заместване и замяна на шрифтове изглеждаше очарователна, чиято същност беше следната: програмистът задава параметрите на шрифта, които иска да има, а самият Windows, въз основа на шрифтовете, налични в системата, ще направи необходимите трансформации и ще синтезира необходимия шрифт от наличните. Впоследствие се оказа, че тази технология не може да бъде задоволително работеща (тъй като на практика това е трудна задача от областта на изкуствения интелект). Също така функцията ви позволява да извършвате трансформации на шрифта - да го разтягате и компресирате, да показвате текст под ъгъл. Сега се използва рядко. Графичните пакети използват свои собствени алгоритми за трансформация и често използват PostScript шрифтове.
Долната линия е, че само онези шрифтове и стилове, които присъстват в системата, могат да бъдат показани качествено и без трансформации (т.е. с помощта на съвети, които са деактивирани по време на трансформации). За повечето съвременни програминеобходимо е висококачествено показване на текст, така че никакви трансформации и замествания не са неподходящи. На практика само две поведения са разумни: или програмата ще използва точно шрифта, който е поискала, във формата, в която е създадена от разработчика, или ще откаже да работи при липса на шрифт.
Като се има предвид горното, няма да разглеждаме подробно параметрите на функцията CreateFont(). Вместо това ще разгледаме пример за код, който ви позволява да зададете размера на шрифта, стила и вида на шрифта, минимизирайки възможните трансформации и синтез на шрифтове при липса на даден такъв. Можете да използвате същите параметри за функцията CreateFont() във вашите програми. Също така е препоръчително да проверите за наличието на шрифт, ако не е стандартен. Ето кода, използван в примерната програма (указателят към обекта на шрифта се съхранява в променливата m_pFont):
Примерна програма
В този пример ще поставим декларации и описания на обекти за приложението и главния прозорец в отделни файлове. Почти винаги така се проектират C++ приложенията. Така ще имаме четири изходни файла.