Справочник программиста на персональном компьютере фирмы IBM. Принтер - Пропорциональная печать
ОГЛАВЛЕНИЕ
6.3.3 Пропорциональная печать.
Вообще говоря, пропорциональная печать требует специального
принтера, который хранит в ПЗУ информацию о ширине каждого симво-
ла. Цветной принтер IBM имеет режим пропорциональной печати,
который включается последовательностью 27,78,1, а выключается -
27,78,0. Программа, которая форматирует вывод на такой принтер,
должна знать информацию о ширине каждого символа (ее можно найти
в документации). Имея эту информацию, она может вычислить сколько
слов поместится на одной строке.
Имейте ввиду, что некоторые матричные принтеры автоматически
выводят пропорциональный текст в режиме за два прохода. Если
слова в строке разделяются добавочными пробелами в графическом
режиме, то принтер может переходить ко второму проходу после
печати каждого слова, вместо того, чтобы повторить сразу всю
строку. Поскольку принтеры относительно медленно меняют направле-
ние перемещения печатающей головки, то в этом случае печать текс-
та, выравненного по правому краю, в пропорциональном режиме может
занимать очень много времени и оказывается непосильной ношей для
принтера. Эта проблема не возникает при однонаправленной пропор-
циональной печати. Отметим, что цветной принтер IBM может автома-
тически комбинировать пропорциональную печать с автоматическим
выравниванием правого края, что делает специальное программирова-
ние ненужным.
Изощренные программисты могут заставить любой графический
принтер печатать в пропорциональном режиме. Программа должна
иметь в памяти картину битов для каждого символа (см. [6.3.4]).
Вместо того, чтобы посылать на принтер код ASCII, который вызы-
вает изображение символа из ПЗУ, используется данная цепочка
битов для создания графического изображения строки текста. Затем
вся нужная строка данных выводится на принтер в графическом режи-
ме. Этот подход расходует много памяти на хранение графических
образов символов, однако он позволяет полностью контролировать
выводимое изображение.
Высокий уровень.
В данном примере включается режим пропорциональной печати, а
затем выводится первая строка выходных данных программы. Ширина
пропорционального шрифта считывается в массив FONTWIDTH из после-
довательного файла.
100 '''считываем массив ширин шрифта
110 DIM FONTWIDTH(127) 'отводим массив для ширин
120 OPEN "FONTS" FOR INPUT AS #1 'открываем файл ширин
130 FOR N = 32 TO 127 'хранятся ширины для кодов 32-127
140 INPUT #1, FONTWIDTH(N) 'читаем ширину из массива
150 NEXT 'следующий элемент
160 '''вычисляем сколько символов поместится в строке
170 CHARPTR = 0 'указатель в буфере
180 LINE$ = "" 'хранит строку для вывода
190 LINELENGTH = 0 'счетчик длины в точках
200 WHILE LINELENGTH <480 'добавляем до заполнения строки
210 C$ = PEEK(BUFFERPTR+CHARPTR) 'берем символ из буфера данных
220 LINELENGTH = LINELENGTH + FONTWIDTH(ASC(C$))
230 LINE$ = LINE$+C$ 'добавляем к строке вывода
240 CHARPTR = CHARPTR+1 'увеличиваем указатель
250 WEND 'на обработку следующего символа
260 '''по концу строки возвращаемся к концу последнего слова
270 IF C$ = "" THEN 310 'если последний пробел, то уход
280 FOR N = LEN(LINE$) TO 1 STEP -1 'идем назад от конца
290 IF MID$(LINE$,N,1) = " " THEN 310 'этот символ пробел?
300 NEXT 'есчли нет, то берем следующий
310 LINELENGTH = N - 1 'если да, то предыдущий - последний
320 '''инициализируем пропорциональную печать и посылаем данные
330 LPRINT CHR$(27);CHR$(78);CHR$(1); 'управляющие коды
340 FOR N = 1 TO LINELENGTH 'для каждого символа
350 LPRINT PEEK(BUFFERPTR+N-1); 'печатаем его
360 NEXT 'и идем на следующий символ
Низкий уровень.
Программа на языке ассемблера должна работать совершенно ана-
логично приведенному бейсиковскому примеру. Одно из преимуществ
ассемблера состоит в том, что для просмотра ширин символов можно
использовать инструкцию XLAT. Поместите символ в AL, DS:DX должны
указывать на таблицу, после чего можно использовать XLAT. Ширина
символа будет возвращена в AL:
;---просмотр ширин символов
LEA SI,DATA_BUFFER ;указываем на буфер данных
LEA BX,WIDTH_TABLE ;указываем на таблицу ширин
MOV AL,[SI] ;получаем байт данных
XLAT WIDTH_TABLE ;теперь его ширина в AL