This articles present a C++ interface for the Ghostscript DLL. Ghostscript[^] (GS) is a (very)
famous interpretor for the Postscript
language[^], it is used to render .ps files to a variety of image
formats and printers. For the majority of case, using the
gswin32.exe with command line parameters is good enough.
However, someone might want to integrate GS into it's application with using
The solution could be using the C API interface to the DLL functions
given by GS, however it is not suited for the (lazy) MSVC user: there are no
available projects or workspace to use this API and you have to use
make (an old UNIX souvenir) to rebuild the source (a
To avoid all those problems, a C++ wrapper for the dll has been coded with
the following features:
- Dynamic loading of
gsdll32.dll, by searching the path or the
- retrieving of all the C API methods in the dll
- Intelligent class for the initialization of the Ghostscript engine,
- make Ghostscript render to GDI+.
- UNICODE compliant
Note that all the classes are documented with Doxygen.
Before getting into work, you may take a look at this quote from the
Ghostscript licensing policy:
GNU Ghostscript may not be incorporated into commercial products which
forbid copying or for which customers cannot obtain source code for no more than
the cost of reproduction, although it may be distributed ("aggregated")
with commercial products; AFPL Ghostscript may not be incorporated into
commercial products at all, and may be distributed commercially only under
extremely limited circumstances. However, Ghostscript is also available for
commercial licensing, which in addition to the right to incorporate Ghostscript
into commercial products includes support, a limited warranty, high-quality
fonts, and other benefits. For more information about commercial licensing of
Ghostscript, please contact our commercial distribution partner, the only entity
legally authorized to distribute Ghostscript per se on any terms other than the
GNU or AFPL licenses
So if you plan to use this wrapper in a commercial applications, take a look
at the note on Commercial
There are 2 main classes used to build the interface to
CAPI is the interface to the
handles dll loading/unloading, method retreiving and interface,
CAPISettings is used to set all the format output options,
flags, display callbacks and other possible parameters of the ghostscript
engine. Once this object is ready, it is used to start an engine.
Here's a brief description of the other classes:
|Load, unload ghostscript library|
|C API interface|
|Base class for display callbacks|
|GDI+ and ghostscript interface|
All the classes are in the
gsdll namespace. From now on, we will
consider the following:
using namespace gsdll;
Make sure Ghostscript is installed on your machine before trying to use this
package (tested with AFPL Ghostscript 8.0).
Initializing Ghostscript with CAPISettings
CAPISettings is used to set-up the Ghostscript
You can choose the device in the
Here are the main output devices among all the available:
DevicePNG16m, 24-bit PNG,
DeviceBMP16m, 24-bit BMP,
DevicePDF, Adobe PDF writer
DeviceDisplay, custom ouput device (more details about this
As mentionned aboce, the user can provide GS with a custom output device
type. This type of device is used to make GS render to GDI+
object and will be discussed later.
GS also allows you to control where it sends its output. With a display
device this isn't necessary as the device handles presenting the output on
screen internally. Some specialized printer drivers operate this way as well,
but most devices are general and need to be directed to a particular file or
To send the output to a file, use the SetOutputFile method. For instance, to
direct all output into the file ABC.xyz, use
When printing on MS Windows systems, output normally goes directly to the
printer, PRN. When using GS as a file rasterizer (converting PostScript or PDF
to a raster image format) you will of course want to specify an appropriately
named file for the output.
GS also accepts the special filename '-' which indicates the output should be
writtent to stardard output (the command shell).
Be aware that filenames beginning with the character have a special meaning
in PostScript. If you need to specify a file name that actually begins with ,
you must prepend the os% filedevice explicitly. For example to output to a file
named abc, you need to specify
Please see GS and the PostScript Language and the PostScript Language
Reference Manual for more details on and filedevices. Note that on MS Windows
systems, the character also has a special meaning for the command processor
(shell), so you will have to double it.
Specifying a single output file works fine for printing and rasterizing
figures, but sometimes you want images of each page of a multi-page document.
You can tell GS to put each page of output in a series of similarly named files.
To do this place a template '%d' in the filename which GS will replace with the
You can also control the number of digits used in the file name:
'ABC-1.png', ... , 'ABC-10.png', ...
'ABC-001.pgm', ... , 'ABC-010.pgm', ...
'ABC_p0001.tiff', ... , 'ABC_p0510.tiff', ... , 'ABC_p5238.tiff'
Generally 03d is the best option for normal documents. As noted above, on MS
Windows systems, you will have to double the character.
There are several option to control the raster quality:
SetResolution, sets the output resolution in dpi,
SetTextAlphaBits, controls the text sub-sampling,
SetGraphicAlphaBits, controls the text sub-sampling.
If rendering to JPEG, you can set the output quality from 0 (bad quality,
good compression) to 100 (good quality, bad compression):
There are plenty of available flags to control the output of GS. Some are
implemented in the
CAPISettings class, they will suit the basic
needs. However, for the advanced user, it is possible to set custom arguments
Starting the engine:
Once you have set all the parameters, just build a
CAPISettings object in the constructor:
CAPI gsapi( settings);
Using the Ghostcript engine with CAPI
CAPI instance has been built successfully, you have to
feed it with Postscript. You can do that in numerous ways:
- Sending an entire file:
- Sending a string
gsapi.RunString(_T("1 2 add == flush\n"));Note that you can specify
the number of characters to be read.
- Sending numerous strings:
gs.RunStringContinue(_T("more ps code"));
When rasterizing, GS produces numerous messages (notification or error
messages). These messages are redirected to 2 string streams (static members of
Implementing your own ouput device with CCallback
As mentioned above, it is possible to implement your own output device. This
is made by furnishing GS with a series of function callbacks. In order to help
the user, these callbacks have been encapsulated into a virtual base class:
In order to write your own device, you must derive a class from
CCallback and implement all the following virtual functions:
|New device has been opened.|
|Device is about to be closed.|
|Device has been closed.|
|Device is about to be resized.|
|Device has been resized. New pointer to raster returned argument. |
|Showpage If you want to pause on showpage, then don't return immediately.
DWORD GetFormat() const
|returns the display format|
Here a snipet to attach your custom device to GS:
I will not go more into details about the use of those functions. For the
interrested user, the creation of a custom output device is illustrated with
CGDIpCallback which implements the outputing to GDI+
Crossing the bridge between GS and GDI+: CGDIpCallback
This class implements the necessary callback in order to have a output device
When the callback
Size is called, the address of the raster
buffer is stored and a
Bitmap is created with the appropriate
After that, when
Page is called, the raster is blitted into the
Bitmap. Each time
Page is called, the bitmap is stored
in a bitmap list for later use. These bitmaps can be accessed using
for (it=bc.begin(); it!=bc.end();++it)
The GS dll accepts only 1 instance running in the same thread. Hence, once an
engine is started, no other can be build successfully until it is destroyed.
The demo project is Postscript engine. Enter some postscript code and raster,
if successful, the result is displayed in the dialog window.
- Added UNICODE support
- Better DLL search in CModule. Thanks to Russel Lang from Ghostgum.com
- Added licensing policy
- 2-11-2002, initial release.
Jonathan de Halleux is Civil Engineer in Applied Mathematics. He finished his PhD in 2004 in the rainy country of Belgium. After 2 years in the Common Language Runtime (i.e. .net), he is now working at Microsoft Research on Pex (http://research.microsoft.com/pex).