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

Контуры символов


Напомню, что по способу представления в компьютере шрифты делятся на векторные и растровые. Каждый словарь шрифта в PostScript содержит описание вида входящих в данный шрифт символов. В большинстве шрифтов символы описываются контуром (представленным в виде векторов), который заполняется каким-либо цветом при печати конкретного символа. Растровые шрифты описывают символы как линии, которые должны быть начерчены или как битовую карту.

<картинка с контурами букв>

Контурное или линейное описания символа могут быть непосредственно использованы в операторе charpath. Вместо рисования траектории оператор charpath добавляет её к текущей пути. Это позволяет производить над результатом различные операции заполнения отсечения и т.д. Он берет из стека строку и логическое выражение и добавляет к текущему пути контур символа, который описан в данной строке. Логическое выражение определяет тип оставляемого контура т.е. что произойдёт, если траектория символа предназначена для штриховки, а не для заполнения или оконтуривания. Если значение операнда false, то charpath просто добавляет траекторию символа, которая точно отображает описание символа в словаре шрифта, к текущему пути (результат удобный только для штрихового заполнения). Если операнд true, то charpath применяет к траектории символа оператор strokepath и полученный результат можно использовать для заливки каким-либо цветом (но не для штриховки). Если все символы шрифта будут заливаться, то разницы не видно. Оператор charpath не работает с теми частями символа, которые определенны как изображения или маски не являющиеся траекториями.

Например:

(B) false charpath

(B) true charpath

< 2 картинки>

Следует учесть, что контуры некоторых шрифтов защищены. в реализации языка PostScript Level 1 это относится ко всем шрифтам, в PostScript Level 2 – только некоторых специальных шрифтов и не относится к обычным шрифтам Type 1 или Type 3. Если текущий шрифт защищён, использование charpath, чтобы получить их контуры, вызывает блокирование работы операторов pathforall и upath до тех пор пока контуры символов из такого шрифта остаются в текущей траектории.

Путь построенный с помощью charpath может быть вычерчен либо заполнен (залит).

Пример использования тривиальная рекламная виньетка с названием вашей фирмы. Для этого поэспериментируйте с текстом этой процедуры.
% Їа®жҐ¤гал

/Helvetica-Bold findfont

24 scalefont setfont

/oshow % б⥪Ґ (бва®Є )

{true charpath stroke} def

/CircleName

{30 30 360

{gsave

rotate 0 0 moveto

( PC Magazine) oshow

grestore

} for

} def

%

150 350 translate

.3 setlinewidth

CircleName

gsave 0.8 setgray fill grestore

stroke

showpage
<сюда вставить рис. после выполнения>

Траектория отсечения


В графическом состоянии PostScript имеется траектория отсечения

(clipping path), представляющая собой границы области на текущей странице, в которой изображения могут быть нарисованы. Первоначально этот путь совпадал с углами бумаги, используемой принтером. Текущая траектория отсечения может быть изменена с помощью оператора clip. Этот оператор делает текущую траекторию траекторией отсечения. Все последующие "рисующие" операторы будут отсекаться, если изображение выходит за границы траектории отсечения.

Например, следующая программа конструирует траекторию в виде треугольника и делает его траекторией отсечения. Затем она рисует прямоугольную сетку и после печати мы видим, что осталось только та часть сетки, которая попала в этот прямоугольник.
/triangle

/inch {72 mul} def

{newpath

0 0 moveto

2 inch 0 lineto

1 inch 2.8 inch lineto

closepath} def

/vgrid

{newpath

0 9 2 inch

{0 moveto

0 3 inch rlineto} for

stroke} def

/hgrid

{newpath

0 10 2.8 inch

{0 exch moveto

2 inch 0 rlineto} for

stroke} def

% main program

200 300 translate

triangle clip

vgrid

hgrid

showpage
<сюда вставить после выполнения>
В качестве отсекающих границ может быть использован любая траектория, включая и след символа, оставляемый оператором сharpath.
Урок шестой
Начать это занятие, наверное, нужно с извинений. В тексте предыдущего урока (см. №12/1996) по техническим причинам во всех строчках с описанием синтаксиса операторов PostScript вместо правой стрелки (), показывающей результат операции, напечатан символ “n”. Сделайте, пожалуйста, авторучкой замену.
Встраивание PostScript-программ в документы
Так как в России наиболее широко для издательской подготовки текстов и даже для вёрстки используется Word для Windows, то следующей вопрос, который требует пояснения, – как встроить программу на PostScript в документ Word. Дело в том, что Word имеет собственный формат файлов, а программа на PostScript – это обычный ASCII-текст. Разработчики решили эту задачу просто: они оставили для таких случаев лазейку, которая называется поле print. Напомню, что полями в Word называются специальные команды редактора, заключённые в фигурные скобки. Поле print предназначено для того, чтобы выводить символы непосредственно на принтер (например, команды прямого управления принтером, команды на языке PCL и, конечно, PostSript-программы). Формат поля:

{print \p Size “текст”}

Ключ \p указывает, что в поле текст будет записана PostSript-программа. Операторы PostScript, заданные в этом поле, могут работать только в окне рисования, определённом атрибутом Size, значения которого приведены в таблице.


Аргумент

Значение

page

Рисунок на всей текущей странице (по умолчанию)

para

В пределах абзаца (высотой не менее дюйма), содержащего поле print

pic

Рисунок располагается после поля print и до конца абзаца, содержащего это поле

row

Рисунок в текущей строке таблицы

cell

Рисунок в текущем элементе таблицы

Dict

Используется для создания определений и процедур на PostScript, которые будут выполнены позже на той же самой странице. Поэтому dict не следует использовать для рисования.


Так как текст и графика документа Word печатаются на той же PostScript-странице, что и результат PostScript-программы, не следует использовать операторы, которые изменяют или сбрасывают среду PostScript, а именно, избегайте операторов: banddevice, copypage, framedevice, grestoreall, initgraphics, initmatrix, nulldevice, renderbands и showpage.

При работе с PostScript в Word вам доступны переменные, которые я свёл в следующую таблицу. Значения, представленные этими переменными, даны в пунктах.


Size

Переменная

Описание

Для всех аргументов

wp$x
wp$y
wp$page

wp$fpage
wp$date

wp$time

wp$box

Ширина прямоугольника рисования для заданного аргумента Size

Высота прямоугольника рисования для заданного аргумента Size

Текущий номер страницы

Отформатированный номер страницы (строка)

Текущая дата (строка)

Текущая дата (строка)

Путь, содержащий прямоугольник рисования

page, para

wp$top
wp$bottom
wp$left
wp$right

Верхняя граница (page); расстояние до (para)

нижняя граница (page); расстояние после (para)

Левая граница (page); левый отступ (para)

Правая граница (page); правый отступ (para)

page

wp$col


wp$colx

wp$colxb

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

Ширина каждого столбца

Расстояние между столбцами

para

wp$first

wp$style

Отступ до первой строки

Стиль


Пример.

{print \p page "/Times-Roman findfont strsize scalefont 0.8 setgray" }
Ещё о типах данных

Все данные, доступные PostScript-программам, существуют в виде объектов. Объекты делятся на простые, не имеющие внутренней структуры, и сложные (или составные). К последним относятся строки, массивы и словари.

Говоря о строках в PostScript, следует отметить, что в нём, как и в языке Си, есть возможность с помощью обратной косой черты и следующего за ним символа задавать специальные и управляющие символы. Вот ещё одна полезная таблица с такими комбинациями знаков.

\n новая строка

\r возврат каретки

\t табуляция

\b возврат на позицию

\f перевод формата

\\ обратная косая черта

\( левая скобка

\) правая скобка

\ddd символ с восьмеричным кодом ddd

Если за \ следует символ, не перечисленный выше, то и он, и обратная косая черта игнорируются. Следующие две строки одинаковы:

(Строка с символом перевода строки.



(Строка с символом перевода строки.\n)

Ещё один тип данных, о котором мы почти не говорили, – словари. Словарь – это ассоциативная таблица, элементы которой – пары PostScript-объектов. Первый элемент пары называется ключом, а второй – значением.

Обычно в качестве ключей используются имена объектов, а в качестве значений – переменные и процедуры. В частности, шрифты в PostScript также задаются словарями: именам символов соответствуют процедуры рисования образов этих символов. Есть и другие примеры использования словарей. В языке есть операторы, которые ищут ключ и выбирают соответствующее ему значение, вставляют пару ключ--значение в словарь и выполняют некоторые другие действия.

Для работы со словарями в языке имеется специальный стек. Словарь, находящийся в вершине этого стека, называется текущим словарём. Обычно, встречая имя объекта в выполняемой программе, интерпретатор обращается с ним к текущему словарю. Если он не находит там это имя, он обращается к словарю, расположенному в стеке словарей вслед за текущим, и так далее, пока не будут просмотрены все словари в стеке.

В интерпретаторе имеется два встроенных словаря, называющихся systemdict и userdict (в PostScript Level 2 к ним добавился ещё один словарь – globaldict). Первый из них связывает (ассоциирует) имена всех операторов языка с их значениями (т. е. действиями, которые выполняются самим интерпретатором). Второй словарь предназначен для связи имён переменных среды с их значениями. Оба встроенных словаря находятся внизу стека (userdict над systemdict) и не могут быть из него удалены.
Операторы для работы со словарями
Создать пустой словарь ёмкостью N элементов можно с помощью оператора dict. Его синтаксис:

число_элементов dict словарь

Этот пустой словарь помещается в стек операндов. Аргумент число_элементов не может быть отрицательным.

Оператор currentdict выполняет обратное действие – помещает копию текущего словаря в стек операндов.

Синтаксис: - currentdict словарь

Оператор countdictstack пересчитывает число словарей, находящихся в стеке словарей, и помещает это число в стек операндов.
Синтаксис: - countdictstack int
Оператор cleardictstack извлекает из стека все словари, кроме постоянных.

Синтаксис: - cleardictstack -
Для замены или внесения нового элемента в словарь используется оператор put. На самом деле этот оператор полиморфен и позволяет также заменять элементы массивов и строк.

Синтаксис:

массив индекс значение put -

словарь ключ значение put -

строка индекс целое put -
Если первый операнд массив или строка, то второй рассматривается как индекс, значение которого лежит в диапазоне от 0 до n-1 (где n – длина строки или массива). Элемент с этим индексом замещается третьим операндом.

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

Пример.

/mydict 10 dict def

mydict /A 65 put

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

Синтаксис:

массив индекс put значение

словарь ключ put значение

строка индекс put целое

Пример.

/abc [1 2 3] def

currentdict /abc get [1 2 3]

Со словарём очень интересно работает также оператор forall. Ранее его действие рассматривалось только по отношению к массиву, но он, как и два предыдущих оператора, работает и со словарями, и со строками.

Синтаксис:

массив proc forall -

словарь proc forall -

строка proc forall -
Если первый операнд — словарь, то forall помещает ключ и значение в стек операндов и выполняет заданную процедуру (proc) над каждой парой ключ--значение в словаре. Если процедура пустая "{}", то таким образом все пары из словаря просто переписываются в стек операндов.
Объекты типа operator
Этот несколько необычный для языков программирования тип объектов в PostScript означает одно из встроенных в язык действий, вызываемое при исполнении объекта. Операторы имеют имена, большинство из которых хранится в systemdict в качестве ключей, а значением является программа, реализующая семантику данного оператора.

Другие типы объектов (name, file, mark, null, save, fontID), которые не были рассмотрены до сих пор, мы изучим в разделах, с ними непосредственно связанных. Но вот что важно для объектов всех типов: каждый объект кроме типа и значения имеет один или несколько атрибутов, которые влияют на поведении объекта при его исполнении или когда над ним выполняются определённые операции (кроме случая, когда объект рассматривается только как данные).
Атрибуты объекта
Каждый объект либо литерал (literal), либо исполняемый(executable). Это важно для интерпретатора при исполнении PostScript-программы. Отметим, что при такие операторы, как "[" и "]" создают литеральные объекты, а операторы "{" и "}" – исполняемые. Другим атрибутом объекта является тип доступа (access) к нему. Имеется четыре типа доступа (расположены в списке по возрастанию ограничений): неограниченный (unlimited), только чтение (read only), только исполнение (execute-only) и без доступа (none).

Как правило, объект имеет неограниченный доступ. Это означает, что допускается применение к нему всех операторов, какие определены для работы с ним. Объекты с атрибутом "только чтение" не допускают модификацию своего значения и могут быть только считаны или выполнены. Аналогично, атрибут "только исполнение" определяет, что объект не может быть прочитан, а только исполнен интерпретатором. И наконец, объекты с атрибутом "без доступа" служат для каких-то внутренних целей, о которых я в данный момент ничего не знаю. Понятно, что они не используются программами напрямую. Для получения типа объекта служит оператор type.

Синтаксис: объект type имя_типа

Результатом операции может быть одно из перечисленных имен:

arraytype booleantype dicttype

filetype fonttype integertype

marktype nametype nulltype

operatortype realtype savetype

stringtype
Следующие три оператора проверяют соответственно тип доступа объекта: wcheck - возвращает true, если объект имеет атрибут ulimited; xcheck – возвращает true, если объект исполняемый, и false, если литерал; rcheck – возвращает true, если объект "только для чтения".

Синтаксис у них одинаковый. Например, для wcheck он выглядит так:

объект wcheck лог_значение
Операторы cvlit и cvx позволяют изменить атрибут объекта, находящегося в вершине стека операндов, с исполняемого на литеральный и наоборот.

Синтаксис: объект cvlit объект

объект cvx объект

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