Как я могу нарисовать путь, который заполняет всю страницу в Postscript?

Я хочу создать изображение в постскриптуме с прозрачной дырой, как это:

Желаемое изображение с прозрачным отверстием

Лучшее решение, которое я могу придумать, состояло в том, чтобы создать обтравочный контур, который заполняет страницу while, за исключением дыры, например:

Отсечение пути

Мой текущий код постскриптума для всего этого выглядит следующим образом:

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 100 100
%%Pages: 1
%%EndComments
%%EndProlog


% Create clipping path

newpath
-200 -200 moveto
 200 -200 lineto
 200  200 lineto
-200  200 lineto
closepath
70 50 moveto
60 50 10 360 0 arcn
closepath
clip

% Draw rest of the image
% In the actual image I am working on this rest of the image
% has a bunch of complex shapes.

newpath
20 20 moveto
66 20 lineto
66 70 lineto
20 70 lineto
closepath

0 0.5 0.5 setrgbcolor
fill

Часть, которая беспокоит меня в моем решении, заключается в том, что для рисования пути отсечения мне нужно было нарисовать большой прямоугольник, который был больше, чем вся страница, с некоторыми жестко закодированными большими координатами (от -200 до +200). Есть лучший способ сделать это?

Я бы предпочел просто иметь возможность сказать постскрипту рисовать за пределами круга с центром в 60 50 для контура отсечения, без необходимости создавать большой прямоугольник, который создает все. Это возможно?

Если это невозможно, я бы предпочел, по крайней мере, способ создать большой прямоугольник, не полагаясь на жестко заданные координаты, возможно, путем запроса координат углов изображения. Есть ли способ сделать это?


person hugomg    schedule 03.09.2017    source источник


Ответы (1)


Хорошо, во-первых, вам нужно быть осторожным с вашей терминологией, «изображение» в PostScript — это растровое изображение (см. оператор image), поэтому, когда вы говорите об изображении, любой, кто понимает PostScript, думает в терминах растрового изображения.

Во-вторых, вы создаете здесь EPS, а не полную программу PostScript, и поэтому вам абсолютно не следует не возиться с полными страницами, результаты, скорее всего, не будут такими, как любой пользователь. может ожидать. Написав за пределами BoundingBox, объявленного вашим EPS, вы сделаете его недействительным. На практике большинство приложений поместит «обрезку» вокруг вашего EPS, совпадающую с его BoundingBox, но это не значит, что вы должны полагаться на него.

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

Я не понимаю, почему это:

newpath
20 20 moveto
66 20 lineto
66 70 lineto
20 70 lineto
closepath
70 50 moveto
60 50 10 360 0 arcn
closepath
clip

newpath
20 20 moveto
66 20 lineto
66 70 lineto
20 70 lineto
closepath

0 0.5 0.5 setrgbcolor
fill

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

Очевидно, вы хотели бы обернуть это в пару gsave/grestore, чтобы впоследствии можно было отменить клип.

Чтобы ответить на актуальный вопрос; если бы вы писали полную программу PostScript, вы бы ожидали, что сами выдадите запрос на размер носителя, соответствующий размеру носителя, необходимому для документа. Таким образом, вы уже знаете размер носителя. Однако на уровне языка 2 или 3 вы всегда можете запросить у переводчика текущий размер носителя:

currentpagedevice /PageSize get

вернет массив с двумя элементами, шириной и высотой выбранного носителя в единицах PostScript.

Внезапно я не могу вспомнить, как получить размер носителя в PostScript уровня 1, но на самом деле вам не о чем беспокоиться.

person KenS    schedule 03.09.2017
comment
Реальный рисунок, с которым я работаю, намного сложнее, чем просто прямоугольник с отверстием в нем, и трудно каждый раз вручную пересчитывать поле отсечения. Другая трудность заключается в том, что на реальном чертеже, над которым я работаю, я рисую отверстие после применения глобального преобразования масштабирования, которое делает координаты ограничивающей рамки менее очевидными. Тогда будет ли использование currentpagedevice лучшим способом не повторяться? - person hugomg; 03.09.2017
comment
Если делаете ЭПС, то нет. Как я уже сказал, если вы закроете всю страницу, вы превысите BoundingBox вашей EPS и тем самым сделаете ее недействительной. Помимо потенциального загрязнения страницы, в которую включен EPS. Если вы создаете настоящий PostScript, вы можете сделать это, хотя обычно это не одобряется. Если вы создаете программу PostScript, вам следует запросить нужный размер носителя (таким образом давая переводчику и оператору возможность вмешаться). По сути, вы должны знать максимальный размер, который вы собираетесь рисовать, будь то BoundingBox или Media size. - person KenS; 03.09.2017
comment
Ах, тогда ладно. IIRC комментарий %%BoundingBox является обязательным в файлах EPS. Есть ли способ запросить эти измерения внутри моего скрипта, чтобы я мог не повторяться? - person hugomg; 03.09.2017
comment
BoundingBox действительно обязателен. Вы не можете (или не должны) запрашивать BoundingBox, потому что вы создаете его сами, когда пишете EPS. Кроме того, это комментарий (преднамеренно указанный таким образом), который интерпретаторы PostScript игнорируют, поэтому нет, вы не можете получить его каким-либо определенным образом. По сути, вам нужно отслеживать ограничивающие рамки объектов, чтобы вы могли создать правильный комментарий BoundingBox в EPS, который вы пишете, и чтобы вы знали, насколько большими должны быть другие объекты, если они зависят от объекта, который вы уже написали ( или собираетесь писать). - person KenS; 04.09.2017