Линии, строки и прямоугольные области. Подпрограммы для рисования линий.
Ускорение цикла рисования
В примере 7.5 после каждой переадресации выполняется проверка принадлежности нового значения адреса текущему сегменту и, в случае необходимости, устанавливается следующее окно видеопамяти. Вероятность того, что новое значение адреса выйдет за границу сегмента, достаточно мала. Например, при установке видеорежимов 110h или 111h (Hi-color, 640x480) рабочее пространство видеопамяти занимает 9 неполных окон. Если создаваемое изображение заполняет все это пространство, то только в восьми случаях из 307 200 возникнет необходимость изменения окна, а в остальных случаях проверка адресов не требуется. Сказанное не означает, что она вообще не нужна. Для сокращения количества дополнительных действий надо изменить способ проверки.
Один из вариантов сокращения бесполезных действий заключается в том, чтобы перед началом рисования лиж-ши проверять, помещается она в текущем сегменте или выходит за его пределы. Это исключает необходимость контроля адресов в цикле рисования. Если линия целиком расположена в одном сегменте, то цикл рисования выполняется один раз. В противном случае после рисования части линии, расположенной в текущем окне, устанавливается следующее окно и повторяется цикл рисования остатка линии.
Замечание
Рисование линии по частям в режимах PPG уже описано ранее, а соответствующая подпрограмма приведена в примере 3.8.
Подпрограмма Twopart
Нас интересует не простое рисование, а возможность ускорения выполнения различных действий с точками, расположенными на прямой линии. Поэтому текст примера 7.6 является своеобразным управляющим алгоритмом, который для выполнения конкретных действий вызывает вспомогательную подпрограмм у baseip. В данном примере она рисует прямую линию.
Входные параметры подпрограммы Twopart полностью соответствуют параметрам подпрограммы horiine (пример 7.5) и расположены в тех же регистрах.
Пример 7.6. Рисование линии по част-ям в режимах Hi-Color.
push dx coxp аняем содержимое регистра dx mov dx, di копируем адрес в регистр dx shl ex, 01!! для True Color – shl ex, 02 add dx, ex сумма исходного адреса и размера линии jc @F › прямая расположена в двух окнах xor dx, dx очис тка регистра dx @@: sub ex, dx количество точек в текущем окне shr сх, 01!! для True Color – shr ex, 02 call baseip рисуем всю линию или ее первую часть or di, di адрес в пределах текущего окна? jne hrl_exit › да, линия нарисована полностью call NxtWin установка следующего окна add ex, dx количество не нарисованных точек je hrl_exit линия нарисована полностью shr ex, 01!! для True Color – shr ex, 02 call baselp рисуем остаток линии hrl exit: pop dx восстановление содержимого dx ret возврат из подпрограммы ; Подпрограмма, выполняющая основные действия baselp: mov es: [di],ax!! для True Color – mov es: [di], eax. add di, bytppnt переадресация операнда loop baselp управление повторами цикла ret возврат из подпрограммы
Выполнение примера 7.6 начинается с сохранения в стеке содержимого регистра dx, поскольку оно изменяется в подпрограмме. При входе регистр сх содержит количество рисуемых точек, его надо преобразовать в количество байтов, с помощью сдвига и сложить с исходным адресом видеопамяти (в регистре dx). Если при этом происходит переполнение, то линия не помешается в текущем окне и ее надо рисовать по частям. В противном случае регистр dx очищается. После этого вычисляется количество точек в первой части и вызывается подпрограмма baselp, рисующая начало линии.
При первом вызове baselp может быть нарисована вся линия или только ее первая часть. Это важно знать для выполнения дальнейших действий. Они начинаются с проверки значения адреса, находящегося в регистре di.
Возможен случай, когда при первом рисовании достигнута граница окна. В таком случае в регистре di находится 0, но нулевой адрес принадлежит не текущему, а следующему окну видеопамяти. Поэтому если регистр di очищен, то обязательно надо сменить окно видеопамяти. Если же содержимое di отлично от нуля, то нарисована вся линия.
— Регулярная проверка качества ссылок по более чем 100 показателям и ежедневный пересчет показателей качества проекта.
— Все известные форматы ссылок: арендные ссылки, вечные ссылки, публикации (упоминания, мнения, отзывы, статьи, пресс-релизы).
— SeoHammer покажет, где рост или падение, а также запросы, на которые нужно обратить внимание.
SeoHammer еще предоставляет технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Зарегистрироваться и Начать продвижение
После установки окна суммируется содержимое регистров сх и dx. Если сумма равна нулю, то линия нарисована целиком, а код ее последней точки был записан в последнее слово сегмента. В противном случае количество байтов, полученное в регистре сх, преобразуется в количество точек и повторно вызывается подпрограмма baselp. Перед возвратом на вызывающий модуль восстанавливается исходное содержимое регистра dx, соответствующая команда имеет метку hri_exit.
Замечание
Практическая ценность примера 7.6 заключается в том, что он иллюстрирует способ обработки строки графического объекта по частям. Основные действия локализованы в подпрограмме baselp. Ее можно изменить так, чтобы вместо записи в видеопамять содержимого регистра ах выполнялись другие действия, например инверсия кодов точек, пересылка кодов из видеопамяти в оперативную или наоборот и т. д.