Иллюстрированный самоучитель по SVGA

Прямоугольники

При рисовании прямоугольников можно преследовать две разные цели – закрашивание (заливка) прямоугольной области экрана выбранным цветом или рисование сторон (контура) прямоугольника. Первая задача является более обшей, поэтому сначала мы рассмотрим способы ее решения.

Полоса заданного цвета

Предположим, что ширина прямоугольника равна ширине рабочей области экрана (Horsize), а ее высота (толщина) составляет N точек. В примере 3.12 приведен текст подпрограммы, которая последовательно рисует заданное количество горизонтальных линий длиной Horsize, в результате чего получается полоса нужной высоты.

Перед вызовом подпрограммы надо установить окно видеопамяти, в котором находится левый верхний угол полосы, а его адрес в этом окне записать в регистр di. Количество строк в полосе указывается в регистре сх. Для рисования строк подходит любой вариант подпрограммы horiine, описанный в предыдущем разделе. В зависимости от того, какой из них вы выберете, код цвета указывается только в регистре ai, в обоих байтах регистра ах или в четырех байтах регистра еах.

Пример 3.12. Закрашивание прямоугольной полосы.

stripe: PushReg <di,cx,Cur win> ; сохранение di, ex и Cur win
fillbar: push ex ; сохранение текущего значения сх
mov ex, horsize ; задание размера строки
call horline ; вывод очередной строки
pop ex ; восстановление счетчика строк
loop fillbar ; управление выводом строк
PopReg <Cur win,cx,di> ; восстановление Cur win, ex и di
call SetWin ; восстановление исходного окна
ret ; возврат из подпрограммы

Выполнение подпрограммы примера 3.12 начинается с сохранения в стеке содержимого регистров di, сх и переменной cur_win. Закрашивание производится в цикле, имеющем метку fillbar. Регистр сх используется в этом цикле в качестве счетчика. Кроме того, в нем передается размер строки для подпрограммы horline. Поэтому в начале цикла содержимое сх сохраняется в стеке и восстанавливается после возвращения из horline. Благодаря этому команда loop fillbar работает с той величиной, которая была указана в регистре сх при обращении к подпрограмме stripe.

После завершения цикла fillbar восстанавливаются сохраненные в стеке величины и исходное окно видеопамяти, для чего вызывается подпрограмма setwin. Последняя команда выполняет возврат из подпрограммы.

В рассмотренном примере ширина полосы равнялась ширине рабочей области экрана. В таком случае после записи последней точки текущей строки автоматически происходит переход к началу следующей строки, для этого не нужны никакие дополнительные действия подпрограммы. Если же ширина прямоугольной области меньше Horsize, то адрес начала следующей строки должна устанавливать подпрограмма.

Вычисление адресов строк

Первые точки строк прямоугольной области находятся в одном столбце, поэтому в режимах PPG адреса начала смежных строк различаются на величину Horsize (см. табл. 3.3). Следовательно, если адрес начала текущей строки увеличить на Horsize, то получится адрес начала следующей строки. Обсудим, как это проще всего сделать.

Наиболее очевидный способ – сохранять адрес начала текущей строки и в нужный момент увеличивать его на Horsize. Однако это не самый простой способ, и вот почему. Если при вычислении адреса начала следующей строки происходит переполнение, то надо установить новое окно видеопамяти. Но оно уже могло быть изменено при рисовании текущей строки и повторное изменение недопустимо. Поэтому, прежде чем устанавливать новое окно, надо проверить, не изменилось ли оно при рисовании строки. Таким образом, простой на первый взгляд способ коррекции адреса плох тем, что неизвестно, какому окну видеопамяти соответствует сохраненный адрес и нужны дополнительные проверки для выяснения этого обстоятельства.

Лишние проверки можно исключить, если изменить способ коррекции так, чтобы использовалось текущее значение адреса, которое заведомо соответствует установленному окну видеопамяти. После вывода последней точки строки текущий адрес больше адреса ее первой точки на ширину прямоугольной области.

Следовательно, прибавив к нему значение переменной Horsize, уменьшенное на ширину прямоугольной области, мы получим адрес начала следующей строки. Если при сложении происходит переполнение, то устанавливается следующее окно видеопамяти без проверки каких-либо дополнительных условий. Мы будем использовать такой способ вычислений при построении прямоугольных рисунков различного назначения.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.