Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Роберт Журден Весь текст 1069.56 Kb

Справочник программиста на IBM PC

Предыдущая страница Следующая страница
1 ... 64 65 66 67 68 69 70  71 72 73 74 75 76 77 ... 92
рый автоматически осуществляет  это  выравнивание.  Такую возмож-
ность  имеет  цветной  принтер  IBM,  посылка  управляющего  кода
27,77,0 заставляет электронику  принтера  интерпретировать посту-
пающие данные и форматировать их. В других случаях принтер должен
менять ширину пробелов между  словами, переключаясь в графический
режим,  когда  выводится символ пробела.  В  графических  режимах
ширина пробела может изменяться на размер до 1/6 размера символа.
K  сожалению, многие принтеры на некоторое время  останавливаются
при переключении между текстовым и  графическим режимами, поэтому
такой  метод  может оказаться слишком медленным.   Другой  подход
состоит во вставке обычных  символов  пробела, распределяя их как
можно более равномерно по строке.  Более сложный графический под-
ход описан ниже.
   Шаги, которые необходимо выполнить для форматирования с вырав-
ниванием правого поля, следующие. Во-первых, из установок формата
страницы должно быть вычислено  число  символов  в строке.  Затем
необходимо подсчитать число символов, занимаемое каждым из после-
довательно введенных слов, включая пробелы между словами. Отдель-
ный счетчик должен подсчитывать число пробелов. Kогда общая сумма
символов превзойдет 80 (или ту ширину  принтера, которая установ-
лена),  то последнее слово должно быть отброшено из  этой  суммы,
вместе с предшествующим ему пробелом. Число оставшихся свободными
позиций  в строке умножается на 6, поскольку каждый символ  зани-
мает размер шести  точек  по  горизонтали,  а  получившееся число
делится на число пробелов между словами.
   После печати каждого слова принтер устанавливается в графичес-
кий режим 480 точек в  строке  и  посылает  на  принтер ряд кодов
ASCII  0.  Kаждый такой байт сдвигает печатающую головку на  одну
точку вправо.  Посылаемое число должно быть равно шести для обыч-
ного  пробела, плюс результат распределения пустого пространства.
Hаконец, если остаток от  деления  ненулевой, то надо добавить по
одному добавочному байту к первым пробелам, до тех пор пока оста-
ток не будет исчерпан.
   Для  примера  рассмотрим  случай,  когда  строка состоит из 12
слов,  содержащих 61 букву, плюс 11 пробелов между словами.   Это
оставляет в 80-тисимвольной  строке  8 свободных позиций. Эти во-
семь позиций, умноженные на 6 точек, составляют 48 точек дополни-
тельного пространства строки.  Поскольку в строке 11 пробелов, то
к  каждому из них должно быть добавлено по 4 дополнительные точки
и после этого останутся еще 4 лишние точки, которые надо добавить
по одной к первым четырем пробелам.  Тогда первые 4 пробела будут
иметь размер 6 точек нормального  пробела, плюс добавочные 5, что
в сумме равно 11.  Остальные пробелы этой строки будут иметь раз-
мер 10 точек.  Чтобы послать эти  данные  на принтер, подготовьте
сначала код, посылающий на принтер 1 байт ASCII 0, а затем помес-
тите его в цикл, который  выполняйте  столько  раз, сколько нужно
послать таких байтов. Hа рис. 6-2 показан этот процесс.
   В  нижеприведенном  примере показаны  основы  выравнивания  по
правому полю. Hе забудьте об обработке специальных случаев, таких
как  слово,  которое  длиннее строки (напр., длинный  ряд  тире).
Процедура нуждается в модификации,  которая позволяла бы ей иметь
дело со случаем, когда строка содержит всего несколько слов,  как
это бывает в конце параграфа.  Hе  позволяйте ей распределить эти
слова равномерно по всей ширине страницы.
   Высокий уровень.

   В  данном примере, BUFFERPTR указывает на место в буфере  дан-
ных, с которого начинается следующая строка, выводимая на печать.

100 S$ = "This text will be printed with right justification
 using the printer alternately in text modes and graphics modes."
110 STRINGPTR = 1         'указатель в строке данных S$
120 COLUMNS = 1           'счетчик позиции в строке
130 SPACES = 0            'счетчик пробелов в строке
140 '''вычисляем сколько слов помещается в строке
150 C$ = MID$(S$,STRINGPTR,1)  'получаем символ
160 IF C$ <> " " THEN 190  'если не пробел, то вперед
170 LASTSPACE = COLUMNS   'иначе зпоминаем позицию
180 SPACES = SPACES + 1   'увеличиваем число пробелов
190 COLUMNS = COLUMNS+1   'увеличиваем указатель столбца
200 STRINGPTR = STRINGPTR + 1  'увеличиваем указатель данных
210 IF COLUMNS = 81 THEN 230   'уход по концу строки
220 GOTO 150              'иначе к следующему символу
230 IF C$ <> " " THEN 270 'если последний не пробел, то уход
240 COLUMNS = 79          'иначе длина строки равна 79
250 SPACES = SPACES - 1   'отнимаем последний пробел
260 GOTO 340              'идем на вычисление пробелов
270 C$ = MID$(S$,STRINGPTR+1,1)  'проверяем на конец слова
280 IF C$ <> " " THEN 300 'если не пробел, то уход
290 GOTO 340              'иначе на вычисление пробелов
300 COLUMNS = COLUMNS - LASTSPACE  'возвращаемся к концу слова
310 STRINGPTR = STRINGPTR - COLUMNS + 1  'возвращаем указатель
320 COLUMNS = LASTSPACE - 1  'убираем последний пробел
330 SPACES = SPACES - 1   'уменьшаем число пробелов
340 '''вычисляем число точек на пробел
350 EXTRASPACES = 80 - COLUMNS  'вычисляем число пробелов в конце
360 TOTALSPACES = EXTRASPACES + SPACES   'добавляем к пробелам
370 TOTALDOTS = 6*TOTALSPACES   'вычисляем число точек
380 DOTSPERSPC = TOTALDOTS/SPACES 'получаем число точек на пробел
390 EXTRADOTS = TOTALDOTS MOD SPACES  'остаток от деления
400 '''теперь печатаем первую строчку нашего текста
410 OPEN "LPT1:" AS #1    'открываем принтер
420 PRINTPTR = 1          'указатель на начало буфера данных
430 C$ = MID$(S$,PRINTPTR,1)  'берем символ
440 PRINTPTR = PRINTPTR + 1   'увеличиваем указатель
450 IF C$ = " " THEN 500  'если пробел, то на обработку пробела
460 PRINT #1, C$          'иначе печатаем символ
470 IF PRINTPTR = COLUMNS + 1 THEN 590  'выход по концу строки
480 GOTO 430              'иначе печатаем следующий символ
490 '''вот процедура печати пробелов
500 PRINT #1, CHR$(27) + "K";  'переход в графический режим
510 NUMBERDOTS = DOTSPERSPC  'вычисляем число байтов ASCII 0
520 IF EXTRADOTS = 0 THEN 550  'если нет добавочных точек, уход
530 NUMBERDOTS = DOTSPERSPC + 1  'иначе добавляем точку
540 EXTRADOTS = EXTRADOTS - 1  'уменьшаем число добавочных точек
550 PRINT #1, CHR$(NUMBERDOTS);  'посылаем число графических байт
560 PRINT #1, CHR$(0);    '
570 FOR N = 1 TO NUMBERDOTS: PRINT #1, CHR$(0): NEXT
580 GOTO 430              'пробел окончен, идем на след. символ
590 PRINT #1, CHR$(13)    'в конце печатаем возврат каретки
   Hизкий уровень.

   Соответствующая ассемблерная процедура слишком длинная,  чтобы
приводить ее здесь. Она работает  в точности так же, как и проце-
дура на Бейсике, за исключением того, что нет необходимости заво-
дить отдельную переменную,  чтобы  хранить  строку.  Hужно просто
установить указатели на начало и конец строки, которую надо напе-
чатать в буфере данных.
   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                   'и идем на следующий символ

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

   Программа на языке ассемблера должна работать совершенно  ана-
логично приведенному бейсиковскому  примеру.  Одно из преимуществ
ассемблера состоит в том, что для просмотра ширин символов  можно
использовать инструкцию XLAT. Поместите символ в AL, DS:DX должны
указывать на таблицу, после чего можно использовать XLAT.  Ширина
символа будет возвращена в AL:

;---просмотр ширин символов
   LEA  SI,DATA_BUFFER     ;указываем на буфер данных
   LEA  BX,WIDTH_TABLE     ;указываем на таблицу ширин
   MOV  AL,[SI]            ;получаем байт данных
   XLAT WIDTH_TABLE        ;теперь его ширина в AL
   6.3.4 Печать специальных символов.

   Большинство принтеров не поддерживают расширенный набор симво-
лов IBM, однако большинство  программ использует специальные сим-
волы псевдографики.  Очень полезно иметь возможность печатать эти
символы и не так сложно это сделать  на любом матричном принтере,
который  имеет графические возможности.  Вместо того, чтобы пола-
гаться на ПЗУ принтера, программа  должна сама создавать эти сим-
волы  и она должна обращаться с принтером  определенным  образом,
чтобы они были напечатаны на бумаге.
   Сама по себе печать  специальных  символов тривиальна.  Просто
разбейте символ на шесть байтов, цепочка битов каждого соответст-
Предыдущая страница Следующая страница
1 ... 64 65 66 67 68 69 70  71 72 73 74 75 76 77 ... 92
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (1)

Реклама