Skip to content
/ PS.F Public

Library of Fortran routine for generating good quality encapsulated postscript (eps) figures.

License

GPL-3.0, GPL-3.0 licenses found

Licenses found

GPL-3.0
LICENSE
GPL-3.0
COPYING
Notifications You must be signed in to change notification settings

djwebb/PS.F

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

!
!======================================================================
!
!    File: README
!    Copyright 2020  David J. Webb
!
!    This file is part of PS.F.
!
!    PS.F is free software: you can redistribute it and/or modify
!    it under the terms of the GNU General Public License as published by
!    the Free Software Foundation, either version 3 of the License, or
!    (at your option) any later version.
!
!    PS.F is distributed in the hope that it will be useful,
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU General Public License for more details.
!
!    You should have received a copy of the GNU General Public License
!    along with PS.F.  If not, see <https://www.gnu.org/licenses/>.
!
!======================================================================
!

Introduction
============

File PS.F contains a library of fortran routines designed to generate an uncompressed text based encapsulated postscript (eps) file.  The library uses of a subset of the commands described in "Postscript Language reference manual", published by Addison-Wesley.

The resulting files are usually of good enough quality for publication.  If necessary additional editing can be carried with programs such as 'inkscape'.  If pdf versions of the files are required, these can be generated by inkscape or with the linux command 'eps2pdf'.  The routine 'contc' may be used to reduce size of the eps file needed to represent an image (i.e. and array of cells filled with different colours) by combining adjacent cells of the same colour.

The file INSTALL explains how the routines in "ps.F" may be compiled as part of a program or compiled separately and placed in a library.

Two example programs plot1.F and plot2.F are also included with this distribution

All floating point variables used by the library are eight byte (64-bit) variables, denoted below as real(DP).

Plotting spaces
===============

The routines make use of three plotting spaces, with routines available to define each space.

A)  At the top level is the users 'a' co-ordinate system, made up of the spatial variables being plotted.  These may be 'x' against 'y', 'speed' against 'time', 'latitude' against 'longitude' or anything similar.
B)  In most cases the 'a' and 'b' spaces are the same, but if a special transformation is used, for example a map transform from Mercator longitude and latitude to coordinates in a rectangular frame, then the 'b' space is the space after transformation.
C)  The 'c' space if the final page space.  Normally the limits of the 'a' space will be defined, for eample speed from 0 to 20 km/s and time from 0 to 200 seconds, and this space will then be fitted into a rectangle defined in the 'c' space.

If the 'b' space is used, it is the 'b' space limits which are fitted into the 'c' space frame.

Subroutines in PS Library
========================

This is a list of the 'ps' subroutines, grouped by activity.
For more information see the comments and the fortran code itself in file "ps.F".

1.  Initialising the eps file
=============================

  The file is initialised using routine 'psinit'.  It has three forms:

    subroutine psinit(page, filename)
      character(len=*) :: page
      !  This should either be 'a4v' for an A4 size page with portrait orientation
      !                     or 'a4h' for an A4 page with landscape orientation.
      character(len=*) :: filename
      !  This is the name of the new file

    subroutine psinit( rllx,rlly,rurx,rury,isize)
      real(DP) :: rllx,rlly,rurx,rury
      !  The x and y coordinates of the lower left corner and the upper right corned of the plotting paper.
    integer  :: isize
      !  This is set to 0 for portrait mode and 1 for landscape mode.  As a filename is not provided, the new file has the name 'POST.ps'.

    subroutine psinit(rllx,rlly,rurx,rury,isize,filename)
       !  Variables as above.

2.  Closing the eps file
========================

    call showpage               !  Postscript command to actually draw the page
    call psclose                !  Close the output file

      !  The file is closed by calling routine showpage, followed by routine psclose.

3.  Setting the a, b and c space limits
=======================================

    subroutine ps_set_a_limits(x1,x2,y1,y2)
    subroutine ps_set_b_limits(x1,x2,y1,y2)
    subroutine ps_set_c_limits(x1,x2,y1,y2)

      !  These routines set the minimum and maximum values for the horizontal 'x' and vertical 'y' axes in each of the three spaces.  Space 'b' only needs to be set if complex transformations are used.  Often there is only one plot on a page, but if more than one sub-plot is required these routines are called before each of the sub-plots.
      !  The 'c' space is in pixels :: 1 cm = 72/2.54 pixels  :: 1 inch = 72 pixels

    subroutine ps_use_a_space  !  Following coordinates use 'a' space
    subroutine ps_use_c_space  !  Following coordinates use 'c' space

    subroutine pstran(xa, ya, xc, yc)
      !  Convert from user 'a' coordinaes to page 'c' coordinates.  May be used when adding text to a figure.

    subroutine query_pagesize(xmin,xmax,ymin,ymax)
       !  Returns the page limits in the 'c' space

3.  Simple plot commands
========================

    These apply to the 'a' space unless subroutine 'ps_use_c_space' has been called.

    subroutine newpath           !  Start a new path
    subroutine move2(x, y)       !  Move to the first point (x,y) in a path
    subroutine draw2(x, y)       !  Move to the next point in a path
    subroutine closepath         !  Complete the path back to the beginning
    subroutine endline           !  Join all the points of the path with a solid line
    subroutine stroke            !  As endline
    subroutine fill              !  Fill the area defined by a path with colour

3a.  Arc commands
=================

    subroutine arc(x, y, r, a1, a2)
      !  Draw arc, centre (x,y) radius 'r', anti-clockwise starting at an angle 'a1' degrees to the horizontal and ending at angle 'a2'.  If there is a current point, a straight line is drawn first to the start of the arc.

    subroutine arcn(x, y, r, a1, a2)
      !  As arc, but draw the arc in a clockwise direction.

    subroutine arcto(x1, y1, x2, y2, r)
      !  Draw a straight line from the current point in the direction of (x1,y1), but then follow a circle radius 'r' to become tangent to the line joining (x1,y1) with (x2,y2).
      !  The routine normally returns the first and second tangent points but here the values are discarded.

4.  Specify colours
===================

    subroutine setrgb(red, blue, green)
      Set the (real(DP)) red, green and blue components of the next item to be plotted.
      Each value should be in the range 0d0 to 1d0.
    subroutine setgrey(gray)
    subroutine setgray(gray)
      Set the (real(DP)) grey colour.  Black corresponds to 0d0 and white to 1d0
    subroutine setblack
    subroutine setwhite
      Set the colour as described.

5.  Specify line properties
===========================

    subroutine setlinewidth(w)    !  Specify line width in pixels
    subroutine setdash(l1,l2)     !  Integers specifying length in pixels of the solid and
                                  !  dashed portion of a line.  Turned off if l1 equals zero
    subroutine setlinejoin(ijoin) !  = 0  Normal mitre joining style
                                  !  = 1  Use circle to join outer edges of joining lines
                                  !  = 2  Use a bevel join, truncating mitre point.
    subroutine setmiterlimit(ratio) !  Ratio of greatest width at a mitred corner
                                  ! to the width of the line.  If necessary a bevel join
                                  ! is used to prevent this happening.  Default value is 10.0.
    subroutine setlinecap(icap)   !  = 0  Lines stop at final point
                                  !  = 1  Add curved cap to end of line
                                  !  = 2  Add projecting equare cap to end of line.

6.  Masks
=========

   subroutine setpsmask(x1, x2, y1, y2) ! Sets a rectangular mask are in 'a' space
                                        ! Nothing is plotted outside this space.
   subroutine psmask(ii)                ! ii = 0 turn masking off
                                        !    = 1 turn masking on

7.  Text
========

    subroutine pstext(xx,yy,string) !  Write text 'string'
                                    !  starting at c-space position (xx, yy)
    subroutine pstext(xx,yy,string,irel) !  As before but (xx,yy) is now the c-distance
                                    !  moved relative to the current position - after the
                                    !  last move2, draw2 or pstext command.
    subroutine pstext2(xx,yy,string,iposn)
                                    !  Write text 'string'
                                    !  iposn = 0 : start at (xx,yy)
                                    !        = 1 : centre on (xx,yy)
                                    !        = 2 : end at (xx,yy)
    subroutine pstext3(xx,yy,angle,string,iposn,iback)
                              !  If iposn = 0, bottom left at (xx,yy)
                              !             1, bottom centre on (xx,yy)
                              !             2, bottom right at (xx,yy)
                              !             3, middle centre at (xx,yy)
                              !  If iback = 0,  plot text only
                              !             1, plot white background before plotting text
                              !             2, plot white background only
    subroutine setfont(ifont, isize) !  Integer ifont is font type (see below)
                                     !  Integer isize is font size in pixels
                              ! ifont = 1  : Times-Roman
                              !         2  : Times-Bold
                              !         3  : Times-Italic
                              !         4  : Times-BoldItalic
                              !         5  : Helvetica
                              !         6  : Helvetica-Bold
                              !         7  : Helvetica-Oblique
                              !         8  : Helvetica-BoldOblique
                              !         9  : Courier-Roman
                              !         10 : Courier-Bold
                              !         11 : Courier-Oblique
                              !         12 : Courier-BoldOblique
                              !         13 : Symbol

8.  Tick marks
==============

  subroutine ticks(iaxis,tbase,tincr,ntick,nannot,rfmt,ifmt,sign_a)
          !  iaxis  = 1 annotate bottom horizontal axis
          !         = 2 annotate left vertical axis
          !  tbase  = real(DP) base value for ticks
          !  tincr  = real(DP) increment value between ticks
          !  ntick  = number of ticks between large ticks
          !  nannot = number of ticks between annotations
          !Optional parameters
          !  rfmt   = format for annotation     (to override default)
          !  ifmt   = integer format for annotation
          !  sign_a = change sign of annotation (may be used to make
          !                                            depths positive)

   subroutine ticks2(iaxis,tbase,tincr,ntick,nannot,rfmt,ifmt,sign_a, tick_len, xoff1, yoff1)
          !  iaxis  = 1 annotate bottom horizontal axis
          !         = 2 annotate left vertical axis
          !         = 3 annotate top horizontal axis
          !         = 4 annotate right vertical axis
          !  tbase  = real(DP) base value for ticks
          !  tincr  = real(DP) increment value between ticks
          !  ntick  = number of ticks between large ticks
          !  nannot = number of ticks between annotations
          !Optional parameters
          !  rfmt   = "(string)" format for annotation     (to override default)
          !  ifmt   = "(string)" integer format for annotation
          !  sign_a = change sign of annotation (may be used to make
          !                                            depths positive)
          !  tick_len = length of ticks (default 0.15 cm)

      subroutine ticks_y(iaxis, delta_year,  delta_yeara,
     &                          delta_month, delta_montha, month_annot)

  subroutine to draw tickmarks identifying years and months.  All parameters are integers.
          !  iaxis        = axis to annotate 1 =bottom, 2 = left
          !  delta_year   = interval between year ticks
          !  delta_yeara  = interval between year annotation (0 = none)
          !  depta_month  = interval between month ticks
          !  delta_montha = interval between month annotation
          !  month_annot  = Number of letters in month annotation (1 or 3)

9.  Mapping  - Routines using 'b' space
=======================================

     subroutine setmap(name)

           ! This sets the mapping for 'a' space to 'b' space.
           !   name = "eqeq"     :: 'b' space equals 'a' space (Default).
           !        = "mercator" :: Use mercator projection
           !        = "ortho"    :: use orthographic projection

    subroutine setmap2(name1, name)

           !  This allows an addition initial projection from an offset latitude-longitude set of axes to the normal longitude-latitude grid
           !  name1 = "eqeq"    :: No additional transform (Default)
           !        = "euler"   :: Transform the latitude and longitude
           !  name  =  properties as for subroutine setmap.

    subroutine eqeq(x,y,i)
           !  Subroutine used for the 'eqeq' transformation.
           !    i = +1 forward, transformation from 'a' space to 'b' space
           !        -1 backward transformation

    subroutine mercator(x,y,i)
           !  Subroutine used for the 'mercator' transformation.

    subroutine ortho(x,y,i)
           !  Subroutine used for the 'orthographic' transformation.

    subroutine set_ortho(rlon1,rlat1,ideg)
           !  The orthographic projection uses parallel lines to project the surface of a sphere onto a plane through its centre at right angles to the line of sight.
           !     rlon1 = real(DP) longitude of point nearest observer.
           !     rlat1 = real(DP) latitude of point nearest observer.
           !     ideg  = 1, angles are in degrees - otherwise radians.

    subroutine seteu(alpha, beta, gamma)
           !  Set the Euler angles for an offset sphere

    subroutine transeu(rlon1, rlat1, rlon2, rlat2, deg_in, deg_out, alpha, beta, gamma, deg_eu)
           !  Used for the Euler transform.  This converts latitude and longitude from one spherical coordinate system to a second system.  The Euler angles alpha, beta and gamma define the transformation

10.  Predefined spectra
=======================

    subroutine col_steps1(x,xmin,xmax,ncols,r,g,b,icol,ipal)
           !  Routine to transform 'x' to red, green and blue colours from a
           !  set of 'ncols' colours.  These equally spaced across a predefined
           !  spectrum of colours.
           !  Input:
           !    x   -  real(DP) input variable
           !    xmin - real(DP) minimum value (at start of first colour step)
           !    xmax - real(DP) maximum value (at end of last colour step)
           !    ncols - number of colour steps
           !  Output
           !    r    - real(DP) output red colour (range 0d0 to 1d0)
           !    g    - real(DP) output green colour (range 0d0 to 1d0)
           !    b    - real(DP) output blue colour (range 0d0 to 1d0)
           !    icol - index of final colour in spectrum
           !    ipal - (optional) pallet  1 = standard
           !                              2 = red    - blue
           !                              3 = yellow - green
           !            negative values reverse colour sequence

   subroutine col_rd_bu_11(x,xmin,xmax,nstep,r,g,b,ipal)
           !  Similar to col_steps1 but using the colorbrewer 'ReBu' spectrum.

   subroutine col_spec_1(x,xmin,xmax,nstep,r,g,b,ipal)
           !  Similar to col_rd_bu_11 but using a different spectrum.

11. Miscelaneous commands
=========================
    subroutine gsave        ! store the postscript graphics state
    subroutine grestore     ! restore the graphics state
        If gsave is used before a stroke command, grestore can be called and the same
           path then used with a fill command.
    subroutine grestoreall  ! restore everything

    subroutine ps_push      !  save the values defining the 'a', 'b' and 'c' spaces
    subroutine ps_pop       !  restore the pushed values

    subroutine contc(ic,nxx,nx,ny,xe,ye,nc,rc,gc,bc)
           !  Fill a rectangular space with colour using a scheme to reduce the number of postscript commands
           !    ic  :  2-D integer array defining colours in each grid square
           !    nxx :  first dimension of ic (may differ from nx)
           !    nx  :  size of array in x direction
           !    ny  :  size of array in y direction
           !    xe  :  real(DP) x-coordinates of grid edges (1:nx+1)
           !    ye  :  real(DP) y-coordinates of grid edges (1:ny+1)
           !    nc  :  size of colour arrays
           !    rc  :  real(DP) red array
           !    gc  :  real(DP) green array
           !    bc  :  real(DP) blue array

    subroutine pscomment(string,i1,i2)
           !  Add a comment line to the postscript file
           !    If i1 non-zero add blank line before comment
           !    If i2 non-zero add bank line after comment
           !  Sometimes useful when later editing with a text editor

About

Library of Fortran routine for generating good quality encapsulated postscript (eps) figures.

Resources

License

GPL-3.0, GPL-3.0 licenses found

Licenses found

GPL-3.0
LICENSE
GPL-3.0
COPYING

Stars

Watchers

Forks

Packages

No packages published