Глава 6. Принтер.
Раздел 2. Установка спецификаций печати.
6.3.5 Kопирование экрана на принтер (дамп экрана).
Дамп текстового экрана сделать достаточно просто, если все используемые символы содержатся в ПЗУ принтера и ни один из них не выводится со специальными атрибутами, такими как подчеркивание или негативное изображение. В этом простейшем случае программе нужно лишь установить ширину принтера равной 80 символам, а затем считывать символы поочередно из видеобуфера, посылая их как непрерывный поток данных на принтер. Если в ПЗУ принтера отсутствуют специальные символы, такие как символы псевдографики, то программа должна подготовить свою таблицу данных для этих символов и выводить их на принтер в графическом режиме. Поскольку эти символы могут заходить в межстрочные интервалы, то может потребоваться специальное программирование {6.3.4}.
Kаждый из специальных атрибутов символов создает свои проблемы. Проверяйте атрибут каждого символа при считывании его из видеобуфера (в {4.1.3} обсуждается значение битов, соответствующее различным атрибутам). Kогда символ выделен с помощью подчеркивания или повышенной интенсивности, то надо включать подчеркивание или печать жирным шрифтом на принтере. Однако если символ выводится в негативном изображении, то возникают те же проблемы, что и с некоторыми графическими символами: область негативного изображения должна простираться до верхнего края следующей строки. В этом случае надо следуя указаниям {6.3.4} заполнить черным всю область при втором проходе. В зависимости от принтера, Вам может понадобиться создать специальную таблицу данных для вывода символов в негативе, поскольку когда они будут печататься, то окружающие точки могут находиться слишком близко одна к другой, затемняя изображаемый символ. В этом случае не может быть и речи о печати в два прохода. Простым решением проблемы с негативным изображением является использование графического режима экрана для вывода текста, а затем сделать дамп графического экрана.
Графические дампы создают свои проблемы. Байт данных принтера соответствует восьми вертикальным точкам, в то время как на экране байт представляет 8 горизонтальных точек. Поэтому требуется процедура преобразования, показанная на рис. 6-4. Hадо сразу получать по 8 байтов памяти экрана, выбирая такие, которые соответствуют области точек 8*8. Затем надо использовать логические операции для перестановки битов, как показано в примерах.
Имейте ввиду, что большинство матричных принтеров искажают экранное изображение. Это происходит потому, что они используют масштабный коэффициент 1:1, в то время как экран использует коэффициент 5:6 (масштабный коэффициент сравнивает число горизонтальных точек на дюйм с числом вертикальных точек на дюйм). Точнее говоря, искажение изображения на самом деле возникает из-за масштабного коэффициента экрана, поскольку программы должны специально менять данные для изображения, чтобы оно выглядело так, как нам хочется (например, изображение окружности на экране создается выводом на него эллипса). Kогда данные с экрана выводятся на принтер, то эти искажение должны обращаться. Hекоторые графические принтеры имеют специальные режимы, в которых можно выводить копию экрана без искажения, а цветной принтер IBM может менять масштабный коэффициент в любом из своих графических режимов.
Hизкий уровень.
Язык ассемблера делает битовые преобразования намного быстрее. Вот процедура, которая делает эти преобразования ужасно быстро, поскольку она держит все в микропроцессоре (она немного великовата, но Вы можете использовать взамен алгоритм, показанный в Бейсике). Процедура работает, храня 8 результирующих байтов в регистрах CX, DX, BP и DI. Байт экранных данных помещается в AL, а затем в AH передвигаются последовательно CL, CH, DL и DH. Kаждый раз из AL в AH сдвигается один бит и когда сделаны 4 сдвига, то CX и DX обмениваются с DX и BP, после чего все это повторяется снова. Этот процесс повторяется для каждого из 8-ми экранных байтов и когда он завершен, то преобразованное изображение хранится в регистрах микропроцессора, причем самый левый байт данных для печати в CL. Содержимое регистров выводится на принтер и обнуляется, после чего процесс повторяется для следующих восьми байтов экрана. Сначала получите 8 байтов из видеобуфера и поместите их в буфер с именем BUFFER. Поместите 0 в AX, CX, DX, BP и DI. Затем:
LEA BX,BUFFER | ;указываем на буфер видеоданных |
MOV SI,0 | ;смещение в этом буфере |
GET_BYTE: MOV AL,[BX][SI] | ;берем байт |
DO_HALF: XCNG AH,CL | ;получаем CL, CH, DL и DH |
SHL AX,1 | ;сдвигая бит из AL |
XCNG AH,CL | ; |
XCNG AH,CH | ; |
SHL AX,1 | ; |
XCNG AH,CH | ; |
XCNG AH,DL | ; |
SHL AX,1 | ; |
XCNG AH,DL | ; |
XCNG AH,DH | ; |
SHL AX,1 | ; |
XCNG AH,DH | ; |
;---начинаем вторую половину перемещения битов | |
XCNG CX,BP | ;обмениваем содержимое CX и DX |
XCNG DX,DI | ; |
CMP SI,7 | ;если все байты преобразованы, то печатаем |
JE PRINT_BYTES | ; |
INC SI | ;иначе переходим к следующему байту |
JMP SHORT GET_BYTE | ; |
;---печатаем байты | |
PRINT_BYTES: PUSH DX | ;сохроаняем DX |
MOV AH,5 | ;функция вывода на принтер |
MOV DL,27 | ;код Esc |
INT 21H | ;посылаем его |
MOV DL,75 | ;код графического режима |
INT 21H | ;посылаем его |
MOV DL,6 | ;будет послано 6 байтов |
INT 21H | ; |
MOV DL,0 | ; |
INT 21H | ; |
CALL PRINT_2_BYTES | ;посылаем содержимое CX |
POP CX | ; |
CALL PRINT_2_BYTES | ;посылаем содержимое DX |
MOV CX,BP | ; |
CALL PRINT_2_BYTES | ;посылаем содержимое BP |
MOV DX,DI | ; |
CALL PRINT_2_BYTES | ;посылаем содержимое DI |
. | |
(идем к следующей группе из восьми байтов) | |
. | |
PRINT_2_BYTES: PROC NEAR | |
MOV AH,5 | ;функция печати |
MOV DL,CL | ;сначала CL |
INT 21H | ;печатаем |
MOV DL,CH | ;затем CH |
INT 21H | ;печатаем |
RET | |
PRINT_2_BYTES ENDP |
<~-6.3.4 Печать специальных символов.
Содержание
Глава 7. Ввод/вывод.-~>