0

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
4
  • AutoRotatePages only applies to the pdfwrite device, Orientation will not have any effect on the display device. There is no 'window orientation' in Ghostscript, it is rendering the content precisely as requested by the input PostScript program. However.... I notice you are using PSFitPage which will reorient the content if it fits better that way, so the first thing you should do is drop that. Randomly guessing at controls won't do you any good...... Basically what you want doesn't exist.
    – KenS
    Commented Jan 31 at 8:01
  • Actually... One thing you could do is define a fixed media size (using -dFIXEDWIDTHPOINTS and -dFIXEDHEIGHTPOINTS) such that the media is landscape, and then use -dFitPage. That will auto-rotate the content onto the media, providing the PostScript program executes a media size request. Of course portrait-oriented programs will then render incorrectly.
    – KenS
    Commented Jan 31 at 9:47
  • Thank you, @KenS. Much appreciated. BTW, I wasn't randomly guessing. I reviewed the Ghostscript docs and other postings, and tried to rationalize the best I could. Clearly, I failed. Unfortunately, your own suggestion did work either. It did not create the window viewport oriented in the manner which I desired. Commented Jan 31 at 20:55
  • Well with no PostScript program to test with, anything is going to be speculation....
    – KenS
    Commented Feb 1 at 8:33

0

Browse other questions tagged or ask your own question.