Trying to re-define GS display window orientation for easier viewing/debugging of postscript code

34 views Asked by At

I am trying to change the way is displaying the output in its display window.

I don't want to modify the input file itself. I want to set a Ghostscript control switch to change the "window orientation".

By default, Ghostscript is displaying the output like this:

enter image description here

I want that output to be displayed like this:

enter image description here

I've tried various combinations using

  • AutoRotatePages, and
  • /Orientation with setpagedevice

with all resulting in "no impact" or "window crashes".

What command-line switch(es) and value(s) will achieve that change in the X-window content display?

My test script:

./apr -w -f10 -n test.c >test.ps

#ghostscript -cRotatePages=true test.ps                         ###  FAILED

/snap/bin/gs -v
#/snap/bin/gs -dUserRotation=90 test.ps                         ###  FAILED
#/snap/bin/gs -dAutoRotatePages=/None -c 90 rotate test.ps      ###  FAILED
#/snap/bin/gs -dAutoRotatePages=true test.ps                    ###  FAILED
#/snap/bin/gs -c 90 rotate test.ps                              ###  FAILED
#/snap/bin/gs -dORIENT1=true -dPSFitPage -sPAPERSIZE=letter -dFIXEDMEDIA test.ps 
#/snap/bin/gs -dORIENT1=false test.ps 
#/snap/bin/gs -dORIENT1=true test.ps 
#/snap/bin/gs -dAutoRotatePages=/All test.ps 
#/snap/bin/gs -dAutoRotatePages=/PageByPage test.ps 
#/snap/bin/gs -dAutoRotatePages=/None -c "<</Orientation 0 >>setpagedevice" test.ps
#/snap/bin/gs -cRotatePages=true test.ps
/snap/bin/gs test.ps 

Test Postscript file:

%!

/$a2psdict 100 dict def
$a2psdict begin
% Initialize page description variables.
/inch {72 mul} bind def
/landscape true def
/twinpage false def
/sheetheight 11.64 inch def
/sheetwidth 8.27 inch def
/margin 1.2 inch def
/noborder false def
/noheader false def
/headersize 0.22 inch def
/bodyfontsize 10 def
/lines 46 def
/columns 118 def
/date (Jan 30 2024 19:42:43) def
% Set the duplex mode ON or OFF.
statusdict /setduplexmode known
 {statusdict begin false setduplexmode end} if
%!  PostScript Source Code
%
%  File: /usr/private/a2ps/header.ps
%  Description: PostScript prolog for a2ps ascii to PostScript program.
% 
% General macros.
/xdef {exch def} bind def
/getfont {exch findfont exch scalefont} bind def

% Page description variables and inch function are defined by a2ps program.

% Character size for differents fonts.
   landscape
   { /filenamefontsize 12 def }
   { /filenamefontsize 16 def }
ifelse
/datefontsize filenamefontsize 0.7 mul def
/headermargin filenamefontsize 0.25 mul def
/bodymargin bodyfontsize 0.7 mul def

% Font assignment to differents kinds of "objects"
/filenamefontname /Helvetica-Bold def
/stdfilenamefont filenamefontname filenamefontsize getfont def
/datefont /Helvetica datefontsize getfont def
% Use Courier for others
/bodyfont /Courier bodyfontsize getfont def
%/bodyfont /Helvetica bodyfontsize getfont def

% Logical page attributs (a half of a real page or sheet).
/pagewidth
%%%   bodyfont setfont (0) stringwidth pop columns mul bodymargin dup add add
%%% EAJM %%%        (Change increased the width of the text box outline)
   bodyfont setfont (0) stringwidth pop columns 3 add mul bodymargin dup add add
   def
/pageheight
%%%   bodyfontsize lines mul bodymargin dup add add headersize add
%%% EAJM %%%        (Change raised the top box outline position)
   lines 6 add bodyfontsize mul bodymargin dup add add headersize add
   def

% Coordinates for upper corner of a logical page and for sheet number.
% Coordinates depend on format mode used.
% In twinpage mode, coordinate x of upper corner is not the same for left
% and right pages: upperx is an array of two elements, indexed by sheetside.
%%% /rightmargin margin 3 div def
%%% /leftmargin margin 2 mul 3 div def
%%% /topmargin margin twinpage {3} {2} ifelse div def
%%% EAJM %%%
/rightmargin margin 3 div def
/leftmargin margin 2 mul 3 div def
/topmargin margin twinpage {3} {2} ifelse div def
landscape
{  % Landscape format
%   /uppery rightmargin pageheight add bodymargin add def
%   %%% EAJM %%%    (change shifted position of box outline down)
   /uppery rightmargin 2 div pageheight add bodymargin add def
   /sheetnumbery sheetwidth leftmargin pageheight add datefontsize add sub def
   twinpage
   {  % Two logical pages
      /upperx [ topmargin           % upperx for left page
%       dup 2 mul pagewidth add     % upperx for right page
%%% EAJM %%%    (change eliminated the central margin)
        dup 1 mul pagewidth add     % upperx for right page
          ] def
      /sheetnumberx sheetheight topmargin sub def
   }
   {  /upperx [ topmargin dup ] def
%      /sheetnumberx sheetheight topmargin sub datefontsize sub def
%%% EAJM %%%    
      /sheetnumberx sheetheight topmargin sub datefontsize sub def
   }
   ifelse
}
{  % Portrait format
   /uppery topmargin pageheight add def
   /upperx [ leftmargin dup ] def
   /sheetnumberx sheetwidth rightmargin sub datefontsize sub def
   /sheetnumbery
     sheetheight 
     topmargin pageheight add datefontsize add headermargin headermargin add add
      sub
      def

}
ifelse

% Strings used to make easy printing numbers
/pnum 12 string def
/empty 12 string def

% Other initializations.
/datewidth date stringwidth pop def
/filenameroom
         pagewidth
     filenamefontsize 4 mul datewidth add (Page 999) stringwidth pop add
      sub
   def


% Function startdoc: initializes printer and global variables.
/startdoc
    { /sheetside 0 def          % sheet side that contains current page
      /sheet 1 def          % sheet number
   } bind def

% Function newfile: init file name and reset page number for each new file.
/newfile
    { cleanup
      /filename xdef
      /filenamewidth filename stringwidth pop def
      /filenamefont
     filenamewidth filenameroom gt
     {
           filenamefontname
           filenamefontsize filenameroom mul filenamewidth div
        getfont
     }
     {  stdfilenamefont }
     ifelse
     def
      /pagenum 1 def
    } bind def

% Function printpage: Print a physical page.
/printpage
    { /sheetside 0 def
      twinpage
      {  noborder not
        { sheetnumber }
     if
      }
      {  noheader noborder not and
        { sheetnumber }
     if
      }
      ifelse

      showpage 
%      pagesave restore
      /sheet sheet 1 add def
    } bind def

% Function cleanup: terminates printing, flushing last page if necessary.
/cleanup
    { twinpage sheetside 1 eq and
         { printpage }
      if
    } bind def

% Function startpage: prints page header and page border and initializes
% printing of the file lines.
/startpage
    { sheetside 0 eq
    { % /pagesave save def
      landscape
        { sheetwidth 0 inch translate   % new coordinates system origin
          90 rotate             % landscape format
        } if
    } if
      noborder not { printborder } if
      noheader not { printheader } if
     upperx sheetside get  bodymargin  add
        uppery
        bodymargin bodyfontsize add  noheader {0} {headersize} ifelse  add
     sub
      moveto
      bodyfont setfont
    } bind def

% Function printheader: prints page header.
/printheader
    { upperx sheetside get  uppery headersize sub 1 add  moveto

      datefont setfont
      gsave
        datefontsize headermargin rmoveto
    date show                   % date/hour
      grestore

      gsave
    pagenum pnum cvs pop
       pagewidth (Page 999) stringwidth pop sub
       headermargin
    rmoveto
        (Page ) show pnum show              % page number
      grestore
      empty pnum copy pop

      gsave
        filenamefont setfont
          filenameroom filename stringwidth pop sub 2 div datewidth add
          bodymargin 2 mul 
       add 
       headermargin
    rmoveto
        filename show                   % file name
      grestore

% New function to strip pathname from filename and display below filename in smaller font
      gsave
    datefont setfont
          filenameroom (This is the path prefix from the filename) stringwidth pop sub 2 div datewidth add
          bodymargin 2 mul 
%%% EAJM %%%      No_EFFECT
%%%       bodymargin 1 mul 
       add 
       headermargin 3 mul filenamefontsize 2 mul sub
%%% EAJM %%%      No_EFFECT
%%%    headermargin 2 mul filenamefontsize 1 mul sub
    rmoveto
    (\nThis is the path prefix from the filename) show
                            % path to file
      grestore

    } bind def

% Function printborder: prints border page.
/printborder 
    { upperx sheetside get uppery moveto
      gsave                 % print the four sides
        pagewidth 0 rlineto         % of the square
        0 pageheight neg rlineto
        pagewidth neg 0 rlineto
        closepath stroke
      grestore
      noheader not
         %{ 0 headersize neg rmoveto pagewidth 0 rlineto stroke }
         { 0 headersize 2 mul neg rmoveto pagewidth 0 rlineto stroke }
      if
    } bind def


% Function endpage: adds a sheet number to the page (footnote) and prints
% the formatted page (physical impression). Activated at the end of each
% source page (lines reached or FF character).
/endpage
   { /pagenum pagenum 1 add def
     twinpage  sheetside 0 eq  and
        { /sheetside 1 def }
        { printpage }
     ifelse
   } bind def

% Function sheetnumber: prints the sheet number.
/sheetnumber
    { sheetnumberx sheetnumbery moveto
      datefont setfont
      sheet pnum cvs
     dup stringwidth pop (0) stringwidth pop sub neg 0 rmoveto show
      empty pnum copy pop
    } bind def

% Function s: print a source line
/s  { gsave
        show
      grestore
      0 bodyfontsize neg rmoveto
    } bind def
%%EndProlog

/docsave save def
startdoc
(test.c) newfile
/sheet 1 def
%%Page: 1 1
startpage
(1     /************************************************************************/) s
(2     /* Description: Ascii to PostScript printer program.                    */) s
(3     /* File: apr.c  1996-10-25                                              */) s
(4     /*  files that are exactly multiples of 132 lines \(e.g., man pages\) */) s
(5     /* 4\) Added new options at installation : sheet format \(height/width in */) s
(6     /************************************************************************/) s
(7     int first_page;         /* First page for a file */) s
(8     int nonprinting_chars, chars;   /* Number of nonprinting and total chars */) s
(9     int prefix_width;       /* Width in characters for line prefix */) s
(10    /*          / * specify margin EAJM * /) s
(11                case 'c':) s
(12                MARGIN = 0.8 ;) s
(13                    if \(arg[2] != NULL\)) s
(14                        fprintf\(stderr, "Specify the value for the margin in inches option -c\\n"\);) s
(15                    break;) s
(16    */) s
(17                default:) s
(18                usage:) s
(19                fprintf\(stderr,"Usage: %s [options] [f1 f2 ... fn] | lpr\\n", argv[0]\);) s
(20    ) s
(21                fprintf\(stderr,"          -ns\\t\(don't print surrounding borders\)\\n"\);) s
(22                fprintf\(stderr,"          -nv\\t\(replace non-printing chars by space\)\\n"\);) s
(23                fprintf\(stderr,"          -nw\\t\(don't print in wide format\)\\n"\);) s
(24                fprintf\(stderr,"=== apr * SMILE if you like it ## Andrew Sulistyo |-\) ===\\n\\n"\);) s
(25                exit\(1\);) s
(26       /* Initialize some postcript variables */) s
(27       /* printf\("%%! a2ps 3.0\\n\\n"\);  For some reasons, the "a2ps 3.0" causes BRI's printer to burp. */) s
(28       printf\("$a2psdict begin\\n"\);) s
(29       printf\("%% Initialize page description variables.\\n"\);) s
(30       printf\("/inch {72 mul} bind def\\n"\);) s
(31    ) s
endpage

%%Trailer
cleanup
docsave restore end

My environment:

GPL Ghostscript 10.02.1 (2023-11-01)
UbuntuMATE 20.04
Linux 5.4.0-169-generic #187-Ubuntu SMP Thu Nov 23 14:52:28 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
0

There are 0 answers