содержание   назад


Виктор Кон,   Постскрипт: инструкция к применению

9. Готовые программы с параметрами и другие методы

В языке Постскрипт нет средств создания интерфейса с пользователем, поэтому написать программу в оконном варианте невозможно. Язык создавался в то время, когда таких возможностей просто не было. Однако это все равно не мешает писать готовые программы с параметрами, а в качестве интерфейса можно использовать окно любого текстового редактора и командные файлы операционной системы. Такой режим работы можно еще назвать созданием графики по шаблонам. Что для этого надо делать.
(1) открыть текстовый редактор с файлом шаблона
(2) спасти текст в файл с другим (новым) именем, чтобы не испортить шаблон
(3) отредактировать текст в тех местах, где записаны параметры
(4) Открыть программу GsView с указанным файлом, посмотреть что получилось.
(5) Если что-то неправильно или некрасиво, то исправить, спасти в файл исправления и снова посмотреть, программа GsView все изменения отслеживает в реальном времени и сразу показывает новый рисунок. Но если этого не произошло, то есть кнопка Меню (View/Redisplay) по которой рисунок переделывается с новым содержанием файла.

Вот и все. Когда рисунок удовлетворяет вас по всем пунктам можно считать работу законченной. Шаблоны указанного типа прежде всего удобно создавать для рисунков научной графики. Ниже рассмотрены некоторые из них.
.
.

9.1. Шаблон графика 1D зависимостей внутри осей координат

Для удобства работы шаблон разбит на две части, записанные в два файла. Оба файла находятся в zip архиве, скачать который можно по этой ссылке . Файл [ps-proc.txt] содержит готовые процедуры на языке постскрипт, изучать которые не обязательно. Достаточно только знать как ими пользоваться. Все эти процедуры описаны в данной книге в предыдущих главах. Если кому интересно, то можно все изучить. Основной файл шаблона [figure.eps] подключает этот файл с помощью команды run. Это вполне удобно и работает с версией интерпретатора Gstools (5.50, 2.6). Ссылка на скачивание этой программы стоит в самом начале этой книги. Однако, если посылать файл в редакцию научного журнала, то вместо этой команды следует скопировать в eps файл содержимое указанного выше файла [ps-proc.txt], потому что редакции требуют рисунки в виде одного файла.

Я буду считать, что читатель скачал файлы и открыл их в отдельном окне текстового редактора. Можно использовать любой текстовый редактор, но лучше какой-либо из более продвинутых, чем стандартный Notepad. Вот ссылка на сайт моего текстового редактора . У него есть очень много полезных функций, в том числе, проверка правописания, исправление неправильной раскладки клавиатуры, графика, расчеты и много всего еще. Этот редактор также существует как модуль в более общей программе vkACL, вот ссылка на ее сайт . Итак, открываем текст файла [figure.eps] в текстовом редакторе и смотрим что там написано. Текст очень небольшой. В первой строке стоит указание на формат рисунка. Это просто комментарий, но он необходим. Во второй строке стоит еще один комментарий, который, однако, имеет важное значение для программы Gstools, потому что там указаны 4 числа -- координаты левого нижнего и правого верхнего углов области в единицах pt = 0.353 мм, которую программа и будет показывать в режиме "EPS Clip".

Эта строка также нужна для программы компилятора pdf файла из Latex файла, то есть при создании научной статьи на языке Latex. В журналах IUCr (международного общества кристаллографов, то есть Acta Cryst., J. Synchr. Rad.) eps файлы используются без масштабирования, то есть нужно явно указывать тот размер, который и будет поставлен. Для вставки рисунка в одну колонку стандартный размер по ширине 240. А размер по высоте зависит от содержимого рисунка. На самом деле масштабировать можно, но проще масштабировать сам eps рисунок в eps файле. В третьей строке стоит указанная выше команда run, которая вставляет содержимое файла, имя которого находится в круглых скобках перед ней, вместо самой команды.

Далее через пустую строку записаны два блока команд, которые очень похожи, и отличаются только значениями чисел -- аргументов команд. Достаточно разобрать один блок, чтобы понять как это работает. Я напомню, что в постскрипте аргументы команды пишутся перед именем команды и никак не выделяются. Сами команды могут быть как без аргументов, так и с очень большим числом аргументов. Итак начинаем разбор.

Команда gs (graph save) без аргументов запоминает текущие параметры рисования. Команда slw (set line width) с одним аргументом устанавливает ширину линий при рисовании линий в единицах pt. Сразу скажу, что все размеры на графике измеряются в этих единицах и больше я об этом писать не буду. Команда srgb (set rgb) с 3 аргументами устанавливает цвет линий как комбинацию красного, зеленого и синего. Интервал изменений от 0 (нет) до 1 (максимум). Команда tr (translate) с двумя аргументами устанавливает перемещение всех координат рисунка на указанные отрезки по x и y осям. Это общие команды графики, применимые ко всем объектам на рисунке.

Далее следуют конкретные команды рисования научного графика. Первая команда par имеет 9 аргументов и задает общие параметры графика. Для удобства каждый параметр описан на отдельной строке с номером
1.  длина горизонтальной оси в единицах pt
2.  длина вертикальной оси в единицах pt
3.  длина коротких рисок на осях в единицах pt
4.  длина длинных рисок на осях в единицах pt
5.  размер текста для написания чисел при длинных рисках в единицах pt
6.  значение аргумента на левом конце горизонтальной оси в физических единицах
7.  значение аргумента на правом конце горизонтальной оси в физических единицах
8.  значение функции на нижнем конце вертикальной оси в физических единицах
9.  значение функции на верхнем конце вертикальной оси в физических единицах

Следующая команда parx дополнительно задает параметры горизонтальной оси. Их три. Первый параметр указывает значение, соответствующее первой длинной риске в физических единицах, второй -- интервал значений между двумя длинными рисками, третий -- число коротких рисок между длинными. Эти две команды надо писать перед тем как рисовать сами оси. Далее команда axx без аргументов просто рисует нижнюю горизонтальную ось, а команда axx1 тоже без аргументов рисует верхнюю горизонтальную ось. Удобство такой конфигурации команд в том, что если какую-то ось не надо рисовать, то просто не пишем команду рисования и все.

Далее, команда parf с 3 аргументами задает дополнительные параметры рисования вертикальной оси аналогично команде parx. Затем команда axf рисует левую вертикальную ось, а команда axf1 рисует правую вертикальную ось. Оси нарисованы, осталось начертить кривые значений функций внутри этих осей. Каждую кривую рисует команда figl, которая может иметь очень много аргументов в виде чисел. Более того, перед вызовом этой команды можно снова запустить команду slw и переопределить толщину линий. Также точно командой srgb можно переопределить цвет линий. В указанном примере рисуются две кривые и перед ними один раз переопределяется толщина линий.

Рассмотрим как надо записывать аргументы этой команды. Пусть вам известны N точек кривой с постоянным шагом изменения аргумента. Только такой случай и предполагается. Тогда сначала записываются эти N значений. В указанном примере N = 16. Записывать числа можно в любой нормировке, желательно целыми числами для уменьшения размера файла. Вместо самих чисел при отладке можно указать имя файла командой run, в котором эти числа будут записаны, если их слишком много. Но в окончательном варианте все команды run нужно убрать и заменить их на содержание файлов. После всех значений функции (на отдельной строке для удобства чтения, хотя это не обязательно) нужно записать еще 4 аргумента. Они имеют такой смысл
1. Значение аргумента у первого значения функции
2. Значение аргумента у последнего значения функции
3. Число точек на кривой, то есть число значений функции
4. Множитель, на который надо умножить все значения функции до рисования.
Множитель должен быть таким, чтобы все значения находились в интервале разметки вертикальной оси. Как раз этот множитель позволяет записывать все значения как целые, а потом получить те значения, какие есть на самом деле.

Последняя команда gr (graph restore) восстанавливает те значения графики, которые были сохранены командой gs. Это касается толщины линий, цвета, смещений, вращений и других аналогичных параметров. Таким же точно способом рисуется второй график. Но если первый график смещается вверх на 150, то второй -- на 40. И таким образом первый график оказывается над вторым.

Далее в тексте идут команды рисования текстов как около осей графика, так и на самом графике. Эти команды общие для всех постскрипт рисунков, и они частично описаны в книге, в рпедыдущих главах. Общий принцип таких команд простой. Команда m с двумя аргументами задает координаты текста на рисунке. Команды L, Lc, Le, B, Bc, I, G, H с одним аргументом в виде текста в круглых скобках рисуют этот текст разными шрифтами и с разным положением. Удобно указать их в таблице
L == шрифт Palatino-Roman, текст справа от указанной точки
Lс == шрифт Palatino-Roman, указанная точка в центре текста
Le == шрифт Palatino-Roman, текст слева от указанной точки
B == шрифт Palatino-Bold, жирный текст справа от указанной точки
Bc == шрифт Palatino-Bold, указанная точка в центре жирного текста
I == шрифт Palatino-Italic, наклонный текст справа от указанной точки
G == шрифт Symbol, текст справа от указанной точки
H == шрифт Helvetica, текст справа от указанной точки
Можно приготовить еще больше команд для других шрифтов и других расположений текста, но обычно этих команд вполне хватает для графика. Все шрифты, кроме G, рисуют латинские буквы, а шрифт G может рисовать греческие буквы и специальные символы, хотя они все равно в тексте задаются латинскими буквами. Таблицу соответствия можно выяснить эмпирическим путем. Для этого достаточно нарисовать одинаковые символы в разных шрифтах.

Что касается русских шрифтов, то их в постскрипте нет, точнее не так, они есть, но программа Gstools (5.50, 2.6) их автоматически не понимает. Как работать с русскими текстами написано в книге ранее, и я не буду здесь это переписывать. Для научной графики вполне можно обойтись и без русских текстов. Текст рисуется слева направо и сдвиг курсора происходит автоматически после рисования каждой буквы. После указанных команд можно также писать команды ib или it. Тогда текст перед ними в круглых скобках будет нарисован как нижний или верхний индекс к предыдущему тексту. Что касается размера шрифта, то автоматически предполагается размер 12pt. Если нужен другой размер, то есть два способа.

Первый способ состоит в том, что перед рисованием текста можно указать любую из 5 команд масштабирования, которые имеют имена is1, is2, is3, is4, is5. Эти команды будут увеличивать текст с множителями 1.25, 1.5625, 2, 3.125, 4. После рисования текста масштабирование можно вернуть на место командами ds1, ds2, ds3, ds4, ds5. Каким номером был увеличен текст, таким же номером его надо и уменьшить. Или наоборот, можно сначала уменьшить, а потом увеличить. Использование одного и того же номера гарантирует полное восстановление режима масштабирования.

Второй способ использован в примере. Дело в том, что размер шрифтов в указанных выше командах задается переменной FS. Исходно она определена как 12. Но ее можно переопределить в любое время вот таким текстом /FS 10 def . Это уже чистый постскрипт, команда определения констант. После нее все указанные команды будут рисовать размером 10 pt вместо исходных 12 pt. Такой способ позволяет менять размер шрифтов произвольным образом и много раз в процессе рисования рисунка.

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

Теперь обсудим то, чего на рисунке нет. Рассмотренный пример не показывает всех возможностей графиков. Дело в том, что тут команда axx рисует нижнюю горизонтальную ось с рисками и числами, а команда axx1 рисует верхнюю горизонтальную ось без чисел. Иногда бывает так, что надо наоборот. Для этого есть команда axx0, которая рисует нижнюю горизонтальную ось без чисел, и команда axx2, которая рисует верхнюю горизонтальную ось с числами. Аналогично есть команды axf0 и axf2 для вертикальных осей.

Более того, есть команды рисования логарифмических осей axlx и axlf по горизонтали и по вертикали. Если очень надо, то смотрите описание этих команд в предыдущих главах книги. Но я попробовал такие оси, и мне не понравилось. Проще написать, что рисуется логарифм и дать нормальные оси. Наконец, функции можно рисовать не только линиями, но и маркерами. Для этого есть команда figm, которая по структуре своих аргументов полностью аналогична команде figl, но использует команду mark, которую можно переопределить, если стандартные маркеры, заданные этой командой, не устраивают. Она имеет два аргумента -- координаты точки на графике.

Если захочется рисовать на графике отрезок прямой линии, то можно использовать команду ls, которая имеет 4 аргумента, координаты начала и конца линии. Ломаную линию из многих отрезков можно нарисовать командами m -- один раз, начало, два аргумента, координаты, l -- много раз, координаты второй, третьей и остальных точек, и sl -- один раз, указание на то, что линия закончена и ее можно рисовать. Вместо команды l можно использовать команду rl. Ее аргументами должны быть не абсолютные координаты точки, а разность координат данной точки и предыдущей точки. Иногда задавать такие разности более удобно. Есть команда, которая рисует головку стрелки Arr, она имеет 4 аргумента, координаты точки вершины, угол вращения и масштабирование. Какие значения нужно задавать можно узнать эмпирическим путем. Саму стрелку надо рисовать в два приема, отдельно линию, отдельно головку или две головки, если необходимо.

Для данного шаблона вполне достаточно текстового редактора. Тем не менее, в программе vkACL, которую я указал выше, есть таблица кнопок для вызова готовых ACL программ, и среди них есть кнопка (TDP eps). При запуске этой программы в 8-й строчке меню можно приготовить такой рисунок с обслуживанием. То есть редактор сам откроется и после редактирования 4 строк eps файл будет создан автоматическим. Иногда это упрощает и ускоряет работу.
.
.

9.2. Шаблон карты 2D зависимости (функции двух переменных) на осях координат

Данный шаблон показывает eps картинку, копию которой в png формате можно видеть справа от этого текста. То есть тут функция двух аргументов показана черно-белым контрастом (картинкой) внутри осей координат, а третья ось -- значений функции наложена на карту цветов (в данном случае монохромную), но это не обязательно. При этом третья ось показывает стандартный интервал (0, 1), в то время как реальная функция может иметь любые значения минимума и максимума, но эти значения можно указать в подписи к рисунку. Просто часто значения могут быть или очень большими или очень маленькими и их неудобно показывать на графике.

Шаблон снова представляет собой набор файлов, записанных в архив, скачать который можно по этой ссылке . При этом файл [ps-proc.txt] содержит готовые процедуры на языке постскрипт, изучать которые не обязательно. Это тот же самый файл, что и в предыдущем разделе 9.1. В нем содержатся все необходимые процедуры, в том числе и для рисования осей. Сам шаблон -- это файл (figmap.eps). Вот его мы сейчас и рассмотрим.

Первые три строки файла -- те же самые, что и в предыдущем примере. Во второй строке нужно указать размеры рисунка в единицах pt. Третья строка указывает на файл. Если это требуют, то все таки ссылки на файлы надо заменить на содержимое этих файлов. Далее, через пустую строку записываются 19 чисел и две команды языка постскрипт. Это и есть входные данные рисунка. Эти числа можно сгруппировать в группы из 4, 5, 5, 5 чисел. Первая группа чисел условно имеет названия Xi, Yi, Sc, Sx. Числа Xi, Yi указывают на X и Y размеры рисунка самой карты 2D зависимости. Число Sc -- это отступ шкалы цветов от левого края рисунка карты, Sx -- это отступ подписи под осью X от середины, он может быть обоих знаков.

Певрая группа из пяти чисел имеет следующие обозначения X1, X2, X3, X4, nx. При этом X1, X2 -- это начало и конец оси X в единицах аргумента X функции (X,Y). Далее X3, X4 -- это значение первой длинной риски и шаг до следующей длинной риски. Наконец nx -- это число коротких рисок между длинными. Вторая и третья группы из 5 чисел указывают на то же самое, только для осей Y и Z. Ось Z рисуется около шкалы цветов. Как видим, можно указывать любые значения, но лучше этим пользоваться с осторожностью. Команды /xti и /yti указывают только тексты подписей осей, а положение этих осей на рисунке определяется автоматически с учетом параметров Sc и Sx.

Дальше идет полностью стандартный текст на языке постскрипт с учетов новых команд, определенных в файле [ps-proc.txt]. Если прочитать все предыдущие главы книги, то можно легко понять что конкретно там написано. Это полезно для тех, кто хочет ннаучиться сам писать такие программы. Менять там ничего не надо. А новая команда run указывает на файл с постскрипт кодом картинки шкалы цветов. Как это приготовить я расскажу чуть позже. Весь постскрипт код далее полностью стандартный и содержит параметры, определенные во входных данных или вычисленные из них. Важно, что есть еще одна команда run, которая указывает на постскрипт код самой картинки с картой цветов.

Вот и все. Точнее совсем не все. А где взять файлы с кодом картинок. Да, это реально проблема, которая средствами языка постскрипт не решается. Точнее не так, решить ее можно, но это сложно. Двумерная зависимость обычно вычисляется по какой-либо компьютерной программе и представляет собой матрицу чисел. Этих чисел может быть очень много. И даже записывать эти числа текстом не всегда разумно. Впрочем коммерческие программы так и поступают -- записывают числа текстом и все дела. Но лично я так не поступаю. Я все такие расчеты выполняю с помощью программ на языке ACL, то есть использую указанную выше программу vkACL.

Эта программа способна записывать матрицу чисел в коде компьютера в формате языка Java, так как она на этом языке и написана. Более того, она умеет записывать не только матрицу, но и саму картинку при использовании разных шкал цветов, как монохромных, так и цветных. Обычно картинки записываются в png формате с разрешением 1 байт на пиксель для монохромных и 3 байта на пиксель для цветных шкал цветов. Остается конвертировать png формат картинки в eps формат. Некоторые стандартные программы рисования умеют это делать. Моя программа vkACL тоже это умеет и вот ее-то и разумно использовать. Проще всего использовать указанную выше программу (TDP eps), там это делает 6-я строка, хотя есть и другие программы. А можно и свою написать на языке ACL, кому это интересно.

На всякий случай я добавил в архив 4 готовые файла для картинок шкалы цветов. Но их тоже можно приготовить таким же способом. Для шаблона из eps файла нужно выкинуть все лишние строки и оставить только код, рисующий саму картинку. Как это выглядит можно посмотреть в файлам шкалы цветов. Вообще говоря, можно было бы написать и программу, которая конвертирует матрицу чисел в eps файл, но пока я так и не собрался сделать такую программу просто потому, что в этом нет большой необходимости. Вполне достаточно нарисовать png файл, а потом конвертировать его в eps код. Я специально такой код записываю с файлы с именами (nameEPS.txt) чтобы показать, что это всего лишь текстовый файл, который содержит EPS код, но не eps рисунок.
.
.

9.3. Создаем картинку из серии нескольких картинок

Готовые шаблоны eps файлов с параметрами весьма удобны для создания картинок заданного типа. Они не требуют напрягать память и вспоминать как и что надо делать. Достаточно поменять числа и сразу получаем готовый результат. Но часто возникает необходимость комбинировать несколько картинок в одной. Для такой работы очень помогает команда (filename) run, которая позволяет вставлять постскрипт код из другого файла в данный файл. Этот код может быть написать разным способом и содержать любые команды языка постскрипт. В частности по этой команде можно вставлять и просто eps файлы готовых картинок.

Но в этом случае есть одна тонкость. Дело в том, что в eps файлах есть команда showpage, которая выполняет рисункок. Но в eps файле такая команда должна быть только один раз в самом конце. Поэтому перед вставкой eps файла ее из файла нужно исключать. Это не всегда удобно. Можно использовать более универсальное решение. Временно переопределить эту команду как пустую. Вот как может выглядеть такой код

%!PS-Adobe-2.0 EPSF-2.0
%%BoundingBox: 0 0 1210 680
(ps-proc.txt) run
save /showpage {}bd 0.5 Sc (p001.eps) run 1200 0 tr (p002.eps) run restore
100 640 m is4 ((A))L ds4 720 640 m is4 ((B))L ds4
showpage
%%EOF

Посмотрим что тут делается. У нас были две одинаковые картинки размером 1200 на 1360. Мы указали размер на 10 больше по горизонтали и в 2 раза меньше по вертикали. Затем указали файл (ps-proc.txt), где записаны мои стандартные процедуры, которые часто использутся. В нем могут быть либо все процедуры, либо часть, это на усмотрение пользователя. И вот следующая строка содержит вставку двух картинок из eps файлов. Но перед этим надо спасти состояние параметров, переписать команду showpage на пустую, сделать масшабирование в 2 раза меньше, вставить первый рисунок, сдвинуть позицию и вставить второй рисунок. Позиция сдвигается на полный размер оригинала, потому что она тоже масштабируется. И в конце надо вернуть исходные параметры.

А затем можно добавить на рисунок тексты и все, что захочется. Такая система позволяет быстро и удобно скомбинировать рисунок любой степени сложности в одном eps файле. И все это замечательно работает в том плане, что программа GsView все показывает, а Миктех конвертирует в pdf файл.

.
.
.

9.4. Нестандартные символы на постскрипт картинках

Пожалуй самое слабое место стандартной версии постскрипта состоит в том, что у него мало шрифтов и они описываются по очень старой системе ASCII кодов. Более того, все шрифты обычно используются только с основной таблицей первых 127 символов и относятся к различному написанию латинских букв. Для других символов есть только фонт Symbol, в котором есть некоторые греческие буквы и значки, но уже одним фонтом и в недостаточном количестве.

Указанные в разделе 2.1 фонты можно использовать сразу, любая программа, показывающая постскрипт код, обязана их показать. А вот остальные фонты надо как-то указывать, устанавливать и так далее. Для переносимости их часто надо просто записать в файл и приставлять его к документу. В разделе 4.3 я описал как можно создать свой фонт. Я использовал эту технику для создания фонта из символов русского языка для написания текстов на русском языке. Это, в частности, позволяло мне писать письма на русском языке, которые можно прочитать на любом компьютере любой страны.

Сейчас эту работу выполняет Гугл переводчик, а раньше были проблемы, когда интернета еще не было. В моем фонте русских символов они рисуются линиями, которые могут иметь произвольную ширину. То есть указываются координаты точек, а картинки рисуются в процессе работы компьютера. Однако стандартные фонты сразу даются картинками. И также точно можно сделать нестандартные фонты. А можно просто приготовить банк картинок на разные символы и ставить их куда надо. Большие тексты так писать неудобно, но для небольших подписей вполне сгодится.

Остается вопрос -- где взять картинки. В этом разделе я опишу свой метод. Он состоит в использовании серии программ. Одна из них -- моя программа vkSM. Она позволяет вырезать любую часть экрана ноутбука и спасти ее в файл. Итак, открываем любой документ, в котором есть нужный нам символ, увеличиваем текст до нужных размеров и вырезаем картинку. Но часто на этом дело не заканчивается. В написании некоторых символов могут быть очень тонкие линии. Хотелось бы получить шрифт bold, но не всегда это возможно. Я использовал такой прием.

Обычно буква пишется черным на белом фоне. Делаем негатив (например, с программой FastStone Image Viewer). Затем конвертируем картинку в матрицу чисел. Это делает ACL программа EPS-2, которая есть в меню. И уже с матрицей чисел можно делать все, что угодно. Например, сложить 3 числа по горизонтали в одно и затем обрезать сумму максимумом в 255. Это делает ширину вертикальных линий в 3 раза толще. Для этого я написал отдельную программу работы с матрицами чисел. Затем ACL программа EPS-2 превращает матрицу снова в картинку и остается еще раз сделать негатив. И та же программа EPS-2 готовит постскрипт код любой картинки.

По этой причине, фактически, достаточно собирать картинки символов в png формате. Но можно без труда делать и eps формат, а затем использовать метод, описанный в предыдущем разделе. Я начал собирать коллекцию таких картинок в архиве по ссылке . Пока там только один символ, но со временем может стать больше.
.
.

 


содержание   назад