Fanning Consulting Services (25K)

Configuring the PostScript Device

The FSC_PSConfig program is a program for configuring the IDL PostScript device. The program is similar to (but much more powerful than) PS_Form, an older program offered by Fanning Software Consulting. The FSC_PSConfig program is written as an object.

In addition to configuring the PostScript device, the FSC_PSConfig program allows you to keep track of the current state of the PostScript device at all times. European users will be pleased to know that support for the A4 page and centimeter units are built into the program and can easily be set as program defaults. One of the most useful features of the FSC_PSConfig program is its ability to collect user input via a graphical user interface, which--on a Windows machine with a 24-bit graphics display--looks similar to the illustration below.

The FSC_PSConfig graphical user interface for gathering user input.

-------

Table of Contents

-------

Program Overview

How you use the FSC_PSConfig program is completely up to you. It has been designed to accommodate different programming styles. For example, it can be called from the IDL command line or from within other IDL programs. Typically, the program is used by initializing the object (you can have as many of the objects as you like, so each program can have its own PostScript configuration setup), gathering user input via the built-in Graphical User Interface (GUI), configuring the PostScript device, and drawing your PostScript plot. Here is a typical sequence of commands. Each step will be explained in detail below, but this is a short overview of a typical session. (Users uninterested in the power of the FSC_PSConfig object can access most of the functionality through the PSConfig wrapper function described below.)

Initializing the Object

The first step is to initialize the object. There are a number of keywords that can be used to set properties of the FSC_PSConfig object, but suppose you are going to leave it up to the user to determine exactly how the PostScript device should be configured. Then you might simply initialize the object like this:

   psObject = Obj_New("FSC_PSConfig")

If you typically display PostScript output on an A4 page and prefer size and offset units to be displayed in centimeters rather than inches, then you can initialize the object with the European keyword set, like this.

   psObject = Obj_New("FSC_PSConfig", /European)

The A4 page and centimeter units are now the default for this object. Selecting a European style can also be selected via a check box on the graphical user interface.

Gathering User Input

Next, you might gather the user's input into how he or she would like the PostScript device to be configured. You can do this with a graphical user interface in either modal (blocking) or non-modal mode. Suppose you wish the program to wait for the user's input. You would invoke the graphical user interface in blocking mode with this command:

   psObject->GUI

Configuring the PostScript Device

The real purpose of the FSC_PSConfig object is to return keywords that are appropriate for the PostScript device. The way the PostScript device is configured is to make the PostScript device the current graphics device, and then pass these keywords to the PostScript device via the Device command using the "keyword inheritance" mechanism and the _Extra keyword. The keywords are obtained from the object by calling the GetKeywords method. A typical sequence of commands looks like this:

   thisDevice = !D.Name
   Set_Plot, "PS"
   Device, _Extra=psObject->GetKeywords()

Drawing the PostScript Graphics

The PostScript graphics are now written to the PostScript file in the normal way. (Here a simple Plot command is used, but the graphics command or commands can be as elaborate as you like.)

   Plot, data

Cleaning Up

The final step is to clean up. Note that you do not have to destroy the object, as shown here. In fact, you may want to keep the object around for the entire IDL session, so you always know the current configuration of the PostScript device. Repeated calls to invoke the graphical user interface will show the current state of the PostScript device. Typical clean-up commands will be similar to these:

   Device, /Close_File
   Set_Plot, thisDevice
   Obj_Destroy, psObject

[Return to Contents]

-------

Using the Program

The FSC_PSConfig program is used by calling the program's object methods. This section provides a detailed description of the object methods available to the user. (There are a number of other methods in the object that are used internally to run the program and should not normally be accessed by the user of the program. These are not described here, although they are extensively documented in the source code.)

Initializing the Program

The object is initialized by creating an object of the FSC_PSCONFIG object class:

   psObject = Obj_New("FSC_PSConfig")

At the time the object is initialized, various keywords can be used to set properties of the object. These keywords are typically (but not exclusively) the same keywords that can be used to configure the PostScript device (i.e., the keywords appropriate for the Device command when the PostScript device is the current graphics device). Here is a complete description of the INIT method keywords you can use.

For example, to select a centered, color, encapsulated PostScript file, using the Times Bold PostScript font, and named myplot.eps, you can initialize the object like this:

   psObject = Obj_New("FSC_PSConfig", /Color, /Encapsulate, /Times, /Bold, Filename="myplot.eps")

[Return to Contents]

-------

Description of the Graphical User Interface

The program's graphical user interface is invoked by calling the object's GUI method, like this:

   psObject->GUI

Keywords are available with this method that control how the graphical user interfaces appears and what properties it has. Called as above, the interface is a blocking widget. This means the IDL command line will block and user will be unable to enter IDL commands at the command line until the widget is dismissed by clicking either the Cancel or the Accept button. Valid keywords for this method are these:

The Left Panel

The left panel of the graphical user interface contains eight droplist widgets and looks like this. A description of each droplist follows the illustration.

The left panel of the FSC_PSConfig graphical user interface.

The Center Panel

The center panel of the graphical user interface contains the size and offset information, directions for operating the PostScript "plot", and fields to indicate the output directory and file names. It looks similar to the illustration below. An explanation of each item follows the illustration.

The center panel of the FSC_PSConfig graphical user interface.

If the FontInfo keyword is set when the graphical user interface is invoked, the center panel may also contain graphical elements allowing user input into font selections. These additional fields are described below the illustration.

The center panel of the FSC_PSConfig graphical user interface with font information turned on.

The Right Panel

The right panel of the graphical user interface contains the representation of the PostScript page. This window will change shape and size as different page sizes and orientations are selected. It looks similar to the illustration below. (Note that the colors you see here will only appear on 24-bit displays. On 8-bit displays the colors are less exciting.)

The righ panel of the FSC_PSConfig graphical user interface.

The "plot" in the window can be moved and resized by the user. It represents the "window" on the PostScript page where graphics will be drawn. As such, it controls the XSize, YSize, XOffset, and YOffset Device keywords. The plot window can be moved by clicking somewhere inside it and dragging. If you locate the cursor near an edge of the plot, you can click and drag to resize the window. Cursor changes will occur to indicate whether you are in drag or resize mode. Notice as you do that the size and offset fields in the right panel are updated with the new window sizes and offsets. Notice that the background color of the window changes if the current configuration shown on the form hasn't been saved and the program is in non-blocking mode. It will look similar to the illustration below. The backgound color does not change if the graphical user interface is in blocking mode. (Non-blocking mode is selected with the NoBlock keyword when the graphical user interface is invoked.)

The righ panel of the FSC_PSConfig graphical user interface.

The plot window can be centered in the page by clicking the middle mouse button anywhere inside the PostScript page representation. Note that the middle mouse button can be simulated if you don't have a three-button mouse. For example, on PCs a Ctrl-Click is interpreted as a middle mouse click. Option-Click on a Macintosh will do the same.

If the Color Output droplist is turned On, then the plot is shown in color as a visual clue to the color property.

The center panel of the FSC_PSConfig graphical user interface in color.

The Action Button Panel

The action button panel looks different, depending upon whether the graphical user interface is is blocking (modal) mode or in non-blocking mode. Here is what it looks like in non-blocking mode.

The button panel of the FSC_PSConfig graphical user interface in non-blocking mode.

Here is how it appears in blocking mode.

The button panel of the FSC_PSConfig graphical user interface in blocking mode.

Notice that in blocking mode the Dismiss button is named Cancel and the Apply button is named Accept, but they have similar functions. The only real difference is that the Accept button destroys the widget (as do the Dismiss and Cancel buttons), while the Apply button does not.

The buttons would now look like this:

The button panel of the FSC_PSConfig graphical user interface in blocking mode.

[Return to Contents]

-------

Setting Program Properties

The current configuration of the FSC_PSConfig object can be set at any time by using the SetProperty method of the object. The keywords that can be used to set properties are nearly identical to the keywords avaiable for the INIT method. Here is a list of the keywords and thier meaning.

For example, to create a 7 x 5 inch window on a PostScript landscape page, with color output turned on, and immediately update the display, you can type this:

  psObject->SetProperty, /Landscape, /Color, /Update, XSize=7, YSize=5, /Inches, XOffset=1, YOffset=1

[Return to Contents]

-------

Setting PostScript Configuration Keywords

The whole purpose of the FSC_PSConfig program is to configure the PostScript device by setting the appropriate Device command keywords. This is done by obtaining a structure in which the fields of the structure are the names of the appropriate keywords, and the values of the fields are appropriate for configuring the device the way you want it configured. You pass this structure to the Device command by means of keyword inheritance. In other words, you use the _Extra keyword to accept the structure.

The keyword structure is obtained from the object by calling the GetKeywords method, like this:

   keywordStructure = psObject->GetKeywords()

To verify what this structure looks like, type this:

   IDL> Help, keywordStructure, /Structure

Depending upon how your object is configured, you should see something like this:

   ** Structure <15037f8>, 24 tags, length=68, refs=1:
      BITS_PER_PIXEL  INT              8
      COLOR           INT              0
      ENCAPSULATED    INT              0
      FILENAME        STRING    'D:\RSI\IDL53\DAVID\coyote.ps'
      FONT_SIZE       INT             12
      INCHES          INT              1
      ISOLATIN1       INT              0
      PREVIEW         INT              0
      TT_FONT         INT              0
      XOFFSET         FLOAT           1.75000
      XSIZE           FLOAT           5.00000
      YOFFSET         FLOAT           3.50000
      YSIZE           FLOAT           4.00000
      PORTRAIT        INT              1
      LANDSCAPE       INT              0
      HELVETICA       INT              1
      BOLD            INT              1
      BOOK            INT              0
      DEMI            INT              0
      ITALIC          INT              1
      LIGHT           INT              0
      MEDIUM          INT              0
      NARROW          INT              0
      OBLIQUE         INT              0

Note that your structure may have other keywords defined, depending upon how your object is configured. This is typical.

These keywords are passed to the PostScript device via the _Extra keyword to the Device command. Be sure to select the PostScript device first. The code will typically look something like this:

   thisDevice = !D.Name
   Set_Plot, "PS"
   Device, _Extra=psObject->GetKeywords()

Once the PostScript device is configured, you issue your graphics command or commands as normal. They will go into the PostScript "window" you have described on the PostScript page. Then, be sure to close the file. The code might look something like this:

   Plot, data, Title='Experiment 5A'
   Device, /Close_File
   Set_Plot, thisDevice

A Note About Fonts

Although the PostScript device allows you to set information about PostScript fonts (if you set the FontInfo keyword when you invoked the GUI), there is no guarantee that your graphics commands will be rendered in PostScript fonts. In fact, this is a function of the !P.Font system variable or the Font keyword on a graphics command, and has nothing to do with how the PostScript device is configured per se. This makes it a bit tricky to put font property widgets on a graphical user interface, since the unaware user may be surprised that the output doesn't look like the configuration he or she selected.

I've attempted to get around this problem by letting you know of the user's wishes for font type. But this information doesn't come back in the device keyword structure. Rather, it is returned in a FontType output keyword from the GetKeywords method. In fact, I recommend you always call the method like this when you have asked the user to specify font information in the GUI:

   thisDevice = !D.Name
   Set_Plot, "PS"
   Device, _Extra=psObject->GetKeywords(FontType=fonttype)

This allows you to set the font type correctly on your graphics commands. For example, you could write code like this:

   currentFontType = !P.Font
   !P.Font = fonttype
   Plot, data, Title='Experiment 5A'
   Device, /Close_File
   Set_Plot, thisDevice
   !P.Font = currentFontType

Or, even more simply, you could write code like this:

   Plot, data, Title='Experiment 5A', Font=fonttype
   Device, /Close_File
   Set_Plot, thisDevice

[Return to Contents]

-------

Cleaning Up the Program

Since the FSC_PSConfig program is an object, it is persistent in the IDL session. This is one of the huge advantages of objects. For example, you can create an PostScript configuration object in a start-up file and always have it available in your IDL session. You will always have access to the current configuration of the PostScript device.

But as a persistent entity, you must destroy it when you are done with it or you will have heap memory leaking in your IDL session. This is especially true if you create these objects in other program modules. This is no different for other memory-leaking entities: pointers, pixmaps, etc. The way you clean up an object is to destroy it with the Obj_Destroy command, like this:

   Obj_Destroy, psObject

[Return to Contents]

-------

Example Program using FSC_PSConfig

Sometimes the best way to see how to use a new program is to see an example. Here is an example program, named PS_Plotter, that uses the FSC_PSConfig object to create a window on the PostScript page for two plots: an image plot and a histogram plot of the image data. You will need another useful program from my library to run the program: TVImage. (TVImage is needed because the normal IDL TV command doesn't honor the !P.Multi system variable. Nor is the TV command written in the device-independent way required here.) Here is the compete code for the PS_Plotter program.

   PRO PS_Plotter, image, $
      European=european, $   ; Set this keyword if you want European measurements.
      Object=object          ; Output variable to return FSC_PSConfig object.

      ; Get an image if one is not passed in.

   IF N_Elements(image) EQ 0 THEN BEGIN
      image = BytArr(360, 360)
      file = Filepath(SubDirectory=['examples', 'data'], 'worldelv.dat')
      OpenR, lun, file, /Get_Lun
      ReadU, lun, image
      Free_Lun, lun
   ENDIF 

      ; Create the PostScript configuration object.

   object = Obj_New('FSC_PSConfig', European=Keyword_Set(european))

      ; We want hardware fonts.

   thisFontType = !P.Font
   !P.Font = 1

      ; Get user input to PostScript configuration.

   object->GUI

      ; Configure the PostScript Device.

   thisDevice = !D.Name
   Set_Plot, 'PS'
   keywords = object->GetKeywords(FontType=fonttype)
   Device, _Extra=keywords

      ; Draw the example plots.

   !P.Multi = [ 0, 1, 2]
   TVImage, image
   Plot, Histogram(image), Title='Example Histogram Plot', XTitle='Pixel Value', $
      YTitle='Number of Pixels', XStyle=1, Max_Value=5000

      ; Clean up.

   !P.Multi = 0
   Device, /Close_File
   Set_Plot, thisDevice
   !P.Font = thisfontType

      ; Return the PS_Configuration object or destroy it.

   IF Arg_Present(object) EQ 0 THEN Obj_Destroy, object
   END

If you will be printing on letter-size paper, you want to run the program like this. You will see the graphical user interface of the object in the middle of your display. Fill out the form the way you would like the output file to be configured and click the Accept button.

   IDL> PS_Plotter

If you are in a country that uses A4 paper, you might want to call the program like this:

   IDL> PS_Plotter, /European

A PostScript file will be created in the specified directory. You can print it or use a PostScript file viewer (e.g., Ghostview) to view the file.

Called as above, the FSC_PSConfig object is created and destroyed when the program exits. However, you may wish to play around with some of the object's properties. You can return the object from the PS_Plotter program by using the optional Object keyword, like this:

   IDL> PS_Plotter, Object=psObject

If you want to see how the PostScript file was just configured, you can examine the PostScript Device keywords that were used to create the file:

   IDL> Help, psObject->GetKeywords(), /Structure

Be sure to destroy the object when you are finished with it.

   IDL> Obj_Destroy, psObject

[Return to Contents]

-------

A Wrapper Function for FSC_PSConfig

A number of people are still uncomfortable using objects. So for those people, I have written a function named PSConfig, which acts very much like (in fact, can probably be used as a replacement for) the old PostScript configuration program, PS_Form.

The PSConfig program creates the FSC_PSConfig object, calls the graphical user interface in blocking mode, and then returns the device keywords necessary to configure the PostScript device. The program can be used with commands similar to these:

   keywords = PSConfig(Cancel=cancelled)
   IF NOT cancelled THEN BEGIN
      thisDevice = !D.Name
      Set_Plot, "PS"
      Device, _Extra=keywords
      Plot, Findgen(11)
      Device, /Close_File
      Set_Plot, thisDevice
   ENDIF

You can use the same keywords with PSConfig that you use for the FSC_PSConfig object.

[Return to Contents]

-------

Customizing Your Source Code

I've tried to write the FSC_PSConfig program in such a way that it can be easily customized and extended by you at your site. In particular, it will be easy to add new default set-ups and other page types to the program. The code itself is extensively documented to indicate how this can be done. But, to give you an example, here is how you would add another default set-up, named Company Viewgraph to the code.

Step 1: Add the Name to the Set-Up List

Open the fsc_psconfig__define.pro file and find the DefaultList method. (For example, search for "::DefaultList".) Add your new default name to the list shown there. For example, you would find this code:

defaultlist = [ 'System (Portrait)', $
                'System (Landscape)', $
                'Centered (Portrait)', $
                'Centered (Landscape)', $
                'Square (Portrait)', $
                'Square (Landscape)', $
                'Figure (Small)', $
                'Figure (Large)', $
                'Color (Portrait)', $
                'Color (Landscape)' ]

and change it to this:

defaultlist = [ 'System (Portrait)', $
                'System (Landscape)', $
                'Centered (Portrait)', $
                'Centered (Landscape)', $
                'Square (Portrait)', $
                'Square (Landscape)', $
                'Figure (Small)', $
                'Figure (Large)', $
                'Color (Portrait)', $
                'Color (Landscape)' , $
                'Company Viewgraph']

Step 2: Create the New Set-Up

Next, find the SetDefault method (it will be just below the DefaultList method you just found) and copy one of the defualt setups you find in the CASE statement in that code. For example, here is the System (Portrait) method found there:

CASE thisDefault OF

   'System (Portrait)': BEGIN
         self.bitsSet = '8'
         self.colorSet = 0
         self.directorySet = directoryName
         self.encapsulationSet = 0
         self.filenameSet = defaultFilename + ".ps"
         self.fonttypeSet = !P.Font
         self.fontsizeSet = 12
         self.fontStyleSet = Replicate(0, 8)
         self.fontnameSet = "Helvetica"
         self.inchesSet = units
         self.landscapeSet = 0
         self.isolatinSet = 0
         self.pagetypeSet = pagetype
         self.previewSet = 0
         self.truetypeSet = 0
         IF self.european THEN self.xoffsetSet = 1.61 ELSE self.xoffsetSet = 0.75
         IF self.european THEN self.yoffsetSet = 14.65 ELSE self.yoffsetSet = 5.0
         IF self.european THEN self.xsizeSet = 17.80 ELSE self.xsizeSet = 7.0
         IF self.european THEN self.ysizeSet = 12.70 ELSE self.ysizeSet = 5.0
         self.defaultsSet = 'System (Portrait)'
      ENDCASE

Modify each of the fields you want to change there, and add your changed values to the CASE statement. For example, your Company Viewgraph set-up might be defined like this. Note that you will have to provide both inches and centimeter units for the sizes and offsets.

   'Company Viewgraph': BEGIN
         self.bitsSet = '8'
         self.colorSet = 1
         self.directorySet = "C:\Company\Viewgraphs"
         self.encapsulationSet = 0
         self.filenameSet = "viewgraph_1.view"
         self.fonttypeSet = 1
         self.fontsizeSet = 18
         self.fontStyleSet = Replicate(0, 8)
         self.fontnameSet = "Helvetica"
         self.inchesSet = units
         self.landscapeSet = 0
         self.isolatinSet = 0
         self.pagetypeSet = pagetype
         self.previewSet = 0
         self.truetypeSet = 0
         IF self.european THEN self.xoffsetSet = 0.75 * 2.54 ELSE self.xoffsetSet = 0.75
         IF self.european THEN self.yoffsetSet = 0.75 * 2.54ELSE self.yoffsetSet = 0.75
         IF self.european THEN self.xsizeSet = 7.0 * 2.54 ELSE self.xsizeSet = 7.0
         IF self.european THEN self.ysizeSet = 9.5 *2.54 ELSE self.ysizeSet = 9.5
         self.defaultsSet = 'Company Viewgraph'
      ENDCASE

[Return to Contents]

-------

Other FSC Programs Needed to Run this Program

This FSC_PSConfig program uses a number of other programs from the Coyote library. Here are the programs you will need.

In addition, you may want the following wrapper and example programs, respectively:

All of these programs are available in the Coyote Library.

[Return to Contents]

-------

Disclaimer and Licensing Information

Warranties

Fanning Software Consulting makes no warranties, either express or implied, as to the condition of the software described here or its fitness for any particular purpose. All software code is provided as is. IDL is a registered trademark of Research Systems, Inc. for the computer software used to created these programs. A licensed version of IDL is required to run these programs.

Licensing the Software

All programs written by Fanning Software Consulting and described in this article are issued under a license certified and approved by the Open Source Initiative. The following license is attached to the header of each program. Please do not removed the license information if you distribute this source code in any form.

;###########################################################################
;
; LICENSE
;
; This software is OSI Certified Open Source Software.
; OSI Certified is a certification mark of the Open Source Initiative.
;
; Copyright  2000 Fanning Software Consulting
;
; This software is provided "as-is", without any express or
; implied warranty. In no event will the authors be held liable
; for any damages arising from the use of this software.
;
; Permission is granted to anyone to use this software for any
; purpose, including commercial applications, and to alter it and
; redistribute it freely, subject to the following restrictions:
;
; 1. The origin of this software must not be misrepresented; you must
;    not claim you wrote the original software. If you use this software
;    in a product, an acknowledgment in the product documentation
;    would be appreciated, but is not required.
;
; 2. Altered source versions must be plainly marked as such, and must
;    not be misrepresented as being the original software.
;
; 3. This notice may not be removed or altered from any source distribution.
;
; For more information on Open Source Software, visit the Open Source
; web site: http://www.opensource.org.
;
;###########################################################################

Reporting Program Bugs

Every attempt is made to keep these programs accurate and bug free. If you find a bug, I will be happy to attempt to fix it. Please report any bugs or feature requests to:

David Fanning
Fanning Software Consulting
1645 Sheely Drive
Fort Collins, CO 80526 USA
Phone: 970-221-0438
Fax: 970-221-4762
E-Mail: david@dfanning.com

[Return to Programs Page]

-------

Copyright © 1997-2002 David W. Fanning
Last Updated 30 October 2002