Опубликован: 07.02.2007 | Доступ: свободный | Студентов: 3729 / 1157 | Оценка: 4.56 / 3.95 | Длительность: 23:09:00
Специальности: Художник
Дополнительный материал 2:

Приложение Б. PostScript и TeX

Что такое PostScript?

Язык программирования PostScript разработан фирмой Adobe прежде всего для программирования принтеров. Вот пример файла на языке PostScript и порождаемой им картинки:


%!PS
%%BoundingBox: 0 0 110 150
0 9 9 10 mul {
  dup 0 moveto
  150 lineto
} for stroke
0 9 9 15 mul {
  dup 0 exch moveto
  100 exch lineto
} for stroke

Если вы когда-либо имели дело со стековыми языками программирования (скажем, с языком FORTH), то догадаетесь, что команда dup удваивает вершину стека, а команда exch меняет местами два верхних элемента. Если же нет, тоже ничего страшного — эти знания нам не пригодятся. Важно лишь понимать, что программа на языке PostScript представляет собой файл, который при исполнении порождает рисунок (из одной или нескольких страниц). Этот рисунок вовсе не обязан состоять из линий. Например, PostScript-файл

%!PS-Adobe-2.0 EPSF-2.0
%%Creator: pnmtops
%%Title: kolm.ps
%%Pages: 1
%%BoundingBox: 197 353 415 408
%%EndComments
/readstring {
  currentfile exch readhexstring pop
} bind def
/picstr 227 string def
%%EndProlog
%%Page: 1 1
gsave
197.28 353.64 translate
217.44 54.72 scale
1812 456 1
[ 1812 0 0 -456 0 456 ]
{ picstr readstring }
image
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
<...>
fffffffffffffffffffffff0ffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
<…>
ffffffffffffffffffffffff
grestore
showpage
%%Trailer

(мы опустили большую часть строк — всего в файле их более трех тысяч) порождает рисунок


(определение колмогоровской сложности из рукописи Андрея Николаевича Колмогорова 1970 года; файл был получен ее сканированием). Структура этого файла понятна: строки из букв кодируют черные и белые точки (и буквы f составляют большинство: точки в основном белые).

Аналогично можно задавать и полутоновые рисунки, только нужен очень качественный принтер (или еще более дорогое фотонаборное устройство), чтобы они хорошо печатались.

В язык PostScript включен некоторый минимальный набор шрифтов. Вот пример файла, ссылающегося на встроенные шрифты, и соответствующего рисунка:

%!PS
%%BoundingBox: 0 0 160 40
/Times-Roman findfont 24
scalefont setfont
5 5 moveto
(This is a string) show

К сожалению, русских букв в шрифтах стандарт языка PostScript не предусматривает, так что если заменить This is a string на что-нибудь русское, ничего хорошего не получится.

Да и вообще разных шрифтов предусмотрено немного. Зато стандарт PostScript предусматривает возможность определять свои шрифты, и в этих шрифтах уже могут быть любые буквы, в том числе русские. Например, нехитрая картинка


может быть задана таким файлом:

%!PS-Adobe-2.0 EPSF-2.0
%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software
%%Title: exampl4.dvi
%%BoundingBox: 148 654 241 666
%%EndComments
%DVIPSWebPage: (www.radicaleye.com)
%DVIPSCommandLine: dvips -E -o exampl4.ps exampl4.dvi
%DVIPSParameters: dpi=600, compressed
%DVIPSSource:  TeX output 2002.07.21:2027
%%BeginProcSet: texc.pro
%!
/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[
matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round
exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{
statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0]
N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin
/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array
/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2
array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N
df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A
definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get
}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub}
B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr
1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3
1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx
0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx
sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{
rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp
gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B
/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{
/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{
A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy
get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse}
ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp
fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17
{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add
chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{
1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop}
forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn
/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put
}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{
bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A
mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{
SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{
userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X
1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4
index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N
/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{
/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)
(LaserWriter 16/600)]{A length product length le{A length product exch 0
exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse
end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask
grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot}
imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round
exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto
fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p
delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M}
B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{
p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S
rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end

%%EndProcSet
TeXDict begin 40258437 52099154 1000 600 600 (exampl4.dvi)
@start
%DVIPSBitmapFont: Fa zcr10 10 16
/Fa 16 253 df<121C127FEAFF80A8EA7F00AB123EAB121CABC7FCA8121C127FEAFF80A5
EA7F00121C093C79BB17>33 D<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485A
A2485AA212075B120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA2
7F12077F1203A26C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20
>40 D<12C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA213
1F7FA21480A3EB07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C13
78A25BA2485A485AA2485A48C7FC120E5A5A5A5A5A13527CBD20>I<ED03F090390FF00F
F890393FFC3C3C9039F81F707C3901F00FE03903E007C03A07C003E010000FECF000A248
486C7EA86C6C485AA200075C6C6C485A6D485A6D48C7FC38073FFC38060FF0000EC9FCA4
120FA213C06CB512C015F86C14FE6CECFF804815C03A0F80007FE048C7EA0FF0003E1403
48140116F8481400A56C1401007C15F06CEC03E0003F1407D80F80EB0F80D807E0EB3F00
3901FC01FC39007FFFF0010790C7FC26387EA52A>103 D<EA0380EA0FE0487EA56C5AEA
0380C8FCAAEA03F012FFA312071203B3AA487EB512C0A312387EB717>105
D<3903F00FF000FFEB3FFCECF03F9039F1C01F803A0FF3800FC03803F70013FE496D7EA2
5BA35BB3A3486C497EB500C1B51280A329257EA42E>110 D<3807E01F00FFEB7FC09038
E1E3E09038E387F0380FE707EA03E613EE9038EC03E09038FC0080491300A45BB3A2487E
B512F0A31C257EA421>114 D<EBFF03000313E7380F80FF381E003F487F487F00707F12
F0A2807EA27EB490C7FCEA7FE013FF6C13E06C13F86C7F00037FC67F01071380EB007F14
1F00C0EB0FC01407A26C1303A37E15806C13077EEC0F00B4131E38F3C07C38E1FFF038C0
3F801A277DA521>I<1318A51338A31378A313F8120112031207001FB5FCB6FCA2D801F8
C7FCB215C0A93800FC011580EB7C03017E13006D5AEB0FFEEB01F81A347FB220>I<EB1F
E0EBFFFC3803E03F3907000F80390F8007E0486C6C7E13E06E7EA26E7E6C5A6C5AC8FCA4
147FEB07FFEB3FE0EBFE00EA03F8EA0FF0EA1FC0123F485A90C7FC160C12FEA31401A26C
13036CEB077C903980063E18383FC01E3A0FE0781FF03A03FFF00FE03A007F8007C02627
7DA52A>193 D<B539C001FF80A32607F800EBF8006C48EB03E0ED0780030EC7FC5D5D15
F0EC01C04A5A4AC8FC140E141E147F5C01F17F9038F39FC09038F70FE013FE496C7E9038
F003F86E7EA26E7E157F6F7E151F826F7E82486CEB1FFCB539C03FFFC0A32A247EA32E>
203 D<EB03FE90380FFF8090383E03E09038F800F84848137C48487F48487F4848EB0F80
001F15C090C712074815E0A2007EEC03F0A400FE15F8A9007E15F0A2007F14076C15E0A2
6C6CEB0FC0000F15806D131F6C6CEB3F006C6C137EC66C13F890387E03F090381FFFC0D9
03FEC7FC25277EA52A>207 D<3903F01FE000FFEB7FF89038F1E07E9039F3801F803A0F
F7000FC0D803FEEB07E049EB03F04914F849130116FC150016FEA3167FAA16FEA3ED01FC
A26DEB03F816F06D13076DEB0FE001F614C09039F7803F009038F1E07E9038F0FFF8EC1F
C091C8FCAB487EB512C0A328357EA42E>210 D<EB03FC90381FFF8090387E03E03901F8
0070484813F83907E001FC380FC003A2EA1F80123F90380001F848EB00F01500A2127E12
FEAA127E127FA26C14067F001F140E6D130C000F141C6C6C13386C6C13706C6C13E03900
7C07C090381FFF00EB07F81F277DA525>I<007FB612FCA3397E007E000078153C007015
1C0060150CA200E0150EA2481506A5C71400B114FF90B6FCA327247DA32E>I<0018EB1F
F8D81C01B5FCD81E0714E03A1F1F801FF89039FC0003FC01F0EB00FF01C06E7E496E7E90
C8EA0FE0001E82707E001C6F7E707E1218707EA2CAEA7F80A218C0173F18E0A3171F18F0
A591B7FCA391C8121FA518E0173FA318C0001E167FD87F801680487EEFFF00A24C5AA24C
5A494A5A007EC85B00704B5A6C4B5A6CED7F80000F4BC7FCD807E0EB03FCD801FEEB1FF8
D8007FB512E0010F91C8FC9038007FF8343D7EBA3C>252 D E
%EndDVIPSBitmapFont
end
%%EndProlog
%%BeginSetup
%%Feature: *Resolution 600dpi
TeXDict begin

%%EndSetup
1 0 bop 639 523 a Fa(\374\324)q(\317)28 b(\323\324\322)r(\317\313\301)f
(\(string\)!)p eop
%%Trailer
end
userdict /end-hook known{end-hook}if
%%EOF

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

Для начала мы применили LaTeX к файлу exampl4.tex такого содержания:

\documentclass{article}
\pagestyle{empty}
\begin{document}
Это строка (string)!
\end{document}

Получился файл exampl4.dvi, который в свою очередь был обработан командой

dvips -E -o exampl4.ps exampl4.dvi

Программа dvips (о которой мы еще будем говорить) и изготовила нам файл exampl4.ps (приведенный выше). Мы не беремся объяснить смысл входящих в этот файл команд, но видно, что вначале идут комментарии (строки с процентами), затем определения вспомогательных команд (занимающие целую страницу), затем (после пустой строки) идет описание шрифта zcr10 (основной русский шрифт в использованной нами русификации), и лишь потом идут собственно изображаемые символы (последние строки файла). При этом латинские буквы слова string так прямо и записаны в файле, а русские буквы заданы своими кодами. Например, "\317" (что означает восьмеричный код 317) соответствует букве "о" и встречается дважды: как третья буква в слове "Это" и как четвертая буква в слове "строка". (Знатоки смогут заключить отсюда, что в используемых нами шрифтах скорее всего применяется так называемая "кодировка koi8-r".)

Таким образом, на PostScript-принтере можно напечатать текст любым шрифтом, только надо предварить этот текст описанием шрифта.

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

Василий Майоров
Василий Майоров
Даврон Юсупалиев
Даврон Юсупалиев
Евгений Шаров
Евгений Шаров
Россия, Североморск, школа№11, 1991