<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Information for Ghostscript developers</title><link rel="stylesheet" type="text/css" href="gs.css" title="Ghostscript Style"><!-- $Id: Develop.htm,v 1.159 2005/10/20 19:46:23 ray Exp $ --></head> <body><!-- [1.0 begin visible header] ============================================ --> <!-- [1.1 begin headline] ================================================== --> <h1>Information for Ghostscript developers</h1> <!-- [1.1 end headline] ==================================================== --> <!-- [1.2 begin table of contents] ========================================= --> <h2>Table of contents</h2> <blockquote><ul><li><a href="#Introduction">Introduction</a><li><a href="#Architecture">Architecture</a><ul><li><a href="#Design_goals">Design goals</a><li><a href="#Design_principles">Design principles</a><li><a href="#Large_scale_structure">Large-scale structure</a><li><a href="#Object_oriented_constructs">Object-oriented constructs</a></ul><li><a href="#File_roadmap">File roadmap</a><ul><li><a href="#Substrate">Substrate</a><li><a href="#Graphics_library">Graphics library</a><ul><li><a href="#Library_support">Support</a>, <a href="#Paths">Paths</a>, <a href="#Text">Text</a>, <a href="#Images">Images</a>, <a href="#Paint">Paint</a>, <a href="#Clipping">Clipping</a>, <a href="#Other_graphics">Other graphics</a>, <a href="#Driver_support">Driver support</a>, <a href="#FAPI_support_gx">Font API support</a> <a href="#Visual_trace">Visual Trace</a></ul><li><a href="#Device_drivers">Device drivers</a><ul><li><a href="#Internal_devices">Internal devices</a>, <a href="#PS_and_PDF_writers">PostScript and PDF writers</a>, <a href="#High_level_devices">Other high-level devices</a>, <a href="#Other_maintained_drivers">Other maintained drivers</a>, <a href="#Contributed_drivers">Contributed drivers</a></ul><li><a href="#PostScript_interpreter">PostScript interpreter</a><ul><li><a href="#Main_program">Main program</a>, <a href="#Data_structures">Data structures</a>, <a href="#Stacks">Stacks</a>, <a href="#Interpreter_loop">Interpreter loop</a>, <a href="#Scanning_parsing">Scanning/parsing</a>, <a href="#Standard_operators">Standard operators</a>, <a href="#Non_standard_operators">Non-standard operators</a>, <a href="#Interpreter_support">Interpreter support</a>, <a href="#PostScript_code">PostScript code</a></ul><li><a href="#PDF_interpreter">PDF interpreter</a><li><a href="#PPD">PostScript Printer Description</a><li><a href="#Build_process">Build process</a><ul><li><a href="#Makefile_structure">Makefile structure</a>, <a href="#dev_files">.dev files</a>, <a href="#Generators">Generators</a>, <a href="#Build_support">Support</a></ul><li><a href="#Utilities">Utilities</a><ul><li><a href="#Utilities_in_PostScript">Utilities in PostScript</a><li><a href="#Utility_scripts">Utility scripts</a></ul></ul><li><a href="#Memory_management">Memory management</a><ul><li><a href="#Memory_manager_architecture">Memory manager architecture</a><ul><li><a href="#Objects_vs_strings">Objects vs strings</a>, <a href="#Structure_descriptors">Structure descriptors</a>, <a href="#Garbage_collection">Garbage collection</a>, <a href="#Movability">Movability</a>, <a href="#Parent_hierarchy">Parent hierarchy</a>, <a href="#Allocator_API">Allocator API</a></ul><li><a href="#Freeing_storage">Freeing storage</a><ul><li><a href="#Explicit_freeing">Explicit freeing</a>, <a href="#Reference_counting">Reference counting</a>, <a href="#Real_garbage_collection">(Real) garbage collection</a></ul><li><a href="#Special_implementations">Special implementations</a><ul><li><a href="#malloc">malloc</a>, <a href="#Locking">Locking</a>, <a href="#Retrying">Retrying</a></ul><li><a href="#Standard_implementation">Standard implementation</a><li><a href="#PostScript_interpreter_extensions">PostScript interpreter extensions</a><ul><li><a href="#Refs">Refs (PostScript "objects")</a>, <a href="#save_forgetsave_restore">save/.forgetsave/restore</a>, <a href="#Stable_allocators">Stable allocators</a>, <a href="#Interpreter_GC">Garbage collection</a></ul></ul><li><a href="#Portability">Portability</a><ul><li><a href="#Structural">Structural</a><ul><li><a href="#CPU_and_compiler">CPU and compiler</a>, <a href="#Library_headers">Library headers</a>, <a href="#Cross_platform_APIs">Cross-platform APIs</a>, <a href="#Makefiles">Makefiles</a></ul><li><a href="#Coding">Coding</a><ul><li><a href="#Explicit_dependencies">Explicit dependencies</a>, <a href="#Implicit_dependencies">Implicit dependencies</a></ul><li><a href="#Platform_specific_code">Platform-specific code</a></ul><li><a href="#Adding_features_and_options">Adding features and options</a><li><a href="#Troubleshooting">Troubleshooting</a></ul></blockquote> <!-- [1.2 end table of contents] =========================================== --> <!-- [1.3 begin hint] ====================================================== --> <p>For other information, see the <a href="Readme.htm">Ghostscriptoverview</a> and the documentation related to <ahref="Maintain.htm">maintaining Ghostscript</a>. <!-- [1.3 end hint] ======================================================== --> <hr> <!-- [1.0 end visible header] ============================================== --> <!-- [2.0 begin contents] ================================================== --> <h2><a name="Introduction"></a>Introduction</h2> <p>This document provides a wealth of information about Ghostscript'sinternals, primarily for developers actively working on Ghostscript. It isprimarily <strong>descriptive</strong>, documenting the way things are; thecompanion <a href="C-style.htm">C style guide</a> is primarily<strong>prescriptive</strong>, documenting what developers should do whenwriting new code. <p>THIS FILE IS A WORK IN PROGRESS. MANY SECTIONS ARE PLACE-HOLDERS. <h2><a name="Architecture"></a>Architecture</h2> <h3><a name="Design_goals"></a>Design goals</h3> <p>Ghostscript has the following high-level design goals (not listed in orderof importance): <ul><li>Functionality<ul><li>Ability to interpret the current PostScript and PDF languages, asdefined (and occasionally, in the case of conflict, as implemented) byAdobe.<li>Ability to convert PostScript to and from PDF, comparable toAdobe products.<li>Ability to produce output for a wide range of resolutions (fromTV-resolution displays to imagesetters) and color models (black and white,multilevel gray, bilevel or multi-level RGB and CMYK, 6- or 8-colorinkjet printers, spot color).</ul><li>Performance<ul><li>Ability to render PostScript and PDF with commercial-quality performance(memory usage, speed, and output quality) on all platforms.<li>Specifically, ability to render PostScript effectively in embeddedenvironments with constrained RAM, including the ability to put the code andsupporting data in ROM.</ul><li>Licensing<ul><li>Licensing that supports both the Open Source / Free software communitiesand a commercial licensing business.<li>Freedom from licensing restrictions or fees imposed by third parties.</ul><li>Other<ul><li>Easy source portability to any platform (CPU, operating system, anddevelopment tools) that has an ANSI C compiler.<li>Support for writing new interpreters and new drivers with no change toany existing code; specifically, ability to support PCL 5e, PCL 5c, and PCLXL interpreters, and the ever-changing roster of inkjet printers.</ul></ul> <p>These goals often conflict: part of Ghostscript's claim to quality is thatthe conflicts have been resolved well. <h3><a name="Design_principles"></a>Design principles</h3> <p>Part of what has kept Ghostscript healthy through many years of major coderevisions and functional expansion is consistent and conscientious adherenceto a set of design principles. We hope the following list captures the mostimportant ones. <h4>Non-preemption</h4> <p>Ghostscript is designed to be used as a component. As such, it must shareits environment with other components. Therefore, it must not requireownership of, or make decisions about, inherently shared resources.Specifically, it must not assume that it can "own" either the locus ofcontrol or the management of the address space. <p>Not owning control means that whenever Ghostscript passes control to itscaller, it must do so in a way that doesn't constrain what the caller can donext. The caller must be able to call any other piece of software, wait foran external event, execute another task, etc., without having to worry aboutGhostscript being in an unknown state. While this is easy to arrange in amulti-threaded environment (by running Ghostscript in a separate thread),multi-threading APIs are not well standardized at this time (December 2000),and may not be implemented efficiently, or at all, on some platforms.Therefore, Ghostscript must choose between only two options for interactingwith its caller: to <em>return</em>, preserving its own state in datastructures, or to <em>call back</em> through a caller-supplied procedure.Calling back constrains the client program unacceptably: the callbackprocedure only has the options of either returning, or aborting Ghostscript.In particular, if it wants (for whatever reason) to multi-task Ghostscriptwith another program, it cannot do so in general, especially if the otherprogram also uses callback rather than suspension. Therefore, Ghostscripttries extremely hard to return, rather than calling back, for all callerinteraction. In particular: <ul> <li>For callers that want to pass input to Ghostscript piece by piece,Ghostscript returns with an <b><tt>e_NeedInput</tt></b> code rather thanusing a callback. This allows the caller complete flexibility in itscontrol structure for managing the source of input. (It might, for example,be generating the input dynamically.) <li>In the future, the same arrangement should be used for input from<b><tt>stdin</tt></b> and output to <b><tt>stdout</tt></b> and<b><tt>stderr</tt></b>. <li>Likewise, scheduling of Ghostscript's own threads (contexts), currentlydone with a callback, should be done with suspension. The DisplayGhostscript project (GNU DGS) is working on this. </ul> <p>The one area where suspension is not feasible with Ghostscript's currentarchitecture is device output. Device drivers are called from deep withinthe graphics library. (If Ghostscript were being redesigned from scratch,we might try to do this with suspension as well, or at least optionalsuspension.) <p>Not owning management of the address space means that even thoughGhostscript supports garbage collection for its own data, it must not do anyof the things that garbage collection schemes for C often require: it mustnot replace 'malloc' and 'free', must not require its clients to use its ownallocator, must not rely on manipulating the read/write status of memorypages, must not require special compiler or run-time support (e.g., APIs forscanning the C stack), must not depend on the availability ofmulti-threading, and must not take possession of one of a limited number oftimer interrupts. However, in order not to constrain its own code unduly,it must also not require using special macros or calls to enter or leaveprocedures or assign pointers, and must not constrain the variety of C datastructures any more than absolutely necessary. It achieves all of thesegoals, at the expense of some complexity, some performance cost (mostly forgarbage collection), and some extra manual work required for each structuretype allocated by its allocator. The details appear in the <ahref="#Memory_management">Memory management</a> section below. <h4>Multi-instantiability</h4> <p>From many years of experience with the benefits of object-oriented design,we have learned that when the word "the" appears in a software design --"the" process scheduler, "the" memory manager, "the" output device, "the"interpreter, "the" stack -- it often flags an area in which the softwarewill have difficulty adapting to future needs. For this reason, Ghostscriptattempts to make every internal structure capable of existing in multipleinstances. For example, Ghostscript's memory manager is not a one-of-a-kindentity with global state and procedures: it is (or rather they are, sinceGhostscript has multiple memory managers, some of which have multipleinstances) objects with their own state and (virtual) procedures.Ghostscript's PostScript interpreter has no writable non-local data(necessary, but not sufficient, to allow multiple instances), and in thefuture will be extended to be completely reentrant and instantiable. Thedevice driver API is designed to make this easy for drivers as well. Thegraphics library is currently not completely reentrant or instantiable: wehope this will occur in the future. <h4>Late configuration binding</h4> <p>Ghostscript is designed to make configuration choices as late as possible,subject to simplicity and performance considerations. The major bindingtimes for such choices are compilation, linking, startup, and dynamic. <ul> <li>Compilation binds only CPU and compiler characteristics (including datatype size, presence of floating point hardware, and data alignment), andwhether the code will be used for production, debugging, or profiling. <li>Linking binds the choice of what features and device drivers will beincluded in the executable. (Work is underway to make the choice of driversdynamic.) <li>Startup binds essentially nothing. Almost every option and parameterthat can appear on the command line can also be changed dynamically. <li>The selection of output device, all parameters associated with thedevice, the selection of debugging printout and self-checking (in debuggingconfigurations), the macro-allocation of memory, and almost all otheroperational parameters are dynamic. </ul> <p>In addition, a number of major implementation decisions are made dynamicallydepending on the availability of resources. For example, Ghostscriptchooses between banded and non-banded rendering depending on memoryavailability. <h3><a name="Large_scale_structure"></a>Large-scale structure</h3> <p>At the largest design scale, Ghostscript consists of 4 layers. Layer Nis allowed to use the facilities of all layers M <= N. <ol> <li>The bottom layer is called the <a href="#Substrate">substrate</a>. Itincludes facilities like memory management, streams, fixed-point arithmetic,and low-level interfaces to the operating system. The substrate is writtenin C, with a little C++ and/or assembler code for some platforms. <li>The layer above the substrate is the graphics layer. It consists of twoseparate sub-parts. The graphics layer is written in C. <ul> <li>The <a href="#Graphics_library">graphics library</a> manages graphicsstate information for, and decomposes and renders 2-D images describedusing, a graphics model that is approximately the union of those ofPostScript, PDF, and PCL 5e/5c/XL. <li>The <a href="#Device_drivers">device drivers</a> are called by thegraphics library to produce actual output. The graphics library, and allhigher layers, call device driver procedures only through virtual functions. </ul> <li>The principal clients of the graphics layer are language interpreters.Ghostscript as distributed includes the <ahref="#PostScript_interpreter">PostScript interpreter</a>; there are alsointerpreters for PCL 5e, PCL 5c, and PCL XL, which are not currently freelyredistributable and are not included in the standard Ghostscript package.The PostScript interpreter is written partly in C and partly in PostScript. <li>The <a href="#PDF_interpreter">PDF interpreter</a> is actually a clientof the PostScript interpreter: it is written entirely in PostScript. </ol> <p>The most important interface in Ghostscript is the API between the graphicslibrary and the device drivers: new printers (and, to a lesser extent,window systems, displays, plotters, film recorders, and graphics fileformats) come on the scene frequently, and it must be possible to produceoutput for them with a minimum of effort and distruption. This API is theonly one that is extensively documented (see <ahref="Drivers.htm">Drivers.htm</a>) and kept stringently backward-compatiblethrough successive releases. <h3><a name="Object_oriented_constructs"></a>Object-oriented constructs</h3> <p>Ghostscript makes heavy use of object-oriented constructs, includinganalogues of classes, instances, subclassing, and class-associatedprocedures. Since Ghostscript is written in C, not C++, implementing theseconstructs requires following coding conventions. The <ahref="C-style.htm#Objects">"Objects"</a> section of the C style guideexplains these. <p>The memory manager API provides run-time type information about each class,but this information does not include anything about subclassing. See under<a href="#Structure_descriptors">Structure descriptors</a> below. <hr> <h2><a name="File_roadmap"></a>File roadmap</h2> <p>This section of the document provides a roadmap to all of the Ghostscriptsource files. <h3><a name="Substrate"></a>Substrate</h3> <h4>Runtime Context</h4> <dl><dt>The libctx provides pointers to memory, stdio, and various other runtime portablility services.<dd><a href="../src/gslibctx.h">src/gslibctx.h</a>,<a href="../src/gslibctx.c">src/gslibctx.c</a>.</dl> <h4>Memory manager</h4> <p>See <a href="#Memory_management">below</a>. <h4>Streams</h4> <dl> <dt>Framework, file and string streams:<dd><a href="../src/gsdsrc.c">src/gsdsrc.c</a>,<a href="../src/gsdsrc.h">src/gsdsrc.h</a>,<a href="../src/scommon.h">src/scommon.h</a>,<a href="../src/sfxboth.c">src/sfxboth.c</a>,<a href="../src/sfxfd.c">src/sfxfd.c</a>,<a href="../src/sfxstdio.c">src/sfxstdio.c</a>,<a href="../src/stream.h">src/stream.h</a>,<a href="../src/stream.c">src/stream.c</a>,<a href="../src/strimpl.h">src/strimpl.h</a>. <dt>Standard filters:<dd> <dl> <dt>CCITTFax:<dd><a href="../src/scf.h">src/scf.h</a>,<a href="../src/scfd.c">src/scfd.c</a>,<a href="../src/scfdgen.c">src/scfdgen.c</a>,<a href="../src/scfdtab.c">src/scfdtab.c</a>,<a href="../src/scfe.c">src/scfe.c</a>,<a href="../src/scfetab.c">src/scfetab.c</a>,<a href="../src/scfparam.c">src/scfparam.c</a>,<a href="../src/scfx.h">src/scfx.h</a>. <dt>DCT (JPEG):<dd><a href="../src/gsjconf.h">src/gsjconf.h</a>,<a href="../src/gsjmorec.h">src/gsjmorec.h</a>,<a href="../src/sdcparam.c">src/sdcparam.c</a>,<a href="../src/sdcparam.h">src/sdcparam.h</a>,<a href="../src/sdct.h">src/sdct.h</a>,<a href="../src/sdctc.c">src/sdctc.c</a>,<a href="../src/sdctd.c">src/sdctd.c</a>,<a href="../src/sdcte.c">src/sdcte.c</a>,<a href="../src/sddparam.c">src/sddparam.c</a>,<a href="../src/sdeparam.c">src/sdeparam.c</a>,<a href="../src/sjpeg.h">src/sjpeg.h</a>,<a href="../src/sjpegc.c">src/sjpegc.c</a>,<a href="../src/sjpegd.c">src/sjpegd.c</a>,<a href="../src/sjpege.c">src/sjpege.c</a>. <dt>JBIG2:<a href="../src/sjbig2.h">src/sjbig2.h</a>,<a href="../src/sjbig2.c">src/sjbig2.c</a>. <dt>JPX (JPEG 2000):<a href="../src/sjpx.h">src/sjpx.h</a>,<a href="../src/sjpx.c">src/sjpx.c</a>.<dt>Other compression/decompression:Lines 1–500 of 4686. Load more
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Information for Ghostscript developers</title> <link rel="stylesheet" type="text/css" href="gs.css" title="Ghostscript Style"> <!-- $Id: Develop.htm,v 1.159 2005/10/20 19:46:23 ray Exp $ --> </head> <body> <!-- [1.0 begin visible header] ============================================ --> <!-- [1.1 begin headline] ================================================== --> <h1>Information for Ghostscript developers</h1> <!-- [1.1 end headline] ==================================================== --> <!-- [1.2 begin table of contents] ========================================= --> <h2>Table of contents</h2> <blockquote><ul> <li><a href="#Introduction">Introduction</a> <li><a href="#Architecture">Architecture</a> <ul> <li><a href="#Design_goals">Design goals</a> <li><a href="#Design_principles">Design principles</a> <li><a href="#Large_scale_structure">Large-scale structure</a> <li><a href="#Object_oriented_constructs">Object-oriented constructs</a> </ul> <li><a href="#File_roadmap">File roadmap</a> <ul> <li><a href="#Substrate">Substrate</a> <li><a href="#Graphics_library">Graphics library</a> <ul> <li><a href="#Library_support">Support</a>, <a href="#Paths">Paths</a>, <a href="#Text">Text</a>, <a href="#Images">Images</a>, <a href="#Paint">Paint</a>, <a href="#Clipping">Clipping</a>, <a href="#Other_graphics">Other graphics</a>, <a href="#Driver_support">Driver support</a>, <a href="#FAPI_support_gx">Font API support</a> <a href="#Visual_trace">Visual Trace</a> </ul> <li><a href="#Device_drivers">Device drivers</a> <ul> <li><a href="#Internal_devices">Internal devices</a>, <a href="#PS_and_PDF_writers">PostScript and PDF writers</a>, <a href="#High_level_devices">Other high-level devices</a>, <a href="#Other_maintained_drivers">Other maintained drivers</a>, <a href="#Contributed_drivers">Contributed drivers</a> </ul> <li><a href="#PostScript_interpreter">PostScript interpreter</a> <ul> <li><a href="#Main_program">Main program</a>, <a href="#Data_structures">Data structures</a>, <a href="#Stacks">Stacks</a>, <a href="#Interpreter_loop">Interpreter loop</a>, <a href="#Scanning_parsing">Scanning/parsing</a>, <a href="#Standard_operators">Standard operators</a>, <a href="#Non_standard_operators">Non-standard operators</a>, <a href="#Interpreter_support">Interpreter support</a>, <a href="#PostScript_code">PostScript code</a> </ul> <li><a href="#PDF_interpreter">PDF interpreter</a> <li><a href="#PPD">PostScript Printer Description</a> <li><a href="#Build_process">Build process</a> <ul> <li><a href="#Makefile_structure">Makefile structure</a>, <a href="#dev_files">.dev files</a>, <a href="#Generators">Generators</a>, <a href="#Build_support">Support</a> </ul> <li><a href="#Utilities">Utilities</a> <ul> <li><a href="#Utilities_in_PostScript">Utilities in PostScript</a> <li><a href="#Utility_scripts">Utility scripts</a> </ul> </ul> <li><a href="#Memory_management">Memory management</a> <ul> <li><a href="#Memory_manager_architecture">Memory manager architecture</a> <ul> <li><a href="#Objects_vs_strings">Objects vs strings</a>, <a href="#Structure_descriptors">Structure descriptors</a>, <a href="#Garbage_collection">Garbage collection</a>, <a href="#Movability">Movability</a>, <a href="#Parent_hierarchy">Parent hierarchy</a>, <a href="#Allocator_API">Allocator API</a> </ul> <li><a href="#Freeing_storage">Freeing storage</a> <ul> <li><a href="#Explicit_freeing">Explicit freeing</a>, <a href="#Reference_counting">Reference counting</a>, <a href="#Real_garbage_collection">(Real) garbage collection</a> </ul> <li><a href="#Special_implementations">Special implementations</a> <ul> <li><a href="#malloc">malloc</a>, <a href="#Locking">Locking</a>, <a href="#Retrying">Retrying</a> </ul> <li><a href="#Standard_implementation">Standard implementation</a> <li><a href="#PostScript_interpreter_extensions">PostScript interpreter extensions</a> <ul> <li><a href="#Refs">Refs (PostScript "objects")</a>, <a href="#save_forgetsave_restore">save/.forgetsave/restore</a>, <a href="#Stable_allocators">Stable allocators</a>, <a href="#Interpreter_GC">Garbage collection</a> </ul> </ul> <li><a href="#Portability">Portability</a> <ul> <li><a href="#Structural">Structural</a> <ul> <li><a href="#CPU_and_compiler">CPU and compiler</a>, <a href="#Library_headers">Library headers</a>, <a href="#Cross_platform_APIs">Cross-platform APIs</a>, <a href="#Makefiles">Makefiles</a> </ul> <li><a href="#Coding">Coding</a> <ul> <li><a href="#Explicit_dependencies">Explicit dependencies</a>, <a href="#Implicit_dependencies">Implicit dependencies</a> </ul> <li><a href="#Platform_specific_code">Platform-specific code</a> </ul> <li><a href="#Adding_features_and_options">Adding features and options</a> <li><a href="#Troubleshooting">Troubleshooting</a> </ul></blockquote> <!-- [1.2 end table of contents] =========================================== --> <!-- [1.3 begin hint] ====================================================== --> <p>For other information, see the <a href="Readme.htm">Ghostscript overview</a> and the documentation related to <a href="Maintain.htm">maintaining Ghostscript</a>. <!-- [1.3 end hint] ======================================================== --> <hr> <!-- [1.0 end visible header] ============================================== --> <!-- [2.0 begin contents] ================================================== --> <h2><a name="Introduction"></a>Introduction</h2> <p> This document provides a wealth of information about Ghostscript's internals, primarily for developers actively working on Ghostscript. It is primarily <strong>descriptive</strong>, documenting the way things are; the companion <a href="C-style.htm">C style guide</a> is primarily <strong>prescriptive</strong>, documenting what developers should do when writing new code. <p> THIS FILE IS A WORK IN PROGRESS. MANY SECTIONS ARE PLACE-HOLDERS. <h2><a name="Architecture"></a>Architecture</h2> <h3><a name="Design_goals"></a>Design goals</h3> <p> Ghostscript has the following high-level design goals (not listed in order of importance): <ul> <li>Functionality <ul> <li>Ability to interpret the current PostScript and PDF languages, as defined (and occasionally, in the case of conflict, as implemented) by Adobe. <li>Ability to convert PostScript to and from PDF, comparable to Adobe products. <li>Ability to produce output for a wide range of resolutions (from TV-resolution displays to imagesetters) and color models (black and white, multilevel gray, bilevel or multi-level RGB and CMYK, 6- or 8-color inkjet printers, spot color). </ul> <li>Performance <ul> <li>Ability to render PostScript and PDF with commercial-quality performance (memory usage, speed, and output quality) on all platforms. <li>Specifically, ability to render PostScript effectively in embedded environments with constrained RAM, including the ability to put the code and supporting data in ROM. </ul> <li>Licensing <ul> <li>Licensing that supports both the Open Source / Free software communities and a commercial licensing business. <li>Freedom from licensing restrictions or fees imposed by third parties. </ul> <li>Other <ul> <li>Easy source portability to any platform (CPU, operating system, and development tools) that has an ANSI C compiler. <li>Support for writing new interpreters and new drivers with no change to any existing code; specifically, ability to support PCL 5e, PCL 5c, and PCL XL interpreters, and the ever-changing roster of inkjet printers. </ul> </ul> <p> These goals often conflict: part of Ghostscript's claim to quality is that the conflicts have been resolved well. <h3><a name="Design_principles"></a>Design principles</h3> <p> Part of what has kept Ghostscript healthy through many years of major code revisions and functional expansion is consistent and conscientious adherence to a set of design principles. We hope the following list captures the most important ones. <h4>Non-preemption</h4> <p> Ghostscript is designed to be used as a component. As such, it must share its environment with other components. Therefore, it must not require ownership of, or make decisions about, inherently shared resources. Specifically, it must not assume that it can "own" either the locus of control or the management of the address space. <p> Not owning control means that whenever Ghostscript passes control to its caller, it must do so in a way that doesn't constrain what the caller can do next. The caller must be able to call any other piece of software, wait for an external event, execute another task, etc., without having to worry about Ghostscript being in an unknown state. While this is easy to arrange in a multi-threaded environment (by running Ghostscript in a separate thread), multi-threading APIs are not well standardized at this time (December 2000), and may not be implemented efficiently, or at all, on some platforms. Therefore, Ghostscript must choose between only two options for interacting with its caller: to <em>return</em>, preserving its own state in data structures, or to <em>call back</em> through a caller-supplied procedure. Calling back constrains the client program unacceptably: the callback procedure only has the options of either returning, or aborting Ghostscript. In particular, if it wants (for whatever reason) to multi-task Ghostscript with another program, it cannot do so in general, especially if the other program also uses callback rather than suspension. Therefore, Ghostscript tries extremely hard to return, rather than calling back, for all caller interaction. In particular: <ul> <li>For callers that want to pass input to Ghostscript piece by piece, Ghostscript returns with an <b><tt>e_NeedInput</tt></b> code rather than using a callback. This allows the caller complete flexibility in its control structure for managing the source of input. (It might, for example, be generating the input dynamically.) <li>In the future, the same arrangement should be used for input from <b><tt>stdin</tt></b> and output to <b><tt>stdout</tt></b> and <b><tt>stderr</tt></b>. <li>Likewise, scheduling of Ghostscript's own threads (contexts), currently done with a callback, should be done with suspension. The Display Ghostscript project (GNU DGS) is working on this. </ul> <p> The one area where suspension is not feasible with Ghostscript's current architecture is device output. Device drivers are called from deep within the graphics library. (If Ghostscript were being redesigned from scratch, we might try to do this with suspension as well, or at least optional suspension.) <p> Not owning management of the address space means that even though Ghostscript supports garbage collection for its own data, it must not do any of the things that garbage collection schemes for C often require: it must not replace 'malloc' and 'free', must not require its clients to use its own allocator, must not rely on manipulating the read/write status of memory pages, must not require special compiler or run-time support (e.g., APIs for scanning the C stack), must not depend on the availability of multi-threading, and must not take possession of one of a limited number of timer interrupts. However, in order not to constrain its own code unduly, it must also not require using special macros or calls to enter or leave procedures or assign pointers, and must not constrain the variety of C data structures any more than absolutely necessary. It achieves all of these goals, at the expense of some complexity, some performance cost (mostly for garbage collection), and some extra manual work required for each structure type allocated by its allocator. The details appear in the <a href="#Memory_management">Memory management</a> section below. <h4>Multi-instantiability</h4> <p> From many years of experience with the benefits of object-oriented design, we have learned that when the word "the" appears in a software design -- "the" process scheduler, "the" memory manager, "the" output device, "the" interpreter, "the" stack -- it often flags an area in which the software will have difficulty adapting to future needs. For this reason, Ghostscript attempts to make every internal structure capable of existing in multiple instances. For example, Ghostscript's memory manager is not a one-of-a-kind entity with global state and procedures: it is (or rather they are, since Ghostscript has multiple memory managers, some of which have multiple instances) objects with their own state and (virtual) procedures. Ghostscript's PostScript interpreter has no writable non-local data (necessary, but not sufficient, to allow multiple instances), and in the future will be extended to be completely reentrant and instantiable. The device driver API is designed to make this easy for drivers as well. The graphics library is currently not completely reentrant or instantiable: we hope this will occur in the future. <h4>Late configuration binding</h4> <p> Ghostscript is designed to make configuration choices as late as possible, subject to simplicity and performance considerations. The major binding times for such choices are compilation, linking, startup, and dynamic. <ul> <li>Compilation binds only CPU and compiler characteristics (including data type size, presence of floating point hardware, and data alignment), and whether the code will be used for production, debugging, or profiling. <li>Linking binds the choice of what features and device drivers will be included in the executable. (Work is underway to make the choice of drivers dynamic.) <li>Startup binds essentially nothing. Almost every option and parameter that can appear on the command line can also be changed dynamically. <li>The selection of output device, all parameters associated with the device, the selection of debugging printout and self-checking (in debugging configurations), the macro-allocation of memory, and almost all other operational parameters are dynamic. </ul> <p> In addition, a number of major implementation decisions are made dynamically depending on the availability of resources. For example, Ghostscript chooses between banded and non-banded rendering depending on memory availability. <h3><a name="Large_scale_structure"></a>Large-scale structure</h3> <p> At the largest design scale, Ghostscript consists of 4 layers. Layer N is allowed to use the facilities of all layers M <= N. <ol> <li>The bottom layer is called the <a href="#Substrate">substrate</a>. It includes facilities like memory management, streams, fixed-point arithmetic, and low-level interfaces to the operating system. The substrate is written in C, with a little C++ and/or assembler code for some platforms. <li>The layer above the substrate is the graphics layer. It consists of two separate sub-parts. The graphics layer is written in C. <ul> <li>The <a href="#Graphics_library">graphics library</a> manages graphics state information for, and decomposes and renders 2-D images described using, a graphics model that is approximately the union of those of PostScript, PDF, and PCL 5e/5c/XL. <li>The <a href="#Device_drivers">device drivers</a> are called by the graphics library to produce actual output. The graphics library, and all higher layers, call device driver procedures only through virtual functions. </ul> <li>The principal clients of the graphics layer are language interpreters. Ghostscript as distributed includes the <a href="#PostScript_interpreter">PostScript interpreter</a>; there are also interpreters for PCL 5e, PCL 5c, and PCL XL, which are not currently freely redistributable and are not included in the standard Ghostscript package. The PostScript interpreter is written partly in C and partly in PostScript. <li>The <a href="#PDF_interpreter">PDF interpreter</a> is actually a client of the PostScript interpreter: it is written entirely in PostScript. </ol> <p> The most important interface in Ghostscript is the API between the graphics library and the device drivers: new printers (and, to a lesser extent, window systems, displays, plotters, film recorders, and graphics file formats) come on the scene frequently, and it must be possible to produce output for them with a minimum of effort and distruption. This API is the only one that is extensively documented (see <a href="Drivers.htm">Drivers.htm</a>) and kept stringently backward-compatible through successive releases. <h3><a name="Object_oriented_constructs"></a>Object-oriented constructs</h3> <p> Ghostscript makes heavy use of object-oriented constructs, including analogues of classes, instances, subclassing, and class-associated procedures. Since Ghostscript is written in C, not C++, implementing these constructs requires following coding conventions. The <a href="C-style.htm#Objects">"Objects"</a> section of the C style guide explains these. <p> The memory manager API provides run-time type information about each class, but this information does not include anything about subclassing. See under <a href="#Structure_descriptors">Structure descriptors</a> below. <hr> <h2><a name="File_roadmap"></a>File roadmap</h2> <p> This section of the document provides a roadmap to all of the Ghostscript source files. <h3><a name="Substrate"></a>Substrate</h3> <h4>Runtime Context</h4> <dl> <dt> The libctx provides pointers to memory, stdio, and various other runtime portablility services. <dd> <a href="../src/gslibctx.h">src/gslibctx.h</a>, <a href="../src/gslibctx.c">src/gslibctx.c</a>. </dl> <h4>Memory manager</h4> <p> See <a href="#Memory_management">below</a>. <h4>Streams</h4> <dl> <dt> Framework, file and string streams: <dd> <a href="../src/gsdsrc.c">src/gsdsrc.c</a>, <a href="../src/gsdsrc.h">src/gsdsrc.h</a>, <a href="../src/scommon.h">src/scommon.h</a>, <a href="../src/sfxboth.c">src/sfxboth.c</a>, <a href="../src/sfxfd.c">src/sfxfd.c</a>, <a href="../src/sfxstdio.c">src/sfxstdio.c</a>, <a href="../src/stream.h">src/stream.h</a>, <a href="../src/stream.c">src/stream.c</a>, <a href="../src/strimpl.h">src/strimpl.h</a>. <dt> Standard filters: <dd> <dl> <dt> CCITTFax: <dd> <a href="../src/scf.h">src/scf.h</a>, <a href="../src/scfd.c">src/scfd.c</a>, <a href="../src/scfdgen.c">src/scfdgen.c</a>, <a href="../src/scfdtab.c">src/scfdtab.c</a>, <a href="../src/scfe.c">src/scfe.c</a>, <a href="../src/scfetab.c">src/scfetab.c</a>, <a href="../src/scfparam.c">src/scfparam.c</a>, <a href="../src/scfx.h">src/scfx.h</a>. <dt> DCT (JPEG): <dd> <a href="../src/gsjconf.h">src/gsjconf.h</a>, <a href="../src/gsjmorec.h">src/gsjmorec.h</a>, <a href="../src/sdcparam.c">src/sdcparam.c</a>, <a href="../src/sdcparam.h">src/sdcparam.h</a>, <a href="../src/sdct.h">src/sdct.h</a>, <a href="../src/sdctc.c">src/sdctc.c</a>, <a href="../src/sdctd.c">src/sdctd.c</a>, <a href="../src/sdcte.c">src/sdcte.c</a>, <a href="../src/sddparam.c">src/sddparam.c</a>, <a href="../src/sdeparam.c">src/sdeparam.c</a>, <a href="../src/sjpeg.h">src/sjpeg.h</a>, <a href="../src/sjpegc.c">src/sjpegc.c</a>, <a href="../src/sjpegd.c">src/sjpegd.c</a>, <a href="../src/sjpege.c">src/sjpege.c</a>. <dt> JBIG2: <a href="../src/sjbig2.h">src/sjbig2.h</a>, <a href="../src/sjbig2.c">src/sjbig2.c</a>. <dt> JPX (JPEG 2000): <a href="../src/sjpx.h">src/sjpx.h</a>, <a href="../src/sjpx.c">src/sjpx.c</a>. <dt> Other compression/decompression: