Справочник программиста на персональном компьютере фирмы IBM. Принтер
Страница 19. Печать специальных символов


     6.3.4 Печать специальных символов.


   Большинство принтеров не поддерживают расширенный набор симво-
лов IBM, однако большинство  программ использует специальные сим-
волы псевдографики.  Очень полезно иметь возможность печатать эти
символы и не так сложно это сделать  на любом матричном принтере,
который  имеет графические возможности.  Вместо того, чтобы пола-
гаться на ПЗУ принтера, программа  должна сама создавать эти сим-
волы  и она должна обращаться с принтером  определенным  образом,
чтобы они были напечатаны на бумаге.
   Сама по себе печать  специальных  символов тривиальна.  Просто
разбейте символ на шесть байтов, цепочка битов каждого соответст-
вует структуре точек в каждом из шести столбцов точек, составляю-
щих  символ.   Например, чтобы напечатать  символ  горизонтальной
двойной черты, код ASCII  которого  205, программа должна вывести
цепочку битов 00100100 шесть раз в режиме 480 точек в строке. Это
количество в  точности  соответствует  ширине  символа, поскольку
6/480  равно 1/80 строки.  Чтобы перевести принтер именно в  этот
графический режим необходимо подать управляющий код 27,75.  Затем
пошлите число идущих вслед графических данных, которое передается
в виде пары байт, причем младший байт  первый. Наконец, идут сами
6  битов  данных, которые в данном случае  равны  сумме  значений
битов 2 и 5 (4 + 32 = 36). Вся  последовательность целиком выгля-
дит так: 27, 75, 6, 0, 36, 36, 36, 36, 36, 36. Для более высокого
разрешения могут быть использованы более точные графические режи-
мы;  вообще говоря добавочные расходы времени машины ничтожны, по
сравнению со скоростью операций принтера.
   Имеется  частная проблема, когда символы псевдографики  должны
соприкасаться друг с другом по вертикали.   Обычно принтеры печа-
тают строку, состоящую из столбца восьми точек, затем  спускаются
вниз на высоту 12  точек,  оставляя  тем  самым поле размером в 4
точки между строками символов. Символы псевдографики должны печа-
таться и в этом поле, а в некоторых случаях они занимают в высоту
12 точек. Поскольку большинство печатающих головок имеет только 8
иголок, то единственным  решением  проблемы является печать таких
символов  за  два прохода, продвигая бумагу вперед  перед  вторым
проходом. В этом случае символ  перевода строки (ASCII 10) вообще
не используется.  Вместо этого, принтер попеременно делает интер-

валы высотой то в 8, то в 4 точки.  При втором проходе часть иго-
лок будут на том месте, где уже имеются отпечатанные точки,  поэ-
тому надо чтобы биты для этих иголок были сброшены в 0, чтобы они
не работали.
   Чтобы  продвинуть бумагу на высоту четырех точек надо  послать
код 27, 65, 4, 27, 50, а на  высоту восьми точек - 27, 65, 8, 27,
50.   При  этом вызывается автоматический возврат каретки.  В  то
время когда выполняется первый проход, готовится временная строка
текста, которая будет печататься при втором проходе.  Если данный
символ обычный, то  в  соответствующую  позицию  временной второй
строки  символов  надо  поместить  пробел (ASCII  32).   Но  если
встречается специальный  графический символ, который должен печа-
таться  в четырехточечном поле, то надо поместить его код ASCII в
соответствующюю позицию второй строки. Например:

Позиция символа   1    2    3    4    5    6    7    8    9   10

Код ASCII        205  32   98   111  114  105  110  103  32   205
Код 2-й строки   205  32   32   32   32   32   32   32   32   205

В памяти должна храниться  отдельная  таблица  цепочек битов этих
символов  для  второго прохода.  Для двойной  вертикальной  черты
содержимое таблицы для первого  прохода  будет 0, 255, 0, 255, 0,
0,  а для второго - 0, 15, 0, 15, 0, 0.  Отметим, что во втором и
четвертом байте для  второго  прохода  верхние  4  бита сброшены,
чтобы не было надпечатки.
   Короче,  когда начинается печать, то в первую  очередь  прове-
ряется является ли данный символ пседографическим, и если нет, то
он  посылается  на печать, как обычный код ASCII.   Во  временную
строку, используемую для печати второго  прохода вставляется про-
бел.   Затем обрабатывается следующий символ.  Когда  встречается
символ псевдографики, то 6 кодирующих  его байтов берутся из таб-
лицы, принтер переводится в графический режим для вывода 6 байтов
и посылаются данные.  Затем  принтер автоматически возвращается в
текстовый  режим.  В соответствующую позицию строки  для  второго
прохода помещается код ASCII  этого  символа псевдографики.  Этот
процесс  продолжается до конца строки, после чего делается прогон
бумаги на высоту четырех точек.  При повторном проходе надо опять
поочередно  рассмотреть каждый символ.  Если это пробел, то  надо
печатать символ пробела (т.е.  не печатать ничего, а просто прод-
винуть  головку к следующему символу).  Если же  это  графический
символ, то  надо  найти  соответствующий  ему  данные для второго
прохода  в  отдельной таблице и напечатать его таким же  образом,
как и при первом проходе. Повторно используйте строку для второго
прохода  с каждой печатаемой строкой.  На рис.  6-3 показана  эта
процедура.

   Высокий уровень.


   В данном примере текст разделен  на две колонки, при этом неп-
рерывная  линия разделяет страницу посредине.  Для простоты печа-
тается только одна строка,  однако  этот  пример может печатать и
целую страницу, если вставить цикл FOR/NEXT в строках 325 и  505.

Для демонстрации двух подходов  при  первом проходе печатается по
одному  символу,  в то время как при  втором  проходе  печатается
целая строка.

100 '''таблица данных для первого прохода (только коды 178 и 179)
110 DATA 0, 0, 255, 0, 0, 0
120 DATA 4, 4, 255, 0, 0, 0
130 '''аналогичная таблица для второго прохода
140 DATA 0, 0, 15, 0, 0, 0
150 DATA 0, 0, 15, 0, 0, 0
160 '''помещаем первую таблицу в массив
170 DIM FIRSTPASS$(45)       'описываем массив
180 FOR N = 1 TO 2           'заполняем его
190 Y$ = ""                  'Y$ хранит 6 байтов на символ
200 FOR M=1 TO 6: READ X: Y$ = Y$+CHR$(X): NEXT
210 FIRSTPASS$(N) = Y$: NEXT 'помещаем в массив
220 '''помещаем в массив вторую таблицу
230 DIM SECONDPASS$(45)      '
240 FOR N = 1 TO 2           '
250 Y$ = ""                  '
260 FOR M=1 TO 6: READ X: Y$ = Y$+CHR$(X): NEXT
270 SECONDPASS$(N) = Y$: NEXT '
280 '''печатаем текст следующей строки
290 TEXT$ = "Here is one column"+CHR$(179)+"Here is the
             second column"

300 TEMP$ = STRING$(80,32)   'создаем строку для 2-го прохода
310 GRAPH$ = CHR$(27)+CHR$(75)+CHR$(6)+CHR$(0)
320 OPEN "LPT1:" AS #1       'открываем принтер
330 FOR N = 1 TO LEN(TEXT$)  'для каждого символа текста
340 C$ = MID$(TEXT$,N,1)     'берем символ и проверяем его
350 IF C$ < CHR$(128) THEN PRINT #1,C$;: GOTO 400
360 '''предполагаем, что все остальные символы - псевдографика
370 PRINT #1,GRAPH$;         'входим в графический режим
380 PRINT #1,FIRSTPASS$(ASC(C$) - 178);выводим 1-й проход
390 MID$(TEMP$,N) = C$       'маркер в строке 2-го прохода
400 NEXT
410 '''смещаемся на 8 точек вниз и делаем второй проход
420 PRINT #1,CHR$(27)+CHR$(65)+CHR$(4)+CHR$(141);
430 Z$ = ""                  'Z$ содержит строку для 2-го прохода
440 FOR N = 1 TO LEN(TEXT$)  'для каждого символа текста
450 C$ = MID$(TEMP$,N,1)     'берем символ и обрабатываем его
460 IF C$ = CHR$(32) THEN Z$ = Z$+" ": GOTO 480
470 Z$ = Z$+GRAPH$+SECONDPASS$(ASC(C$) - 178)
480 NEXT
490 PRINT #1,Z$              'печатаем всю строку сразу
500 PRINT #1,CHR$(10);       'добавляем в конце перевод строки

   Низкий уровень.


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

позиции в наборе ASCII. Затем  подготовьте  небольшую таблицу ин-
дексов с помощью инструкции XLAT, с помощью которой можно  быстро
искать данные в этой таблице.


 
« Предыдущая статья   Следующая статья »