Вывод текста

Описываемые ниже стандартные процедуры и функции поддерживают вывод текстовых сообщений в графическом режиме. Это не одно и то же, что использование процедур Write или WriteLn. Дело в том, что специально для графического режима разработаны процедуры, обеспечивающие вывод сообщений различными шрифтами в горизонтальном или вертикальном направлении, с изменением размеров и т.д. Однако в стандартных шрифтах, разработанных для этих целей фирмой Borland, отсутствует кириллица, что исключает вывод русскоязычных сообщений.

С другой стороны, процедуры Write и WriteLn после загрузки в память второй половины таблицы знакогенератора (а эта операция легко реализуется в адаптерах EGA и VGA) способны выводить сообщения с использованием национального алфавита, но не обладают мощными возможностями специальных процедур.

Ниже описываются стандартные средства модуля Graph для вывода текста.

Процедура OutText.

Выводит текстовую строку, начиная с текущего положения указателя. Заголовок:

Procedure OutText(Txt: String);

Здесь Txt - выводимая строка.

При горизонтальном направлении вывода указатель смещается в конец выведенного текста, при вертикальном - не меняет своего положения. Строка выводится в соответствии с установленным стилем и выравниванием. Если текст выходит за границы экрана, то при использовании штриховых шрифтов он отсекается, а в случае стандартного шрифта не выводится.

Процедура OutTextXY.

Выводит строку, начиная с заданного места. Заголовок: 

Procedure OutTextXY (X,Y: Integer; Txt: String);

Здесь X, Y - координаты точки вывода; Txt - выводимая строка. Отличается от процедуры OutText только координатами вывода. Указатель не меняет своего положения.

Процедура SetTextStyle.

Устанавливает стиль текстового вывода на графический экран. Заголовок:

Procedure SetTextStyle(Font,Direct,Size: Word);

Здесь Font - код (номер) шрифта; Direct - код направления; Size - код размера шрифта.

Для указания кода шрифта можно использовать следующие предварительно определенные константы:

const

DefaultFont = 0;{Точечный шрифт 8x8}

TriplexFont = 1;{Утроенный шрифт TRIP.CHR} 

SmallFont = 2;{Уменьшенный шрифт LITT.CHR}

SansSerifFont = 3;{Прямой шрифт SANS.CHR}

GothicFont = 4;{Готический шрифт GOTH.CHR}

Замечу, что эти константы определяют все шрифты для версий 4.0, 5.0, 5.5 и 6.0. В версии 7,0 набор шрифтов значительно расширен, однако для новых шрифтов не предусмотрены соответствующие мнемонические константы. В этой версии помимо перечисленных Вы можете при обращении к SetTextStyle использовать такие номера шрифтов:

Номер

Файл

Краткое описание

5

scri.chr

«Рукописный» шрифт

6

simp.chr

Одноштриховый шрифт типа Courier

7

tscr.chr

Красивый наклонный шрифт типа Times Italic

8

Icom.chr

Шрифт типа Times Roman

9

euro . chr

Шрифт типа Courier увеличенного размера

10

bold.chr

Крупный двухштриховый шрифт

Шрифт DefaultFont входит в модуль Graph и доступен в любой момент. Это -единственный матричный шрифт, т.е. его символы создаются из матриц 8x8 пикселей. Все остальные шрифты - векторные: их элементы формируются как совокупность векторов (штрихов), характеризующихся направлением и размером. Векторные шрифты отличаются более богатыми изобразительными возможностями, но главная их особенность заключается в легкости изменения размеров без существенного ухудшения качества изображения. Каждый из этих шрифтов размещается в отдельном дисковом файле. Если Вы собираетесь использовать какой-либо векторный шрифт, соответствующий файл должен находиться в Вашем каталоге, в противном случае вызов этого шрифта игнорируется и подключается стандартный.

Замечу, что шрифт DefaultFont создается графическим драйвером в момент инициации графики на основании анализа текстового шрифта. Поэтому, если Ваш ПК способен выводить кириллицу в текстовом режиме, Вы сможете с помощью этого шрифта выводить русскоязычные сообщения и в графическом режиме. В остальных шрифтах эта возможность появляется только после их модификации.

Для задания направления выдачи текста можно использовать константы:

const

HorizDir = 0;{Слева направо}

VertDir = 1;{Снизу вверх}

Как видим, стандартные процедуры OutText и OutTextXY способны выводить сообщения лишь в двух возможных направлениях - слева направо или снизу вверх. Зная структуру векторных шрифтов, нетрудно построить собственные процедуры вывода, способные выводить сообщения в любом направлении.

Каждый шрифт способен десятикратно изменять свои размеры. Размер выводимых символов кодируется параметром Size, который может иметь значение в диапазоне от 1 до 10 (точечный шрифт - в диапазоне от 1 до 32). Если значение параметра равно 0. устанавливается размер 1, если больше 10 - размер 10. Минимальный размер шрифта. при котором еще отчетливо различаются все его детали, равен 4 (для точечного шрифта - 1).

Следующая программа демонстрирует различные шрифты. Их размер выбран так. чтобы строки имели приблизительно одинаковую высоту. Перед исполнением программы скопируйте все шрифтовые файлы с расширением .CHR в текущий каталог.

Uses Graph, CRT; 

const

FontNames: array [1..10] of String[4] =

( 'TRIP' , 'LITT'' SANS ' , ' GOTH ' , 'SCRI ' , ' SIMP ' ,'TSCR ' , ' LOOM ' , ' EURO',' BOLD ' );

Tabl = 50;

Tab2 = 150;

Tab3 =220; 

var

d, r, Err,{Переменные для инициации графики}

Y,dY,{Ордината вывода и ее приращение}

Size,{Размер символов}

MaxFont,{Максимальный номер шрифта}

k: Integer;{Номер шрифта}

NT, SizeT, SynibT: String;{Строки вывода}

c: Char;

 {-------------------}

Procedure OutTextWithTab ( S1, S2, S3, S4: String); 

{Выводит строки S1..S4 с учетом позиций табуляции Таb1..ТаbЗ} 

begin

MoveTo( (Tab1-TextWidth(Sl) ) div2,Y);

OutText (S1) ;

MoveTo(Tabl+(Tab2-Tabl-TextWidth(S2)) div2,Y);

OutText (S2) ;

MoveTo(Tab2+(Tab3-Tab2-TextWidth(S3)) div 2,Y); 

OutText(S3);

if S4='Symbols' then {Заголовок колонки Symbols} 

MoveTo((Tab3+GetMaxX-TextWidth(S4)) div 2,Y)

else {Остальные строки} 

MoveTo(Tab3+3,Y); 

OutText(S4) 

end;

{------------}

begin

{Инициируем графику} 

InitGraph(d,r, ' '); 

Err := GraphResult; if ErrogrOk then

WriteLn(GraphErrorMsg(Err)) 

else 

begin

{Определяем количество шрифтов:} 

{$IFDEF VER70'}

MaxFont := 10; . 

{$ELSE}

MaxFont := 4; 

{$ENDIF}

SetTextStyle(l,0,4); 

Y := 0;

OutTextWi thTab('N','Name',Size','Symbols');

{Определяем высоту Y линии заголовка}

Y := 4*TextHeight('Z') div3;

Line(0,Y,GetMaxX,Y) ;

{Определяем начало Y таблицы и высоту dY каждой строки}

Y := 3*TextHeight('Z') div 2;

dY := (GetMaxY-Y) div (MaxFont);

{Готовим строку символов}

SymbT := '';

for с := 'a' to 'z' do

SymbT := SymbT+c; 

{Цикл вывода строк таблицы} 

for k := 1 to MaxFont do 

begin

Size := 0;

{Увеличиваем размер до тех пор, пока высота строки не станет приблизительно равна dY} 

repeat

inc(Size);

SetTextStyle(k,0,Size+1); 

until (TextHeight('Z')>=dY) or (Size=10)

or (Textwidth(FontNames[k])>(Tab2-Tab1)); 

{Готовим номер NT и размер SizeT шрифта} 

Str(k,NT);

Str(Size,SizeT);

{Выводим строку таблицы}

SetTextStyle(k,HorizDir,Size);

OutTextWithTab(NT,FontNames[k],SizeT,SymbT);

inc(Y,dY) 

end;

{Рисуем линии рамки} 

Rectangle(0,0,GetMaxX,GetMaxY); 

Line(Tab1,0,Tabl,GetMaxY); 

Line(Tab2,0,Tab2,GetMaxY); 

Line(Tab3,0,ТаЬЗ,GetMaxY); 

{Ждем инициативы пользователя} 

ReadLn; 

CloseGraph

end 

end.

Процедура SetTextJustify.

Задает выравнивание выводимого текста по отношению к текущему положению указателя или к заданным координатам. Заголовок:

Procedure SetTextJustify(Horiz,Vert: Word);

Здесь Horiz - горизонтальное выравнивание; Vert - вертикальное выравнивание. Выравнивание определяет как будет размещаться текст - левее или правее указанного места, выше, ниже или по центру. Здесь можно использовать такие константы:

const

LeftText = 0;{Указатель слева от текста}

CenterText= 1;{Симметрично слева и справа,верху и снизу}

RightText = 2;{Указатель справа от текста}

BottomText= 0;{Указатель снизу от текста} 

TopText = 2;{Указатель сверху от текста}

Обратите внимание на неудачные, с моей точки зрения, имена мнемонических констант: если, например, Вы зададите LeftText, что в переводе означает «Левый Текст», сообщение будет расположено справа от текущего положения указателя (при выводе процедурой OutTextXY - справа от заданных координат). Также «наоборот» трактуются и остальные константы.

Следующая программа иллюстрирует различные способы выравнивания относительно центра графического экрана.

Uses Graph, CRT; 

var

d, r, e : Integer; 

begin

{Инициируем графику} 

d := Detect; InitGraph(d,, r, ' ') ; 

e := GraphResult;

if e <> grOk then 

WriteLn(GraphErrorMsg(e))

else 

begin

{Выводим перекрестие линий в центре экрана}

Line(0,GetMaxY div 2,GetMaxX,GetMaxY div 2);

Line(GetMaxX div 2,0,GetMaxX div 2,GetMaxY);

{Располагаем текст справа и сверху от центра}

SetTextStyle(TriplexFont,HorizDir,3);

SetTextJustify(LeftText,BottomText);

OutTextXY (GetMaxX div 2, GetMaxY div 2, 'LeftText,BottomText');

{Располагаем текст слева и снизу}

SetTextJustify (RightText, TopText);

OutTextXY (GetMaxX div 2, GetMaxY div 2,'RightText, TopText'); 

if ReadKey=#0 then d := ord(ReadKey);

CloseGraph 

end 

end.

Процедура SetUserCharSize.

Изменяет размер выводимых символов в соответствии с заданными пропорциями. Заголовок:

Procedure SetUserCharSize(XI,X2,Yl,Y2: Word);

Здесь X1...Y2 - выражения типа Word, определяющие пропорции по горизонтали и вертикали.

Процедура применяется только по отношению к векторным шрифтам. Пропорции задают масштабный коэффициент, показывающий во сколько раз увеличится ширина и высота выводимых символов по отношению к стандартно заданным значениям. Коэффициент по горизонтали находится как отношение X1 к Х2, по вертикали - как отношение Y1 к Y2. Чтобы, например, удвоить ширину символов, необходимо задать X1=2 и Х2=1. Стандартный размер символов устанавливается процедурой SetTextStyle, которая отменяет предшествующее ей обращение к SetUserCharSize.

В следующем примере демонстрируется изменение пропорций уменьшенного шрифта.

Uses Graph, CRT; 

var

d, r, e : Integer; 

begin

{Инициируем графику}

d := Detect; .InitGraph (d, r, '');

e := GraphResult;

if e <> grOk then

WriteLn(GraphErrorMsg(e)) 

else 

begin

MoveTo (0, GetMaxY div 2); SetTextStyle (SmallFont, HorizDir, 5);

SetTextJustify (LeftText, BottomText);

{Выводим сообщение стандартной высотой 5}

OutText ('Normal Width,');

{Удваиваем ширину шрифта}

SetUserCharSize (2, 1, 1, 1);

OutText (' Double Width, ');

{Удваиваем высоту, возвращаем стандартную ширину}

SetUserCharSize (I, 1, 2, 1) ;

OutText ('Double Height,');

SetUserCharSize (2, 1, 2, 1) ;

OutText (' Double Width and Height');

if ReadKey=#0 then d := ord(ReadKey);

CloseGraph

end

end.

Функция TextWidth.

Возвращает длину в пикселях выводимой текстовой строки. Заголовок:

Function TextWidth (Txjt: String): Word;

Учитываются текущий стиль вывода и коэффициенты изменения размеров символов, заданные соответственно процедурами SetTextStyle и SetUserCharSize.

Функция TextHeight.

Возвращает высоту шрифта в пикселях. Заголовок: 

Function TextHeight(Txt: String): Word;

Процедура GetTextSettings.

Возвращает текущий стиль и выравнивание текста. Заголовок:

Procedure GetTextSettins(var Textlnfo: TextSettingsType);

Здесь Textlnfo - переменная типа TextSettingsType, который в модуле Graph определен следующим образом:

type

TextSettingsType = record

Font : Word; {Номер шрифта}

Direction: Word; {Направление}

CharSize : Word; {Код размера}

Horiz : Word; {Горизонтальное выравнивание}

Vert : Word; {Вертикальное выравнивание}

end;

Функция InstallUserFont.

Позволяет программе использовать нестандартный векторный шрифт. Заголовок функции:

Function InstallUserFont(FileName: String): Integer; 

Здесь FileName - имя файла, содержащего векторный шрифт.

Как уже говорилось, в стандартную поставку Турбо Паскаля версий 4.0 - 6.0 включены три векторных шрифта, для версии 7.0 - 10. Функция InstallUserFont позволяет расширить этот набор. Функция возвращает идентификационный номер нестандартного шрифта, который может использоваться при обращении к процедуре SetTextStyle.

Функция InstallUserDriver.

Включает нестандартный графический драйвер в систему BGI-драйверов. Заголовок функции:

Function InstallUserDriver(FileName: String; AutoDetectPtr: Pointer): Integer;

Здесь FileName - имя файла, содержащего программу драйвера; AutoDetectPtr - адрес точки входа в специальную процедуру автоопределения типа дисплея, которая в числе прочих процедур должна входить в состав драйвера.

Эта функция расширяет и без того достаточно обширный набор стандартных графических драйверов и предназначена в основном для разработчиков аппаратных средств.