Вывод на дисплей: Часть III
4.1. Атрибуты символов
Когда дисплей установлен в текстовый режим в любой из видеосистем, каждой позиции на экране отводится два байта памяти. Первый байт содержит номер кода ASCII символа, а второй байт - атрибуты символа. Для указания цветов экрана одни и те же номера кодов используются в бейсике, Си и прерываниях операционной системы (см. таблицу 4.1.).
Числ. Значение | Цветовой атрибут | Символ или фон? |
---|---|---|
0 | Чёрный | Символ |
1 | Синий | Символ |
2 | Зелёный | Символ |
3 | Циан (голубой) | Символ |
4 | Красный | Символ |
5 | Пурпурный | Символ |
6 | Коричневый | Символ |
7 | Светло-серый | Символ |
8 | Тёмно-серый | Символ |
9 | Светло-синий | Символ |
10 | Светло-зелёный | Символ |
11 | Светло-голубой | Символ |
12 | Светло-красный | Символ |
13 | Светло-пурпурный | Символ |
14 | Жёлтый | Символ |
15 | Белый | Символ |
0 | Чёрный | Фон |
16 | Синий | Фон |
32 | Зелёный | Фон |
48 | Циан (голубой) | Фон |
64 | Красный | Фон |
80 | Пурпурный | Фон |
96 | Коричневый | Фон |
112 | Светло-серый | Фон |
128 | Мигание | Символ |
Примечание: Атрибут = Символ+Фон (+ Мигание) |
Младшие четыре бита байта атрибутов устанавливают цвет самого символа (бит 3 включает высокую интенсивность цвета). Следующие три бита устанавливают фон символа, и при обычных обстоятельствах старший бит включает и выключает мигание. Образование шестнадцати цветов из 4-х бит проиллюстрировано в таблице 4.2.
Сопоставление кодов цветов экрана в 16-ти цветной палитре | ||||
---|---|---|---|---|
Канал | Интенсивность | |||
Красный | Зелёный | Синий | Низкая (0) | Высокая (1) |
0 | 0 | 0 | Чёрный (0) | Серый (8) |
0 | 0 | 1 | Синий (1) | Светло-синий (9) |
0 | 1 | 0 | Зелёный (2) | Светло-зелёный (10) |
0 | 1 | 1 | Циан (3) | Светлый циан (11) |
1 | 0 | 0 | Красный (4) | Ярко-красный (12) |
1 | 0 | 1 | Магента (5) | Светлая магента (13) |
1 | 1 | 0 | Коричневый (6) | Жёлтый (14) |
1 | 1 | 1 | Белый (7) | Ярко-белый (15) |
4.1.1. Реализация на ассемблере
Прерывания DOS и BIOS предоставляют очень скудные возможности для работы с цветным текстом. Только функция 9 прерывания 10H принимает байт атрибутов при выводе символа. Функция 0AH прерывания 10H выводит символ без указания цвета - он принимается равным цвету по-умолчанию. Функция 0DH прерывания также оставляет нетронутым байт атрибутов.
Функция вывода на экран DOS прерывания 21H всегда выводит белые символы на чёрном фоне. Единственный способ обойти это ограничение - использовать escape-последовательности (см. таблицу 2.2).
Приведём примеры на языке ассемблера вывода сначала обычной строки (белым по чёрному), а затем надпись: "Внимание!" жёлтым цветом на красном фоне.
Пример 4.1.
; --- в сегменте данных STRING_01 DB 'Я хочу обратить Ваше',0AH,0DH,'$' STRING_02 DB 'Внимание!$' NORM_COLOR DB 27, '[0m$' ATTENT_COLOR DB 27, '[1;33;41m$' CLEAR_COLOR DB 27, '[0m$' ; --- в сегменте кода ; --- вывод строк MOV AH, 9 ; функция вывода страницы LEA DX, NORM_COLOR ; Обычный цвет INT 21H LEA DX, STRING_01 ; Первая строка INT 21H LEA DX, ATTENT_COLOR ; Выделение цветом INT 21H LEA DX, STRING_02 ; Вторая строка INT 21H LEA DX, CLEAR_COLOR ; Сброс атрибутов текста INT 21H
Смотри Листинг программы ex04001.asm
4.1.2. Реализация на языках Си
В стандарте на язык Си (ANSI C) нет функций для работы с цветом. Вместо этого рекомендуется использовать escape - последовательности, при условии, что у Вас в системе установлен драйвер ANSI.SYS
В этом случае пример 4.1. запишется следующим образом:
Пример 4.2.
/* ex04002.c */ /* Вставка заголовочных файлов */ #include <stdio.h> #include <conio.h> /* описание констант */ const char NORM_COLOR[] = "\x1b[0m"; //Нормальный режим const char ATTENT_COLOR[] = "\x1b[1;33;41m"; // Выделение цветом /* Основная программа */ void main( void ) { /* Определение временной переменной */ char cJunk; /* Вывод строк */ puts( NORM_COLOR ); puts( "\nЯ хочу обратить Ваше" ); puts( ATTENT_COLOR ); puts( "Внимание!\x1b[0m" ); /* Завершение работы программы */ cputs( "Press key Enter to exit...\r\n" ); cJunk = getche(); } /* Конец программы */
Ниже рассмотрены некоторые функции для "цветного" вывода средствами Turbo C++ и SPHINX C--.
ФУНКЦИЯ | TEXTATTR |
ОПИСАНА В: | <conio.h> (содержит только прототип); |
СИНТАКСИС: |
void textattr( newattr ); int newattr; |
НАЗНАЧЕНИЕ: | Устанавливает текстовые атрибуты; |
ОПИСАНИЕ: |
textattr позволяет устанавливать цвет фона и цвет символов одновременно за один вызов. (Обычно вы устанавливаете атрибуты с помощью textcolor и textbackground ); Эта функция не относится к символам, находящимся в текущий момент на экране; она относится только к тому, что отображается функциями (такими как cprintf ) выполняющими вывод в текстовом режиме, после того, как была вызвана функция textattr. |
Информация цвета кодируется в параметре newattr следующим образом (смотри рисунок 4.1):
В этом 8-битном параметре newattr:
Если бит мигания включён, то символ будет мигать. Это можно осуществить путём добавления константы BLINK в атрибут. Если вы используете символьные цветовые константы, определённые в conio.h для создания текстовых атрибутов с помощью textattr, запомните следующие ограничения на цвет фона:
- Вы можете выбрать только первые 8 цветов для фона;
- Вы должны сдвинуть выбранный цвет фона влево на 4 бита для перемещения его в правильную битовую позицию.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Нет; |
ПЕРЕНОСИМОСТЬ: | textattr работает только на IBM PC и совместимых системах; |
ФУНКЦИЯ | TEXTCOLOR |
ОПИСАНА В: | <conio.h> (содержится прототип функции); |
СИНТАКСИС: |
void textcolor( newcolor); int newcolor; |
НАЗНАЧЕНИЕ: | Устанавливает цвет символов в текстовом режиме; |
ОПИСАНИЕ: | textcolor выбирает цвет символа. Эта функция оказывает влияние на функции, производящие прямой вывод на экран в текстовом режиме. Вы можете выбрать цвет, используя символьную константу, определённую в conio.h. Если вы используете эту константу, вы должны включить файл conio.h ; |
Эта функция не относится к символам, находящимся в текущий момент на экране; она относится только к тем символам, которые выводятся функциями (такими как cprintf ) в текстовом режиме, осуществлявшим вывод на дисплей после вызова textcolor.
Следующая таблица отображает возможные цвета (как символьные константы ) и их числовые значения (Таблица 4.4.).
Вы можете сделать символы мигающими, добавляя BLINK к цвету символов. Встроенная константа BLINK предназначена для этой цели. Например:
textcolor(CYAN+BLINK);
Замечание. Некоторые мониторы не определяют интенсивность сигнала, используемую для создания восьми "light" (светлый) цветов (8-15). На таких мониторах светлые цвета будут изображаться как их "тёмные" эквиваленты (0-7). Аналогично, системы, которые не отображают цвет, используют эти номера как оттенки одного цвета, особые образцы или особые атрибуты (такие как подчёркивание, полужирный шрифт, курсив и т.п.). То, что вы увидите при этом на экране, зависит от оборудования.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Нет; |
ПЕРЕНОСИМОСТЬ: | Только на IBM PC и совместимых компьютерах. Соответствующая функция существует в Turbo Pascal; |
Эта функция не относится к символам, находящимся в текущий момент на экране; она относится только к тем символам, которые выводятся функциями (такими как cprintf ) в текстовом режиме, осуществлявшим вывод на экран после вызова этой функции.
Символьные константы в таблице 4.5:
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Нет; |
ПЕРЕНОСИМОСТЬ: | Только с IBM PC и совместимыми компьютерами. Соответствующая функция существует в Turbo Pascal; |
Пример 4.3.
Использование функций управления атрибутами символов textcolor и textbackground.
/* ex04003.c */ /* Работает только в системе Borland C/C++ 3.10 */ /* Вставка заголовочных файлов */ #include <conio.h> /* Основная программа */ void main( void ) { /* Определение временной переменной */ char cJunk; /* Вывод строк */ textcolor( LIGHTGRAY); textbackground( BLACK ); cputs( "\r\nЯ хочу обратить Ваше\r\n" ); textcolor( YELLOW); textbackground( RED ); cputs( "Внимание!" ); textcolor( LIGHTGRAY); textbackground( BLACK ); /* Завершение работы программы */ cputs( "\r\n\r\nPress key Enter to exit...\r\n" ); cJunk = getche(); } /* Конец программы */
4.1.3. Реализация в оболочке DOS Command Shell и NDOS
В командной оболочке NDOS есть штатная функция: be, с помощью которой можно менять цвет выводимых символов и их фон. Её синтаксис следующий:
be "команда" "опции и параметры"
а также
be "имя batch-файла".dat
Все команды и опции команды be приведены в приложении №1 (пункт 4.4 данной лекции). Здесь же приведём пример batch файла, реализующий пример 4.3.:
Пример 4.4. Файл ex04005.dat
cls white on black rowcol 1, 1 "Я хочу обратить Ваше" rowcol 2, 1 "Внимание!" bright yellow on red
Примечание: Этот файл запускается из командной строки командой:
Пример 4.5
be ex04005.dat
4.1.4. Реализация на языках Perl и Python
Вывод текста с "нестандартными" атрибутами на языках Perl и Python не возможен.
4.1.5. Реализация на языке Prolog
Вывод текста с атрибутами цвета на языке ПРОЛОГ осуществляется с использованием предиката attribute, который может читать и устанавливать текстовый атрибут;
Приведём синтаксис предиката attribute
ФУНКЦИЯ: | attribute |
СИНТАКСИС: | attribute(Attr), где Attr - атрибут символа (целое число); |
НАЗНАЧЕНИЕ: | Устанавливает или выдаёт текущий атрибут символа; |
ОПИСАНИЕ: | attribute устанавливает или считывает текущий атрибут вывода. Вывод при помощи write или writef даёт отображение экрана с этим атрибутом. Каждое окно имеет свой атрибут вывода. Когда вы создаёте окно, атрибут вывода автоматически принимает значение атрибута окна, но вы можете изменить его предикатом attribute ; |
ШАБЛОНЫ: | (i) (o) ; |
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: | Всегда успех; |
ОШИБКИ: | Никогда не даёт; |
Пример 4.3, записанный на языке ПРОЛОГ, будет выглядеть следующим образом:
Пример 4.6.
/* Файл ex04006.pro */ domains /* Описываем переменные */ CNorm_color= char predicates attent norm_color clauses /* Определяем правила */ norm_color :- attribute( '\07' ). attent :- attribute( '\78' ), nl, write( "Внимание!" ). goal /* Вывод нормального текста */ norm_color, nl, write( "Я хочу обратить Ваше" ),nl, /* Вывод текста с изменёнными атрибутами */ attent, /* Возвращение нормальных атрибутов */ norm_color, nl, /* Вывод завершающей надписи */ write( "Press key Enter to exit..." ), readchar( _ ). /* Конец программы */
4.2. Escape-последовательности
Как Вы, наверное, уже уяснили то, что основным способом манипуляции положением позиции курсора, сменой атрибутов текста при выводе на экран является использование так называемых escape-последовательностей. Наиболее широко их применяют в "консольных" приложениях MS-DOS и UNIX, но часто используют и в других операционных системах. Эти последовательности стандартизированы американским национальным институтом стандартов (ANSI). Сводку используемых при выводе на экран escape - последовательностей см. в таблице 2.1.
Для поддержки escape- последовательностей в операционных системах MS-DOS, Windows 9x/ME необходимо в файле CONFIG.SYS загрузить драйвер ANSI.SYS, при помощи директив DEVICE или DEVICEHIGH. В остальных операционных системах поддержка расширений ANSI включена по-умолчанию (в реестре и файлах конфигурации). Если escape- последовательности всё же не работают, смотрите настройки Вашего компьютера (в файлах конфигурации и в реестре).
4.3. Резюме
После прочтения последних трёх лекций Вы уяснили, каким образом символьные данные выводятся на дисплей с использованием "функций среднего уровня". Материал может показаться Вам не актуальным - ведь Вы уже привыкли работать в "оконном интерфейсе", в котором шрифтовое и абзацное оформление текста намного богаче. Однако если Вы хотите делать свои консольные приложения (а вы их обязательно будете делать в первую очередь) хотя бы чуть-чуть более привлекательными, чем это предоставляют стандартные потоки вывода на дисплей, Вы обязательно обратитесь к этим функциям.
Кроме того, Вы ознакомились с принципиально важными функциями для вывода текста на экран, имеющие при консольном выводе не меньшее значение, чем функции манипулирования контекстом Windows, о котором речь пойдёт в последующих лекциях.