Построение рисунков. Варианты построения строк.
В отличие от геометрических фигур рисунки не создаются в процессе выполнения задачи, а готовятся заранее и хранятся в файлах, на внешних носителях. К сожалению (или к счастью), не существует единого стандарта структуры таких файлов, но существуют специальные программы для их преобразования из одного стандарта (формата) в другой. Кроме того, такое преобразование выполняют все распространенные графические редакторы. Поэтому вы можете выбрать один из стандартов и использовать только его.
В Приложении А данной книги подробно описан один из основных стандартов – BMP. По мере изложения основного материала будут рассмотрены некоторые характеристики и других наиболее распространенных стандартов.
В структуре файла, содержащего точечный рисунок, можно выделить три основные части: заголовок, палитру и образ рисунка.
Заголовок располагается в начале файла и содержит исчерпывающую информацию, необходимую для вывода рисунка на экран или на печать.
Палитра находится после заголовка или после образа рисунка. Она содержит коды использованных в рисунке цветов. Описанию назначения палитры и способов работы с ней посвящена следующая глава книги.
Образ рисунка содержит коды точек, образующих рисунок. Адрес его начала (смещение) в файле обычно указывается в заголовке. В некоторых случаях перед построением или в процессе построения рисунка может потребоваться преобразование его образа.
Прежде чем выводить рисунок на экран, весь файл или его часть надо прочитать в оперативную память, выделить из заголовка все необходимые величины и установить палитру используемых цветов. Мы будем считать, что все подготовительные действия выполнены, и образ рисунка находится в оперативной памяти. Такое допущение позволит рассматривать графические аспекты построения рисунков в чистом виде.
Точечные рисунки, независимо от их конкретного содержания, всегда занимают на экране прямоугольную область, а их образы хранятся в файлах в виде последовательности строк одинакового размера. Поэтому построение рисунка сводится к последовательному построению его строк на экране монитора. Изложение материала мы начнем с нескольких примеров подпрограмм для работы со строками рисунков.
Строки рисунков отличаются от линий геометрических фигур тем, что их образы существуют в оперативной или в видеопамяти. Поэтому в простых случаях надо просто переместить коды точек из одного места памяти в другое. В данной главе нас будут интересовать строки, у которых код точки занимает 1 байт.
Построение строки слева направо
В примере 3.15 приведен текст подпрограммы, выполняющей копирование образа строки из оперативной памяти в видеопамять. В результате на экране появится изображение строки. Копирование производится в прямом направлении, т. е. в сторону увеличения адресов.
Перед обращением к подпрограмме устанавливается окно видеопамяти, в котором должны располагаться точки строки, а в регистре di указывается адрес первой (левой) точки. Кроме того, пара регистров fs:si должна содержать адрес начала строки в оперативной памяти, fs – сегмент, a si – смещение (относительный адрес) в этом сегменте. Размер строки (количество точек) помещается в регистр сх. Напомним, что es должен содержать код видеосегмента (значение переменной vbuff).
Пример 3.15. Построение строки 256-цветного рисунка.
drawline: | movs | byte ptr [di], fs:[si] | ; | запись кода точки в видеобуфер |
or | di, di | ; | начало нового сегмента? | |
jne | @F | ; | › нет, обход команды call NxtWin | |
call | NxtWin | ; | установка следующего окна | |
@@: | loop | drawline | ; | управление повторами цикла |
ret | ; | возврат из подпрограммы |
Сравните второй вариант примера 3.6 и пример 3.15. Приведенные в них тексты различаются только первой командой. Вместо stosb, записывающей в видеопамять содержимое регистра ai, в данном случае используется строковая операция movs, копирующая в видеопамять байты оперативной памяти. Обратите внимание на то, что в записи строковой операции сегментный регистр приемника (es) указывать не обязательно, а сегментный регистр источника (fs) вы можете изменить по своему усмотрению.
Подпрограмма примера 3.15 выводит точки в порядке увеличения их адресов. В некоторых случаях может возникнуть необходимость выводить точки в обратном порядке (справа налево) в сторону уменьшения адресов. Как можно нарисовать линию в направлении справа налево, было показано во втором варианте примера 3.7. Если в этом примере команду lodsb заменить командой movs byte ptr [di], fs:[si], то подпрограмма будет строить строку рисунка в обратном направлении. Когда и зачем может понадобиться такая замена, мы обсудим при описании построения рисунков.