Постскриптум: рисование градиента - PullRequest
3 голосов
/ 21 сентября 2011

Я учусь Постскриптум Я пытаюсь создать метод, который бы рисовал вертикальный градиент .

Вот мой код:

%!PS-Adobe-3.0

%%%%%%%%%%%%%%%%%%%%%%%
% draw a RECTANGLE
/Rect {
/h exch def % height
/w exch def % width
w 0 rlineto
0 h rlineto
-1.0 w mul  0 rlineto
0 -1.0 h mul rlineto
} def
%%%%%%%%%%%%%%%%%%%%%%%
% draw a Gradient
/VGrad {
/h exch def % height
/w exch def % width
/c2 exch def %gray-end
/c1 exch def %gray-start
/index 0.0  def %loop-index

0 1 h { %loop over height
    gsave
    c2 c1 sub  index h div mul c1 add setgray

    w h index sub Rect
    stroke

    /index index 1.0 add def % index++
    grestore
    } for

} def
%%%%%%%%%%%%%%%%%%%%%%%
%test script
200 600 moveto
.1 .9 100 10 VGrad

showpage

Но GS выдает ошибку:

GPL Ghostscript 8.70 (2009-07-31)
Copyright (C) 2009 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Error: /undefinedresult in --div--
Operand stack:
   0   1   2   3   4   5   0.8   5.0   0.0
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push   1862   1   3   %oparray_pop   1861   1   3   %oparray_pop   1845   1   3   %oparray_pop   1739   1   3   %oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   6   1   10   --nostringval--   %for_pos_int_continue   --nostringval--
Dictionary stack:
   --dict:1150/1684(ro)(G)--   --dict:0/20(G)--   --dict:75/200(L)--
Current allocation mode is local
Current file position is 588
GPL Ghostscript GPL Ghostscript 8.708.70: : Unrecoverable error, exit code 1
Unrecoverable error, exit code 1

где я не прав?

Ответы [ 3 ]

6 голосов
/ 26 октября 2011

Ваша программа будет выполняться быстрее, используя умные манипуляции со стеком и эффекты CTM.

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

Также приятно опубликовать с использованием и, возможно, образец страницы (легко обрезать, когда вам это не нужно, но когда вам нужно это нужно ... ?? !!) В любом случае, вот ваша программа переписана по-моему , FWIW.

Как я уже сказал, вывод его не так хорош в его нынешнем виде. Но вы можете изменить градиент, изменив функцию передачи серого с помощью currenttransfer и settransfer и / или изменив вычисление полей на логорифмическое масштабирование, изменив диапазон и скорость серых оттенков. Эти вещи должно быть легче увидеть в «более узком» коде. Комментарии стека помогают вам «проверить свое понимание» в конце каждой строки.

Редактировать: Я не мог перестать играть с ним! Я вычеркнул цикл и выявил еще несколько параметров.

Редактировать: Еще одно расширение. А как насчет красивой картинки?

%!

/box { % x y w h
    4 2 roll moveto % w h
    1 index 0 rlineto % w h
    0 exch rlineto % w
    neg 0 rlineto %
    closepath
} def

/poly { % n
    0.5 0 moveto
    { ? rotate 0.5 0 lineto } % n proc
    dup 0 360 4 index div put % n {360/n...}
    repeat
    closepath
} def

% num-slices shapeproc matrix grayproc  agrad  -
% repeatedly (fill shape, concat matrix, transform currentgray)
/agrad {
    3 dict begin /gray exch def /mat exch def /shape exch def
    ({ //shape exec //mat concat currentgray //gray exec setgray })
    token pop exch pop end bind repeat
} def

/shapes [
    { -0.5 -0.5 1 1 box fill }   %box shape
    { 0 0 0.5 0 360 arc fill }   %circle shape
    { 0 0 0.5 0 180 arc fill }   %fan shape
    { 5 poly fill } %pentagon
    { 6 poly fill } %hexagon
    ] def

/mats [
    {1 index 2 exch div 1 exch sub   dup matrix scale } %pyramid matrix
    {1 index 2 exch div 1 exch sub   1 matrix scale } %horizontal matrix
    {1 index 2 exch div 1 exch sub   1 exch matrix scale } %vertical matrix
    ] def

% mat-no shape-no gray0 grayF n x y w h  dograd  -
/dograd {
    gsave
        4 2 roll translate % m sh g0 gF n w h
        scale % m sh g0 gF n
        3 1 roll % m sh n g0 gF
        1 index sub 2 index div % m sh n g0 (gF-g0)/n
        [ exch /add cvx ] cvx % m sh n g0 grayproc
        3 1 roll setgray % m sh grayproc n
        3 -1 roll shapes exch get % m gray n shape
        4 -1 roll mats exch get exec % gray n shape mat
        4 -1 roll %n shape matrix gray
        agrad
    grestore
} def

%mat shape g0 gF n x y w h
0 4 .7 .1 20 300 400 600 800 dograd

0 0 0 1 10 100 650 200 200 dograd
1 1 0 1 20 300 650 200 200 dograd
2 2 .5 1 30 500 650 200 200 dograd

0 3 1 0 40 100 400 200 200 dograd
1 4 1 .5 50 300 400 200 200 dograd
2 1 .5 0 60 500 400 200 200 dograd

0 2 .1 .9 10 100 150 200 200 dograd
1 3 .2 .8 20 300 150 200 200 dograd
2 4 .3 .7 30 500 150 200 200 dograd

showpage

png output

3 голосов
/ 25 сентября 2011

Хорошо, я обнаружил проблему: похоже, index - зарезервированное слово. Вот функциональная версия:

/box
{
4 dict begin
/height exch def
/width exch def
/y exch def
/x exch def
x y moveto
width 0 rlineto
0 height rlineto
width -1 mul 0 rlineto
0 height -1 mul rlineto
end
} bind def


/gradient
{
4 dict begin
/height exch def
/width exch def
/y exch def
/x exch def
/i 0 def
height 2 div /i exch def

0 1 height 2 div {
    1 i height 2.0 div div sub setgray
    newpath
    x  
    y height 2 div i sub  add
    width
    i 2 mul
    box
    closepath
    fill
    i 1 sub /i exch def
    }for
newpath
0 setgray
0.4 setlinewidth
x y width height box
closepath
stroke
end
} bind def
2 голосов
/ 22 сентября 2011

Я не пытался полностью понять ваш код.Но сообщение об ошибке пытается сказать, что вы делите на ноль (посмотрите на верхний элемент оставшегося стека операндов: «0»).

Просто добавив «1» в переменную hinsert 1 add после h) заставляет вашу программу PostScript запускаться через интерпретатор Ghostscript и позволяет ему что-то рисовать (хотя это может выглядеть не так, как вы предполагали ....).

...