Установите размер страницы после выдачи операторов рисования/шоу

Я разрабатываю эмулятор принтера (частично) в PostScript. Система команд, которую я хочу эмулировать, предназначена для термопринтеров на рулонной бумаге, которые в основном используются для печати чеков в точках продаж. Я бы предпочел выполнять операции в том же порядке, что и реальный принтер, а это означает, что моя программа не знает размер страницы, пока не встретит команду «вырезать». Я хочу, чтобы программа работала с принтерами CUPS переменного размера бумаги ¹.

Могу ли я изменить высоту страницы после выполнения команд рисования/отображения без исчезновения заполненных частей документа?

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

Например, если я запускаю следующую программу:

<< /PageSize [ 100 30 ] >> setpagedevice

0 0 moveto
(Text) show
showpage

Я получаю вывод:

Установите размер страницы после выдачи операторов рисования/шоу

Но когда я изменяю код, чтобы настроить размер страницы прямо перед командой showpage:

<< /PageSize [ 100 30 ] >> setpagedevice

0 0 moveto
(Text) show

<< /PageSize [ 100 100 ] >> setpagedevice

showpage

Я получаю только пустое изображение:

Установите размер страницы после выдачи операторов рисования/шоу

Я знаю, что могу отложить выполнение операторов рисования/отображения, поэтому моя программа вычисляет размер документа перед рисованием и выполняет операции только тогда, когда встречает команду вырезания. Я мог бы реализовать это сам, в настоящее время мне не нужна помощь с таким решением. Мне скорее интересно, возможно ли более простое решение для обрезки уже нарисованного документа до рассчитанного размера страницы.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
207
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не можете использовать операции маркировки, а тогда выбрать размер страницы в PostScript. Установка размера носителя в PostScript выполняет неявное стирание, которое очищает все отметки на странице.

См. примечание на стр. 408 3-го издания PLRM (Раздел 6.1.1 Словарь PageDevice):

Note: setpagedevice is a page-oriented operator used to control the output processing of one or more pages of a page description. Any call to setpagedevice implicitly invokes erasepage and initgraphics, and thus must precede the descriptions of the pages to be affected.

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

ata2001 20.07.2019 17:14

Благодаря KenS я понял, что не так с моим первоначальным подходом, поэтому я придумал альтернативное решение, откладывая выполнение операторов маркировки и заранее вычисляя высоту страницы. Ниже приведено неполное доказательство концепции моего метода реализации простого чекового принтера с переменным размером страницы:

%!
/feed {
        0                     % return to left margin
        currentpoint exch pop % y coordinate
        20 sub moveto         % feed 20 points
} def

% deferred feed
/_feed {
         /feed cvx % push executable name on stack
         dup exec  % execute procedure, to save position in current point
} def

% deferred show
/_show {
         dup                 % duplicate string
         stringwidth rmoveto % simulate position change
         /show cvx           % push show operator on stack
         2 array
         astore cvx          % create procedure for showing the text
} def

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

% Set font
/DejaVuSansMono findfont
16 scalefont
setfont

% The receipt itself
0 0 moveto
(text) _show
_feed
(text) _show
_feed

% Save coordinates
currentpoint
/y exch def
/x exch def

% Calculate and set document height based on position
/pageheight y neg def
<< /PageSize [ 100 pageheight ] >> setpagedevice

% Translate the negative y coordinates
0 pageheight 16 sub translate

% reset position
0 0 moveto

% Execute all procedures on the operand stack
count array astore { exec } forall

showpage

Вывод этого скрипта: слово "текст" появляется дважды, изображение автоматически обрезается до нужной высоты

Конечно, это неполно, но я хотел продемонстрировать это как можно проще. Надеюсь, кому-то будет интересно/полезно.

Другие вопросы по теме