Заставить Ghostscript обрабатывать портретные страницы иначе, чем альбомные страницы?

#ghostscript

Вопрос:

Я новичок в ghostscript. Я пытаюсь добавить дополнительное поле к страницам в формате PDF. Моя командная строка работает для страниц в портретном режиме, но портит страницы в альбомном режиме. Я хочу добавить ширину в 30 пунктов и поле в 42 пункта по всему периметру для портретных страниц (чтобы сохранить одинаковое соотношение сторон), поэтому увеличьте размер страницы формата А4 вдвое. Для пейзажа я переворачиваю цифры.

При изменении команды таким образом, чтобы она работала для альбомных страниц, теперь она портит портретные страницы.

Есть ли способ условно изменить страницы, чтобы они работали как на книжных, так и на альбомных страницах?

Мои команды были (для Windows)

  • Работает для портретного режима:

gswin64 -o c:tempoutport.pdf -sDEVICE=pdfwrite -g6550x9270 -c "lt;lt;/Install {30 42 translate}gt;gt; setpagedevice" -f "mysource.pdf"

  • Работает для альбомных страниц

gswin64 -o c:tempoutland.pdf -sDEVICE=pdfwrite -g9270x6550 -c "lt;lt;/Install {42 30 translate}gt;gt; setpagedevice" -f "mysource.pdf"

Я делаю это, так как изначально для PDF-файла требовалось поле размером 2 см вокруг текста. Но теперь мне нужен (примерно) запас в 3 см. Таким образом, когда я распечатаю его, он будет напечатан в формате А4 с отступом в см и правильным соотношением сторон.

Комментарии:

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

2. Спасибо @KenS за ваше предложение. Однако это выше моего понимания — можно ли было бы дать код, который сделал бы это?

3. Спасибо @KJ. Теперь я добавил в свой вопрос, почему я этого хочу: изначально PDF требовал поля 2 см вокруг текста. Но теперь мне нужен (примерно) запас в 3 см.

Ответ №1:

Неохотно мне придется опубликовать это в качестве ответа, потому что оно слишком велико для комментария.

Создайте текстовый файл с этим содержимым, назовите его чем-нибудь запоминающимся, например ‘intelligent_resize.ps’:

 %! userdict begin /ResetPageSize true def end  lt;lt;  /BeginPage  {  userdict /ResetPageSize known not  {  (Error: ResetPageSize undefined!n) print flush  //true  }  {  userdict /ResetPageSize get  } ifelse   {  userdict /ResetPageSize //false put  currentpagedevice /PageSize get aload pop  2 copy gt  {  60 add exch 84 add exch  2 array astore /PageSize exch  1 dict dup 4 2 roll put  setpagedevice  42 30 translate  }  {  84 add exch 60 add exch  2 array astore /PageSize exch  1 dict dup 4 2 roll put  setpagedevice  30 42 translate  } ifelse  }  {  userdict /ResetPageSize //true put  } ifelse  } gt;gt; setpagedevice  

Затем используйте эту командную строку (или что-то подобное):

 gswin64 -o c:tempoutport.pdf -sDEVICE=pdfwrite intelligent_resize.ps "mysource.pdf"  

Это устанавливает процедуру BeginPage, которая запускается в начале каждой страницы, но с элементом управления в userdict, чтобы определить, что делает эта процедура.

Если элемент управления имеет значение true, он устанавливает значение false (предотвращает рекурсию в setpagedevice), проверяет, является ли носитель портретным или альбомным, добавляет 60, 84 или 84,60 точек к ширине и высоте, в зависимости от ориентации, и переводит содержимое на 30,42 или 42,30.

Если элемент управления имеет значение false, он устанавливает его в значение true.

Поэтому нас вызывают, когда начинается первая страница, элемент управления имеет значение true, поэтому мы сбрасываем элемент управления, вычисляем новый размер носителя и вызываем setpagedevice, чтобы установить этот новый размер. Это означает, что мы снова вызываем BeginPage. На этот раз элемент управления имеет значение false, поэтому мы возвращаем ему значение true и возвращаемся к нашей исходной процедуре BeginPage, которая затем преобразует CTM вновь созданной страницы.

Затем выполняется содержимое страницы. Мы переходим к следующей странице и снова заходим по кругу. Таким образом, это «должно» работать для PDF-файлов, содержащих смесь ориентаций. Код в его нынешнем виде просто расширяет все страницы на требуемое количество и перецентрирует содержимое, он не пытается подогнать содержимое под страницу другого размера или что-то сложное.

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

Я попробовал его на файле с портретом письма и файле с пейзажем письма, и, похоже, он сделал то, что вы хотите.

Комментарии:

1. Спасибо @kens: это отличное решение, которое делает именно то, что я хочу.