PostScript является примером языка, в котором мощные графические средства встроены в рамки легко расширяемого интерпретируемого языка программирования с простым синтаксисом, универсальной моделью данных и широким спектром возможностей для управления выполнением программ.
Появление языка PostScript (1982 год) было вызвано потребностью в средствах описания процессов автоматического синтеза двумерных текстово-графических изображений на растровых устройствах вывода информации. В таком качестве он получил достаточно широкое признание. Целый ряд принтеров аппаратно интерпретируют описания документов на языке PostScript.
Модель синтеза изображений
Успех PostScript во многом был предопределен свойствами принятой за основу модели синтеза изображений (imaging model). В основе лежит stencil/paint-модель, что можно перевести как "раскраска через трафарет". Под трафаретом (stencil) здесь понимается некоторый контур, специфицируемый бесконечно тонкой границей, составленной из гладких кривых в непрерывном координатном пространстве. Раскраска (paint) - это нанесение либо краски одного цвета, либо любого изображения на поверхность отображения. Предполагается, что эта операция всегда выполняется через трафарет.
Такая модель полна, поскольку и линии и текстовые символы могут быть определены через трафареты. Она проста для понимания вследствие удачного выбора метафоры. За счет абстрактности модели синтеза изображений PostScript приобрел свойство независимости от характеристик устройств отображения.
PostScript-программист выражает процесс построения желаемой картины с помощью графических примитивов (операторов языка).
Трафарет в языке PostScript специфицируется произвольными комбинациями векторов, дуг и кривых высокого порядка с помощью операторов конструирования траекторий (path construction operators). Траектории определяются в терминах точек, специфицируемых координатами на так называемых страницах (pages). По умолчанию используется координатная система PostScript, которая может быть изменена операторами линейных трансформаций координатного пространства (coordinates system operators), выполняющими сдвиг начала координат, изменение масштаба, вращение. Построение изображений на странице осуществляется операторами раскраски (painting operators). Построенная страница воспроизводится на устройстве отображения оператором showpage.
Операторы PostScript, как правило, требуют несколько аргументов, часть из них задается явно, другие же - неявно, как побочный эффект ранее выполненных операторов установки графического состояния (graphics state operators). Среди таких неявных аргументов наиболее существенными являются current page (текущая страница), current path (определяет текущий трафарет), current clipping path (определяет границу рабочей области текущей страницы), current transformation matrix (матрица, задающая отображение координатного пространства пользователя в координатное пространство устройства отображения), current font (текущий фонт, определяющий графические представления текстовых символов). Кроме того, в графическое состояние входят текущее значение цвета, толщина линий, текущее положение в координатном пространстве и других. В языке предусмотрены операторы для сохранения и восстановления графических состояний.
Учитывая специфику структур данных и механизмов работы с описаниями символов и фонтов, соответствующие операторы выделены в PostScript в отдельную группу (character and font operators). Эти операторы позволяют описывать, выбирать и модифицировать фонты.
Для полноты представления о графических возможностях PostScript перечислим основные операторы из группы painting-операторов: fill (закрашивает область страницы, задаваемую текущей траекторией), stroke (вырисовывает линию по текущей траектории), show (специальный оператор для вывода изображения символа из текущего фонта), image (помещает на текущую страницу дискретное изображение, полученное либо из внешнего источника, либо синтезированного программно), imagemask (получает изображение аналогично image, но использует его как маску для закраски текущим цветом).
Характеристика синтаксиса и модели вычислений
Синтаксис этого языка очень похож на синтаксис языка Forth. Выражения языка записываются в постфиксной нотации, в которой операнды предшествуют операторам. PostScript содержит большое число встроенных операторов, но имена их не зарезервированы и могут быть переопределены программистом. Количество специальных символов очень мало.
К отличительной особенности PostScript относится отсутствие какого-либо синтаксического оформления понятия программы. PostScript-интерпретатор не считывает программу целиком перед ее выполнением, а обрабатывает ее последовательно. Из последовательности символов текстового представления программы (входного потока) по синтаксическим правилам формируются лексемы (tokens), из одной или более лексем создается PostScript-объект (значение данных в памяти интерпретатора) и затем этот объект сразу выполняется. Далее этот процесс повторяется до конца входного потока. При этом, конечно, выполнение программы может иметь побочные эффекты. В частности, они могут выражаться в создании процедурных объектов в памяти интерпретатора, предназначенных для последующих вызовов.
Модель данных языка включает в себя обычный набор типов данных (числа, строки, массивы, булевы значения, файлы). Одним из основных понятий PostScript является "словарь" (dictionary) - ассоциативная таблица, к элементам которой относятся пары "имя - значение". Наряду с перечисленными типами объектами манипуляций и передач в PostScript-программе могут быть и те элементы, которые обычно рассматриваются как элементы программ (имена, операторы, процедуры). В этом языке любой объект может трактоваться как данные и может быть выполнен как часть программы. За счет этого PostScript приобрел свойства, характерные для языков программирования символьных вычислений, таких, как ЛИСП.
Каждый PostScrip-объект имеет скрытую структуру из трех элементов: тип, атрибуты (литеральный/выполнимый, право доступа) и значение. Эти элементы объекта относительно независимы. Например, два объекта могут иметь один и тот же тип, разделять одно назначение, но иметь разные значения атрибутов). Текущее состояние элементов объекта определяет семантику его выполнения.
В основу модели вычислений языка PostScript положены принципы вычислений на стеках. Для представления состояния выполнения программ PostScript-интерпретатор использует четыре различных стека - стек операндов (operand stack), стек словарей (dictionary stack), стек вызовов (execution stack) и стек графических состояний (graphics state stack).
Стек операндов используется для передачи операндов PostScript-операторам и для размещения результатов выполнения операторов. На этот стек могут быть положены любые PostScript-объекты. Контроль типов операндов осуществляется динамически для всех встроенных операторов.
Стек словарей определяет текущий контекст для неявного поиска значений выполнимых имен. Поиск ведется сверху вниз по всем словарям стека до первого определения данного имени. Таким образом, на основе стека словарей реализуется модель динамического связывания имен и значений.
Верхний элемент стека словарей называется текущим словарем (current dictionary). Как правило, именно в этот словарь помещаются определения имен (пары "имя - значение") в ходе выполнения программы. Однако есть возможности для размещения новых определений в словари непосредственно через их имена. Указанные возможности задания новых определений и переопределения ранее установленных значений, а также операторы изменения стека словарей делают PostScript легко расширяемым языком, а PostScript-программы - очень гибкими.
На стеке вызовов сохраняются выполнимые объекты (процедуры и файлы). Когда интерпретатор прерывает выполнение одного объекта для выполнения другого, то он кладет прерванный объект на этот стек, а когда завершает выполнение объекта, то снимает верхний объект со стека и продолжает его выполнение.
Как должно быть ясно из сказанного, графическое состояние имеет сложную структуру, состоящую из множества объектов. Текущие значения этих объектов определяют контекст выполнения графических операторов в текущей точке выполнения программы. PostScript-программа может сохранять и восстанавливать графические состояния с помощью двух операторов - gsave и grestore. Для этого и используется стек графических состояний.
Упомянутые стеки полностью независимы, и доступ к ним осуществляется различными средствами. Стек операндов и стек словарей управляются непосредственно выполняемой программой. Наоборот, стеком вызовов полностью управляет интерпретатор, а из программы он может только читаться, но не модифицироваться. Доступ к этим стекам и стеку графических состояний поддерживается соответствующими операторами языка.
В целом возможности PostScript как языка общего назначения определяются семантикой встроенных операторов следующих типов:
- Операторы манипулирования стеком операндов.
- Операторы для работы со словарями и стеком словарей.
- Операторы манипулирования строками и массивами.
- Арифметические и математические операторы.
- Операторы сравнения и логические операторы.
- Операторы изменения и анализа атрибутов, приведения типов объектов.
- Операторы управления вычислениями.
- Операторы доступа к файлам.
Программа рисования дерева, изображенного на рисунке и построенного при
помощи ALG-систем, написана на языке PostScript.
//Вычислительная техника и ее применение, N6'91.