microbik.ru
  1 ... 8 9 10 11 12

Виртуальная память
Виртуальной памятью (обозначается VM) называется область памяти, в которой хранятся значения составных объектов. В некоторых реализациях PostScript может сохранять VM в файле в конце сеанса и восстанавливать её в начале следующего. Сохранить и восстановить текущее состояние VM во время выполнения программы можно также с помощью операторов save и restore, а проверить состояние VM – с помощью оператора vmstatus.
Цветовые модели в PostScript
В языке поддерживаются две цветовые модели: HSB (тон-насыщенность-яркость) и RGB (красный-зеленый-голубой). В каждой из этих моделей можно задать любой цвет с помощью трёх числовых параметров. В более простой модели RGB цвет задаётся сочетанием интенсивности трёх основных цветов: красного, зеленого и голубого. Интенсивность цвета задаётся числом в диапазоне от 0 до 1, причём 0 означает полное отсутствие данного цвета, а 1 – его максимальную интенсивность. Если для всех трёх цветов заданы равные интенсивности, то в результате получится чистый серый цвет с градацией по всей шкале от белого (0, 0, 0) до черного (1, 1, 1). Напомню, что уровень серого цвета обычно устанавливается оператором setgray.

В HSB тон задаёт собственно цвет. Он определяется его расположением на цветовом круге: 0 -- чистый красный, 120 -- зелёный, 240 -- синий. Остальные цвета получаются из смешения двух соседних. (Так, 60 -- жёлтый, , 180 -- голубой, 300 -- фиолетовый.) Насыщенность – густота цвета заданного тона: 0 соответствует отсутствию цвета, а 1 – максимальной его насыщенности. Яркость – общая интенсивность цвета (содержание белого цвета в данном цвете): 0 соответствует чёрному цвету, а 1 – белому (максимальной интенсивности).

Цвет может быть задан с помощью соответствующих модели операторов setrgbcolor и sethsbcolor.
Выборка произвольного элемента из стека
Оператор index удаляет неотрицательное целое число n из стека операндов, отсчитывает n-й элемент от вершины стека и помещает копию этого элемента в стек. Это очень напоминает выборку элемента массива. При этом первый элемент в стеке имеет индекс 0. Вместе с операторами copy, dup и roll он позволяет свободно манипулировать содержимым стека операндов.
Синтаксис: an ... a0 n index an ... a0 an

где an ... a0 – элементы стека операндов.
Пример.

Обозначим буквами содержимое стека, тогда:

A D G 0 index A D G G

A D G J F 4 index A D G J F A
Оператор clear извлекает все объекты из стека операндов и уничтожает их.
Синтаксис: a1 ... an clear -
Оператор count пересчитывает число элементов в стеке операндов и возвращает его в вершине стека.
Синтаксис: a1 ... an count a1 ... an n
Примеры.

clear count - 0

clear 1 2 3 count 1 2 3 3
Оператор countexecstack считает число объектов в стеке исполнения и помещает это число в стек операндов.
Синтаксис:- countexecstack int
Оператор counttomark считает число любых объектов в стеке операндов начиная с вершины стека и до первого маркера (не включая его самого).
Синтаксис: mark ob1 ... obn counttomark mark ob1 ... obn n
Пример.

1 mark 2 3 counttomark 1 mark 2 3 2
Оператор cleartomark извлекает любые объекты из стека операндов, пока не будет достигнут маркер, который также удаляется из стека.
Синтаксис: mark ob1 ... obn cleartomark -
Ещё о работе с отсечениями
Операторы clip и clippath мы рассмотрели на прошлом занятии. Теперь несколько углубим эту важную тему.

Оператор eoclip находит пересечение внутри текущей траектории отсечения с внутренней областью текущей траектории, чтобы создать новый, меньший текущий путь отсечения. Область внутри текущего пути определяется по правилу чётное-нечётное, тогда как область внутри текущего пути отсечения определяется правилом, использованным при создании данного пути отсечения.

За исключением указанных правил, действие оператора eoclip аналогично действию оператора clip.
Синтаксис: - eoclip -
Оператор initclip замещает параметр текущей траектории отсечения в состоянии графической среды на траекторию отсечения, устанавливаемую для текущего графического устройства по умолчанию. Этот путь обычно соответствует границам максимально большой области для вывода изображения. Для устройств, ориентированных на постраничный вывод, его размерности устанавливаются оператором setpagedevice. Для экрана область отсечения, устанавливаемая оператором initclip, не очень хорошо определена.

Ситуаций, когда в PostScript-программе следует применять оператор initclip, не так много. Описание страницы, в которой применён этот оператор, обычно даёт некорректный результат, если оно встроено в другую, составную страницу.
Синтаксис: - initclip -
Оператор eoviewclip (L2) аналогичен оператору viewclip за исключением того, что использует правило чётный-нечётный для определения области внутри пути отсечения.
Синтаксис: - eoviewclip -
К сожалению, за одно занятие удаётся рассказать не так много, как хотелось бы, поэтому рекомендую посмотреть очень полезные примеры программ на PostScript из Голубой книги по адресу: http://www.fwi.uva.nl/~heederik/ps/bluebook/
Урок седьмой
О работе с файлами
Отмечу, что здесь по сравнению с другими языками нет почти ничего нового. В PostScript файл определяется как конечная последовательность символов, заканчивающаяся маркером "конец файла". Нет разницы между файлом, хранящимся на диске, и файлом, получаемым по линии связи или генерируемым "на лету" каким-либо приложением. Различаются входные (input) и выходные (output) файлы. Входные файлы служат для интерпретатора PostScript источником исполняемых программ и они могут им читаться как последовательность символов. При этом входной файл может быть закрыт явно с помощью оператора closefile, либо неявно – при достижении маркера конца файла. Файл – это один из объектов языка. Объект такого типа создаётся с помощью оператора file. По существу это обычное открытие файла. Кстати, существует ограничение на число одновременно открытых файлов (зависит от ОС).

Синтаксис: имя_файла тип_доступа file файл

Аргумент имя_файла должен соответствовать соглашениям операционной системы, в которой работает интерпретатор. В PostScript существуют предопределённые имена файлов, такие как %stdin и %stdout. Тип_доступа задаётся одной из букв:

'r' – входной файл (только чтение);

'w' – выходной файл (только запись).

Для удобства в языке есть несколько операторов чтения: read, readstring, readhexstring и readline.

Оператор read проверяет есть ли в файле ещё непрочитанные символы. Если нет (конец файла), закрывает файл и возвращает в стеке false. В противном случае читает из файла следующий символ, помещает его в стек, а затем, как признак успешной операции, помещает в стек true.

Синтаксис: файл read байт true 'if not EOF

false 'if EOF

Оператор readline читает из файла последовательность символов, ограниченную символом конца строки, и сохраняет их в аргументе строка (при этом сам терминатор строки туда не записывается). Если строка заполнена раньше, чем встретился символ новой строки, возникает ошибка, которая называется rangecheck. При успешном завершении операции чтения в стеке возвращается также true, иначе – false.

Синтаксис: файл строка readline подстрока true 'if not EOF

false 'if EOF

Так как изображение в PostScript часто кодируется как массив 16-ричных чисел и, если оно достаточно большое, его неудобно держать внутри программы, то считать его из файла поможет специальный оператор – readhexstring.

Он последовательно считывает 16-ричные цифры из файла проверяя их на диапазон 0-9, A-F. Происходит последовательное формирование из двух цифр одного байта и запоминание его в строке. При этом все символы типа пробелов, табуляций и возвратов каретки игнорируются. Чтение заканчивается, когда достигается конец файла. Ограничения на максимальную длину строки накладываются операционной системой. Синтаксис как и у оператора readline.

Такой же синтаксис имеет и оператор readstring. От readline он отличается только тем, что считанные символы рассматриваются как целые числа в диапазоне от 0 до 255. Особо рассматривается только символ новой строки.

Информация о числе байтов, доступных для чтения в файле, возвращается оператором bytesavaiable. Если результат равен -1, достигнут конец файла.

Синтаксис: файл bytesavaiable число_байтов

Оператор currentfile возвращает объект типа file, из которого интерпретатор PostScript читал наиболее недавно.

Синтаксис: - currentfile файл

Обычно возвращается стандартный файл ввода. Если не было чтения из какого-либо файла, то оно производится из файла программы. При этом указатель текущей позиции устанавливается после последнего считанного интерпретатором слова (оператора или элемента данных). Данное свойство используется для того, чтобы поместить в переменные текст или рисунок, находящиеся непосредственно в программе. Это демонстрирует пример, взятый из описания оператора:

/str 128 string def

currentfile str readline

строка, помещаемая в переменную текст

pop /text exch def
Оператор closefile разрывает связь между объектом типа file и соответствующим ему реальным файлом.

Синтаксис: файл closefile -

Наконец, среди операторов ввода-вывода есть ещё ряд вспомогательных и очевидных операторов типа status, flush.
Соглашения по структуре программы
Язык PostScript не определяет общую структуру PostScript-программы, однако существуют некоторые соглашения, облегчающие её структуризацию. Для записи информации о программе используются комментарии специального вида. Такой комментарий занимает строку целиком и начинается не с одного знака процента, а с двух. Специальные комментарии делятся на три группы: заголовочные комментарии (header comments), комментарии тела программы (body comments) и комментарии эпилога(trailer comments).

Заголовочные комментарии предшествуют тексту программы. Комментарии тела программы служат для разделения разных частей описания страницы. Комментарии эпилога следуют после текста программы и дают о ней дополнительную информацию.
Заголовочные комментарии

Некоторые из этих комментариев могут помещаться в конце программы по усмотрению программиста или приложения, генерирующего PostScript-файл.
%%DocumentFonts: шрифт1 шрифт2 ...

где шрифт1 шрифт2 – имена PostScript-шрифтов, используемых в документе. Данная информация может использоваться некоторыми утилитами, загружающими шрифты в принтер до печати документа. Допускается указывать (atend), означающее присутствие, ожидание или что-то в этом роде.

%%Title: текст

задаёт заголовок документа. текст – строка заголовка.

%%Creator: имя_создателя

содержит имя программиста (или программы), породившего данный текст.

%%CreationDate: дата_и_время_создания

%%For: текст

указывает имя персоны, для которой был создан документ. Если комментарий %%For пропущен, подразумевается автор документа, указанный в %%Creator.

%%Pages: страниц

число страниц в документе (неотрицательное целое число), либо слово (atend).

%%BoundingBox: llx lly urx ury

координаты левого нижнего и правого верхнего угла в системе координат пользователя, либо слово (atend).

%%EndComments

завершает секцию заголовочных комментариев.

Пример.

%!PS-Adobe-2.1

%%Creator: Adobe Illustrator(TM) 3.2

%%For: (Eduard Projdakov) (PC Week/RE)

%%Title: (NewPS)

%%CreationDate: (2/10/97) (4:30 PM)

%%BoundingBox: 429 490 495 565

%%Pages: (atend)

%%DocumentFonts: (atend)

%%EndComments
Комментарии тела программы

%%EndProlog

конец секции пролога программы.

%%Page: метка порядковый_номер

где метка – текст с названием страницы, а порядковый_номер – номер страницы в многостраничном документе.

%%PageFonts: шрифт1 шрифт2 ...

задает список шрифтов, используемых для текущей страницы документа.

%%Trailer

отмечает конец тела программы и начало эпилога.
Комментарии эпилога
Эта секция состоит из комментариев типа %%DocumentFonts, %%Pages и %%BoundingBox.
Операторы рисования
В языке PostScript в операторах рисования важно знать когда точка считается внутренней по отношению к текущей траектории (отсечению), а когда – внешней. Есть два правила определения внутренней точки: чётный-нечётный и ненулевого поворота (on-zero winding). Оба правила основываются на подсчете пересечений лучей из проверяемой точки с текущей траекторией.

Метод ненулевого поворота заключается в следующем: из проверяемой точки по всем направлениям рисуются лучи, а затем анализируются места пересечения с сегментом траектории. Начиная со счётчика равного нулю мы добавляем к нему единицу, если луч пересекает траекторию слева направо, вычитаем единицы, если он пересекает её справа налево. Если счётчик равен нулю, точка внешняя, иначе – внутренняя. Правило не определяет, что происходит в случае, если луч проходит по касательной или перпендикулярно к сегменту.

Правило чётный-нечётный отличается от предыдущего тем, что подсчитывается просто число пересечений лучом сегментов траектории. Если число чётное, точка внутри области. Если нечётное – внешняя.

Для простых фигур результат применения каждого из правил совпадает. Различие проявляется на более сложных фигурах.

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

(Замечу, что страница целиком очищается с помощью не имеющего аргументов оператора erasepage, который закрашивает её серым цветом уровня 1, не изменяя состояния графической среды. Этот оператор выполняется также автоматически после оператора showpage.)

Синтаксис: - fill -

Перед рисованием fill явным образом закрывает любые открытые подпути текущей траектории. Для её сохранения следует использовать последовательность операторов gsave fill grestore.

Для заливки области по правилу чётный-нечётный используется оператор eofill. В остальном он полностью идентичен оператору fill.

Задание. Чтобы почувствовать разницу между двумя этими правилами, нарисуйте с помощью PostScript две одинаковых пятиугольных звезды (не убирая внутренние линии) и заполните их внутренние области с помощью операторов fill и eofill соответственно.

Для того, чтобы поместить графическое изображение на страницу, используется оператор image.

Синтаксис:

ширина высота бит/точка матрица процедура image -

Изображение помещается в прямоугольную область размером ширина на высоту точек, каждая из которых представлена значением из бит/точка данных (1, 2, 4 или 8 битов на точку). Данные изображения считываются как последовательность символов, причём, если точка кодируется менее 8 битами, то данные упакованы в байте слева направо.

Изображение на странице имеет свою собственную систему координат, за начало которой (0,0) принят нижний левый угол прямоугольной области изображения, а верхний правый угол имеет координаты (ширина, высота). Операнд матрица задаёт преобразование из пространства пользователя в систему координат изображения.

Последний операнд (процедура) последовательно выполняется оператором image, чтобы получить данные изображения. Обычно эти данные читаются из файла с помощью оператора readhexstring.

<< предыдущая страница   следующая страница >>