Семь уроков по PostScript

         

Оператор ifelse


Позволяет выбрать в зависимости от условия выполнение одной или другой последовательности операторов. Его формат:

условие {op.1} {op>2} ifelse

Если результат выполнения условия true, выполняется последовательность {op.1}, иначе --

{op.2}.

У попа была собака

Эта фраза замечательна тем, что мы с детства получаем представление о рекурсии. PostScript поддерживает рекурсивный  вызов процедур, т. е. когда процедура вызывает сама себя. Классический пример -- вычисление факториала:

/factorial % в стеке n

{dup 1 gt

{ dup 1 sub factorial mul} if

} def

% вызов

5 factorial

cvs show

Новый оператор cvs преобразует число из вершины стека и помещает его в заданную строку. Дело в том, что оператор show может печатать только строки. Кроме чисел, cvs преобразует и логические величины  -- они заменяются в зависимости от значения словами true или false. Вот пример процедуры, печатающей целое число из стека:

/printint

 {(   ) cvs show} def  % строка первоначально содержит 3 пробела

Оператор string создает строку длиной n. Определение строковой переменной

выглядит так:

/nstr 7 string def

где 7 -- длина строки (знаков).

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

Занятие четвёртое

Начиная весной эту серию уроков у меня было сомнение -- хватит ли материала на семь занятий. Задав в Интернет поиск по ключевому слову PostScript и получив сообщение, что найдено более 99 тыс. документов, где оно встречается, я успокоился – об этом языке писать можно до 2000 года. Кроме того, обнаружилась книга по PostScript и на русском языке. Это изданный Физматлитом в 1993 г. учебник: Ф.Доймлинг, Д.Стиллеску "Язык программирования PostScript. 20 уроков быстрого освоения". В ней очень детально описывается то, что нами будет пройдено на четырех первых уроках. Следует отметить, что наши занятия методически следуют книге "PostScript Language Tutorial and Cookbook" (Adobe Systems & Addison Wesley, 1987), являющейся де-факто описанием стандарта языка и потому именуемой "Голубой книгой". Тем у кого это издание есть, я рекомендую подождать седьмого урока, который будет отчасти посвящён текущему состоянию языка, литературе и другим не описанным в "Голубой книге" вопросам.


Ну, а если у вас по ходу чтения уроков возникли вопросы, предложения или пожелания, вы можете связаться с автором по телефону (095)237-8901 или по адресу chief@pcweek.ru.

Циклы

В языке PostScript имеется три основных конструкции циклов: простой цикл, индексируемый цикл и условный цикл.

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

4 {pop} repeat

Здесь всё достаточно прозрачно, непривычно, может быть, только то, что в качестве одного из аргументов выступает повторяемая процедура.

Задание. Нарисуйте последовательность из N вложенных кругов, квадратов, эллипсов.

Индексируемый цикл напоминает широко известную по Бейсику конструкцию for... to... next. Оператор for берет из стека четыре операнда: начальное значение счетчика цикла, его приращение, конечное значение счетчика цикла и повторяемую процедуру. За исключением последнего операнда всё выглядит как и в обычной конструкция for. Следует учитывать, что непосредственно перед выполнением этой процедуры for  помещает в стек  текущее значение счетчика и, если он не используется, то его следует оттуда явным образом удалять.

Следующая строка напечатает звездочку через каждые 15 единиц на странице:

0 15 450 {0 moveto (*) show } for

Задание. Нарисуйте пунктирную линию.

Вторая важная особенность for в том, что его операнды не обязательно должны быть целыми числами. Вот пример использования этого для возможной модификации шрифта:

/Helvetica findfont 30 scalefont setfont

/printword

{ 0 0 moveto (PC Magazine) show} def

200 300 translate

.95 -.05  0  % начало приращения, конец

{setgray printword -1.5 translate} for

1 setgray printword

showpage

<рис. файл p4_1.ps>

Условный цикл соответствует конструкции repeat...until в Паскале. Строится он из двух операторов: loop и exit. Опертор loop повторяет выполнение процедуры до тех пор пока в ней не встретится оператор exit, который заканчивает циклическое выполнение, причем не только в конструкции loop, но и в for, repeat и forall (об этой специальной форме цикла будет расказано ниже). Если в повторяемой процедуре нет оператора exit, то цикл будет бесконечным, например:

{(PC Magazine) show} loop

будет бесконечно печатать слово PC Magazine.

Нарисуем незамысловатую последовательность кругов просто, чтобы продемонстрировать работу loop - exit.

/pagewidth 8 72 mul def

/circle

{x y radius 0 360 arc stroke} def

/new-x

{x radius add

/x exch def} def

/dolineofcrle

{/y exch def

/radius exch def

/x 0 def

{x pagewidth le

 {circle new-x}

 {exit} ifelse

} loop

} def

% main

15 200 dolineofcrle

25 200 dolineofcrle

showpage


Содержание раздела